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

📄 simpleinit.c

📁 Util-linux 软件包包含许多工具。其中比较重要的是加载、卸载、格式化、分区和管理硬盘驱动器
💻 C
📖 第 1 页 / 共 3 页
字号:
    {	err (_ ("lstat of path failed\n") );	return 1;    }    if ( S_ISLNK (statbuf.st_mode) )    {	if (stat (path, &statbuf) != 0)	{	    if ( (errno == ENOENT) && ignore_dangling_symlink ) return 0;	    err (_ ("stat of path failed\n") );	    return 1;	}    }    if ( !( statbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH) ) ) return 0;    if ( !S_ISDIR (statbuf.st_mode) ) return (*func) (path);    if ( ( dp = opendir (path) ) == NULL )    {	err (_ ("open of directory failed\n") );	return 1;    }    while ( ( de = readdir (dp) ) != NULL )    {	int retval;	char newpath[PATH_SIZE];	if (de->d_name[0] == '.') continue;	retval = sprintf (newpath, "%s/%s", path, de->d_name);	if (newpath[retval - 1] == '~') continue;  /*  Common mistake  */	if ( ( retval = process_path (newpath, func, 1) ) ) return retval;    }    closedir (dp);    return 0;}   /*  End Function process_path  */static int preload_file (const char *path){    int fd;    char ch;    if ( ( fd = open (path, O_RDONLY, 0) ) < 0) return 0;    while (read (fd, &ch, 1) == 1) lseek (fd, 1024, SEEK_CUR);    close (fd);    return 0;}   /*  End Function preload_file  */static int run_file (const char *path){    const char *ptr;    if ( ( ptr = strrchr ( (char *) path, '/' ) ) == NULL ) ptr = path;    else ++ptr;    return (run_command (path, ptr, 0) == SIG_FAILED) ? 1 : 0;}   /*  End Function run_file  */static void spawn (int i){	pid_t pid;	int j;	signed long ds_taken;	struct timeval ct;	if (inittab[i].toks[0] == NULL) return;	/*  Check if respawning too fast  */	gettimeofday (&ct, NULL);	ds_taken = ct.tv_sec - inittab[i].last_start.tv_sec;	/* On the first iteration last_start==0 and ds_taken	   may be very large. Avoid overflow. -- Denis Vlasenko */	if (ds_taken > 10000)		ds_taken = 10000;	ds_taken *= 10;	ds_taken += (ct.tv_usec - inittab[i].last_start.tv_usec) / 100000;	if (ds_taken < 1)		ds_taken = 1;	inittab[i].rate = (9 * inittab[i].rate + 1000 / ds_taken) / 10;	if (inittab[i].rate > MAX_RESPAWN_RATE) {		char txt[256];		inittab[i].toks[0] = NULL;		inittab[i].pid = -1;		inittab[i].rate = 0;		sprintf (txt,"respawning: \"%s\" too fast: quenching entry\n",			 inittab[i].tty);		err (_(txt));		return;	}	if((pid = fork()) < 0) {		inittab[i].pid = -1;		err(_("fork failed\n"));		return;	}	if(pid) {		/* this is the parent */		inittab[i].pid = pid;		inittab[i].last_start = ct;		sched_yield ();		return;	} else {		/* this is the child */		char term[40];#ifdef SET_TZ		char tz[CMDSIZ];#endif		char *env[3];				setsid();		for(j = 0; j < getdtablesize(); j++)			(void) close(j);		(void) sprintf(term, "TERM=%s", inittab[i].termcap);		env[0] = term;		env[1] = (char *)0;#ifdef SET_TZ		(void) sprintf(tz, "TZ=%s", tzone);		env[1] = tz;#endif		env[2] = (char *)0;		execve(inittab[i].toks[0], inittab[i].toks, env);		err(_("exec failed\n"));		sleep(5);		_exit(1);	}}static void read_inittab (void){	FILE *f;	char buf[CMDSIZ];	int i,j,k;	int has_prog = 0;	char *ptr, *getty;	char prog[PATH_SIZE];#ifdef SPECIAL_CONSOLE_TERM	char tty[50];	struct stat stb;#endif	char *termenv;		termenv = getenv("TERM");	/* set by kernel */	/* termenv = "vt100"; */				if(!(f = fopen(_PATH_INITTAB, "r"))) {		err(_("cannot open inittab\n"));		return;	}	prog[0] = '\0';	i = 0;	while(!feof(f) && i < NUMCMD - 2) {		if(fgets(buf, CMDSIZ - 1, f) == 0) break;		buf[CMDSIZ-1] = 0;		for(k = 0; k < CMDSIZ && buf[k]; k++) {			if ((buf[k] == '#') || (buf[k] == '\n')) { 				buf[k] = 0; break; 			}		}		if(buf[0] == 0 || buf[0] == '\n') continue;		ptr = strchr (buf, '=');		if (ptr) {			ptr++;			if ( !strncmp (buf, "bootprog", 8) ) {				while ( isspace (*ptr) ) ++ptr;				strcpy (prog, ptr);				has_prog = 1;				continue;			}			if ( !strncmp (buf, "fileprefix", 10) ) {				while ( isspace (*ptr) ) ++ptr;				strcpy (script_prefix, ptr);				continue;			}			if ( !strncmp (buf, "PATH", 4) ) {				while ( isspace (*ptr) ) ++ptr;				setenv ("PATH", ptr, 1);				continue;			}			if ( !strncmp (buf, "INIT_PATH", 9) ) {				while ( isspace (*ptr) ) ++ptr;				strcpy (init_path, ptr);				continue;			}			if ( !strncmp (buf, "finalprog", 8) ) {				while ( isspace (*ptr) ) ++ptr;				strcpy (final_prog, ptr);				continue;			}		}					(void) strcpy(inittab[i].line, buf);		(void) strtok(inittab[i].line, ":");		xstrncpy(inittab[i].tty, inittab[i].line, 10);		xstrncpy(inittab[i].termcap, strtok((char *)0, ":"), 30);		getty = strtok((char *)0, ":");		(void) strtok(getty, " \t\n");		inittab[i].toks[0] = getty;		j = 1;		while((ptr = strtok((char *)0, " \t\n")))			inittab[i].toks[j++] = ptr;		inittab[i].toks[j] = (char *)0;#ifdef SPECIAL_CONSOLE_TERM		/* special-case termcap for the console ttys */		(void) sprintf(tty, "/dev/%s", inittab[i].tty);		if(!termenv || stat(tty, &stb) < 0) {			err(_("no TERM or cannot stat tty\n"));		} else {			/* is it a console tty? */			if(major(stb.st_rdev) == 4 && minor(stb.st_rdev) < 64)				xstrncpy(inittab[i].termcap, termenv, 30);		}#endif		i++;	}	fclose(f);	numcmd = i;	if (has_prog) {		int len;		char path[PATH_SIZE];		strcpy (path, script_prefix);		strcat (path, prog);		len = strlen (path);		if (path[len - 1] == '/') path[len - 1] = '\0';		if (access (path, R_OK | X_OK) == 0)			strcpy (boot_prog, path);	}}   /*  End Function read_inittab  */static void sighup_handler (int sig){	int i,j;	int oldnum;	struct initline	savetab[NUMCMD];	int had_already;	signal (SIGHUP, SIG_IGN);	memcpy(savetab, inittab, NUMCMD * sizeof(struct initline));	oldnum = numcmd;			read_inittab ();		for(i = 0; i < numcmd; i++) {		had_already = 0;		for(j = 0; j < oldnum; j++) {			if(!strcmp(savetab[j].tty, inittab[i].tty)) {				had_already = 1;				if((inittab[i].pid = savetab[j].pid) < 0)					spawn(i);			}		}		if (!had_already) spawn (i);	}	signal (SIGHUP, sighup_handler);}   /*  End Function sighup_handler  */static void sigtstp_handler (int sig){    stopped = ~stopped;    if (!stopped) sighup_handler (sig);}   /*  End Function sigtstp_handler  */static void sigterm_handler (int sig){    int i;    for (i = 0; i < numcmd; i++)	if (inittab[i].pid > 0) kill (inittab[i].pid, SIGTERM);}   /*  End Function sigterm_handler  */static void sigint_handler (int sig){    pid_t pid;    caught_sigint = 1;    kill (rc_child, SIGKILL);    if (no_reboot) _exit (1) /*kill (0, SIGKILL)*/;    sync ();    sync ();    pid = fork ();    if (pid > 0) return;  /*  Parent                     */    if (pid == 0) 	  /*  Child: reboot properly...  */	execl (_PATH_REBOOT, _PATH_REBOOT, (char *) 0);    /* fork or exec failed, try the hard way... */    my_reboot (LINUX_REBOOT_CMD_RESTART);}   /*  End Function sigint_handler  */static void sigchild_handler (int sig){    if (!do_longjmp) return;    siglongjmp (jmp_env, 1);}static void sigquit_handler (int sig){    execl (_PATH_REBOOT, _PATH_REBOOT, NULL); /*  It knows pid=1 must sleep  */}#ifdef SET_TZstatic void set_tz (void){	FILE *f;	int len;	if((f=fopen(TZFILE, "r")) == (FILE *)NULL) return;	fgets(tzone, CMDSIZ-2, f);	fclose(f);	if((len=strlen(tzone)) < 2) return;	tzone[len-1] = 0; /* get rid of the '\n' */	setenv("TZ", tzone, 0);}#endifstatic void write_wtmp (void){    int fd, lf;    struct utmp ut;        memset((char *)&ut, 0, sizeof(ut));    strcpy(ut.ut_line, "~");    memset(ut.ut_name, 0, sizeof(ut.ut_name));    time(&ut.ut_time);    ut.ut_type = BOOT_TIME;    if ((lf = open(_PATH_WTMPLOCK, O_CREAT|O_WRONLY, 0660)) >= 0) {	flock(lf, LOCK_EX|LOCK_NB); /* make sure init won't hang */	if((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND)) >= 0) {	    write(fd, (char *)&ut, sizeof(ut));	    close(fd);	}	flock(lf, LOCK_UN|LOCK_NB);	close(lf);    }}   /*  End Function write_wtmp  */struct needer_struct{    struct needer_struct *next;    pid_t pid;};struct service_struct{    struct service_struct *prev, *next;    /*  Script services chain         */    struct needer_struct *needers;         /*  Needers waiting for service   */    struct script_struct *attempting_providers;    int failed;                /*  TRUE if attempting provider failed badly  */    char name[1];};struct script_struct{    pid_t pid;    struct script_struct *prev, *next;              /*  For the list         */    struct service_struct *first_service, *last_service; /*First is true name*/    struct script_struct *next_attempting_provider; /*  Provider chain       */};struct list_head{    struct script_struct *first, *last;    unsigned int num_entries;};static struct list_head available_list = {NULL, NULL, 0};static struct list_head starting_list = {NULL, NULL, 0};static struct service_struct *unavailable_services = NULL;  /*  For needers  */static int num_needers = 0;static int process_pidstat (pid_t pid, int status);static void process_command (const struct command_struct *command);static struct service_struct *find_service_in_list (const char *name,						    struct service_struct *sv);static struct script_struct *find_script_byname    (const char *name,struct list_head *head, struct service_struct **service);static struct script_struct *find_script_bypid (pid_t pid,						struct list_head *head);static void insert_entry (struct list_head *head, struct script_struct *entry);static void remove_entry (struct list_head *head, struct script_struct *entry);static void signal_needers (struct service_struct *service, int sig);static void handle_nonworking (struct script_struct *script);static int force_progress (void);static void show_scripts (FILE *fp, const struct script_struct *script,			  const char *type);static const char *get_path (const char *file);static pid_t mywait (int *status)/*  [RETURNS] The pid for a process to be reaped, 0 if no process is to be    reaped, and less than 0 if the boot scripts appear to have finished.*/{    pid_t pid;    sigset_t ss;    long buffer[COMMAND_SIZE / sizeof (long)];    struct command_struct *command = (struct command_struct *) buffer;    if (initctl_fd < 0) return wait (status);    /*  Some magic to avoid races which can result in lost signals   */    command->command = -1;    if ( sigsetjmp (jmp_env, 1) )    {   /*  Jump from signal handler  */

⌨️ 快捷键说明

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