⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 init.c

📁 为samsung2410 ARM移植的busybox工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
		if (*cmdpath == '-') {			/* skip over the dash */			++cmdpath;			/* find the last component in the command pathname */			s = get_last_path_component(cmdpath);			/* make a new argv[0] */			if ((cmd[0] = malloc(strlen(s)+2)) == NULL) {				message(LOG | CONSOLE, "malloc failed");				cmd[0] = cmdpath;			} else {				cmd[0][0] = '-';				strcpy(cmd[0]+1, s);			}		}		if (get_enter == TRUE) {			/*			 * Save memory by not exec-ing anything large (like a shell)			 * before the user wants it. This is critical if swap is not			 * enabled and the system has low memory. Generally this will			 * be run on the second virtual console, and the first will			 * be allowed to start a shell or whatever an init script 			 * specifies.			 */			messageND(LOG, "Waiting for enter to start '%s' (pid %d, console %s)\n",					cmd[0], getpid(), terminal);			write(fileno(stdout), press_enter, sizeof(press_enter) - 1);			getc(stdin);		}		/* Log the process name and args */		messageND(LOG, "Starting pid %d, console %s: '%s'\n",				getpid(), terminal, command);#if defined BB_FEATURE_INIT_COREDUMPS		if (stat (CORE_ENABLE_FLAG_FILE, &sb) == 0) {			struct rlimit limit;			limit.rlim_cur = RLIM_INFINITY;			limit.rlim_max = RLIM_INFINITY;			setrlimit(RLIMIT_CORE, &limit);		}#endif		/* Now run it.  The new program will take over this PID, 		 * so nothing further in init.c should be run. */		execve(cmdpath, cmd, environment);		/* We're still here?  Some error happened. */		message(LOG | CONSOLE, "Bummer, could not run '%s': %s\n", cmdpath,				strerror(errno));		exit(-1);	}	return pid;}static int waitfor(char *command, char *terminal, int get_enter){	int status, wpid;	int pid = run(command, terminal, get_enter);	while (1) {		wpid = wait(&status);		if (wpid > 0 && wpid != pid) {			continue;		}		if (wpid == pid)			break;	}	return wpid;}/* Make sure there is enough memory to do something useful. * * Calls "swapon -a" if needed so be sure /etc/fstab is present... */static void check_memory(){	struct stat statBuf;	if (check_free_memory() > 1000)		return;#if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__)	if (stat("/etc/fstab", &statBuf) == 0) {		/* swapon -a requires /proc typically */		waitfor("mount proc /proc -t proc", console, FALSE);		/* Try to turn on swap */		waitfor("swapon -a", console, FALSE);		if (check_free_memory() < 1000)			goto goodnight;	} else		goto goodnight;	return;#endif  goodnight:	message(CONSOLE,			"Sorry, your computer does not have enough memory.\n");	loop_forever();}/* Run all commands to be run right before halt/reboot */static void run_actions(initActionEnum action){	initAction *a, *tmp;	for (a = initActionList; a; a = tmp) {		tmp = a->nextPtr;		if (a->action == action) {			waitfor(a->process, a->console, FALSE);			delete_initAction(a);		}	}}#ifndef DEBUG_INITstatic void shutdown_system(void){	sigset_t block_signals;	/* first disable all our signals */	sigemptyset(&block_signals);	sigaddset(&block_signals, SIGHUP);	sigaddset(&block_signals, SIGCHLD);	sigaddset(&block_signals, SIGUSR1);	sigaddset(&block_signals, SIGUSR2);	sigaddset(&block_signals, SIGINT);	sigaddset(&block_signals, SIGTERM);	sigprocmask(SIG_BLOCK, &block_signals, NULL);	/* Allow Ctrl-Alt-Del to reboot system. */	init_reboot(RB_ENABLE_CAD);	message(CONSOLE|LOG, "\nThe system is going down NOW !!\n");	sync();	/* Send signals to every process _except_ pid 1 */	message(CONSOLE|LOG, "Sending SIGTERM to all processes.\n");	kill(-1, SIGTERM);	sleep(1);	sync();	message(CONSOLE|LOG, "Sending SIGKILL to all processes.\n");	kill(-1, SIGKILL);	sleep(1);	/* run everything to be run at "shutdown" */	run_actions(SHUTDOWN);	sync();	if (kernelVersion > 0 && kernelVersion <= KERNEL_VERSION(2,2,11)) {		/* bdflush, kupdate not needed for kernels >2.2.11 */		bdflush(1, 0);		sync();	}}static void halt_signal(int sig){	shutdown_system();	message(CONSOLE|LOG,#if #cpu(s390)			/* Seems the s390 console is Wierd(tm). */			"The system is halted. You may reboot now.\n",#else			/* secondConsole is NULL for a serial console */			"The system is halted. Press %s or turn off power\n",			(secondConsole == NULL)? "Reset" : "CTRL-ALT-DEL"#endif		   );	sync();	/* allow time for last message to reach serial console */	sleep(2);	if (sig == SIGUSR2 && kernelVersion >= KERNEL_VERSION(2,2,0))		init_reboot(RB_POWER_OFF);	else		init_reboot(RB_HALT_SYSTEM);	loop_forever();}static void reboot_signal(int sig){	shutdown_system();	message(CONSOLE|LOG, "Please stand by while rebooting the system.\n");	sync();	/* allow time for last message to reach serial console */	sleep(2);	init_reboot(RB_AUTOBOOT);	loop_forever();}static void ctrlaltdel_signal(int sig){	run_actions(CTRLALTDEL);}#endif							/* ! DEBUG_INIT */static void new_initAction(initActionEnum action, char *process, char *cons){	initAction *newAction;	if (*cons == '\0')		cons = console;	/* If BusyBox detects that a serial console is in use, 	 * then entries not refering to the console or null devices will _not_ be run.	 * The exception to this rule is the null device.	 */	if (secondConsole == NULL && strcmp(cons, console)		&& strcmp(cons, "/dev/null"))		return;	if (strcmp(cons, "/dev/null") == 0 && action == ASKFIRST)		return;	newAction = calloc((size_t) (1), sizeof(initAction));	if (!newAction) {		message(LOG | CONSOLE, "Memory allocation failure\n");		loop_forever();	}	newAction->nextPtr = initActionList;	initActionList = newAction;	safe_strncpy(newAction->process, process, 255);	newAction->action = action;	safe_strncpy(newAction->console, cons, 255);	newAction->pid = 0;//    message(LOG|CONSOLE, "process='%s' action='%d' console='%s'\n",//      newAction->process, newAction->action, newAction->console);}static void delete_initAction(initAction * action){	initAction *a, *b = NULL;	for (a = initActionList; a; b = a, a = a->nextPtr) {		if (a == action) {			if (b == NULL) {				initActionList = a->nextPtr;			} else {				b->nextPtr = a->nextPtr;			}			free(a);			break;		}	}}/* NOTE that if BB_FEATURE_USE_INITTAB is NOT defined, * then parse_inittab() simply adds in some default * actions(i.e., runs INIT_SCRIPT and then starts a pair  * of "askfirst" shells).  If BB_FEATURE_USE_INITTAB  * _is_ defined, but /etc/inittab is missing, this  * results in the same set of default behaviors. * */static void parse_inittab(void){#ifdef BB_FEATURE_USE_INITTAB	FILE *file;	char buf[256], lineAsRead[256], tmpConsole[256];	char *id, *runlev, *action, *process, *eol;	const struct initActionType *a = actions;	int foundIt;	file = fopen(INITTAB, "r");	if (file == NULL) {		/* No inittab file -- set up some default behavior */#endif		/* Reboot on Ctrl-Alt-Del */		new_initAction(CTRLALTDEL, "/sbin/reboot", console);#if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__)		/* Swapoff on halt/reboot */		new_initAction(SHUTDOWN, "/sbin/swapoff -a", console);#endif		/* Umount all filesystems on halt/reboot */		new_initAction(SHUTDOWN, "/bin/umount -a -r", console);		/* Askfirst shell on tty1 */		new_initAction(ASKFIRST, LOGIN_SHELL, console);		/* Askfirst shell on tty2 */		if (secondConsole != NULL)			new_initAction(ASKFIRST, LOGIN_SHELL, secondConsole);		/* Askfirst shell on tty3 */		if (thirdConsole != NULL)			new_initAction(ASKFIRST, LOGIN_SHELL, thirdConsole);		/* Askfirst shell on tty4 */		if (fourthConsole != NULL)			new_initAction(ASKFIRST, LOGIN_SHELL, fourthConsole);		/* sysinit */		new_initAction(SYSINIT, INIT_SCRIPT, console);		return;#ifdef BB_FEATURE_USE_INITTAB	}	while (fgets(buf, 255, file) != NULL) {		foundIt = FALSE;		/* Skip leading spaces */		for (id = buf; *id == ' ' || *id == '\t'; id++);		/* Skip the line if it's a comment */		if (*id == '#' || *id == '\n')			continue;		/* Trim the trailing \n */		eol = strrchr(id, '\n');		if (eol != NULL)			*eol = '\0';		/* Keep a copy around for posterity's sake (and error msgs) */		strcpy(lineAsRead, buf);		/* Separate the ID field from the runlevels */		runlev = strchr(id, ':');		if (runlev == NULL || *(runlev + 1) == '\0') {			message(LOG | CONSOLE, "Bad inittab entry: %s\n", lineAsRead);			continue;		} else {			*runlev = '\0';			++runlev;		}		/* Separate the runlevels from the action */		action = strchr(runlev, ':');		if (action == NULL || *(action + 1) == '\0') {			message(LOG | CONSOLE, "Bad inittab entry: %s\n", lineAsRead);			continue;		} else {			*action = '\0';			++action;		}		/* Separate the action from the process */		process = strchr(action, ':');		if (process == NULL || *(process + 1) == '\0') {			message(LOG | CONSOLE, "Bad inittab entry: %s\n", lineAsRead);			continue;		} else {			*process = '\0';			++process;		}		/* Ok, now process it */		a = actions;		while (a->name != 0) {			if (strcmp(a->name, action) == 0) {				if (*id != '\0') {					strcpy(tmpConsole, "/dev/");					strncat(tmpConsole, id, 200);					id = tmpConsole;				}				new_initAction(a->action, process, id);				foundIt = TRUE;			}			a++;		}		if (foundIt == TRUE)			continue;		else {			/* Choke on an unknown action */			message(LOG | CONSOLE, "Bad inittab entry: %s\n", lineAsRead);		}	}	return;#endif /* BB_FEATURE_USE_INITTAB */}extern int init_main(int argc, char **argv){	initAction *a, *tmp;	pid_t wpid;	int status;#ifndef DEBUG_INIT	/* Expect to be invoked as init with PID=1 or be invoked as linuxrc */	if (getpid() != 1#ifdef BB_FEATURE_LINUXRC			&& strstr(applet_name, "linuxrc") == NULL#endif	                  )	{			show_usage();	}	/* Set up sig handlers  -- be sure to	 * clear all of these in run() */	signal(SIGUSR1, halt_signal);	signal(SIGUSR2, halt_signal);	signal(SIGINT, ctrlaltdel_signal);	signal(SIGTERM, reboot_signal);	/* Turn off rebooting via CTL-ALT-DEL -- we get a 	 * SIGINT on CAD so we can shut things down gracefully... */	init_reboot(RB_DISABLE_CAD);#endif	/* Figure out what kernel this is running */	kernelVersion = get_kernel_revision();	/* Close whatever files are open, and reset the console. */	close(0);	close(1);	close(2);	/* Figure out where the default console should be */	console_init();	set_term(0);	chdir("/");	setsid();	/* Make sure PATH is set to something sane */	putenv("PATH="_PATH_STDPATH);	/* Hello world */	message(MAYBE_CONSOLE|LOG, "init started:  %s\n", full_version);	/* Make sure there is enough memory to do something useful. */	check_memory();	/* Check if we are supposed to be in single user mode */	if (argc > 1 && (!strcmp(argv[1], "single") ||					 !strcmp(argv[1], "-s") || !strcmp(argv[1], "1"))) {		/* Ask first then start a shell on tty2-4 */		if (secondConsole != NULL)			new_initAction(ASKFIRST, LOGIN_SHELL, secondConsole);		if (thirdConsole != NULL)			new_initAction(ASKFIRST, LOGIN_SHELL, thirdConsole);		if (fourthConsole != NULL)			new_initAction(ASKFIRST, LOGIN_SHELL, fourthConsole);		/* Start a shell on tty1 */		new_initAction(RESPAWN, LOGIN_SHELL, console);	} else {		/* Not in single user mode -- see what inittab says */		/* NOTE that if BB_FEATURE_USE_INITTAB is NOT defined,		 * then parse_inittab() simply adds in some default		 * actions(i.e., runs INIT_SCRIPT and then starts a pair 		 * of "askfirst" shells */		parse_inittab();	}	/* Make the command line just say "init"  -- thats all, nothing else */	fixup_argv(argc, argv, "init");	/* Now run everything that needs to be run */	/* First run the sysinit command */	run_actions(SYSINIT);	/* Next run anything that wants to block */	run_actions(WAIT);	/* Next run anything to be run only once */	for (a = initActionList; a; a = tmp) {		tmp = a->nextPtr;		if (a->action == ONCE) {			run(a->process, a->console, FALSE);			/* Now remove the "once" entry from the list */			delete_initAction(a);		}	}	/* If there is nothing else to do, stop */	if (initActionList == NULL) {		message(LOG | CONSOLE,				"No more tasks for init -- sleeping forever.\n");		loop_forever();	}	/* Now run the looping stuff for the rest of forever */	while (1) {		for (a = initActionList; a; a = a->nextPtr) {			/* Only run stuff with pid==0.  If they have			 * a pid, that means they are still running */			if (a->pid == 0) {				switch (a->action) {				case RESPAWN:					/* run the respawn stuff */					a->pid = run(a->process, a->console, FALSE);					break;				case ASKFIRST:					/* run the askfirst stuff */					a->pid = run(a->process, a->console, TRUE);					break;					/* silence the compiler's incessant whining */				default:					break;				}			}		}		/* Wait for a child process to exit */		wpid = wait(&status);		if (wpid > 0) {			/* Find out who died and clean up their corpse */			for (a = initActionList; a; a = a->nextPtr) {				if (a->pid == wpid) {					a->pid = 0;					message(LOG,							"Process '%s' (pid %d) exited.  Scheduling it for restart.\n",							a->process, wpid);				}			}		}		sleep(1);	}}/*Local Variables:c-file-style: "linux"c-basic-offset: 4tab-width: 4End:*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -