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

📄 fixincl.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Install modified versions of certain ANSI-incompatible system header   files which are fixed to work correctly with ANSI C and placed in a   directory that GNU C will search.   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  */#include "auto-host.h"#include "gansidecl.h"#include "system.h"#include <signal.h>#include "gnu-regex.h"#include "server.h"static const char program_id[] = "fixincl version 1.0";#define MINIMUM_MAXIMUM_LINES   128/* If this particular system's header files define the macro `MAXPATHLEN',   we happily take advantage of it; otherwise we use a value which ought   to be large enough.  */#ifndef MAXPATHLEN# define MAXPATHLEN     4096#endif#define NAME_TABLE_SIZE (MINIMUM_MAXIMUM_LINES * MAXPATHLEN)#ifndef EXIT_SUCCESS# define EXIT_SUCCESS 0#endif#ifndef EXIT_FAILURE# define EXIT_FAILURE 1#endifchar *file_name_buf;#define tSCC static const char#define tCC  const char#define tSC  static chartypedef int t_success;#define FAILURE         (-1)#define SUCCESS           0#define PROBLEM           1#define SUCCEEDED(p)    ((p) == SUCCESS)#define SUCCESSFUL(p)   SUCCEEDED (p)#define FAILED(p)       ((p) < SUCCESS)#define HADGLITCH(p)    ((p) > SUCCESS)#define NUL             '\0'/*  Test Descriptor    Each fix may have associated tests that determine    whether the fix needs to be applied or not.    Each test has a type (from the te_test_type enumeration);    associated test text; and, if the test is TT_EGREP or    the negated form TT_NEGREP, a pointer to the compiled    version of the text string.    */typedef enum{  TT_TEST, TT_EGREP, TT_NEGREP} te_test_type;typedef struct test_desc tTestDesc;struct test_desc{  te_test_type type;  const char *pz_test_text;  regex_t *p_test_regex;};typedef struct patch_desc tPatchDesc;/*  Fix Descriptor    Everything you ever wanted to know about how to apply    a particular fix (which files, how to qualify them,    how to actually make the fix, etc...)    */#define FD_MACH_ONLY      0x0000#define FD_MACH_IFNOT     0x0001#define FD_SHELL_SCRIPT   0x0002#define FD_SKIP_TEST      0x8000typedef struct fix_desc tFixDesc;struct fix_desc{  const char*   fix_name;       /* Name of the fix */  const char*   file_list;      /* List of files it applies to */  const char**  papz_machs;     /* List of machine/os-es it applies to */  regex_t*      unused;  int           test_ct;  int           fd_flags;  tTestDesc*    p_test_desc;  const char**  patch_args;};/*  Working environment strings.  Essentially, invocation 'options'.  */char *pz_dest_dir = NULL;char *pz_src_dir = NULL;char *pz_machine = NULL;char *pz_find_base = NULL;int find_base_len = 0;pid_t process_chain_head = (pid_t) -1;const char incl_quote_pat[] = "^[ \t]*#[ \t]*include[ \t]*\"[^/]";regex_t incl_quote_re;char *load_file  _P_((const char *));void process  _P_((char *, const char *));void run_compiles ();void wait_for_pid _P_(( pid_t ));void initialize ();#include "fixincl.x"/* * * * * * * * * * * * * * * * * * * * *  MAIN ROUTINE */intmain (argc, argv)     int argc;     char **argv;{  static const char gnu_lib_mark[] =    "This file is part of the GNU C Library";#ifndef NO_BOGOSITY_LIMITS# define BOGUS_LIMIT    MINIMUM_MAXIMUM_LINES  size_t loop_ct;#endif  char *apz_names[BOGUS_LIMIT];  size_t file_name_ct;  /* Before anything else, ensure we can allocate our file name buffer. */  file_name_buf = (char *) malloc (NAME_TABLE_SIZE);  if (file_name_buf == (char *) NULL)    {      fprintf (stderr, "fixincl cannot allocate 0x%08X bytes\n",               NAME_TABLE_SIZE);      exit (EXIT_FAILURE);    }  switch (argc)    {    case 1:      break;    case 2:      if (strcmp (argv[1], "-v") == 0)        {          static const char zFmt[] = "echo '%s'";          /* The 'version' option is really used to test that:               1.  The program loads correctly (no missing libraries)               2.  we can correctly run our server shell process               3.  that we can compile all the regular expressions.           */          run_compiles ();          sprintf (file_name_buf, zFmt, program_id);          fputs (file_name_buf + 5, stdout);          exit (strcmp (run_shell (file_name_buf), program_id));        }      freopen (argv[1], "r", stdin);      break;    default:      fputs ("fixincl ERROR:  too many command line arguments\n", stderr);      exit (EXIT_FAILURE);    }  initialize ();#ifndef NO_BOGOSITY_LIMITS  /*  Some systems only allow so many calls to fork(2).      This is inadequate for this program.  Consequently,      we must let a grandfather process spawn children      that then spawn all the processes that do the real work.      */  for (;;)    {      file_name_ct = 0;      {        char *pz_buf = file_name_buf;        /* Only the parent process can read from stdin without confusing           the world. (How does the child tell the parent to skip           forward?  Pipes and files behave differently.)  */        while (  (file_name_ct < BOGUS_LIMIT)              && (pz_buf < (file_name_buf + NAME_TABLE_SIZE - MAXPATHLEN)))          {            if (fgets (pz_buf, MAXPATHLEN, stdin) == (char *) NULL)              break;            while (isspace (*pz_buf))              pz_buf++;            if ((*pz_buf == '\0') || (*pz_buf == '#'))              continue;            apz_names[file_name_ct++] = pz_buf;            pz_buf += strlen (pz_buf);            while (isspace (pz_buf[-1]))              pz_buf--;            *pz_buf++ = '\0';          }      }      /*  IF we did not get any files this time thru          THEN we must be done.  */      if (file_name_ct == 0)        return EXIT_SUCCESS;      fflush (stdout);      fflush (stderr);      {        pid_t child = fork ();        if (child == NULLPROCESS)          break;        if (child == NOPROCESS)          {            fprintf (stderr, "Error %d (%s) forking in main\n",                     errno, strerror (errno));            exit (EXIT_FAILURE);          }#ifdef DEBUG        fprintf (stderr, "Waiting for %d to complete %d files\n",                 child, file_name_ct);#endif        wait_for_pid( child, file_name_ct );      }    }#else /*#*/ error "NON-BOGUS LIMITS NOT SUPPORTED?!?!"#endif  /*  For every file specified in stdandard in      (except as throttled for bogus reasons)...      */  for (loop_ct = 0; loop_ct < file_name_ct; loop_ct++)    {      char *pz_data;      char *pz_file_name = apz_names[loop_ct];      if (access (pz_file_name, R_OK) != 0)        {          int erno = errno;          fprintf (stderr, "Cannot access %s from %s\n\terror %d (%s)\n",                   pz_file_name, getcwd ((char *) NULL, MAXPATHLEN),                   erno, strerror (erno));        }      else if (pz_data = load_file (pz_file_name), (pz_data != (char *) NULL))        {          if (strstr (pz_data, gnu_lib_mark) == (char *) NULL)            process (pz_data, pz_file_name);          free ((void *) pz_data);        }    }  return EXIT_SUCCESS;}/* * * * * * * * * * * * */voidinitialize(){  static const char var_not_found[] =    "fixincl ERROR:  %s environment variable not defined\n";  {    static const char var[] = "TARGET_MACHINE";    pz_machine = getenv (var);    if (pz_machine == (char *) NULL)      {        fprintf (stderr, var_not_found, var);        exit (EXIT_FAILURE);      }  }  {    static const char var[] = "DESTDIR";    pz_dest_dir = getenv (var);    if (pz_dest_dir == (char *) NULL)      {        fprintf (stderr, var_not_found, var);        exit (EXIT_FAILURE);      }  }  {    static const char var[] = "SRCDIR";    pz_src_dir = getenv (var);    if (pz_src_dir == (char *) NULL)      {        fprintf (stderr, var_not_found, var);        exit (EXIT_FAILURE);      }  }  {    static const char var[] = "FIND_BASE";    pz_find_base = getenv (var);    if (pz_find_base == (char *) NULL)      {        fprintf (stderr, var_not_found, var);        exit (EXIT_FAILURE);      }    find_base_len = strlen( pz_find_base );  }  /*  Compile all the regular expressions now.      That way, it is done only once for the whole run.      */  run_compiles ();  signal (SIGQUIT, SIG_IGN);  signal (SIGIOT,  SIG_IGN);  signal (SIGPIPE, SIG_IGN);  signal (SIGALRM, SIG_IGN);  signal (SIGTERM, SIG_IGN);  /*     Make sure that if we opened a server process, we close it now.     This is the grandparent process.  We don't need the server anymore     and our children should make their own.  */  close_server ();  (void)wait ( (int*)NULL );}/* * * * * * * * * * * * *    wait_for_pid  -  Keep calling `wait(2)' until it returns   the process id we are looking for.  Not every system has   `waitpid(2)'.  We also ensure that the children exit with success. */voidwait_for_pid(child, file_name_ct)     pid_t child;     int file_name_ct;{  for (;;) {    int status;    pid_t dead_kid = wait (&status);    if (dead_kid == child)      {        if (! WIFEXITED( status ))          {            fprintf (stderr, "child process %d is hung on signal %d\n",                     child, WSTOPSIG( status ));            exit (EXIT_FAILURE);          }        if (WEXITSTATUS( status ) != 0)          {            fprintf (stderr, "child process %d exited with status %d\n",                     child, WEXITSTATUS( status ));            exit (EXIT_FAILURE);          }        break; /* normal child completion */      }    /*       IF there is an error, THEN see if it is retryable.

⌨️ 快捷键说明

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