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

📄 sdiff.c

📁 制作2.6内核的CLFS时 使用的diffutils-2.8.7.tar.gz包
💻 C
📖 第 1 页 / 共 2 页
字号:
	int i;	for (i = 0;  diffargv[i];  i++)	  cmdsize += quote_system_arg (0, diffargv[i]) + 1;	command = p = xmalloc (cmdsize);	for (i = 0;  diffargv[i];  i++)	  {	    p += quote_system_arg (p, diffargv[i]);	    *p++ = ' ';	  }	p[-1] = 0;	errno = 0;	diffout = popen (command, "r");	if (! diffout)	  perror_fatal (command);	free (command);      }#else      {	int diff_fds[2];# if HAVE_WORKING_VFORK	sigset_t procmask;	sigset_t blocked;# endif	if (pipe (diff_fds) != 0)	  perror_fatal ("pipe");# if HAVE_WORKING_VFORK	/* Block SIGINT and SIGPIPE.  */	sigemptyset (&blocked);	sigaddset (&blocked, SIGINT);	sigaddset (&blocked, SIGPIPE);	sigprocmask (SIG_BLOCK, &blocked, &procmask);# endif	diffpid = vfork ();	if (diffpid < 0)	  perror_fatal ("fork");	if (! diffpid)	  {	    /* Alter the child's SIGINT and SIGPIPE handlers;	       this may munge the parent.	       The child ignores SIGINT in case the user interrupts the editor.	       The child does not ignore SIGPIPE, even if the parent does.  */	    if (initial_handler (handler_index_of_SIGINT) != SIG_IGN)	      signal_handler (SIGINT, SIG_IGN);	    signal_handler (SIGPIPE, SIG_DFL);# if HAVE_WORKING_VFORK	    /* Stop blocking SIGINT and SIGPIPE in the child.  */	    sigprocmask (SIG_SETMASK, &procmask, 0);# endif	    close (diff_fds[0]);	    if (diff_fds[1] != STDOUT_FILENO)	      {		dup2 (diff_fds[1], STDOUT_FILENO);		close (diff_fds[1]);	      }	    execvp (diffargv[0], (char **) diffargv);	    _exit (errno == ENOENT ? 127 : 126);	  }# if HAVE_WORKING_VFORK	/* Restore the parent's SIGINT and SIGPIPE behavior.  */	if (initial_handler (handler_index_of_SIGINT) != SIG_IGN)	  signal_handler (SIGINT, catchsig);	if (initial_handler (handler_index_of_SIGPIPE) != SIG_IGN)	  signal_handler (SIGPIPE, catchsig);	else	  signal_handler (SIGPIPE, SIG_IGN);	/* Stop blocking SIGINT and SIGPIPE in the parent.  */	sigprocmask (SIG_SETMASK, &procmask, 0);# endif	close (diff_fds[1]);	diffout = fdopen (diff_fds[0], "r");	if (! diffout)	  perror_fatal ("fdopen");      }#endif      lf_init (&diff_filt, diffout);      lf_init (&lfilt, left);      lf_init (&rfilt, right);      interact_ok = interact (&diff_filt, &lfilt, lname, &rfilt, rname, out);      ck_fclose (left);      ck_fclose (right);      ck_fclose (out);      {	int wstatus;	int werrno = 0;#if ! (HAVE_WORKING_FORK || HAVE_WORKING_VFORK)	wstatus = pclose (diffout);	if (wstatus == -1)	  werrno = errno;#else	ck_fclose (diffout);	while (waitpid (diffpid, &wstatus, 0) < 0)	  if (errno == EINTR)	    checksigs ();	  else	    perror_fatal ("waitpid");	diffpid = 0;#endif	if (tmpname)	  {	    unlink (tmpname);	    tmpname = 0;	  }	if (! interact_ok)	  exiterr ();	check_child_status (werrno, wstatus, EXIT_FAILURE, diffargv[0]);	untrapsig (0);	checksigs ();	exit (WEXITSTATUS (wstatus));      }    }  return EXIT_SUCCESS;			/* Fool `-Wall'.  */}static voiddiffarg (char const *a){  static size_t diffargs, diffarglim;  if (diffargs == diffarglim)    {      if (! diffarglim)	diffarglim = 16;      else if (PTRDIFF_MAX / (2 * sizeof *diffargv) <= diffarglim)	xalloc_die ();      else	diffarglim *= 2;      diffargv = xrealloc (diffargv, diffarglim * sizeof *diffargv);    }  diffargv[diffargs++] = a;}/* Signal handling */static bool volatile ignore_SIGINT;static int volatile signal_received;static bool sigs_trapped;static voidcatchsig (int s){#if ! HAVE_SIGACTION  signal (s, SIG_IGN);#endif  if (! (s == SIGINT && ignore_SIGINT))    signal_received = s;}#if HAVE_SIGACTIONstatic struct sigaction catchaction;static voidsignal_handler (int sig, void (*handler) (int)){  catchaction.sa_handler = handler;  sigaction (sig, &catchaction, 0);}#endifstatic voidtrapsigs (void){  int i;#if HAVE_SIGACTION  catchaction.sa_flags = SA_RESTART;  sigemptyset (&catchaction.sa_mask);  for (i = 0;  i < NUM_SIGS;  i++)    sigaddset (&catchaction.sa_mask, sigs[i]);#endif  for (i = 0;  i < NUM_SIGS;  i++)    {#if HAVE_SIGACTION      sigaction (sigs[i], 0, &initial_action[i]);#else      initial_action[i] = signal (sigs[i], SIG_IGN);#endif      if (initial_handler (i) != SIG_IGN)	signal_handler (sigs[i], catchsig);    }#ifdef SIGCHLD  /* System V fork+wait does not work if SIGCHLD is ignored.  */  signal (SIGCHLD, SIG_DFL);#endif  sigs_trapped = true;}/* Untrap signal S, or all trapped signals if S is zero.  */static voiduntrapsig (int s){  int i;  if (sigs_trapped)    for (i = 0;  i < NUM_SIGS;  i++)      if ((! s || sigs[i] == s)  &&  initial_handler (i) != SIG_IGN)	{#if HAVE_SIGACTION	  sigaction (sigs[i], &initial_action[i], 0);#else	  signal (sigs[i], initial_action[i]);#endif	}}/* Exit if a signal has been received.  */static voidchecksigs (void){  int s = signal_received;  if (s)    {      cleanup (0);      /* Yield an exit status indicating that a signal was received.  */      untrapsig (s);      kill (getpid (), s);      /* That didn't work, so exit with error status.  */      exit (EXIT_TROUBLE);    }}static voidgive_help (void){  fprintf (stderr, "%s", _("\ed:\tEdit then use both versions, each decorated with a header.\n\eb:\tEdit then use both versions.\n\el:\tEdit then use the left version.\n\er:\tEdit then use the right version.\n\e:\tEdit a new version.\n\l:\tUse the left version.\n\r:\tUse the right version.\n\s:\tSilently include common lines.\n\v:\tVerbosely include common lines.\n\q:\tQuit.\n\"));}static intskip_white (void){  int c;  for (;;)    {      c = getchar ();      if (! isspace (c) || c == '\n')	break;      checksigs ();    }  if (ferror (stdin))    perror_fatal (_("read failed"));  return c;}static voidflush_line (void){  int c;  while ((c = getchar ()) != '\n' && c != EOF)    continue;  if (ferror (stdin))    perror_fatal (_("read failed"));}/* interpret an edit command */static booledit (struct line_filter *left, char const *lname, lin lline, lin llen,      struct line_filter *right, char const *rname, lin rline, lin rlen,      FILE *outfile){  for (;;)    {      int cmd0, cmd1;      bool gotcmd = false;      cmd1 = 0; /* Pacify `gcc -W'.  */      while (! gotcmd)	{	  if (putchar ('%') != '%')	    perror_fatal (_("write failed"));	  ck_fflush (stdout);	  cmd0 = skip_white ();	  switch (cmd0)	    {	    case 'l': case 'r': case 's': case 'v': case 'q':	      if (skip_white () != '\n')		{		  give_help ();		  flush_line ();		  continue;		}	      gotcmd = true;	      break;	    case 'e':	      cmd1 = skip_white ();	      switch (cmd1)		{		case 'b': case 'd': case 'l': case 'r':		  if (skip_white () != '\n')		    {		      give_help ();		      flush_line ();		      continue;		    }		  gotcmd = true;		  break;		case '\n':		  gotcmd = true;		  break;		default:		  give_help ();		  flush_line ();		  continue;		}	      break;	    case EOF:	      if (feof (stdin))		{		  gotcmd = true;		  cmd0 = 'q';		  break;		}	      /* Fall through.  */	    default:	      flush_line ();	      /* Fall through.  */	    case '\n':	      give_help ();	      continue;	    }	}      switch (cmd0)	{	case 'l':	  lf_copy (left, llen, outfile);	  lf_skip (right, rlen);	  return true;	case 'r':	  lf_copy (right, rlen, outfile);	  lf_skip (left, llen);	  return true;	case 's':	  suppress_common_lines = true;	  break;	case 'v':	  suppress_common_lines = false;	  break;	case 'q':	  return false;	case 'e':	  {	    int fd;	    if (tmpname)	      tmp = fopen (tmpname, "w");	    else	      {		if ((fd = temporary_file ()) < 0)		  perror_fatal ("mkstemp");		tmp = fdopen (fd, "w");	      }	    if (! tmp)	      perror_fatal (tmpname);	    switch (cmd1)	      {	      case 'd':		if (llen)		  {		    if (llen == 1)		      fprintf (tmp, "--- %s %ld\n", lname, (long int) lline);		    else		      fprintf (tmp, "--- %s %ld,%ld\n", lname,			       (long int) lline,			       (long int) (lline + llen - 1));		  }		/* Fall through.  */	      case 'b': case 'l':		lf_copy (left, llen, tmp);		break;	      default:		lf_skip (left, llen);		break;	      }	    switch (cmd1)	      {	      case 'd':		if (rlen)		  {		    if (rlen == 1)		      fprintf (tmp, "+++ %s %ld\n", rname, (long int) rline);		    else		      fprintf (tmp, "+++ %s %ld,%ld\n", rname,			       (long int) rline,			       (long int) (rline + rlen - 1));		  }		/* Fall through.  */	      case 'b': case 'r':		lf_copy (right, rlen, tmp);		break;	      default:		lf_skip (right, rlen);		break;	      }	    ck_fclose (tmp);	    {	      int wstatus;	      int werrno = 0;	      ignore_SIGINT = true;	      checksigs ();	      {#if ! (HAVE_WORKING_FORK || HAVE_WORKING_VFORK)		char *command =		  xmalloc (quote_system_arg (0, editor_program)			   + 1 + strlen (tmpname) + 1);		sprintf (command + quote_system_arg (command, editor_program),			 " %s", tmpname);		wstatus = system (command);		if (wstatus == -1)		  werrno = errno;		free (command);#else		pid_t pid;		pid = vfork ();		if (pid == 0)		  {		    char const *argv[3];		    int i = 0;		    argv[i++] = editor_program;		    argv[i++] = tmpname;		    argv[i] = 0;		    execvp (editor_program, (char **) argv);		    _exit (errno == ENOENT ? 127 : 126);		  }		if (pid < 0)		  perror_fatal ("fork");		while (waitpid (pid, &wstatus, 0) < 0)		  if (errno == EINTR)		    checksigs ();		  else		    perror_fatal ("waitpid");#endif	      }	      ignore_SIGINT = false;	      check_child_status (werrno, wstatus, EXIT_SUCCESS,				  editor_program);	    }	    {	      char buf[SDIFF_BUFSIZE];	      size_t size;	      tmp = ck_fopen (tmpname, "r");	      while ((size = ck_fread (buf, SDIFF_BUFSIZE, tmp)) != 0)		{		  checksigs ();		  ck_fwrite (buf, size, outfile);		}	      ck_fclose (tmp);	    }	    return true;	  }	default:	  give_help ();	  break;	}    }}/* Alternately reveal bursts of diff output and handle user commands.  */static boolinteract (struct line_filter *diff,	  struct line_filter *left, char const *lname,	  struct line_filter *right, char const *rname,	  FILE *outfile){  lin lline = 1, rline = 1;  for (;;)    {      char diff_help[256];      int snarfed = lf_snarf (diff, diff_help, sizeof diff_help);      if (snarfed <= 0)	return snarfed != 0;      checksigs ();      if (diff_help[0] == ' ')	puts (diff_help + 1);      else	{	  char *numend;	  uintmax_t val;	  lin llen, rlen, lenmax;	  errno = 0;	  llen = val = strtoumax (diff_help + 1, &numend, 10);	  if (llen < 0 || llen != val || errno || *numend != ',')	    fatal (diff_help);	  rlen = val = strtoumax (numend + 1, &numend, 10);	  if (rlen < 0 || rlen != val || errno || *numend)	    fatal (diff_help);	  lenmax = MAX (llen, rlen);	  switch (diff_help[0])	    {	    case 'i':	      if (suppress_common_lines)		lf_skip (diff, lenmax);	      else		lf_copy (diff, lenmax, stdout);	      lf_copy (left, llen, outfile);	      lf_skip (right, rlen);	      break;	    case 'c':	      lf_copy (diff, lenmax, stdout);	      if (! edit (left, lname, lline, llen,			  right, rname, rline, rlen,			  outfile))		return false;	      break;	    default:	      fatal (diff_help);	    }	  lline += llen;	  rline += rlen;	}    }}/* Return true if DIR is an existing directory.  */static booldiraccess (char const *dir){  struct stat buf;  return stat (dir, &buf) == 0 && S_ISDIR (buf.st_mode);}#ifndef P_tmpdir# define P_tmpdir "/tmp"#endif#ifndef TMPDIR_ENV# define TMPDIR_ENV "TMPDIR"#endif/* Open a temporary file and return its file descriptor.  Put into   tmpname the address of a newly allocated buffer that holds the   file's name.  Use the prefix "sdiff".  */static inttemporary_file (void){  char const *tmpdir = getenv (TMPDIR_ENV);  char const *dir = tmpdir ? tmpdir : P_tmpdir;  char *buf = xmalloc (strlen (dir) + 1 + 5 + 6 + 1);  int fd;  int e;  sigset_t procmask;  sigset_t blocked;  sprintf (buf, "%s/sdiffXXXXXX", dir);  sigemptyset (&blocked);  sigaddset (&blocked, SIGINT);  sigprocmask (SIG_BLOCK, &blocked, &procmask);  fd = mkstemp (buf);  e = errno;  if (0 <= fd)    tmpname = buf;  sigprocmask (SIG_SETMASK, &procmask, 0);  errno = e;  return fd;}

⌨️ 快捷键说明

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