From 1f414ac48f4a946930e35c5003b5f020ad8168c4 Mon Sep 17 00:00:00 2001 From: Bruce Korb Date: Wed, 3 Mar 1999 07:41:52 +0000 Subject: [PATCH] Merge from fixincl-branch From-SVN: r25558 --- gcc/fixinc/Makefile.in | 45 +- gcc/fixinc/fixincl.c | 1179 ++++++++++++++++++++++---------------- gcc/fixinc/fixincl.sh | 35 +- gcc/fixinc/fixincl.x | 91 ++- gcc/fixinc/hackshell.tpl | 1 - gcc/fixinc/inclhack.def | 15 +- gcc/fixinc/inclhack.sh | 100 ++-- gcc/fixinc/inclhack.tpl | 32 +- gcc/fixinc/mkfixinc.sh | 44 +- gcc/fixinc/procopen.c | 260 +++++++++ gcc/fixinc/regex.c | 2 - gcc/fixinc/regex.h | 2 - gcc/fixinc/server.c | 524 ++++++----------- gcc/fixinc/server.h | 72 +-- 14 files changed, 1406 insertions(+), 996 deletions(-) create mode 100644 gcc/fixinc/procopen.c diff --git a/gcc/fixinc/Makefile.in b/gcc/fixinc/Makefile.in index e220c22d470..c1aa9c22f5e 100644 --- a/gcc/fixinc/Makefile.in +++ b/gcc/fixinc/Makefile.in @@ -1,5 +1,5 @@ -# Makefile for GNU C++ compiler. -# Copyright (C) 1987, 88, 90-5, 1998 Free Software Foundation, Inc. +# Makefile for GNU compilers. +# Copyright (C) 1998, 1999 Free Software Foundation, Inc. #This file is part of GNU CC. @@ -22,6 +22,7 @@ # Its purpose is to build the any-platforms fixinc.sh script. CFLAGS = -g +FIXINC_DEFS = @fixinc_defs@ CC = @CC@ SHELL = /bin/sh @@ -39,11 +40,11 @@ default : gen # Specify the directories to be searched for header files. # Both . and srcdir are used, in that order. -INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config +INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config -I$(srcdir)/../../include # Always use -I$(srcdir)/config when compiling. .c.o: - $(CC) -c $(CFLAGS) $(CPPFLAGS) $(INCLUDES) $< + $(CC) -c $(CFLAGS) $(FIXINC_DEFS) $(CPPFLAGS) $(INCLUDES) $< # The only suffixes we want for implicit rules are .c and .o. .SUFFIXES: @@ -55,12 +56,11 @@ INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config ## ## Makefile for constructing the "best" include fixer we can ## -## $Id: Makefile.in,v 1.2 1998/12/16 21:18:54 law Exp $ -## ## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # OBJ = fixincl.o server.o regex.o HDR = server.h regex.h +LIBERTY = ../../libiberty/libiberty.a SH_TARGET = inclhack.sh fixincl.sh BIN_TARGET = fixincl @@ -75,13 +75,13 @@ gen : $(SH_TARGET) fixincl.x $(OBJ): $(HDR) fixincl: $(OBJ) - @echo $(CC) -o $@ $(OBJ) $(LIB) ; \ - if $(CC) -o $@ $(OBJ) $(LIB) ; then : ; else \ + @echo $(CC) -o $@ $(OBJ) $(LIBERTY) $(LIB) ; \ + if $(CC) -o $@ $(OBJ) $(LIBERTY) $(LIB) ; then : ; else \ rm -f $@ ; (echo "#! /bin/sh" ; echo exit 1 ) > $@ ; \ chmod 777 $@ ; fi regex.o: regex.c - -$(CC) $(CFLAGS) -DSTDC_HEADERS=1 -c regex.c + -$(CC) $(CFLAGS) $(FIXINC_DEFS) -DSTDC_HEADERS=1 -c $(srcdir)/regex.c fixincl.o : fixincl.x fixincl.c server.o : server.c server.h @@ -92,21 +92,28 @@ fixincl.x: fixincl.tpl inclhack.def autogen -T $(srcdir)/fixincl.tpl -b fixincl \ $(srcdir)/inclhack.def ; \ else echo You need to install autogen ; \ - $(CP) $(srcdir)/$@ . ; fi + if [ `pwd` != `cd $(srcdir) ; pwd` ] ; then \ + $(CP) $(srcdir)/$@ . ; \ + else touch $@ ; fi ; fi inclhack.sh: inclhack.def inclhack.tpl hackshell.tpl @if ( autogen --help > /dev/null 2>&1 ) ; then \ echo autogen inclhack.def ; \ - autogen inclhack.def ; \ + autogen -L$(srcdir) $(srcdir)/inclhack.def ; \ else echo You need to install autogen ; \ - $(CP) $(srcdir)/$@ . ; fi + if [ `pwd` != `cd $(srcdir) ; pwd` ] ; then \ + $(CP) $(srcdir)/$@ . ; \ + else touch $@ ; fi ; fi fixincl.sh: inclhack.def inclhack.tpl @if ( autogen --help > /dev/null 2>&1 ) ; then \ echo autogen -DPROGRAM=1 -b fixincl inclhack.def ; \ - autogen -DPROGRAM=1 -b fixincl inclhack.def ; touch $@ ; \ + autogen -DPROGRAM=1 -b fixincl -L$(srcdir) \ + $(srcdir)/inclhack.def ; touch $@ ; \ else echo You need to install autogen ; \ - $(CP) $(srcdir)/$@ . ; fi + if [ `pwd` != `cd $(srcdir) ; pwd` ] ; then \ + $(CP) $(srcdir)/$@ . ; \ + else touch $@ ; fi ; fi clean: rm -f *.o $(TARGETS) fixincl.x @@ -120,13 +127,19 @@ install: $(TARGETS) @rm -f ../fixinc.sh ; \ if ( ./fixincl -v > /dev/null 2>&1 ) ; then \ echo cp fixincl.sh ../fixinc.sh ; \ - cp fixincl.sh ../fixinc.sh ; \ + if [ -f ./fixincl.sh ] ; \ + then cp fixincl.sh ../fixinc.sh ; \ + else cp $(srcdir)/fixincl.sh ../fixinc.sh ; fi ; \ chmod 555 ../fixinc.sh ; \ rm -f ../fixincl ; \ echo cp fixincl .. ; \ cp fixincl .. ; \ chmod 555 ../fixincl ; \ else \ + echo Could not install binary fixincludes. ; \ + echo Installing shell script instead. ; \ echo cp inclhack.sh ../fixinc.sh ; \ - cp inclhack.sh ../fixinc.sh ; \ + if [ -f ./inclhack.sh ] ; \ + then cp inclhack.sh ../fixinc.sh ; \ + else cp $(srcdir)/inclhack.sh ../fixinc.sh ; fi ; \ fi diff --git a/gcc/fixinc/fixincl.c b/gcc/fixinc/fixincl.c index 97aae47a4a4..951fb857c04 100644 --- a/gcc/fixinc/fixincl.c +++ b/gcc/fixinc/fixincl.c @@ -1,219 +1,291 @@ -/* - * $Id: fixincl.c,v 1.2 1998/12/16 21:19:03 law Exp $ - * - * 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. - * - * See README-fixinc for more information. - * - * fixincl is free software. - * - * You may redistribute it and/or modify it under the terms of the - * GNU General Public License, as published by the Free Software - * Foundation; either version 2, or (at your option) any later version. - * - * fixincl is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with fixincl. See the file "COPYING". If not, - * write to: The Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ +/* 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 modify +it under the terms of the GNU General Public License as published by +the 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 of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#ifdef FIXINC_BROKEN +/* The fixincl program is known to not run properly on this particular + system. Instead of producing a probably broken executable, we force + a compilation error and let the mkfixinc.sh script install the + inclhack.sh shell script instead. */ +# include "The fixincl program does not work properly on this system!" +#endif + +#include "config.h" + +#include #include #include -#include +#ifdef HAVE_SYS_WAIT_H #include +#endif #include #include +#ifdef HAVE_UNISTD_H #include +#endif #include #include #include +#ifdef HAVE_FCNTL_H #include +#endif #include #include "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) + +char *file_name_buf; + #define tSCC static const char #define tCC const char #define tSC static char -typedef int tSuccess; +typedef int t_success; + +#define FAILURE (-1) +#define SUCCESS 0 +#define PROBLEM 1 -#define FAILURE ((tSuccess)-1) -#define SUCCESS ((tSuccess) 0) -#define PROBLEM ((tSuccess) 1) +#define SUCCEEDED(p) ((p) == SUCCESS) +#define SUCCESSFUL(p) SUCCEEDED (p) +#define FAILED(p) ((p) < SUCCESS) +#define HADGLITCH(p) ((p) > SUCCESS) -#define SUCCEEDED( p ) ((p) == SUCCESS) -#define SUCCESSFUL( p ) SUCCEEDED( p ) -#define FAILED( p ) ((p) < SUCCESS) -#define HADGLITCH( p ) ((p) > SUCCESS) +#define NUL '\0' -#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 - } -teTestType; +{ + TT_TEST, TT_EGREP, TT_NEGREP +} te_test_type; typedef struct test_desc tTestDesc; struct test_desc - { - teTestType type; - const char *pzTest; - regex_t *pTestRegex; - }; +{ + 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_SKIP_TEST 0x8000 typedef struct fix_desc tFixDesc; struct fix_desc - { - const char* pzFixName; /* Name of the fix */ - const char* pzFileList; /* List of files it applies to */ - const char** papzMachs; /* List of machine/os-es it applies to */ - regex_t* pListRegex; - int testCt; - int fdFlags; - tTestDesc* pTestDesc; - const char** papzPatchArgs; - }; - -char *pzDestDir = (char *) NULL; -char *pzSrcDir = (char *) NULL; -char *pzMachine = (char *) NULL; - -pid_t chainHead = (pid_t) - 1; - -const char zInclQuote[] = "^[ \t]*#[ \t]*include[ \t]*\"[^/]"; -regex_t inclQuoteRegex; - -char zFileNameBuf[0x8000]; - -char *loadFile (const char *pzFile); -void process (char *data, const char *dir, const char *file); -void runCompiles (void); +{ + 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; + +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 (const char *pzFile); +void process (char *data, const char *file); +void run_compiles (void); #include "fixincl.x" - +/* * * * * * * * * * * * * * * * * * * + * + * MAIN ROUTINE + */ int main (argc, argv) int argc; char **argv; { - static const char zGnuLib[] = - "This file is part of the GNU C Library"; - static const char zVarNotFound[] = - "fixincl ERROR: %s environment variable not defined\n"; + static const char gnu_lib_mark[] = + "This file is part of the GNU C Library"; + static const char var_not_found[] = + "fixincl ERROR: %s environment variable not defined\n"; #ifndef NO_BOGOSITY_LIMITS -# define BOGUS_LIMIT 256 - size_t loopCt; +# define BOGUS_LIMIT MINIMUM_MAXIMUM_LINES + size_t loop_ct; #endif - char *apzNames[BOGUS_LIMIT]; - size_t fileNameCt; + char *apz_names[BOGUS_LIMIT]; + size_t file_name_ct; - if (argc != 1) + /* 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) { - if (argc != 2) - { - fputs ("fixincl ERROR: too many command line arguments\n", stderr); - exit (EXIT_FAILURE); - } + 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) { - fputs ("$Id: fixincl.c,v 1.2 1998/12/16 21:19:03 law Exp $\n", stderr); - exit (EXIT_SUCCESS); + 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); } { - static const char zVar[] = "TARGET_MACHINE"; - pzMachine = getenv( zVar ); - if (pzMachine == (char *)NULL) + static const char var[] = "TARGET_MACHINE"; + pz_machine = getenv (var); + if (pz_machine == (char *) NULL) { - fprintf( stderr, zVarNotFound, zVar ); + fprintf (stderr, var_not_found, var); exit (EXIT_FAILURE); } } { - static const char zVar[] = "DESTDIR"; - pzDestDir = getenv( zVar ); - if (pzDestDir == (char *)NULL) + static const char var[] = "DESTDIR"; + pz_dest_dir = getenv (var); + if (pz_dest_dir == (char *) NULL) { - fprintf( stderr, zVarNotFound, zVar ); + fprintf (stderr, var_not_found, var); exit (EXIT_FAILURE); } } { - static const char zVar[] = "SRCDIR"; - pzSrcDir = getenv( zVar ); - if (pzSrcDir == (char *)NULL) + static const char var[] = "SRCDIR"; + pz_src_dir = getenv (var); + if (pz_src_dir == (char *) NULL) { - fprintf( stderr, zVarNotFound, zVar ); + fprintf (stderr, var_not_found, var); exit (EXIT_FAILURE); } } - runCompiles (); + /* 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 ); - signal ( SIGCHLD, SIG_IGN ); + signal (SIGQUIT, SIG_IGN); + signal (SIGIOT, SIG_IGN); + signal (SIGPIPE, SIG_IGN); + signal (SIGALRM, SIG_IGN); + signal (SIGTERM, SIG_IGN); #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 (;;) { - char *pzBuf; + char *pz_buf; pid_t child; - /* - * 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.) - */ - for (fileNameCt = 0, pzBuf = zFileNameBuf; - (fileNameCt < BOGUS_LIMIT) - && (pzBuf - < (zFileNameBuf + sizeof (zFileNameBuf) - MAXPATHLEN)); - ) + /* 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.) */ + file_name_ct = 0; + pz_buf = file_name_buf; + while ( (file_name_ct < BOGUS_LIMIT) + && (pz_buf < (file_name_buf + NAME_TABLE_SIZE - MAXPATHLEN))) { - - if (fgets (pzBuf, MAXPATHLEN, stdin) == (char *) NULL) + if (fgets (pz_buf, MAXPATHLEN, stdin) == (char *) NULL) break; - while (isspace (*pzBuf)) - pzBuf++; - apzNames[fileNameCt++] = pzBuf; - pzBuf += strlen (pzBuf); - while (isspace (pzBuf[-1])) - pzBuf--; - *pzBuf++ = '\0'; + 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 (fileNameCt == 0) + /* IF we did not get any files this time thru + THEN we must be done. */ + if (file_name_ct == 0) return EXIT_SUCCESS; child = fork (); @@ -226,37 +298,53 @@ main (argc, argv) errno, strerror (errno)); exit (EXIT_FAILURE); } +#ifdef DEBUG + fprintf (stderr, "Waiting for %d to complete %d files\n", + child, file_name_ct); +#endif + { + int status; + pid_t dead_kid = wait (&status); - waitpid (child, (int *) NULL, 0); + if (dead_kid != child) + fprintf (stderr, "fixincl woke up from a strange child %d (not %d)\n", + dead_kid, child); +#ifdef DEBUG + else + fprintf (stderr, "child finished %d files %s\n", file_name_ct, + status ? strerror (status & 0xFF) : "ok"); +#endif + } } #else #error "NON-BOGUS LIMITS NOT SUPPORTED?!?!" #endif - /* - * For every file specified in stdandard in - * (except as throttled for bogus reasons)... - */ - for (loopCt = 0; loopCt < fileNameCt; loopCt++) +#ifdef DEBUG + fprintf (stderr, "Child start -- processing %d files\n", + file_name_ct); +#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 *pzData; - char *pzFile = apzNames[loopCt]; + char *pz_data; + char *pz_file_name = apz_names[loop_ct]; - if (access (pzFile, R_OK) != 0) + if (access (pz_file_name, R_OK) != 0) { int erno = errno; fprintf (stderr, "Cannot access %s from %s\n\terror %d (%s)\n", - pzFile, getcwd ((char *) NULL, MAXPATHLEN), + pz_file_name, getcwd ((char *) NULL, MAXPATHLEN), erno, strerror (erno)); } - else if (pzData = loadFile (pzFile), - (pzData != (char *) NULL)) + else if (pz_data = load_file (pz_file_name), (pz_data != (char *) NULL)) { - - if (strstr (pzData, zGnuLib) == (char *) NULL) - process (pzData, pzDestDir, pzFile); - - free ((void *) pzData); + if (strstr (pz_data, gnu_lib_mark) == (char *) NULL) + process (pz_data, pz_file_name); + free ((void *) pz_data); } } @@ -264,50 +352,57 @@ main (argc, argv) } +/* * * * * * * * * * * * * + + load_file loads all the contents of a file into malloc-ed memory. + Its argument is the name of the file to read in; the returned + result is the NUL terminated contents of the file. The file + is presumed to be an ASCII text file containing no NULs. */ char * -loadFile (pzFile) - const char *pzFile; +load_file (pz_file_name) + const char *pz_file_name; { - char *pzDta; - size_t fileSize; + char *pz_data; + size_t file_size; { struct stat stbf; - if (stat (pzFile, &stbf) != 0) + + if (stat (pz_file_name, &stbf) != 0) { fprintf (stderr, "error %d (%s) stat-ing %s\n", - errno, strerror (errno), pzFile); + errno, strerror (errno), pz_file_name); return (char *) NULL; } - fileSize = stbf.st_size; + file_size = stbf.st_size; } - if (fileSize == 0) + if (file_size == 0) return (char *) NULL; - pzDta = (char *) malloc ((fileSize + 16) & ~0x00F); - if (pzDta == (char *) NULL) + pz_data = (char *) malloc ((file_size + 16) & ~0x00F); + if (pz_data == (char *) NULL) { fprintf (stderr, "error: could not malloc %d bytes\n", - fileSize); + file_size); exit (EXIT_FAILURE); } { - FILE *fp = fopen (pzFile, "r"); - size_t sizeLeft = fileSize; - char *readPtr = pzDta; + FILE *fp = fopen (pz_file_name, "r"); + size_t size_left = file_size; + char *read_ptr = pz_data; if (fp == (FILE *) NULL) { fprintf (stderr, "error %d (%s) opening %s\n", errno, - strerror (errno), pzFile); - free ((void *) pzDta); + strerror (errno), pz_file_name); + free ((void *) pz_data); return (char *) NULL; } do { - size_t sizeRead = fread ((void *) readPtr, 1, sizeLeft, fp); + size_t sizeRead = fread ((void *) read_ptr, 1, size_left, fp); if (sizeRead == 0) { @@ -317,164 +412,215 @@ loadFile (pzFile) if (ferror (fp)) { fprintf (stderr, "error %d (%s) reading %s\n", errno, - strerror (errno), pzFile); - free ((void *) pzDta); + strerror (errno), pz_file_name); + free ((void *) pz_data); fclose (fp); return (char *) NULL; } } - readPtr += sizeRead; - sizeLeft -= sizeRead; + read_ptr += sizeRead; + size_left -= sizeRead; } - while (sizeLeft != 0); + while (size_left != 0); - *readPtr = '\0'; + *read_ptr = '\0'; fclose (fp); - return pzDta; } + return pz_data; } +/* * * * * * * * * * * * * + + run_compiles run all the regexp compiles for all the fixes once. + */ void -runCompiles () +run_compiles () { - tSCC zBadComp[] = "fixincl ERROR: cannot compile %s regex for %s\n" + tSCC z_bad_comp[] = "fixincl ERROR: cannot compile %s regex for %s\n" "\texpr = `%s'\n" "\terror %s\n"; - tFixDesc *pFD = fixDescList; - int fixCt = FIX_COUNT; - tTestDesc *pTD; - int tstCt; - int reCt = REGEX_COUNT; - const char *pzErr; - regex_t *pRegex = (regex_t *) malloc (REGEX_COUNT * sizeof (regex_t)); - - if (pRegex == (regex_t *) NULL) + tFixDesc *p_fixd = fixDescList; + int fix_ct = FIX_COUNT; + tTestDesc *p_test; + int test_ct; + int re_ct = REGEX_COUNT; + const char *pz_err; + regex_t *p_re = (regex_t *) malloc (REGEX_COUNT * sizeof (regex_t)); + + if (p_re == (regex_t *) NULL) { fprintf (stderr, "fixincl ERROR: cannot allocate %d bytes for regex\n", REGEX_COUNT * sizeof (regex_t)); exit (EXIT_FAILURE); } + /* The patterns we search for are all egrep patterns. + In the shell version of this program, we invoke egrep + with the supplied pattern. Here, we will run + re_compile_pattern, but it must be using the same rules. */ + re_set_syntax (RE_SYNTAX_EGREP); - pzErr = re_compile_pattern (zInclQuote, strlen (zInclQuote), - &inclQuoteRegex); - if (pzErr != (char *) NULL) + pz_err = re_compile_pattern (incl_quote_pat, sizeof (incl_quote_pat)-1, + &incl_quote_re); + if (pz_err != (char *) NULL) { - fprintf (stderr, zBadComp, "quoted include", "runCompiles", - zInclQuote, pzErr); + fprintf (stderr, z_bad_comp, "quoted include", "run_compiles", + incl_quote_pat, pz_err); exit (EXIT_FAILURE); } - /* - * FOR every fixup, ... - */ + /* FOR every fixup, ... */ do { - pTD = pFD->pTestDesc; - tstCt = pFD->testCt; - - if (pFD->papzMachs != (const char**)NULL) { - const char** papzMachs = pFD->papzMachs; - char* pz = zFileNameBuf; - char* pzSep = ""; - tCC* pzIfTrue; - tCC* pzIfFalse; - tSCC zSkip[] = "skip"; - tSCC zRun[] = "run"; - - sprintf( pz, "case %s in\n", pzMachine ); - pz += strlen( pz ); - - if (pFD->fdFlags & FD_MACH_IFNOT) { - pzIfTrue = zSkip; - pzIfFalse = zRun; - } else { - pzIfTrue = zRun; - pzIfFalse = zSkip; - } + p_test = p_fixd->p_test_desc; + test_ct = p_fixd->test_ct; - for (;;) { - const char* pzMach = *(papzMachs++); - if (pzMach == (const char*)NULL) - break; - sprintf( pz, "%s %s", pzSep, pzMach ); - pz += strlen( pz ); - pzSep = " | \\\n"; - } - sprintf( pz, " )\n echo %s ;;\n * )\n echo %s ;;\nesac", - pzIfTrue, pzIfFalse ); - pz = runShell( zFileNameBuf ); - if (*pz == 's') { - pFD->fdFlags |= FD_SKIP_TEST; - continue; + /* IF the machine type pointer is not NULL (we are not in test mode) + AND this test is for or not done on particular machines + THEN ... */ + + if ( (pz_machine != NULL) + && (p_fixd->papz_machs != (const char**) NULL) ) + { + const char **papz_machs = p_fixd->papz_machs; + char *pz = file_name_buf; + char *pz_sep = ""; + tCC *pz_if_true; + tCC *pz_if_false; + tSCC skip[] = "skip"; + tSCC run[] = "run"; + + /* Construct a shell script that looks like this: + + case our-cpu-platform-os in + tests-cpu-platform-os-pattern ) + echo run ;; + * ) + echo skip ;; + esac + + where 'run' and 'skip' may be reversed, depending on + the sense of the test. */ + + sprintf (pz, "case %s in\n", pz_machine); + pz += strlen (pz); + + if (p_fixd->fd_flags & FD_MACH_IFNOT) + { + pz_if_true = skip; + pz_if_false = run; + } + else + { + pz_if_true = run; + pz_if_false = skip; + } + + /* FOR any additional machine names to test for, + insert the " | \\\n" glue and the machine pattern. */ + + for (;;) + { + const char* pz_mach = *(papz_machs++); + + if (pz_mach == (const char*) NULL) + break; + sprintf (pz, "%s %s", pz_sep, pz_mach); + pz += strlen (pz); + pz_sep = " | \\\n"; + } + sprintf (pz, " )\n echo %s ;;\n * )\n echo %s ;;\nesac", + pz_if_true, pz_if_false); + + /* Run the script. + The result will start either with 's' or 'r'. */ + + pz = run_shell (file_name_buf); + if (*pz == 's') + { + p_fixd->fd_flags |= FD_SKIP_TEST; + continue; + } } - } - /* - * FOR every test for the fixup, ... - */ - while (--tstCt >= 0) + /* FOR every test for the fixup, ... */ + + while (--test_ct >= 0) { - switch (pTD->type) + switch (p_test->type) { case TT_EGREP: case TT_NEGREP: - if (--reCt < 0) + /* You might consider putting the following under #ifdef. + The number of re's used is computed by autogen. + So, it is static and known at compile time. */ + + if (--re_ct < 0) { fputs ("out of RE's\n", stderr); exit (EXIT_FAILURE); } - pTD->pTestRegex = pRegex++; - pzErr = re_compile_pattern (pTD->pzTest, - strlen (pTD->pzTest), - pTD->pTestRegex); - if (pzErr != (char *) NULL) + p_test->p_test_regex = p_re++; + pz_err = re_compile_pattern (p_test->pz_test_text, + strlen (p_test->pz_test_text), + p_test->p_test_regex); + if (pz_err != (char *) NULL) { - fprintf (stderr, zBadComp, "select test", pFD->pzFixName, - pTD->pzTest, pzErr); + fprintf (stderr, z_bad_comp, "select test", p_fixd->fix_name, + p_test->pz_test_text, pz_err); exit (EXIT_FAILURE); } } - pTD++; + p_test++; } } - while (pFD++, --fixCt > 0); + while (p_fixd++, --fix_ct > 0); } +/* * * * * * * * * * * * * + + create_file Create the output modified file. + Input: the name of the file to create + Returns: a file pointer to the new, open file */ + +#define S_IRALL (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) + FILE * -createFile (pzFile) - const char *pzFile; +create_file (pz_file_name) + const char *pz_file_name; { int fd; FILE *pf; char fname[MAXPATHLEN]; - sprintf (fname, "%s/%s", pzDestDir, pzFile); - unlink (fname); + sprintf (fname, "%s/%s", pz_dest_dir, pz_file_name); - fd = open (fname, O_WRONLY | O_CREAT); + fd = open (fname, O_WRONLY | O_CREAT | O_TRUNC, S_IRALL); + /* We may need to create the directories needed... */ if ((fd < 0) && (errno == ENOENT)) { - char *pzDir = strchr (fname + 1, '/'); + char *pz_dir = strchr (fname + 1, '/'); struct stat stbf; - while (pzDir != (char *) NULL) + while (pz_dir != (char *) NULL) { - *pzDir = NUL; + *pz_dir = NUL; if (stat (fname, &stbf) < 0) { mkdir (fname, S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); } - *pzDir = '/'; - pzDir = strchr (pzDir + 1, '/'); + *pz_dir = '/'; + pz_dir = strchr (pz_dir + 1, '/'); } - fd = open (fname, O_WRONLY | O_CREAT); + + /* Now, lets try the open again... */ + fd = open (fname, O_WRONLY | O_CREAT | O_TRUNC, S_IRALL); } if (fd < 0) { @@ -482,353 +628,410 @@ createFile (pzFile) errno, strerror (errno), fname); exit (EXIT_FAILURE); } - fprintf (stderr, "Fixed: %s\n", pzFile); + fprintf (stderr, "Fixed: %s\n", pz_file_name); pf = fdopen (fd, "w"); #ifdef LATER { - static const char zHdr[] = - "/*\n" - " * DO NOT EDIT THIS FILE.\n" - " *\n" - " * It has been auto-edited by fixincludes from /usr/include/%s\n" - " * This had to be done to correct non-standard usages in the\n" - " * original, manufacturer supplied header file.\n" - " */\n\n"; - - fprintf (pf, zHdr, pzFile); + static const char hdr[] = + "/* DO NOT EDIT THIS FILE.\n\n" + " It has been auto-edited by fixincludes from /usr/include/%s\n" + " This had to be done to correct non-standard usages in the\n" + " original, manufacturer supplied header file. */\n\n"; + + fprintf (pf, hdr, pz_file_name); } #endif return pf; } -tSuccess -testTest (pTest, pzFile) - tTestDesc *pTest; - char* pzFile; -{ - char *pzRes; - tSuccess res = FAILURE; - static char zCmdBuf[4096]; - tSCC zCmdFmt[] = "file=%s\nif ( test %s ) > /dev/null 2>&1\n" - "then echo TRUE\n" "else echo FALSE\n" "fi"; +/* * * * * * * * * * * * * - sprintf (zCmdBuf, zCmdFmt, pzFile, pTest->pzTest); - pzRes = runShell (zCmdBuf); - if (*pzRes == 'T') + test_test make sure a shell-style test expression passes. + Input: a pointer to the descriptor of the test to run and + the name of the file that we might want to fix + Result: SUCCESS or FAILURE, depending on the result of the + shell script we run. */ + +t_success +test_test (p_test, pz_file_name) + tTestDesc *p_test; + char* pz_file_name; +{ + char *pz_res; + t_success res = FAILURE; + + static char cmd_buf[4096]; + tSCC cmd_fmt[] = + "file=%s\n" + "if ( test %s ) > /dev/null 2>&1\n" + "then echo TRUE\n" + "else echo FALSE\n" + "fi"; + + sprintf (cmd_buf, cmd_fmt, pz_file_name, p_test->pz_test_text); + pz_res = run_shell (cmd_buf); + if (*pz_res == 'T') res = SUCCESS; - free ((void *) pzRes); + free ((void *) pz_res); return res; } -tSuccess -egrepTest (pzDta, pTest) - char *pzDta; - tTestDesc *pTest; +/* * * * * * * * * * * * * + + egrep_test make sure an egrep expression is found in the file text. + Input: a pointer to the descriptor of the test to run and + the pointer to the contents of the file under suspicion + Result: SUCCESS if the pattern is found, FAILURE otherwise + + The caller may choose 'FAILURE' as 'SUCCESS' if the sense of the test + is inverted. */ + +t_success +egrep_test (pz_data, p_test) + char *pz_data; + tTestDesc *p_test; { regmatch_t match; + #ifndef NO_BOGOSITY - if (pTest->pTestRegex == 0) - fprintf (stderr, "fixincl ERROR RE not compiled: `%s'\n", pTest->pzTest); + if (p_test->p_test_regex == 0) + fprintf (stderr, "fixincl ERROR RE not compiled: `%s'\n", + p_test->pz_test_text); #endif - if (regexec (pTest->pTestRegex, pzDta, 1, &match, 0) == 0) + if (regexec (p_test->p_test_regex, pz_data, 1, &match, 0) == 0) return SUCCESS; return FAILURE; } +/* * * * * * * * * * * * * + * + extract_quoted_files + + The syntax, `#include "file.h"' specifies that the compiler is to + search the local directory of the current file before the include + list. Consequently, if we have modified a header and stored it in + another directory, any files that are included by that modified + file in that fashion must also be copied into this new directory. + This routine finds those flavors of #include and for each one found + emits a triple of: + + 1. source directory of the original file + 2. the relative path file name of the #includ-ed file + 3. the full destination path for this file + + Input: the text of the file, the file name and a pointer to the + match list where the match information was stored. + Result: internally nothing. The results are written to stdout + for interpretation by the invoking shell */ void -extractQuotedFiles (pzDta, pzFile, pMatch) - char *pzDta; - const char *pzFile; - regmatch_t *pMatch; +extract_quoted_files (pz_data, pz_file_name, p_re_match) + char *pz_data; + const char *pz_file_name; + regmatch_t *p_re_match; { - char *pzDirEnd = strrchr (pzFile, '/'); - char *pzInclQuot = pzDta; + char *pz_dir_end = strrchr (pz_file_name, '/'); + char *pz_incl_quot = pz_data; - fprintf (stderr, "Quoted includes in %s\n", pzFile); + fprintf (stderr, "Quoted includes in %s\n", pz_file_name); - /* - * Set "pzFile" to point to the containing subdirectory of the source - * If there is none, then it is in our current direcory, ".". - */ - if (pzDirEnd == (char *) NULL) - pzFile = "."; + /* Set "pz_file_name" to point to the containing subdirectory of the source + If there is none, then it is in our current direcory, ".". */ + + if (pz_dir_end == (char *) NULL) + pz_file_name = "."; else - *pzDirEnd = '\0'; + *pz_dir_end = '\0'; for (;;) { - pzInclQuot += pMatch->rm_so; - - /* - * Skip forward to the included file name - */ - while (isspace (*pzInclQuot)) - pzInclQuot++; - while (isspace (*++pzInclQuot)); - pzInclQuot += sizeof ("include") - 1; - while (*pzInclQuot++ != '"'); - - /* - * Print the source directory and the subdirectory of the file - * in question. - */ - printf ("%s %s/", pzSrcDir, pzFile); - pzDirEnd = pzInclQuot; - - /* - * Append to the directory the relative path of the desired file - */ - while (*pzInclQuot != '"') - putc (*pzInclQuot++, stdout); - - /* - * Now print the destination directory appended with the relative - * path of the desired file - */ - printf (" %s/%s/", pzDestDir, pzFile); - while (*pzDirEnd != '"') - putc (*pzDirEnd++, stdout); - - /* - * End of entry - */ + pz_incl_quot += p_re_match->rm_so; + + /* Skip forward to the included file name */ + while (isspace (*pz_incl_quot)) + pz_incl_quot++; + while (isspace (*++pz_incl_quot)) + ; + pz_incl_quot += sizeof ("include") - 1; + while (*pz_incl_quot++ != '"') + ; + + /* Print the source directory and the subdirectory of the file + in question. */ + printf ("%s %s/", pz_src_dir, pz_file_name); + pz_dir_end = pz_incl_quot; + + /* Append to the directory the relative path of the desired file */ + while (*pz_incl_quot != '"') + putc (*pz_incl_quot++, stdout); + + /* Now print the destination directory appended with the + relative path of the desired file */ + printf (" %s/%s/", pz_dest_dir, pz_file_name); + while (*pz_dir_end != '"') + putc (*pz_dir_end++, stdout); + + /* End of entry */ putc ('\n', stdout); - /* - * Find the next entry - */ - if (regexec (&inclQuoteRegex, pzInclQuot, 1, pMatch, 0) != 0) + /* Find the next entry */ + if (regexec (&incl_quote_re, pz_incl_quot, 1, p_re_match, 0) != 0) break; } } -/* - * Process the potential fixes for a particular include file - */ +/* * * * * * * * * * * * * + + Process the potential fixes for a particular include file. + Input: the original text of the file and the file's name + Result: none. A new file may or may not be created. */ + void -process (pzDta, pzDir, pzFile) - char *pzDta; - const char *pzDir; - const char *pzFile; +process (pz_data, pz_file_name) + char *pz_data; + const char *pz_file_name; { - static char zEnvFile[1024] = - {"file="}; - tFixDesc *pFD = fixDescList; - int todoCt = FIX_COUNT; - tFdPair fdp = - {-1, -1}; + static char env_current_file[1024] = { "file=" }; + tFixDesc *p_fixd = fixDescList; + int todo_ct = FIX_COUNT; + t_fd_pair fdp = { -1, -1 }; - /* - * IF this is the first time through, - * THEN put the 'file' environment variable into the environment. - * This is used by some of the subject shell scripts and tests. - */ - if (zEnvFile[5] == NUL) - putenv (zEnvFile); + /* IF this is the first time through, + THEN put the 'file' environment variable into the environment. + This is used by some of the subject shell scripts and tests. */ - /* - * Ghastly as it is, this actually updates the value of the variable: - * - * putenv(3C) C Library Functions putenv(3C) - * - * DESCRIPTION - * putenv() makes the value of the environment variable name - * equal to value by altering an existing variable or creating - * a new one. In either case, the string pointed to by string - * becomes part of the environment, so altering the string will - * change the environment. string points to a string of the - * form ``name=value.'' The space used by string is no longer - * used once a new string-defining name is passed to putenv(). - */ - strcpy (zEnvFile + 5, pzFile); - chainHead = NOPROCESS; + if (env_current_file[5] == NUL) + putenv (env_current_file); /* - * For every fix in our fix list, ... + Ghastly as it is, this actually updates the value of the variable: + + putenv(3C) C Library Functions putenv(3C) + + DESCRIPTION + putenv() makes the value of the environment variable name + equal to value by altering an existing variable or creating + a new one. In either case, the string pointed to by string + becomes part of the environment, so altering the string will + change the environment. string points to a string of the + form ``name=value.'' The space used by string is no longer + used once a new string-defining name is passed to putenv(). */ - for (; todoCt > 0; pFD++, todoCt--) + strcpy (env_current_file + 5, pz_file_name); + process_chain_head = NOPROCESS; + + /* For every fix in our fix list, ... */ + for (; todo_ct > 0; p_fixd++, todo_ct--) { - tTestDesc *pTD; - int tstCt; - tSuccess egrepRes; + tTestDesc *p_test; + int test_ct; - if (pFD->fdFlags & FD_SKIP_TEST) + if (p_fixd->fd_flags & FD_SKIP_TEST) continue; - /* - * IF there is a file name restriction, - * THEN ensure the current file name matches one in the pattern - */ - if (pFD->pzFileList != (char *) NULL) + /* IF there is a file name restriction, + THEN ensure the current file name matches one in the pattern */ + + if (p_fixd->file_list != (char *) NULL) { - const char *pzFil = pzFile; - const char *pzScn = pFD->pzFileList; - size_t nmLen; + const char *pz_fname = pz_file_name; + const char *pz_scan = p_fixd->file_list; + size_t name_len; - while ((pzFil[0] == '.') && (pzFil[1] == '/')) - pzFil += 2; - nmLen = strlen (pzFil); + while ((pz_fname[0] == '.') && (pz_fname[1] == '/')) + pz_fname += 2; + name_len = strlen (pz_fname); for (;;) { - pzScn = strstr (pzScn + 1, pzFil); - if (pzScn == (char *) NULL) - goto nextFix; + pz_scan = strstr (pz_scan + 1, pz_fname); + /* IF we can't match the string at all, + THEN bail */ + if (pz_scan == (char *) NULL) + goto next_fix; - if ((pzScn[-1] == '|') && (pzScn[nmLen] == '|')) + /* IF the match is surrounded by the '|' markers, + THEN we found a full match -- time to run the tests */ + + if ((pz_scan[-1] == '|') && (pz_scan[name_len] == '|')) break; } } - egrepRes = PROBLEM; + /* FOR each test, see if it fails. + IF it does fail, then we go on to the next test */ - /* - * IF there are no tests - * THEN we always run the fixup - */ - for (pTD = pFD->pTestDesc, tstCt = pFD->testCt; - tstCt-- > 0; - pTD++) + for (p_test = p_fixd->p_test_desc, test_ct = p_fixd->test_ct; + test_ct-- > 0; + p_test++) { - switch (pTD->type) +#ifdef DEBUG + static const char z_test_fail[] = + "%16s test %2d failed for %s\n"; +#endif + switch (p_test->type) { case TT_TEST: - /* - * IF *any* of the shell tests fail, - * THEN do not process the fix. - */ - if (!SUCCESSFUL (testTest (pTD, pzFile))) - goto nextFix; + if (!SUCCESSFUL (test_test (p_test, pz_file_name))) + { +#ifdef DEBUG + fprintf (stderr, z_test_fail, p_fixd->fix_name, + p_fixd->test_ct - test_ct, pz_file_name); +#endif + goto next_fix; + } break; case TT_EGREP: - /* - * IF we have not had a successful egrep test - * *AND* this test does not pass, - * THEN mark the egrep test as failing. It starts - * out as a "PROBLEM", meaning that if we do not - * encounter any egrep tests, then we will let it pass. - */ - if ((!SUCCESSFUL (egrepRes)) - && (!SUCCESSFUL (egrepTest (pzDta, pTD)))) - - egrepRes = FAILURE; - + if (!SUCCESSFUL (egrep_test (pz_data, p_test))) + { +#ifdef DEBUG + fprintf (stderr, z_test_fail, p_fixd->fix_name, + p_fixd->test_ct - test_ct, pz_file_name); +#endif + goto next_fix; + } break; case TT_NEGREP: - /* - * IF *any* of the negative egrep tests fail, - * THEN do not process the fix. - */ - if (SUCCESSFUL (egrepTest (pzDta, pTD))) - goto nextFix; + if (SUCCESSFUL (egrep_test (pz_data, p_test))) + { +#ifdef DEBUG + fprintf (stderr, z_test_fail, p_fixd->fix_name, + p_fixd->test_ct - test_ct, pz_file_name); +#endif + goto next_fix; + } break; } } - /* - * IF there were no egrep tests *OR* at least one passed, ... - */ - if (!FAILED (egrepRes)) - { - fprintf (stderr, "Applying %-32s to %s\n", - pFD->pzFixName, pzFile); + fprintf (stderr, "Applying %-32s to %s\n", + p_fixd->fix_name, pz_file_name); + + /* IF we do not have a read pointer, + THEN this is the first fix for the current file. + Open the source file. That will be used as stdin for + the first fix. Any subsequent fixes will use the + stdout descriptor of the previous fix as its stdin. */ - if (fdp.readFd == -1) + if (fdp.read_fd == -1) + { + fdp.read_fd = open (pz_file_name, O_RDONLY); + if (fdp.read_fd < 0) { - fdp.readFd = open (pzFile, O_RDONLY); - if (fdp.readFd < 0) - { - fprintf (stderr, "Error %d (%s) opening %s\n", errno, - strerror (errno), pzFile); - exit (EXIT_FAILURE); - } + fprintf (stderr, "Error %d (%s) opening %s\n", errno, + strerror (errno), pz_file_name); + exit (EXIT_FAILURE); } + } - for (;;) - { - int newFd = chainOpen (fdp.readFd, - (tpChar *) pFD->papzPatchArgs, - (chainHead == -1) - ? &chainHead : (pid_t *) NULL); - if (newFd != -1) - { - fdp.readFd = newFd; - break; - } + /* This loop should only cycle for 1/2 of one loop. + "chain_open" starts a process that uses "fdp.read_fd" as + its stdin and returns the new fd this process will use + for stdout. */ - fprintf (stderr, "Error %d (%s) starting filter process " - "for %s\n", errno, strerror (errno), - pFD->pzFixName); + for (;;) + { + static int failCt = 0; + int fd = chain_open (fdp.read_fd, + (t_pchar *) p_fixd->patch_args, + (process_chain_head == -1) + ? &process_chain_head : (pid_t *) NULL); - if (errno != EAGAIN) - exit (EXIT_FAILURE); - sleep (1); + if (fd != -1) + { + fdp.read_fd = fd; + break; } + + fprintf (stderr, "Error %d (%s) starting filter process " + "for %s\n", errno, strerror (errno), + p_fixd->fix_name); + + if ((errno != EAGAIN) || (++failCt > 10)) + exit (EXIT_FAILURE); + sleep (1); } - nextFix:; + next_fix: + ; } - /* - * IF after all the tests we did not start any patch programs, - * THEN quit now. - */ - if (fdp.readFd < 0) + /* IF after all the tests we did not start any patch programs, + THEN quit now. */ + + if (fdp.read_fd < 0) return; + /* OK. We have work to do. Read back in the output + of the filtering chain. Compare each byte as we read it with + the contents of the original file. As soon as we find any + difference, we will create the output file, write out all + the matched text and then copy any remaining data from the + output of the filter chain. + */ { - FILE *inFp = fdopen (fdp.readFd, "r"); - FILE *oFp = (FILE *) NULL; - char *pzCmp = pzDta; + FILE *in_fp = fdopen (fdp.read_fd, "r"); + FILE *out_fp = (FILE *) NULL; + char *pz_cmp = pz_data; for (;;) { int ch; - ch = getc (inFp); + ch = getc (in_fp); if (ch == EOF) break; - if (oFp != (FILE *) NULL) - putc (ch, oFp); + /* IF we are emitting the output + THEN emit this character, too. + */ + if (out_fp != (FILE *) NULL) + putc (ch, out_fp); - else if (ch != *pzCmp) + /* ELSE if this character does not match the original, + THEN now is the time to start the output. + */ + else if (ch != *pz_cmp) { - oFp = createFile (pzFile); - if (pzCmp != pzDta) + out_fp = create_file (pz_file_name); + + /* IF there are matched data, write it all now. */ + if (pz_cmp != pz_data) { - char c = *pzCmp; - *pzCmp = NUL; - fputs (pzDta, oFp); - *pzCmp = c; + char c = *pz_cmp; + + *pz_cmp = NUL; + fputs (pz_data, out_fp); + *pz_cmp = c; } - putc (ch, oFp); + /* Emit the current unmatching character */ + putc (ch, out_fp); } else - pzCmp++; + /* ELSE the character matches. Advance the compare ptr */ + pz_cmp++; } - if (oFp != (FILE *) NULL) + /* IF we created the output file, ... */ + if (out_fp != (FILE *) NULL) { regmatch_t match; - fchmod (fileno (oFp), S_IRUSR | S_IRGRP | S_IROTH); - fclose (oFp); - if (regexec (&inclQuoteRegex, pzDta, 1, &match, 0) == 0) - extractQuotedFiles (pzDta, pzFile, &match); + /* Close the file and see if we have to worry about + `#include "file.h"' constructs. */ + fclose (out_fp); + if (regexec (&incl_quote_re, pz_data, 1, &match, 0) == 0) + extract_quoted_files (pz_data, pz_file_name, &match); } - - fclose (inFp); + fclose (in_fp); } - - close (fdp.readFd); + close (fdp.read_fd); /* probably redundant, but I'm paranoid */ } diff --git a/gcc/fixinc/fixincl.sh b/gcc/fixinc/fixincl.sh index b6c8484bb4b..1c9ab1413a2 100755 --- a/gcc/fixinc/fixincl.sh +++ b/gcc/fixinc/fixincl.sh @@ -2,7 +2,7 @@ # # DO NOT EDIT THIS FILE (fixincl.sh) # -# It has been autogen-ed Friday October 16, 1998 at 07:29:49 AM PDT +# It has been autogen-ed Wednesday January 27, 1999 at 09:03:56 AM PST # From the definitions inclhack.def # and the template file inclhack.tpl # @@ -10,7 +10,7 @@ # files which are fixed to work correctly with ANSI C and placed in a # directory that GNU C will search. # -# This script contains 104 fixup scripts. +# This script contains 105 fixup scripts. # # See README-fixinc for more information. # @@ -127,10 +127,7 @@ for INPUT in ${INPUTLIST} ; do cd ${ORIGDIR} -cd ${INPUT} || { - echo 'fixincludes: input dir `'$INPUT"' is an invalid directory" - exit 1 -} +cd ${INPUT} || continue # # # # # # # # # # # # # # # # # # # # # # @@ -344,18 +341,20 @@ while [ $# != 0 ]; do # cd ${INPUT} cd $1 - if [ -r $2 ] && [ ! -r $3 ]; then - cp $2 $3 >/dev/null 2>&1 || echo "Can't copy $2" >&2 - chmod +w $3 2>/dev/null - chmod a+r $3 2>/dev/null - echo Copied $2 - for include in `egrep '^[ ]*#[ ]*include[ ]*"[^/]' $3 | + if [ -f $2 ] ; then + if [ -r $2 ] && [ ! -r $3 ]; then + cp $2 $3 >/dev/null 2>&1 || echo "Can't copy $2" >&2 + chmod +w $3 2>/dev/null + chmod a+r $3 2>/dev/null + echo Copied $2 + for include in `egrep '^[ ]*#[ ]*include[ ]*"[^/]' $3 | sed -e 's/^[ ]*#[ ]*include[ ]*"\([^"]*\)".*$/\1/'` - do - dir=`echo $2 | sed -e s'|/[^/]*$||'` - dir2=`echo $3 | sed -e s'|/[^/]*$||'` - newreq="$newreq $1 $dir/$include $dir2/$include" - done + do + dir=`echo $2 | sed -e s'|/[^/]*$||'` + dir2=`echo $3 | sed -e s'|/[^/]*$||'` + newreq="$newreq $1 $dir/$include $dir2/$include" + done + fi fi shift; shift; shift done @@ -384,6 +383,6 @@ done cd $ORIGDIR rm -f include/assert.h -cp ${EGCS_SRCDIR}/assert.h include/assert.h +cp ${srcdir}/assert.h include/assert.h || exit 1 chmod a+r include/assert.h diff --git a/gcc/fixinc/fixincl.x b/gcc/fixinc/fixincl.x index a26e3fe99ce..cd4174219ef 100644 --- a/gcc/fixinc/fixincl.x +++ b/gcc/fixinc/fixincl.x @@ -1,7 +1,7 @@ /* * DO NOT EDIT THIS FILE (fixincl.x) * - * It has been autogen-ed Friday October 16, 1998 at 07:29:50 AM PDT + * It has been autogen-ed Tuesday January 5, 1999 at 09:20:37 AM PST * From the definitions inclhack.def * and the template file fixincl.tpl * @@ -9,7 +9,7 @@ * files which are fixed to work correctly with ANSI C and placed in a * directory that GNU C will search. * - * This script contains 104 fixup scripts. + * This script contains 105 fixup scripts. * * See README-fixinc for more information. * @@ -3005,7 +3005,41 @@ const char* apzUltrix_Ansi_CompatPatch[] = { "sed", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 84 - Ultrix_Atof_Param fix + * Description 84 - Ultrix_Fix_Fixproto fix + */ +tSCC zUltrix_Fix_FixprotoName[] = + "Ultrix_Fix_Fixproto"; +/* + * File name selection pattern + */ +tSCC zUltrix_Fix_FixprotoList[] = + "|" "sys/utsname.h" "|"; +/* + * Machine/OS name selection pattern + */ +#define apzUltrix_Fix_FixprotoMachs (const char**)NULL + +/* + * content selection pattern + */ +tSCC zUltrix_Fix_FixprotoSelect0[] = + "ULTRIX"; + +#define ULTRIX_FIX_FIXPROTO_TEST_CT 1 +tTestDesc aUltrix_Fix_FixprotoTests[] = { + { TT_EGREP, zUltrix_Fix_FixprotoSelect0, (regex_t*)NULL } }; + +/* + * Fix Command Arguments for Ultrix_Fix_Fixproto + */ +const char* apzUltrix_Fix_FixprotoPatch[] = { "sed", + "-e" "/^[ \t]*extern[ \t]*int[ \t]*uname();$/i\\\n" + "struct utsname;\n", + (char*)NULL }; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Description 85 - Ultrix_Atof_Param fix */ tSCC zUltrix_Atof_ParamName[] = "Ultrix_Atof_Param"; @@ -3034,7 +3068,7 @@ const char* apzUltrix_Atof_ParamPatch[] = { "sed", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 85 - Ultrix_Const fix + * Description 86 - Ultrix_Const fix */ tSCC zUltrix_ConstName[] = "Ultrix_Const"; @@ -3067,7 +3101,7 @@ const char* apzUltrix_ConstPatch[] = { "sed", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 86 - Ultrix_Ifdef fix + * Description 87 - Ultrix_Ifdef fix */ tSCC zUltrix_IfdefName[] = "Ultrix_Ifdef"; @@ -3100,7 +3134,7 @@ const char* apzUltrix_IfdefPatch[] = { "sed", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 87 - Ultrix_Nested_Cmnt fix + * Description 88 - Ultrix_Nested_Cmnt fix */ tSCC zUltrix_Nested_CmntName[] = "Ultrix_Nested_Cmnt"; @@ -3125,7 +3159,7 @@ const char* apzUltrix_Nested_CmntPatch[] = { "sed", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 88 - Ultrix_Static fix + * Description 89 - Ultrix_Static fix */ tSCC zUltrix_StaticName[] = "Ultrix_Static"; @@ -3160,7 +3194,7 @@ const char* apzUltrix_StaticPatch[] = { "sed", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 89 - Undefine_Null fix + * Description 90 - Undefine_Null fix */ tSCC zUndefine_NullName[] = "Undefine_Null"; @@ -3200,7 +3234,7 @@ const char* apzUndefine_NullPatch[] = { "sed", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 90 - Va_I960_Macro fix + * Description 91 - Va_I960_Macro fix */ tSCC zVa_I960_MacroName[] = "Va_I960_Macro"; @@ -3236,7 +3270,7 @@ const char* apzVa_I960_MacroPatch[] = { "sed", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 91 - Void_Null fix + * Description 92 - Void_Null fix */ tSCC zVoid_NullName[] = "Void_Null"; @@ -3279,7 +3313,7 @@ const char* apzVoid_NullPatch[] = { "sed", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 92 - Vxworks_Gcc_Problem fix + * Description 93 - Vxworks_Gcc_Problem fix */ tSCC zVxworks_Gcc_ProblemName[] = "Vxworks_Gcc_Problem"; @@ -3327,7 +3361,7 @@ const char* apzVxworks_Gcc_ProblemPatch[] = { "sed", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 93 - Vxworks_Needs_Vxtypes fix + * Description 94 - Vxworks_Needs_Vxtypes fix */ tSCC zVxworks_Needs_VxtypesName[] = "Vxworks_Needs_Vxtypes"; @@ -3360,7 +3394,7 @@ const char* apzVxworks_Needs_VxtypesPatch[] = { "sed", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 94 - Vxworks_Needs_Vxworks fix + * Description 95 - Vxworks_Needs_Vxworks fix */ tSCC zVxworks_Needs_VxworksName[] = "Vxworks_Needs_Vxworks"; @@ -3407,7 +3441,7 @@ const char* apzVxworks_Needs_VxworksPatch[] = { "sed", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 95 - Vxworks_Time fix + * Description 96 - Vxworks_Time fix */ tSCC zVxworks_TimeName[] = "Vxworks_Time"; @@ -3456,7 +3490,7 @@ const char* apzVxworks_TimePatch[] = { "sed", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 96 - X11_Class fix + * Description 97 - X11_Class fix */ tSCC zX11_ClassName[] = "X11_Class"; @@ -3494,7 +3528,7 @@ const char* apzX11_ClassPatch[] = { "sed", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 97 - X11_Class_Usage fix + * Description 98 - X11_Class_Usage fix */ tSCC zX11_Class_UsageName[] = "X11_Class_Usage"; @@ -3527,7 +3561,7 @@ const char* apzX11_Class_UsagePatch[] = { "sed", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 98 - X11_New fix + * Description 99 - X11_New fix */ tSCC zX11_NewName[] = "X11_New"; @@ -3566,7 +3600,7 @@ const char* apzX11_NewPatch[] = { "sed", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 99 - X11_Sprintf fix + * Description 100 - X11_Sprintf fix */ tSCC zX11_SprintfName[] = "X11_Sprintf"; @@ -3593,7 +3627,7 @@ const char* apzX11_SprintfPatch[] = { "sed", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 100 - Zzz_Ki_Iface fix + * Description 101 - Zzz_Ki_Iface fix */ tSCC zZzz_Ki_IfaceName[] = "Zzz_Ki_Iface"; @@ -3628,7 +3662,7 @@ const char* apzZzz_Ki_IfacePatch[] = { "sh", "-c", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 101 - Zzz_Ki fix + * Description 102 - Zzz_Ki fix */ tSCC zZzz_KiName[] = "Zzz_Ki"; @@ -3663,7 +3697,7 @@ const char* apzZzz_KiPatch[] = { "sh", "-c", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 102 - Zzz_Ki_Calls fix + * Description 103 - Zzz_Ki_Calls fix */ tSCC zZzz_Ki_CallsName[] = "Zzz_Ki_Calls"; @@ -3698,7 +3732,7 @@ const char* apzZzz_Ki_CallsPatch[] = { "sh", "-c", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 103 - Zzz_Ki_Defs fix + * Description 104 - Zzz_Ki_Defs fix */ tSCC zZzz_Ki_DefsName[] = "Zzz_Ki_Defs"; @@ -3733,7 +3767,7 @@ const char* apzZzz_Ki_DefsPatch[] = { "sh", "-c", /* * * * * * * * * * * * * * * * * * * * * * * * * * * - * Description 104 - Zzz_Time fix + * Description 105 - Zzz_Time fix */ tSCC zZzz_TimeName[] = "Zzz_Time"; @@ -3770,9 +3804,9 @@ const char* apzZzz_TimePatch[] = { "sh", "-c", * * List of all fixes */ -#define REGEX_COUNT 75 -#define FIX_COUNT 104 -tFixDesc fixDescList[ 104 ] = { +#define REGEX_COUNT 76 +#define FIX_COUNT 105 +tFixDesc fixDescList[ 105 ] = { { zAix_SyswaitName, zAix_SyswaitList, apzAix_SyswaitMachs, (regex_t*)NULL, AIX_SYSWAIT_TEST_CT, FD_MACH_ONLY, @@ -4188,6 +4222,11 @@ tFixDesc fixDescList[ 104 ] = { ULTRIX_ANSI_COMPAT_TEST_CT, FD_MACH_ONLY, aUltrix_Ansi_CompatTests, apzUltrix_Ansi_CompatPatch }, + { zUltrix_Fix_FixprotoName, zUltrix_Fix_FixprotoList, + apzUltrix_Fix_FixprotoMachs, (regex_t*)NULL, + ULTRIX_FIX_FIXPROTO_TEST_CT, FD_MACH_ONLY, + aUltrix_Fix_FixprotoTests, apzUltrix_Fix_FixprotoPatch }, + { zUltrix_Atof_ParamName, zUltrix_Atof_ParamList, apzUltrix_Atof_ParamMachs, (regex_t*)NULL, ULTRIX_ATOF_PARAM_TEST_CT, FD_MACH_ONLY, diff --git a/gcc/fixinc/hackshell.tpl b/gcc/fixinc/hackshell.tpl index b387a43b7a9..2dd5698ce9b 100644 --- a/gcc/fixinc/hackshell.tpl +++ b/gcc/fixinc/hackshell.tpl @@ -1,6 +1,5 @@ [= autogen template include =] [= -# $Id: hackshell.tpl,v 1.2 1998/12/16 21:19:08 law Exp $ # # This file contanes the shell template replacement for the # fixincl program. It is the repetitive guts of the fixincludes logic. diff --git a/gcc/fixinc/inclhack.def b/gcc/fixinc/inclhack.def index 332a3b16e18..09957254c52 100644 --- a/gcc/fixinc/inclhack.def +++ b/gcc/fixinc/inclhack.def @@ -1,4 +1,4 @@ -/* -*- Mode: C -*- $Id: inclhack.def,v 1.2 1998/12/16 21:19:09 law Exp $ */ +/* -*- Mode: C -*- */ autogen definitions inclhack; @@ -2006,6 +2006,19 @@ fix = { }; +/* + * Ultrix V4.[35] puts the declaration of uname before the definition + * of struct utsname, so the prototype (added by fixproto) causes havoc. + */ +fix = { + hackname = ultrix_fix_fixproto; + files = sys/utsname.h; + select = ULTRIX; + sed = "/^[ \t]*extern[ \t]*int[ \t]*uname();$/i\\\n" + "struct utsname;\n"; +}; + + /* * parameter to atof not const on DECstation Ultrix V4.0 and NEWS-OS 4.2R. * also get rid of bogus inline definitions in HP-UX 8.0 diff --git a/gcc/fixinc/inclhack.sh b/gcc/fixinc/inclhack.sh index 9e993eaf65f..f56e9a5f784 100755 --- a/gcc/fixinc/inclhack.sh +++ b/gcc/fixinc/inclhack.sh @@ -2,7 +2,7 @@ # # DO NOT EDIT THIS FILE (inclhack.sh) # -# It has been autogen-ed Friday October 16, 1998 at 07:29:49 AM PDT +# It has been autogen-ed Wednesday January 27, 1999 at 09:03:36 AM PST # From the definitions inclhack.def # and the template file inclhack.tpl # @@ -10,7 +10,7 @@ # files which are fixed to work correctly with ANSI C and placed in a # directory that GNU C will search. # -# This script contains 104 fixup scripts. +# This script contains 105 fixup scripts. # # See README-fixinc for more information. # @@ -125,10 +125,7 @@ for INPUT in ${INPUTLIST} ; do cd ${ORIGDIR} -cd ${INPUT} || { - echo 'fixincludes: input dir `'$INPUT"' is an invalid directory" - exit 1 -} +cd ${INPUT} || continue # # # # # # # # # # # # # # # # # # # # # # @@ -2464,7 +2461,30 @@ extern unsigned int\ # - # Fix 84: Ultrix_Atof_Param + # Fix 84: Ultrix_Fix_Fixproto + # + case "$file" in ./sys/utsname.h ) + if ( test -n "`egrep 'ULTRIX' $file`" + ) > /dev/null 2>&1 ; then + fixlist="${fixlist} + ultrix_fix_fixproto" + if [ ! -r ${DESTDIR}/$file ] + then infile=$file + else infile=${DESTDIR}/$file ; fi + + sed -e '/^[ ]*extern[ ]*int[ ]*uname();$/i\ +struct utsname; +' \ + < $infile > ${DESTDIR}/$file. + + mv -f ${DESTDIR}/$file. ${DESTDIR}/$file + fi # end of selection 'if' + ;; # case end for file name test + esac + + + # + # Fix 85: Ultrix_Atof_Param # case "$file" in ./math.h ) fixlist="${fixlist} @@ -2486,7 +2506,7 @@ extern unsigned int\ # - # Fix 85: Ultrix_Const + # Fix 86: Ultrix_Const # case "$file" in ./stdio.h ) fixlist="${fixlist} @@ -2512,7 +2532,7 @@ extern unsigned int\ # - # Fix 86: Ultrix_Ifdef + # Fix 87: Ultrix_Ifdef # case "$file" in ./sys/file.h ) if ( test -n "`egrep '#ifdef KERNEL' $file`" @@ -2533,7 +2553,7 @@ extern unsigned int\ # - # Fix 87: Ultrix_Nested_Cmnt + # Fix 88: Ultrix_Nested_Cmnt # case "$file" in ./rpc/svc.h ) fixlist="${fixlist} @@ -2551,7 +2571,7 @@ extern unsigned int\ # - # Fix 88: Ultrix_Static + # Fix 89: Ultrix_Static # case "$file" in ./machine/cpu.h ) if ( test -n "`egrep '#include \"r[34]_cpu' $file`" @@ -2574,7 +2594,7 @@ extern unsigned int\ # - # Fix 89: Undefine_Null + # Fix 90: Undefine_Null # if ( test -n "`egrep '^#[ ]*define[ ]*[ ]NULL[ ]' $file`" -a \ -z "`egrep '#[ ]*(ifn|un)def[ ]*[ ]NULL($|[ ])' $file`" @@ -2595,7 +2615,7 @@ extern unsigned int\ # - # Fix 90: Va_I960_Macro + # Fix 91: Va_I960_Macro # case "$file" in ./arch/i960/archI960.h ) if ( test -n "`egrep '__(vsiz|vali|vpad|alignof__)' $file`" @@ -2619,7 +2639,7 @@ extern unsigned int\ # - # Fix 91: Void_Null + # Fix 92: Void_Null # case "$file" in ./curses.h | \ ./dbm.h | \ @@ -2650,7 +2670,7 @@ extern unsigned int\ # - # Fix 92: Vxworks_Gcc_Problem + # Fix 93: Vxworks_Gcc_Problem # case "$file" in ./types/vxTypesBase.h ) if ( test -n "`egrep '__GNUC_TYPEOF_FEATURE_BROKEN_USE_DEFAULT_UNTIL_FIXED__' $file`" @@ -2692,7 +2712,7 @@ extern unsigned int\ # - # Fix 93: Vxworks_Needs_Vxtypes + # Fix 94: Vxworks_Needs_Vxtypes # case "$file" in ./time.h ) if ( test -n "`egrep 'uint_t[ ][ ]*_clocks_per_sec' $file`" @@ -2713,7 +2733,7 @@ extern unsigned int\ # - # Fix 94: Vxworks_Needs_Vxworks + # Fix 95: Vxworks_Needs_Vxworks # case "$file" in ./sys/stat.h ) if ( test -n "`egrep '#[ ]define[ ][ ]*__INCstath' $file`" -a \ @@ -2739,7 +2759,7 @@ extern unsigned int\ # - # Fix 95: Vxworks_Time + # Fix 96: Vxworks_Time # case "$file" in ./time.h ) if ( test -n "`egrep 'VOIDFUNCPTR' $file`" -a \ @@ -2771,7 +2791,7 @@ typedef void (*__gcc_VOIDFUNCPTR) ();\ # - # Fix 96: X11_Class + # Fix 97: X11_Class # case "$file" in ./X11/ShellP.h ) if ( test -z "`egrep '__cplusplus' $file`" @@ -2799,7 +2819,7 @@ typedef void (*__gcc_VOIDFUNCPTR) ();\ # - # Fix 97: X11_Class_Usage + # Fix 98: X11_Class_Usage # case "$file" in ./Xm/BaseClassI.h ) if ( test -z "`egrep '__cplusplus' $file`" @@ -2820,7 +2840,7 @@ typedef void (*__gcc_VOIDFUNCPTR) ();\ # - # Fix 98: X11_New + # Fix 99: X11_New # case "$file" in ./Xm/Traversal.h ) if ( test -z "`egrep '__cplusplus' $file`" @@ -2849,7 +2869,7 @@ typedef void (*__gcc_VOIDFUNCPTR) ();\ # - # Fix 99: X11_Sprintf + # Fix 100: X11_Sprintf # case "$file" in ./X11*/Xmu.h ) fixlist="${fixlist} @@ -2869,7 +2889,7 @@ extern char * sprintf();\ # - # Fix 100: Zzz_Ki_Iface + # Fix 101: Zzz_Ki_Iface # case "$file" in ./sys/ki_iface.h ) if ( test -n "`egrep 'These definitions are for HP Internal developers' $file`" @@ -2896,7 +2916,7 @@ cat > /dev/null ) < $infile > ${DESTDIR}/$file. # - # Fix 101: Zzz_Ki + # Fix 102: Zzz_Ki # case "$file" in ./sys/ki.h ) if ( test -n "`egrep '11.00 HP-UX LP64' $file`" @@ -2923,7 +2943,7 @@ cat > /dev/null ) < $infile > ${DESTDIR}/$file. # - # Fix 102: Zzz_Ki_Calls + # Fix 103: Zzz_Ki_Calls # case "$file" in ./sys/ki_calls.h ) if ( test -n "`egrep 'KI_MAX_PROCS is an arbitrary number' $file`" @@ -2950,7 +2970,7 @@ cat > /dev/null ) < $infile > ${DESTDIR}/$file. # - # Fix 103: Zzz_Ki_Defs + # Fix 104: Zzz_Ki_Defs # case "$file" in ./sys/ki_defs.h ) if ( test -n "`egrep 'Kernel Instrumentation Definitions' $file`" @@ -2977,7 +2997,7 @@ cat > /dev/null ) < $infile > ${DESTDIR}/$file. # - # Fix 104: Zzz_Time + # Fix 105: Zzz_Time # case "$file" in ./sys/time.h ) if ( test -n "`egrep 'For CASPEC, look in' $file`" @@ -3041,18 +3061,20 @@ while [ $# != 0 ]; do # cd ${INPUT} cd $1 - if [ -r $2 ] && [ ! -r $3 ]; then - cp $2 $3 >/dev/null 2>&1 || echo "Can't copy $2" >&2 - chmod +w $3 2>/dev/null - chmod a+r $3 2>/dev/null - echo Copied $2 - for include in `egrep '^[ ]*#[ ]*include[ ]*"[^/]' $3 | + if [ -f $2 ] ; then + if [ -r $2 ] && [ ! -r $3 ]; then + cp $2 $3 >/dev/null 2>&1 || echo "Can't copy $2" >&2 + chmod +w $3 2>/dev/null + chmod a+r $3 2>/dev/null + echo Copied $2 + for include in `egrep '^[ ]*#[ ]*include[ ]*"[^/]' $3 | sed -e 's/^[ ]*#[ ]*include[ ]*"\([^"]*\)".*$/\1/'` - do - dir=`echo $2 | sed -e s'|/[^/]*$||'` - dir2=`echo $3 | sed -e s'|/[^/]*$||'` - newreq="$newreq $1 $dir/$include $dir2/$include" - done + do + dir=`echo $2 | sed -e s'|/[^/]*$||'` + dir2=`echo $3 | sed -e s'|/[^/]*$||'` + newreq="$newreq $1 $dir/$include $dir2/$include" + done + fi fi shift; shift; shift done @@ -3081,6 +3103,6 @@ done cd $ORIGDIR rm -f include/assert.h -cp ${EGCS_SRCDIR}/assert.h include/assert.h +cp ${srcdir}/assert.h include/assert.h || exit 1 chmod a+r include/assert.h diff --git a/gcc/fixinc/inclhack.tpl b/gcc/fixinc/inclhack.tpl index 19cf32e2aa4..06b49aeabe9 100644 --- a/gcc/fixinc/inclhack.tpl +++ b/gcc/fixinc/inclhack.tpl @@ -1,7 +1,6 @@ [= autogen template -*- Mode: ksh -*- sh # -# $Id: inclhack.tpl,v 1.2 1998/12/16 21:19:11 law Exp $ # =] #!/bin/sh @@ -116,10 +115,7 @@ for INPUT in ${INPUTLIST} ; do cd ${ORIGDIR} -cd ${INPUT} || { - echo 'fixincludes: input dir `'$INPUT"' is an invalid directory" - exit 1 -} +cd ${INPUT} || continue # # # # # # # # # # # # # # # # # # # # # # @@ -342,18 +338,20 @@ while [ $# != 0 ]; do # cd ${INPUT} cd $1 - if [ -r $2 ] && [ ! -r $3 ]; then - cp $2 $3 >/dev/null 2>&1 || echo "Can't copy $2" >&2 - chmod +w $3 2>/dev/null - chmod a+r $3 2>/dev/null - echo Copied $2 - for include in `egrep '^[ ]*#[ ]*include[ ]*"[^/]' $3 | + if [ -f $2 ] ; then + if [ -r $2 ] && [ ! -r $3 ]; then + cp $2 $3 >/dev/null 2>&1 || echo "Can't copy $2" >&2 + chmod +w $3 2>/dev/null + chmod a+r $3 2>/dev/null + echo Copied $2 + for include in `egrep '^[ ]*#[ ]*include[ ]*"[^/]' $3 | sed -e 's/^[ ]*#[ ]*include[ ]*"\([^"]*\)".*$/\1/'` - do - dir=`echo $2 | sed -e s'|/[^/]*$||'` - dir2=`echo $3 | sed -e s'|/[^/]*$||'` - newreq="$newreq $1 $dir/$include $dir2/$include" - done + do + dir=`echo $2 | sed -e s'|/[^/]*$||'` + dir2=`echo $3 | sed -e s'|/[^/]*$||'` + newreq="$newreq $1 $dir/$include $dir2/$include" + done + fi fi shift; shift; shift done @@ -382,7 +380,7 @@ done cd $ORIGDIR rm -f include/assert.h -cp ${EGCS_SRCDIR}/assert.h include/assert.h +cp ${srcdir}/assert.h include/assert.h || exit 1 chmod a+r include/assert.h [= diff --git a/gcc/fixinc/mkfixinc.sh b/gcc/fixinc/mkfixinc.sh index fa4a6226abe..38d7d8e5b07 100755 --- a/gcc/fixinc/mkfixinc.sh +++ b/gcc/fixinc/mkfixinc.sh @@ -7,8 +7,10 @@ then exit 1 fi -echo constructing fixinc.sh for $machine -fixincludes="../fixinc.sh" +target=../fixinc.sh + +echo constructing ${target} for $machine +fixincludes="${target}" case $machine in *-*-gnu*) @@ -103,21 +105,47 @@ case $machine in ;; esac +# IF there is no include fixing, +# THEN create a no-op fixer and exit +# if test -z "$fixincludes" then - cat > ../fixinc.sh <<- _EOF_ + cat > ${target} <<- _EOF_ #! /bin/sh exit 0 _EOF_ exit 0 fi -if test -f "$fixincludes" +# IF the fixer is supplied in our source directory, +# THEN copy that into place +# +if test -f ${srcdir}/"${fixincludes}" then - echo copying $fixincludes to ../fixinc.sh - cp $fixincludes ../fixinc.sh + echo copying ${srcdir}/$fixincludes to ${target} + cp ${srcdir}/$fixincludes ${target} exit 0 fi -echo $MAKE install -$MAKE install || cp inclhack.sh .. +# OK. We gotta make the thing. +# +echo $MAKE SHELL=\"$SHELL\" install + +# make and install either the binary or the default script +# +$MAKE SHELL="$SHELL" install && exit 0 + +# Where is our inclhack script? That is the backup +# in case we are unable to make a working binary. +# +if test -f ./inclhack.sh +then + INCLHACK=./inclhack.sh +else + INCLHACK=${srcdir}/inclhack.sh +fi + +echo Could not install binary fixincludes. +echo Installing shell script instead. + +cp ${INCLHACK} ${target} diff --git a/gcc/fixinc/procopen.c b/gcc/fixinc/procopen.c new file mode 100644 index 00000000000..ef52ba41dc8 --- /dev/null +++ b/gcc/fixinc/procopen.c @@ -0,0 +1,260 @@ + +/* + * server.c Set up and handle communications with a server process. + * + * Server Handling copyright 1992-1999 The Free Software Foundation + * + * Server Handling is free software. + * You may redistribute it and/or modify it under the terms of the + * GNU General Public License, as published by the Free Software + * Foundation; either version 2, or (at your option) any later version. + * + * Server Handling is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Server Handling. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * As a special exception, The Free Software Foundation gives + * permission for additional uses of the text contained in his release + * of ServerHandler. + * + * The exception is that, if you link the ServerHandler library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the ServerHandler library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by The Free + * Software Foundation under the name ServerHandler. If you copy code + * from other sources under the General Public License into a copy of + * ServerHandler, as the General Public License permits, the exception + * does not apply to the code that you add in this way. To avoid + * misleading anyone as to the status of such modified files, you must + * delete this exception notice from them. + * + * If you write modifications of your own for ServerHandler, it is your + * choice whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ +#include "config.h" + +#include +#ifdef HAVE_FCNTL_H +#include +#endif +#include +#include +#include +#include +#include +#include + +#include "server.h" + +/* 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 + +#ifndef STDIN_FILENO +# define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +# define STDOUT_FILENO 1 +#endif + +#ifdef DEBUG +#define STATIC +#else +#define STATIC static +#endif +#ifndef tSCC +#define tSCC static const char +#endif +#ifndef NUL +#define NUL '\0' +#endif + +STATIC t_pchar def_args[] = +{ (char *) NULL, (char *) NULL }; + +/* + * chain_open + * + * Given an FD for an inferior process to use as stdin, + * start that process and return a NEW FD that that process + * will use for its stdout. Requires the argument vector + * for the new process and, optionally, a pointer to a place + * to store the child's process id. + */ +int +chain_open (stdin_fd, pp_args, p_child) + int stdin_fd; + t_pchar *pp_args; + pid_t *p_child; +{ + t_fd_pair stdout_pair = {-1, -1}; + pid_t ch_id; + char *pz_cmd; + + /* + * Create a pipe it will be the child process' stdout, + * and the parent will read from it. + */ + if (pipe ((int *) &stdout_pair) < 0) + { + if (p_child != (pid_t *) NULL) + *p_child = NOPROCESS; + return -1; + } + + /* + * If we did not get an arg list, use the default + */ + if (pp_args == (t_pchar *) NULL) + pp_args = def_args; + + /* + * If the arg list does not have a program, + * assume the "SHELL" from the environment, or, failing + * that, then sh. Set argv[0] to whatever we decided on. + */ + if (pz_cmd = *pp_args, + (pz_cmd == (char *) NULL) || (*pz_cmd == '\0')) + { + + pz_cmd = getenv ("SHELL"); + if (pz_cmd == (char *) NULL) + pz_cmd = "sh"; + } + +#ifdef DEBUG_PRINT + printf ("START: %s\n", pz_cmd); + { + int idx = 0; + + while (pp_args[++idx] != (char *) NULL) + printf (" ARG %2d: %s\n", idx, pp_args[idx]); + } +#endif + + /* + * Call fork() and see which process we become + */ + ch_id = fork (); + switch (ch_id) + { + case NOPROCESS: /* parent - error in call */ + close (stdout_pair.read_fd); + close (stdout_pair.write_fd); + if (p_child != (pid_t *) NULL) + *p_child = NOPROCESS; + return -1; + + default: /* parent - return opposite FD's */ + if (p_child != (pid_t *) NULL) + *p_child = ch_id; +#ifdef DEBUG_PRINT + printf ("for pid %d: stdin from %d, stdout to %d\n" + "for parent: read from %d\n", + ch_id, stdin_fd, stdout_pair.write_fd, stdout_pair.read_fd); +#endif + close (stdin_fd); + close (stdout_pair.write_fd); + return stdout_pair.read_fd; + + case NULLPROCESS: /* child - continue processing */ + break; + } + + /* + * Close the pipe end handed back to the parent process + */ + close (stdout_pair.read_fd); + + /* + * Close our current stdin and stdout + */ + close (STDIN_FILENO); + close (STDOUT_FILENO); + + /* + * Make the fd passed in the stdin, and the write end of + * the new pipe become the stdout. + */ + fcntl (stdout_pair.write_fd, F_DUPFD, STDOUT_FILENO); + fcntl (stdin_fd, F_DUPFD, STDIN_FILENO); + + if (*pp_args == (char *) NULL) + *pp_args = pz_cmd; + + execvp (pz_cmd, pp_args); + fprintf (stderr, "Error %d: Could not execvp( '%s', ... ): %s\n", + errno, pz_cmd, strerror (errno)); + exit (EXIT_PANIC); +} + + +/* + * proc2_open + * + * Given a pointer to an argument vector, start a process and + * place its stdin and stdout file descriptors into an fd pair + * structure. The "write_fd" connects to the inferior process + * stdin, and the "read_fd" connects to its stdout. The calling + * process should write to "write_fd" and read from "read_fd". + * The return value is the process id of the created process. + */ +pid_t +proc2_open (p_pair, pp_args) + t_fd_pair *p_pair; + t_pchar *pp_args; +{ + pid_t ch_id; + + /* Create a bi-directional pipe. Writes on 0 arrive on 1 and vice + versa, so the parent and child processes will read and write to + opposite FD's. */ + if (pipe ((int *) p_pair) < 0) + return NOPROCESS; + + p_pair->read_fd = chain_open (p_pair->read_fd, pp_args, &ch_id); + if (ch_id == NOPROCESS) + close (p_pair->write_fd); + + return ch_id; +} + + +/* + * proc2_fopen + * + * Identical to "proc2_open()", except that the "fd"'s are + * "fdopen(3)"-ed into file pointers instead. + */ +pid_t +proc2_fopen (pf_pair, pp_args) + t_pf_pair *pf_pair; + t_pchar *pp_args; +{ + t_fd_pair fd_pair; + pid_t ch_id = proc2_open (&fd_pair, pp_args); + + if (ch_id == NOPROCESS) + return ch_id; + + pf_pair->pf_read = fdopen (fd_pair.read_fd, "r"); + pf_pair->pf_write = fdopen (fd_pair.write_fd, "w"); + return ch_id; +} diff --git a/gcc/fixinc/regex.c b/gcc/fixinc/regex.c index 3c6d502ed86..97cbcc1cfcd 100644 --- a/gcc/fixinc/regex.c +++ b/gcc/fixinc/regex.c @@ -25,8 +25,6 @@ #pragma alloca #endif -/* $Id: regex.c,v 1.3 1999/01/11 13:34:23 law Exp $ */ - #define _GNU_SOURCE /* We need this for `regex.h', and perhaps for the Emacs include files. */ diff --git a/gcc/fixinc/regex.h b/gcc/fixinc/regex.h index 0c3500e814f..a34ca646fe9 100644 --- a/gcc/fixinc/regex.h +++ b/gcc/fixinc/regex.h @@ -18,8 +18,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: regex.h,v 1.3 1999/01/11 13:34:25 law Exp $ */ - #ifndef __REGEXP_LIBRARY_H__ #define __REGEXP_LIBRARY_H__ diff --git a/gcc/fixinc/server.c b/gcc/fixinc/server.c index 296e30778cf..a80be74f700 100644 --- a/gcc/fixinc/server.c +++ b/gcc/fixinc/server.c @@ -1,8 +1,8 @@ /* - * $Id: server.c,v 1.2 1998/12/16 21:19:16 law Exp $ + * server.c Set up and handle communications with a server process. * - * Server Handling copyright 1992-1998 Bruce Korb + * Server Handling copyright 1992-1999 The Free Software Foundation * * Server Handling is free software. * You may redistribute it and/or modify it under the terms of the @@ -20,8 +20,9 @@ * 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * - * As a special exception, Bruce Korb gives permission for additional - * uses of the text contained in his release of ServerHandler. + * As a special exception, The Free Software Foundation gives + * permission for additional uses of the text contained in his release + * of ServerHandler. * * The exception is that, if you link the ServerHandler library with other * files to produce an executable, this does not by itself cause the @@ -32,19 +33,24 @@ * This exception does not however invalidate any other reasons why * the executable file might be covered by the GNU General Public License. * - * This exception applies only to the code released by Bruce Korb under - * the name ServerHandler. If you copy code from other sources under the - * General Public License into a copy of ServerHandler, as the General Public - * License permits, the exception does not apply to the code that you add - * in this way. To avoid misleading anyone as to the status of such - * modified files, you must delete this exception notice from them. + * This exception applies only to the code released by The Free + * Software Foundation under the name ServerHandler. If you copy code + * from other sources under the General Public License into a copy of + * ServerHandler, as the General Public License permits, the exception + * does not apply to the code that you add in this way. To avoid + * misleading anyone as to the status of such modified files, you must + * delete this exception notice from them. * * If you write modifications of your own for ServerHandler, it is your * choice whether to permit this exception to apply to your modifications. * If you do not wish that, delete this exception notice. */ +#include "config.h" +#include +#ifdef HAVE_FCNTL_H #include +#endif #include #include #include @@ -54,6 +60,20 @@ #include "server.h" +/* 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 + +#ifndef STDIN_FILENO +# define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO +# define STDOUT_FILENO 1 +#endif + #ifdef DEBUG #define STATIC #else @@ -66,398 +86,218 @@ #define NUL '\0' #endif -STATIC bool readPipeTimeout; +STATIC bool read_pipe_timeout; -STATIC tpChar defArgs[] = -{(char *) NULL, "-p", (char *) NULL}; -STATIC tpfPair serverPair = -{(FILE *) NULL, (FILE *) NULL}; -STATIC pid_t serverId = NULLPROCESS; +STATIC t_pchar def_args[] = +{ (char *) NULL, (char *) NULL }; +STATIC t_pf_pair server_pair = +{ (FILE *) NULL, (FILE *) NULL }; +STATIC pid_t server_id = NULLPROCESS; /* * Arbitrary text that should not be found in the shell output. * It must be a single line and appear verbatim at the start of * the terminating output line. */ -tSCC zDone[] = "ShElL-OuTpUt-HaS-bEeN-cOmPlEtEd"; -STATIC tpChar pCurDir = (char *) NULL; - -/* - * chainOpen - * - * Given an FD for an inferior process to use as stdin, - * start that process and return a NEW FD that that process - * will use for its stdout. Requires the argument vector - * for the new process and, optionally, a pointer to a place - * to store the child's process id. - */ -int -chainOpen (stdinFd, ppArgs, pChild) - int stdinFd; - tpChar *ppArgs; - pid_t *pChild; -{ - tFdPair stdoutPair = - {-1, -1}; - pid_t chId; - char *pzCmd; - - /* - * Create a pipe it will be the child process' stdout, - * and the parent will read from it. - */ - if ((pipe ((int *) &stdoutPair) < 0)) - { - if (pChild != (pid_t *) NULL) - *pChild = NOPROCESS; - return -1; - } - - /* - * If we did not get an arg list, use the default - */ - if (ppArgs == (tpChar *) NULL) - ppArgs = defArgs; - - /* - * If the arg list does not have a program, - * assume the "SHELL" from the environment, or, failing - * that, then sh. Set argv[0] to whatever we decided on. - */ - if (pzCmd = *ppArgs, - (pzCmd == (char *) NULL) || (*pzCmd == '\0')) - { - - pzCmd = getenv ("SHELL"); - if (pzCmd == (char *) NULL) - pzCmd = "sh"; - } -#ifdef DEBUG_PRINT - printf ("START: %s\n", pzCmd); - { - int idx = 0; - while (ppArgs[++idx] != (char *) NULL) - printf (" ARG %2d: %s\n", idx, ppArgs[idx]); - } -#endif - /* - * Call fork() and see which process we become - */ - chId = fork (); - switch (chId) - { - case NOPROCESS: /* parent - error in call */ - close (stdoutPair.readFd); - close (stdoutPair.writeFd); - if (pChild != (pid_t *) NULL) - *pChild = NOPROCESS; - return -1; - - default: /* parent - return opposite FD's */ - if (pChild != (pid_t *) NULL) - *pChild = chId; -#ifdef DEBUG_PRINT - printf ("for pid %d: stdin from %d, stdout to %d\n" - "for parent: read from %d\n", - chId, stdinFd, stdoutPair.writeFd, stdoutPair.readFd); -#endif - close (stdinFd); - close (stdoutPair.writeFd); - return stdoutPair.readFd; - - case NULLPROCESS: /* child - continue processing */ - break; - } - - /* - * Close the pipe end handed back to the parent process - */ - close (stdoutPair.readFd); - - /* - * Close our current stdin and stdout - */ - close (STDIN_FILENO); - close (STDOUT_FILENO); - - /* - * Make the fd passed in the stdin, and the write end of - * the new pipe become the stdout. - */ - fcntl (stdoutPair.writeFd, F_DUPFD, STDOUT_FILENO); - fcntl (stdinFd, F_DUPFD, STDIN_FILENO); - - if (*ppArgs == (char *) NULL) - *ppArgs = pzCmd; - - execvp (pzCmd, ppArgs); - fprintf (stderr, "Error %d: Could not execvp( '%s', ... ): %s\n", - errno, pzCmd, strerror (errno)); - exit (EXIT_PANIC); -} - - -/* - * p2open - * - * Given a pointer to an argument vector, start a process and - * place its stdin and stdout file descriptors into an fd pair - * structure. The "writeFd" connects to the inferior process - * stdin, and the "readFd" connects to its stdout. The calling - * process should write to "writeFd" and read from "readFd". - * The return value is the process id of the created process. - */ -pid_t -p2open (pPair, ppArgs) - tFdPair *pPair; - tpChar *ppArgs; -{ - pid_t chId; - - /* - * Create a bi-directional pipe. Writes on 0 arrive on 1 - * and vice versa, so the parent and child processes will - * read and write to opposite FD's. - */ - if (pipe ((int *) pPair) < 0) - return NOPROCESS; - - pPair->readFd = chainOpen (pPair->readFd, ppArgs, &chId); - if (chId == NOPROCESS) - close (pPair->writeFd); - - return chId; -} - +tSCC z_done[] = "ShElL-OuTpUt-HaS-bEeN-cOmPlEtEd"; +STATIC t_pchar p_cur_dir = (char *) NULL; /* - * p2fopen - * - * Identical to "p2open()", except that the "fd"'s are "fdopen(3)"-ed - * into file pointers instead. - */ -pid_t -p2fopen (pfPair, ppArgs) - tpfPair *pfPair; - tpChar *ppArgs; -{ - tFdPair fdPair; - pid_t chId = p2open (&fdPair, ppArgs); - - if (chId == NOPROCESS) - return chId; - - pfPair->pfRead = fdopen (fdPair.readFd, "r"); - pfPair->pfWrite = fdopen (fdPair.writeFd, "w"); - return chId; -} - - -/* - * loadData + * load_data * * Read data from a file pointer (a pipe to a process in this context) * until we either get EOF or we get a marker line back. * The read data are stored in a malloc-ed string that is truncated * to size at the end. Input is assumed to be an ASCII string. */ -STATIC char * -loadData (fp) +static char * +load_data (fp) FILE *fp; { - char *pzText; - size_t textSize; - char *pzScan; - char zLine[1024]; + char *pz_text; + size_t text_size; + char *pz_scan; + char z_line[1024]; - textSize = sizeof (zLine) * 2; - pzScan = \ - pzText = malloc (textSize); + text_size = sizeof (z_line) * 2; + pz_scan = pz_text = malloc (text_size); - if (pzText == (char *) NULL) - return pzText; + if (pz_text == (char *) NULL) + return (char *) NULL; for (;;) { - size_t usedCt; + size_t used_ct; alarm (10); - readPipeTimeout = BOOL_FALSE; - if (fgets (zLine, sizeof (zLine), fp) == (char *) NULL) - break; - - if (strncmp (zLine, zDone, sizeof (zDone) - 1) == 0) - break; - - strcpy (pzScan, zLine); - pzScan += strlen (zLine); - usedCt = (size_t) (pzScan - pzText); - - if (textSize - usedCt < sizeof (zLine)) - { - - size_t off = (size_t) (pzScan - pzText); - void *p; - textSize += 4096; - p = realloc ((void *) pzText, textSize); - if (p == (void *) NULL) - { - fprintf (stderr, "Failed to get 0x%08X bytes\n", textSize); - free ((void *) pzText); - return (char *) NULL; - } - - pzText = (char *) p; - pzScan = pzText + off; - } + read_pipe_timeout = BOOL_FALSE; + if (fgets (z_line, sizeof (z_line), fp) == (char *) NULL) + break; + + if (strncmp (z_line, z_done, sizeof (z_done) - 1) == 0) + break; + + strcpy (pz_scan, z_line); + pz_scan += strlen (z_line); + used_ct = (size_t) (pz_scan - pz_text); + + if (text_size - used_ct < sizeof (z_line)) + { + size_t off = (size_t) (pz_scan - pz_text); + void *p; + + text_size += 4096; + p = realloc ((void *) pz_text, text_size); + if (p == (void *) NULL) + { + fprintf (stderr, "Failed to get 0x%08X bytes\n", text_size); + free ((void *) pz_text); + return (char *) NULL; + } + pz_text = (char *) p; + pz_scan = pz_text + off; + } } alarm (0); - if (readPipeTimeout) + if (read_pipe_timeout) { - free ((void *) pzText); + free ((void *) pz_text); return (char *) NULL; } - while ((pzScan > pzText) && isspace (pzScan[-1])) - pzScan--; - *pzScan = NUL; - return realloc ((void *) pzText, strlen (pzText) + 1); + while ((pz_scan > pz_text) && isspace (pz_scan[-1])) + pz_scan--; + *pz_scan = NUL; + return realloc ((void *) pz_text, strlen (pz_text) + 1); } /* - * SHELL SERVER PROCESS CODE + * close_server + * + * Make certain the server process is dead, close the + * pipes to it and from it, finally NULL out the file pointers */ - -#ifdef DONT_HAVE_SIGSEND -typedef enum +static void +close_server () { - P_ALL, P_PID, P_GID, P_UID, P_PGID, P_SID, P_CID + kill ((pid_t) server_id, SIGKILL); + server_id = NULLPROCESS; + fclose (server_pair.pf_read); + fclose (server_pair.pf_write); + server_pair.pf_read = server_pair.pf_write = (FILE *) NULL; } -idtype_t; -typedef long id_t; - -STATIC int -sigsend (idtype, id, sig) - idtype_t idtype; - id_t id; - int sig; -{ - switch (idtype) - { - case P_PID: - kill ((pid_t) id, sig); - break; - - case P_ALL: - case P_GID: - case P_UID: - case P_PGID: - case P_SID: - case P_CID: - errno = EINVAL; - return -1; - /*NOTREACHED */ - } - - return 0; -} -#endif /* HAVE_SIGSEND */ - -STATIC void -closeServer () -{ - kill( (pid_t) serverId, SIGKILL); - serverId = NULLPROCESS; - fclose (serverPair.pfRead); - fclose (serverPair.pfWrite); - serverPair.pfRead = serverPair.pfWrite = (FILE *) NULL; -} - - -struct sigaction savePipeAction; -struct sigaction saveAlrmAction; -struct sigaction currentAction; - -STATIC void -sigHandler (signo) +/* + * sig_handler really only handles the timeout and pipe signals. + * This ensures that we do not wait forever on a request + * to our server, and also that if the server dies, we do not + * die from a sigpipe problem. + */ +static void +sig_handler (signo) int signo; { - closeServer (); - readPipeTimeout = BOOL_TRUE; + close_server (); + read_pipe_timeout = BOOL_TRUE; } -STATIC void -serverSetup () +/* + * server_setup Establish the signal handler for PIPE and ALARM. + * Also establishes the current directory to give to the + * server process at the start of every server command. + */ +static void +server_setup () { -#ifndef SA_SIGINFO -# define SA_SIGINFO 0 -#else - currentAction.sa_sigaction = -#endif - currentAction.sa_handler = sigHandler; - currentAction.sa_flags = SA_SIGINFO; - sigemptyset( ¤tAction.sa_mask ); + static int atexit_done = 0; + + if (atexit_done++ == 0) + atexit (&close_server); - sigaction( SIGPIPE, ¤tAction, &savePipeAction ); - sigaction( SIGALRM, ¤tAction, &saveAlrmAction ); - atexit( &closeServer ); + signal (SIGPIPE, sig_handler); + signal (SIGALRM, sig_handler); - fputs ("trap : INT\n", serverPair.pfWrite); - fflush (serverPair.pfWrite); - pCurDir = getcwd ((char *) NULL, MAXPATHLEN + 1); + fputs ("trap : 1\n", server_pair.pf_write); + fflush (server_pair.pf_write); + p_cur_dir = getcwd ((char *) NULL, MAXPATHLEN + 1); } +/* + * run_shell + * + * Run a shell command on the server. The command string + * passed in is wrapped inside the sequence: + * + * cd + * + * echo + * echo + * + * This ensures that all commands start at a known place in + * the directory structure, that any incomplete output lines + * are completed and that our special marker sequence appears on + * a line by itself. We have chosen a marker that is + * excessively unlikely to be reproduced in normal output: + * + * "ShElL-OuTpUt-HaS-bEeN-cOmPlEtEd" + */ char * -runShell (pzCmd) - const char *pzCmd; +run_shell (pz_cmd) + const char *pz_cmd; { - tSCC zNil[] = ""; + /* IF the shell server process is not running yet, + THEN try to start it. */ + if (server_id == NULLPROCESS) + { + server_id = proc2_fopen (&server_pair, def_args); + if (server_id > 0) + server_setup (); + } - /* - * IF the shell server process is not running yet, - * THEN try to start it. - */ - if (serverId == NULLPROCESS) + /* IF it is still not running, THEN return the nil string. */ + if (server_id <= 0) { - serverId = p2fopen (&serverPair, defArgs); - if (serverId > 0) - serverSetup (); + char *pz = (char *) malloc (1); + + if (pz != (char *) NULL) + *pz = '\0'; + return pz; } - /* - * IF it is still not running, - * THEN return the nil string. - */ - if (serverId <= 0) - return (char *) zNil; + /* Make sure the process will pay attention to us, send the + supplied command, and then have it output a special marker that + we can find. */ + fprintf (server_pair.pf_write, "\\cd %s\n%s\n\necho\necho %s\n", + p_cur_dir, pz_cmd, z_done); + fflush (server_pair.pf_write); - /* - * Make sure the process will pay attention to us, - * send the supplied command, and then - * have it output a special marker that we can find. - */ - fprintf (serverPair.pfWrite, "\\cd %s\n%s\n\necho\necho %s\n", - pCurDir, pzCmd, zDone); - fflush (serverPair.pfWrite); - if (serverId == NULLPROCESS) - return (char *) NULL; + /* IF the server died and we received a SIGPIPE, + THEN return an empty string. */ + if (server_id == NULLPROCESS) + { + char *pz = (char *) malloc (1); + + if (pz != (char *) NULL) + *pz = '\0'; + return pz; + } - /* - * Now try to read back all the data. If we fail due to either - * a sigpipe or sigalrm (timeout), we will return the nil string. - */ + /* Now try to read back all the data. If we fail due to either a + sigpipe or sigalrm (timeout), we will return the nil string. */ { - char *pz = loadData (serverPair.pfRead); + char *pz = load_data (server_pair.pf_read); + if (pz == (char *) NULL) { - fprintf (stderr, "CLOSING SHELL SERVER - command failure:\n\t%s\n", - pzCmd); - closeServer (); - pz = (char *) zNil; + fprintf (stderr, "CLOSING SHELL SERVER - command failure:\n\t%s\n", + pz_cmd); + close_server (); + pz = (char *) malloc (1); + if (pz != (char *) NULL) + *pz = '\0'; } return pz; } diff --git a/gcc/fixinc/server.h b/gcc/fixinc/server.h index aef8df7da84..0c2a0bf6093 100644 --- a/gcc/fixinc/server.h +++ b/gcc/fixinc/server.h @@ -1,8 +1,8 @@ /* - * $Id: server.h,v 1.2 1998/12/16 21:19:17 law Exp $ + * server.c Set up and handle communications with a server process. * - * Server Handling copyright 1992-1998 Bruce Korb + * Server Handling copyright 1992-1999 The Free Software Foundation * * Server Handling is free software. * You may redistribute it and/or modify it under the terms of the @@ -20,8 +20,9 @@ * 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * - * As a special exception, Bruce Korb gives permission for additional - * uses of the text contained in his release of ServerHandler. + * As a special exception, The Free Software Foundation gives + * permission for additional uses of the text contained in his release + * of ServerHandler. * * The exception is that, if you link the ServerHandler library with other * files to produce an executable, this does not by itself cause the @@ -32,12 +33,13 @@ * This exception does not however invalidate any other reasons why * the executable file might be covered by the GNU General Public License. * - * This exception applies only to the code released by Bruce Korb under - * the name ServerHandler. If you copy code from other sources under the - * General Public License into a copy of ServerHandler, as the General Public - * License permits, the exception does not apply to the code that you add - * in this way. To avoid misleading anyone as to the status of such - * modified files, you must delete this exception notice from them. + * This exception applies only to the code released by The Free + * Software Foundation under the name ServerHandler. If you copy code + * from other sources under the General Public License into a copy of + * ServerHandler, as the General Public License permits, the exception + * does not apply to the code that you add in this way. To avoid + * misleading anyone as to the status of such modified files, you must + * delete this exception notice from them. * * If you write modifications of your own for ServerHandler, it is your * choice whether to permit this exception to apply to your modifications. @@ -48,47 +50,45 @@ #define FIXINC_SERVER_H #include +#ifdef HAVE_UNISTD_H #include +#endif /* * Dual pipe opening of a child process */ typedef struct - { - int readFd; - int writeFd; - } -tFdPair; +{ + int read_fd; + int write_fd; +} t_fd_pair; typedef struct - { - FILE *pfRead; /* parent read fp */ - FILE *pfWrite; /* parent write fp */ - } -tpfPair; +{ + FILE *pf_read; /* parent read fp */ + FILE *pf_write; /* parent write fp */ +} t_pf_pair; -typedef char *tpChar; +typedef char *t_pchar; -#define NOPROCESS ((pid_t)-1) -#define NULLPROCESS ((pid_t)0) +#define NOPROCESS ((pid_t) -1) +#define NULLPROCESS ((pid_t)0) -#define EXIT_PANIC 99 +#define EXIT_PANIC 99 typedef enum - { - BOOL_FALSE, BOOL_TRUE - } -bool; +{ + BOOL_FALSE, BOOL_TRUE +} bool; -#define _P_(p) () +#define _P_(p) () -char *runShell _P_ ((const char *pzCmd)); -pid_t p2fopen _P_ ((tpfPair * pfPair, tpChar * ppArgs)); -pid_t p2open _P_ ((tFdPair * pPair, tpChar * ppArgs)); -int -chainOpen _P_ ((int stdinFd, - tpChar * ppArgs, - pid_t * pChild)); +char *run_shell _P_ (( const char *pzCmd)); +pid_t proc2_fopen _P_ (( t_pf_pair * p_pair, t_pchar * pp_args)); +pid_t proc2_open _P_ (( t_fd_pair * p_pair, t_pchar * pp_args)); +int chain_open _P_ (( int in_fd, + t_pchar * pp_args, + pid_t * p_child)); #endif /* FIXINC_SERVER_H */ -- 2.30.2