tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: rpcgen with env variable CPP set to "cc -E"



David Holland writes:
| But I'm wondering if it would be better to pass the lot to system() or
| sh -c instead of reimplementing arg splitting yet again. Or just use
| popen() instead of forking explicitly.

Here is my proposal, with a popen().
I didn't compile/test the __MSDOS__ case (where does that #ifdef come
from??); I replaced the spawnvp by a system, I guess it should work.

The good news is that rpcgen now handle `env CPP="cc -E"` correctly.
The bad news is that it doesn't help me much since cc -E doesn't handle
files ending in .x correctly ... it needs a "-x c" option ... sigh ...
But that's definitely not the rpcgen problem anymore.

Here's the diff:
Index: rpc_main.c
===================================================================
RCS file: /cvsroot/src/usr.bin/rpcgen/rpc_main.c,v
retrieving revision 1.29
diff -u -r1.29 rpc_main.c
--- rpc_main.c  12 Jan 2008 05:49:46 -0000      1.29
+++ rpc_main.c  14 Jan 2008 22:46:37 -0000
@@ -96,11 +96,8 @@
 };
 static int allnc = sizeof(allnv) / sizeof(allnv[0]);
 
-#define ARGLISTLEN     20
-#define FIXEDARGS         2
-
-static char *arglist[ARGLISTLEN];
-static int argcount = FIXEDARGS;
+static char *arglist = NULL;
+static int argcount = 0;
 
 
 int     nonfatalerrors;                /* errors */
@@ -150,7 +147,6 @@
 static void clnt_output __P((char *, char *, int, char *));
 static int do_registers __P((int, char *[]));
 static void addarg __P((char *));
-static void putarg __P((int, char *));
 static void checkfiles __P((char *, char *));
 static int parseargs __P((int, char *[], struct commandline *));
 static void usage __P((void));
@@ -236,6 +232,10 @@
                (void) fclose(fin);
                (void) unlink(dos_cppfile);
        }
+#else
+       if (fin != NULL) {
+               pclose(fin);
+       }
 #endif
        exit(nonfatalerrors);
        /* NOTREACHED */
@@ -309,10 +309,11 @@
 static void 
 clear_args()
 {
-       int     i;
-       for (i = FIXEDARGS; i < ARGLISTLEN; i++)
-               arglist[i] = NULL;
-       argcount = FIXEDARGS;
+       if (arglist != NULL) {
+               free(arglist);
+               arglist = NULL;
+       }
+       argcount = 0;
 }
 
 /*
@@ -323,8 +324,6 @@
        char   *infile;
        char   *define;
 {
-       int     pd[2];
-
        infilename = (infile == NULL) ? "<stdin>" : infile;
 #ifdef __MSDOS__
 #define        DOSCPP  "\\prog\\bc31\\bin\\cpp.exe"
@@ -338,14 +337,14 @@
                    && (cpp = getenv("RPCGENCPP")) == NULL)
                        cpp = DOSCPP;
 
-               putarg(0, cpp);
-               putarg(1, "-P-");
-               putarg(2, CPPFLAGS);
+               clear_args();
+               addarg(cpp);
+               addarg("-P-");
+               addarg(CPPFLAGS);
                addarg(define);
                addarg(infile);
-               addarg(NULL);
 
-               retval = spawnvp(P_WAIT, arglist[0], arglist);
+               retval = system(arglist);
                if (retval != 0) {
                        fprintf(stderr, "%s: C PreProcessor failed\n", cmdname);
                        crash();
@@ -366,25 +365,13 @@
                }
        }
 #else
-       (void) pipe(pd);
-       switch (fork()) {
-       case 0:
-               putarg(0, CPP);
-               putarg(1, CPPFLAGS);
-               addarg(define);
-               addarg(infile);
-               addarg((char *) NULL);
-               (void) close(1);
-               (void) dup2(pd[1], 1);
-               (void) close(pd[0]);
-               execvp(arglist[0], arglist);
-               err(1, "$CPP: %s", CPP);
-       case -1:
-               perror("fork");
-               exit(1);
-       }
-       (void) close(pd[1]);
-       fin = fdopen(pd[0], "r");
+       clear_args();
+       addarg(CPP);
+       addarg(CPPFLAGS);
+       addarg(define);
+       addarg(infile);
+
+       fin = popen(arglist, "r");
 #endif
        if (fin == NULL) {
                f_print(stderr, "%s: ", cmdname);
@@ -843,28 +830,25 @@
 addarg(cp)
        char   *cp;
 {
-       if (argcount >= ARGLISTLEN) {
+       size_t len;
+       char *newarg;
+
+       len = strlen(cp) + 1 /* space, or \0 if arglist == NULL */;
+       newarg = realloc(arglist, argcount + len);
+       if (newarg == NULL) {
                f_print(stderr, "rpcgen: too many defines\n");
                crash();
                /* NOTREACHED */
        }
-       arglist[argcount++] = cp;
-
+       arglist = newarg;
+       if (argcount > 0)
+               strcat(arglist, " ");
+       else
+               arglist[0] = '\0';
+       strcat(arglist, cp);
+       argcount += len;
 }
 
-static void
-putarg(where, cp)
-       char   *cp;
-       int     where;
-{
-       if (where >= ARGLISTLEN) {
-               f_print(stderr, "rpcgen: arglist coding error\n");
-               crash();
-               /* NOTREACHED */
-       }
-       arglist[where] = cp;
-
-}
 /*
  * if input file is stdin and an output file is specified then complain
  * if the file already exists. Otherwise the file may get overwritten


Home | Main Index | Thread Index | Old Index