arch/um/os-Linux/main.c

Source file repositories/reference/linux-study-clean/arch/um/os-Linux/main.c

File Facts

System
Linux kernel
Corpus path
arch/um/os-Linux/main.c
Extension
.c
Size
6341 bytes
Lines
266
Domain
Architecture Layer
Bucket
arch/um
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (setrlimit(RLIMIT_STACK, &lim) < 0) {
			perror("setrlimit");
			exit(1);
		}
	}
}

static void last_ditch_exit(int sig)
{
	uml_cleanup();
	exit(1);
}

static void __init install_fatal_handler(int sig)
{
	struct sigaction action;

	/* All signals are enabled in this handler ... */
	sigemptyset(&action.sa_mask);

	/*
	 * ... including the signal being handled, plus we want the
	 * handler reset to the default behavior, so that if an exit
	 * handler is hanging for some reason, the UML will just die
	 * after this signal is sent a second time.
	 */
	action.sa_flags = SA_RESETHAND | SA_NODEFER;
	action.sa_restorer = NULL;
	action.sa_handler = last_ditch_exit;
	if (sigaction(sig, &action, NULL) < 0) {
		os_warn("failed to install handler for signal %d "
			"- errno = %d\n", sig, errno);
		exit(1);
	}
}

#define UML_LIB_PATH	":" OS_LIB_PATH "/uml"

static void __init setup_env_path(void)
{
	char *new_path = NULL;
	char *old_path = NULL;
	int path_len = 0;

	old_path = getenv("PATH");
	/*
	 * if no PATH variable is set or it has an empty value
	 * just use the default + /usr/lib/uml
	 */
	if (!old_path || (path_len = strlen(old_path)) == 0) {
		if (putenv("PATH=:/bin:/usr/bin/" UML_LIB_PATH))
			perror("couldn't putenv");
		return;
	}

	/* append /usr/lib/uml to the existing path */
	path_len += strlen("PATH=" UML_LIB_PATH) + 1;
	new_path = malloc(path_len);
	if (!new_path) {
		perror("couldn't malloc to set a new PATH");
		return;
	}
	snprintf(new_path, path_len, "PATH=%s" UML_LIB_PATH, old_path);
	if (putenv(new_path)) {
		perror("couldn't putenv to set a new PATH");
		free(new_path);
	}
}

int __init main(int argc, char **argv, char **envp)
{
	char **new_argv;
	int ret, i, err;

	/* Disable randomization and re-exec if it was changed successfully */
	ret = personality(PER_LINUX | ADDR_NO_RANDOMIZE);
	if (ret >= 0 && (ret & (PER_LINUX | ADDR_NO_RANDOMIZE)) !=
			 (PER_LINUX | ADDR_NO_RANDOMIZE)) {
		char buf[4096] = {};
		ssize_t ret;

		ret = readlink("/proc/self/exe", buf, sizeof(buf));
		if (ret < 0 || ret >= sizeof(buf)) {
			perror("readlink failure");
			exit(1);
		}
		execve(buf, argv, envp);
	}

	set_stklim();

Annotation

Implementation Notes