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

📄 util.c

📁 制作2.6内核的CLFS时 patch包
💻 C
📖 第 1 页 / 共 2 页
字号:
  putc ('\n', stderr);  fflush (stderr);  fatal_exit (0);}voidmemory_fatal (void){  fatal ("out of memory");}voidread_fatal (void){  pfatal ("read error");}voidwrite_fatal (void){  pfatal ("write error");}/* Say something from patch, something from the system, then silence . . . */voidpfatal (char const *format, ...){  int errnum = errno;  va_list args;  fprintf (stderr, "%s: **** ", program_name);  va_start (args, format);  vfprintf (stderr, format, args);  va_end (args);  fflush (stderr); /* perror bypasses stdio on some hosts.  */  errno = errnum;  perror (" ");  fflush (stderr);  fatal_exit (0);}/* Tell the user something.  */voidsay (char const *format, ...){  va_list args;  va_start (args, format);  vfprintf (stdout, format, args);  va_end (args);  fflush (stdout);}/* Get a response from the user, somehow or other. */voidask (char const *format, ...){  static int ttyfd = -2;  int r;  va_list args;  va_start (args, format);  vfprintf (stdout, format, args);  va_end (args);  fflush (stdout);  if (ttyfd == -2)    {      /* If standard output is not a tty, don't bother opening /dev/tty,	 since it's unlikely that stdout will be seen by the tty user.	 The isatty test also works around a bug in GNU Emacs 19.34 under Linux	 which makes a call-process `patch' hang when it reads from /dev/tty.	 POSIX.1-2001 XCU line 26599 requires that we read /dev/tty,	 though.  */      ttyfd = (posixly_correct || isatty (STDOUT_FILENO)	       ? open (TTY_DEVICE, O_RDONLY)	       : -1);    }  if (ttyfd < 0)    {      /* No terminal at all -- default it.  */      printf ("\n");      buf[0] = '\n';      buf[1] = '\0';    }  else    {      size_t s = 0;      while ((r = read (ttyfd, buf + s, bufsize - 1 - s)) == bufsize - 1 - s	     && buf[bufsize - 2] != '\n')	{	  s = bufsize - 1;	  bufsize *= 2;	  buf = realloc (buf, bufsize);	  if (!buf)	    memory_fatal ();	}      if (r == 0)	printf ("EOF\n");      else if (r < 0)	{	  perror ("tty read");	  fflush (stderr);	  close (ttyfd);	  ttyfd = -1;	  r = 0;	}      buf[s + r] = '\0';    }}/* Return nonzero if it OK to reverse a patch.  */boolok_to_reverse (char const *format, ...){  bool r = false;  if (noreverse || ! (force && verbosity == SILENT))    {      va_list args;      va_start (args, format);      vfprintf (stdout, format, args);      va_end (args);    }  if (noreverse)    {      printf ("  Skipping patch.\n");      skip_rest_of_patch = true;    }  else if (force)    {      if (verbosity != SILENT)	printf ("  Applying it anyway.\n");    }  else if (batch)    {      say (reverse ? "  Ignoring -R.\n" : "  Assuming -R.\n");      r = true;    }  else    {      ask (reverse ? "  Ignore -R? [n] " : "  Assume -R? [n] ");      r = *buf == 'y';      if (! r)	{	  ask ("Apply anyway? [n] ");	  if (*buf != 'y')	    {	      if (verbosity != SILENT)		say ("Skipping patch.\n");	      skip_rest_of_patch = true;	    }	}    }  return r;}/* How to handle certain events when not in a critical region. */#define NUM_SIGS (sizeof (sigs) / sizeof (*sigs))static int const sigs[] = {#ifdef SIGHUP       SIGHUP,#endif#ifdef SIGPIPE       SIGPIPE,#endif#ifdef SIGTERM       SIGTERM,#endif#ifdef SIGXCPU       SIGXCPU,#endif#ifdef SIGXFSZ       SIGXFSZ,#endif       SIGINT};#if !HAVE_SIGPROCMASK#define sigset_t int#define sigemptyset(s) (*(s) = 0)#ifndef sigmask#define sigmask(sig) (1 << ((sig) - 1))#endif#define sigaddset(s, sig) (*(s) |= sigmask (sig))#define sigismember(s, sig) ((*(s) & sigmask (sig)) != 0)#ifndef SIG_BLOCK#define SIG_BLOCK 0#endif#ifndef SIG_UNBLOCK#define SIG_UNBLOCK (SIG_BLOCK + 1)#endif#ifndef SIG_SETMASK#define SIG_SETMASK (SIG_BLOCK + 2)#endif#define sigprocmask(how, n, o) \  ((how) == SIG_BLOCK \   ? ((o) ? *(o) = sigblock (*(n)) : sigblock (*(n))) \   : (how) == SIG_UNBLOCK \   ? sigsetmask (((o) ? *(o) = sigblock (0) : sigblock (0)) & ~*(n)) \   : (o ? *(o) = sigsetmask (*(n)) : sigsetmask (*(n))))#if !HAVE_SIGSETMASK#define sigblock(mask) 0#define sigsetmask(mask) 0#endif#endifstatic sigset_t initial_signal_mask;static sigset_t signals_to_block;#if ! HAVE_SIGACTIONstatic RETSIGTYPE fatal_exit_handler (int) __attribute__ ((noreturn));static RETSIGTYPEfatal_exit_handler (int sig){  signal (sig, SIG_IGN);  fatal_exit (sig);}#endifvoidset_signals (bool reset){  int i;#if HAVE_SIGACTION  struct sigaction initial_act, fatal_act;  fatal_act.sa_handler = fatal_exit;  sigemptyset (&fatal_act.sa_mask);  fatal_act.sa_flags = 0;#define setup_handler(sig) sigaction (sig, &fatal_act, (struct sigaction *) 0)#else#define setup_handler(sig) signal (sig, fatal_exit_handler)#endif  if (!reset)    {#ifdef SIGCHLD      /* System V fork+wait does not work if SIGCHLD is ignored.  */      signal (SIGCHLD, SIG_DFL);#endif      sigemptyset (&signals_to_block);      for (i = 0;  i < NUM_SIGS;  i++)	{	  bool ignoring_signal;#if HAVE_SIGACTION	  if (sigaction (sigs[i], (struct sigaction *) 0, &initial_act) != 0)	    continue;	  ignoring_signal = initial_act.sa_handler == SIG_IGN;#else	  ignoring_signal = signal (sigs[i], SIG_IGN) == SIG_IGN;#endif	  if (! ignoring_signal)	    {	      sigaddset (&signals_to_block, sigs[i]);	      setup_handler (sigs[i]);	    }	}    }  else    {      /* Undo the effect of ignore_signals.  */#if HAVE_SIGPROCMASK || HAVE_SIGSETMASK      sigprocmask (SIG_SETMASK, &initial_signal_mask, (sigset_t *) 0);#else      for (i = 0;  i < NUM_SIGS;  i++)	if (sigismember (&signals_to_block, sigs[i]))	  setup_handler (sigs[i]);#endif    }}/* How to handle certain events when in a critical region. */voidignore_signals (void){#if HAVE_SIGPROCMASK || HAVE_SIGSETMASK  sigprocmask (SIG_BLOCK, &signals_to_block, &initial_signal_mask);#else  int i;  for (i = 0;  i < NUM_SIGS;  i++)    if (sigismember (&signals_to_block, sigs[i]))      signal (sigs[i], SIG_IGN);#endif}voidexit_with_signal (int sig){  sigset_t s;  signal (sig, SIG_DFL);  sigemptyset (&s);  sigaddset (&s, sig);  sigprocmask (SIG_UNBLOCK, &s, (sigset_t *) 0);  raise (sig);  exit (2);}intsystemic (char const *command){  if (debug & 8)    say ("+ %s\n", command);  fflush (stdout);  return system (command);}/* Replace '/' with '\0' in FILENAME if it marks a place that   needs testing for the existence of directory.  Return the address   of the last location replaced, or 0 if none were replaced.  */static char *replace_slashes (char *filename){  char *f;  char *last_location_replaced = 0;  char const *component_start;  for (f = filename + FILESYSTEM_PREFIX_LEN (filename);  ISSLASH (*f);  f++)    continue;  component_start = f;  for (; *f; f++)    if (ISSLASH (*f))      {	char *slash = f;	/* Treat multiple slashes as if they were one slash.  */	while (ISSLASH (f[1]))	  f++;	/* Ignore slashes at the end of the path.  */	if (! f[1])	  break;	/* "." and ".." need not be tested.  */	if (! (slash - component_start <= 2	       && component_start[0] == '.' && slash[-1] == '.'))	  {	    *slash = '\0';	    last_location_replaced = slash;	  }	component_start = f + 1;      }  return last_location_replaced;}/* Make sure we'll have the directories to create a file.   Ignore the last element of `filename'.  */static voidmakedirs (register char *filename){  register char *f;  register char *flim = replace_slashes (filename);  if (flim)    {      /* Create any missing directories, replacing NULs by '/'s.	 Ignore errors.  We may have to keep going even after an EEXIST,	 since the path may contain ".."s; and when there is an EEXIST	 failure the system may return some other error number.	 Any problems will eventually be reported when we create the file.  */      for (f = filename;  f <= flim;  f++)	if (!*f)	  {	    mkdir (filename,		   S_IRUSR|S_IWUSR|S_IXUSR		   |S_IRGRP|S_IWGRP|S_IXGRP		   |S_IROTH|S_IWOTH|S_IXOTH);	    *f = '/';	  }    }}/* Remove empty ancestor directories of FILENAME.   Ignore errors, since the path may contain ".."s, and when there   is an EEXIST failure the system may return some other error number.  */voidremovedirs (char *filename){  size_t i;  for (i = strlen (filename);  i != 0;  i--)    if (ISSLASH (filename[i])	&& ! (ISSLASH (filename[i - 1])	      || (filename[i - 1] == '.'		  && (i == 1		      || ISSLASH (filename[i - 2])		      || (filename[i - 2] == '.'			  && (i == 2			      || ISSLASH (filename[i - 3])))))))      {	filename[i] = '\0';	if (rmdir (filename) == 0 && verbosity == VERBOSE)	  say ("Removed empty directory %s\n", quotearg (filename));	filename[i] = '/';      }}static time_t initial_time;voidinit_time (void){  time (&initial_time);}/* Make filenames more reasonable. */char *fetchname (char *at, int strip_leading, time_t *pstamp){    char *name;    register char *t;    int sleading = strip_leading;    time_t stamp = (time_t) -1;    while (ISSPACE ((unsigned char) *at))	at++;    if (debug & 128)	say ("fetchname %s %d\n", at, strip_leading);    name = at;    /* Strip up to `strip_leading' leading slashes and null terminate.       If `strip_leading' is negative, strip all leading slashes.  */    for (t = at;  *t;  t++)      {	if (ISSLASH (*t))	  {	    while (ISSLASH (t[1]))	      t++;	    if (strip_leading < 0 || --sleading >= 0)		name = t+1;	  }	else if (ISSPACE ((unsigned char) *t))	  {	    /* Allow file names with internal spaces,	       but only if a tab separates the file name from the date.  */	    char const *u = t;	    while (*u != '\t' && ISSPACE ((unsigned char) u[1]))	      u++;	    if (*u != '\t' && strchr (u + 1, '\t'))	      continue;	    if (set_time | set_utc)	      stamp = str2time (&u, initial_time,				set_utc ? 0L : TM_LOCAL_ZONE);	    else	      {		/* The head says the file is nonexistent if the timestamp		   is the epoch; but the listed time is local time, not UTC,		   and POSIX.1 allows local time offset anywhere in the range		   -25:00 < offset < +26:00.  Match any time in that		   range by assuming local time is -25:00 and then matching		   any ``local'' time T in the range 0 < T < 25+26 hours.  */		stamp = str2time (&u, initial_time, -25L * 60 * 60);		if (0 < stamp && stamp < (25 + 26) * 60L * 60)		  stamp = 0;	      }	    if (*u && ! ISSPACE ((unsigned char) *u))	      stamp = (time_t) -1;	    *t = '\0';	    break;	  }      }    if (!*name)      return 0;    /* If the name is "/dev/null", ignore the name and mark the file       as being nonexistent.  The name "/dev/null" appears in patches       regardless of how NULL_DEVICE is spelled.  */    if (strcmp (at, "/dev/null") == 0)      {	if (pstamp)	  *pstamp = 0;	return 0;      }    /* Ignore the name if it doesn't have enough slashes to strip off.  */    if (0 < sleading)      return 0;    if (pstamp)      *pstamp = stamp;    return savestr (name);}voidFseek (FILE *stream, file_offset offset, int ptrname){  if (file_seek (stream, offset, ptrname) != 0)    pfatal ("fseek");}

⌨️ 快捷键说明

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