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

📄 init.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 3 页
字号:
		close(fd);	}	message(LOG, "console=%s\n", console);}	static void fixup_argv(int argc, char **argv, char *new_argv0){	int len;	/* Fix up argv[0] to be certain we claim to be init */	len = strlen(argv[0]);	memset(argv[0], 0, len);	safe_strncpy(argv[0], new_argv0, len + 1);	/* Wipe argv[1]-argv[N] so they don't clutter the ps listing */	len = 1;	while (argc > len) {		memset(argv[len], 0, strlen(argv[len]));		len++;	}}/* 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(void){	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 */		system("/bin/mount -t proc proc /proc");		/* Try to turn on swap */		system("/sbin/swapon -a");		if (check_free_memory() < 1000)			goto goodnight;	} else		goto goodnight;	return;#endif  goodnight:	message(CONSOLE,			"\rSorry, your computer does not have enough memory.\n");	loop_forever();}static pid_t run(struct init_action *a){	struct stat sb;	int i, j, junk;	pid_t pid, pgrp, tmp_pid;	char *s, *tmpCmd, *cmd[INIT_BUFFS_SIZE], *cmdpath;	char buf[INIT_BUFFS_SIZE+6];    /* INIT_BUFFS_SIZE+strlen("exec ")+1 */	sigset_t nmask, omask;	char *environment[MAXENV+1] = {		termType,		"HOME=/",		"PATH=" _PATH_STDPATH,		"SHELL=" SHELL,		"USER=root",		NULL	};	static const char press_enter[] =#ifdef CUSTOMIZED_BANNER#include CUSTOMIZED_BANNER#endif		"\nPlease press Enter to activate this console. ";	/* inherit environment to the child, merging our values -andy */	for (i=0; environ[i]; i++) {		for (j=0; environment[j]; j++) {			s = strchr(environment[j], '=');			if (!strncmp(environ[i], environment[j], s - environment[j]))				break;		}		if (!environment[j]) {			environment[j++] = environ[i];			environment[j] = NULL;		}	}	/* Block sigchild while forking.  */	sigemptyset(&nmask);	sigaddset(&nmask, SIGCHLD);	sigprocmask(SIG_BLOCK, &nmask, &omask);	if ((pid = fork()) == 0) 	{		/* Clean up */		close(0);		close(1);		close(2);		sigprocmask(SIG_SETMASK, &omask, NULL);		/* Reset signal handlers that were set by the parent process */		signal(SIGUSR1, SIG_DFL);		signal(SIGUSR2, SIG_DFL);		signal(SIGINT,  SIG_DFL);		signal(SIGTERM, SIG_DFL);		signal(SIGHUP,  SIG_DFL);		signal(SIGCONT, SIG_DFL);		signal(SIGSTOP, SIG_DFL);		signal(SIGTSTP, SIG_DFL);		/* Create a new session and make ourself the process		 * group leader for non-interactive jobs */		if ((a->action & (RESPAWN))==0)			setsid();		/* Open the new terminal device */		if ((device_open(a->terminal, O_RDWR|O_NOCTTY)) < 0) {			if (stat(a->terminal, &sb) != 0) {				message(LOG | CONSOLE, "\rdevice '%s' does not exist.\n",						a->terminal);				_exit(1);			}			message(LOG | CONSOLE, "\rBummer, can't open %s\n", a->terminal);			_exit(1);		}		/* Non-interactive jobs should not get a controling tty */		if ((a->action & (RESPAWN))==0)			(void)ioctl(0, TIOCSCTTY, 0);		/* Make sure the terminal will act fairly normal for us */		set_term(0);		/* Setup stdout, stderr for the new process so		 * they point to the supplied terminal */		dup(0);		dup(0);		/* For interactive jobs, create a new session 		 * and become the process group leader */		if ((a->action & (RESPAWN)))			setsid();		/* If the init Action requires us to wait, then force the		 * supplied terminal to be the controlling tty. */		if (a->action & (SYSINIT|WAIT|CTRLALTDEL|SHUTDOWN|RESTART)) {			/* Now fork off another process to just hang around */			if ((pid = fork()) < 0) {				message(LOG | CONSOLE, "Can't fork!\n");				_exit(1);			}			if (pid > 0) {				/* We are the parent -- wait till the child is done */				signal(SIGINT, SIG_IGN);				signal(SIGTSTP, SIG_IGN);				signal(SIGQUIT, SIG_IGN);				signal(SIGCHLD, SIG_DFL);				/* Wait for child to exit */				while ((tmp_pid = waitpid(pid, &junk, 0)) != pid)					;				/* See if stealing the controlling tty back is necessary */				pgrp = tcgetpgrp(0);				if (pgrp != getpid())					_exit(0);				/* Use a temporary process to steal the controlling tty. */				if ((pid = fork()) < 0) {					message(LOG | CONSOLE, "\rCan't fork!\n");					_exit(1);				}       				if (pid == 0) {					setsid();					ioctl(0, TIOCSCTTY, 1);					_exit(0);				}       				while((tmp_pid = waitpid(pid, &junk, 0)) != pid) {					if (tmp_pid < 0 && errno == ECHILD)						break;				}				_exit(0);			}			/* Now fall though to actually execute things */		}		/* See if any special /bin/sh requiring characters are present */		if (strpbrk(a->command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) {			cmd[0] = SHELL;			cmd[1] = "-c";			strcat(strcpy(buf, "exec "), a->command);			cmd[2] = buf;			cmd[3] = NULL;		} else {			/* Convert command (char*) into cmd (char**, one word per string) */			strcpy(buf, a->command);			s = buf;			for (tmpCmd = buf, i = 0;					(tmpCmd = strsep(&s, " \t")) != NULL;) {				if (*tmpCmd != '\0') {					cmd[i] = tmpCmd;					i++;				}			}			cmd[i] = NULL;		}		cmdpath = cmd[0];		/*		   Interactive shells want to see a dash in argv[0].  This		   typically is handled by login, argv will be setup this 		   way if a dash appears at the front of the command path 		   (like "-/bin/sh").		 */		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 (a->action & ASKFIRST) {			/*			 * 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, terminal %s)\n",					cmdpath, getpid(), a->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(), a->terminal, cmdpath);#if defined CONFIG_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, "\rBummer, could not run '%s': %s\n", cmdpath,				strerror(errno));		_exit(-1);	}	sigprocmask(SIG_SETMASK, &omask, NULL);	return pid;}static int waitfor(struct init_action *a){	int pid; 	int status, wpid;	pid = run(a);	while (1) {		wpid = wait(&status);		if (wpid > 0 && wpid != pid) {			continue;		}		if (wpid == pid)			break;	}	return wpid;}/* Run all commands of a particular type */static void run_actions(int action){	struct init_action *a, *tmp;	for (a = init_action_list; a; a = tmp) {		tmp = a->next;		if (a->action == action) {			if (a->action & (SYSINIT|WAIT|CTRLALTDEL|SHUTDOWN|RESTART)) {				waitfor(a);				delete_init_action(a);			} else if (a->action & ONCE) {				run(a);				delete_init_action(a);			} else if (a->action & (RESPAWN|ASKFIRST)) {				/* Only run stuff with pid==0.  If they have				 * a pid, that means it is still running */				if (a->pid == 0) {					a->pid = run(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);	sigaddset(&block_signals, SIGCONT);	sigaddset(&block_signals, SIGSTOP);	sigaddset(&block_signals, SIGTSTP);	sigprocmask(SIG_BLOCK, &block_signals, NULL);	/* Allow Ctrl-Alt-Del to reboot system. */	init_reboot(RB_ENABLE_CAD);	message(CONSOLE|LOG, "\n\rThe system is going down NOW !!\n");	sync();	/* Send signals to every process _except_ pid 1 */	message(CONSOLE|LOG, "\rSending SIGTERM to all processes.\n");	kill(-1, SIGTERM);	sleep(1);	sync();	message(CONSOLE|LOG, "\rSending 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 exec_signal(int sig){	struct init_action *a, *tmp;	sigset_t unblock_signals;		for (a = init_action_list; a; a = tmp) {		tmp = a->next;		if (a->action & RESTART) {			shutdown_system();			/* unblock all signals, blocked in shutdown_system() */			sigemptyset(&unblock_signals);			sigaddset(&unblock_signals, SIGHUP);			sigaddset(&unblock_signals, SIGCHLD);			sigaddset(&unblock_signals, SIGUSR1);			sigaddset(&unblock_signals, SIGUSR2);			sigaddset(&unblock_signals, SIGINT);			sigaddset(&unblock_signals, SIGTERM);			sigaddset(&unblock_signals, SIGCONT);			sigaddset(&unblock_signals, SIGSTOP);			sigaddset(&unblock_signals, SIGTSTP);			sigprocmask(SIG_UNBLOCK, &unblock_signals, NULL);			message(CONSOLE|LOG, "\rTrying to re-exec %s\n", a->command);			execl(a->command, a->command, NULL);				message(CONSOLE|LOG, "\rexec of '%s' failed: %s\n", 				a->command, sys_errlist[errno]);			sync();			sleep(2);			init_reboot(RB_HALT_SYSTEM);			loop_forever();		}	}

⌨️ 快捷键说明

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