bison-patches
[Top][All Lists]
Advanced

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

readpipe patch again


From: Florian Krohm
Subject: readpipe patch again
Date: Fri, 3 May 2002 14:08:10 -0400 (EDT)

OK, here we go again. This time with "cvs diff -u".

Florian

------------ snip snip   new file  lib/readpipe.h ------------------

/*  Copyright (C) 2002 Free Software Foundation, Inc.

    This program 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.

    This program 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 this program; if not, write to the Free Software Foundation,
    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

#ifndef READPIPE_H
# define READPIPE_H 1

# include <stdio.h>

# ifndef PARAMS
#  if defined PROTOTYPES || (defined __STDC__ && __STDC__)
#   define PARAMS(proto) proto
#  else
#   define PARAMS(proto) ()
#  endif
# endif

FILE *read_pipe PARAMS ((const char **argv));
void  close_pipe PARAMS ((FILE *));

#endif /* !READPIPE_H */

-------------snip snip   end of lib/readpipe.h -------------------


Index: bison/ChangeLog
===================================================================
RCS file: /cvsroot/bison/bison/ChangeLog,v
retrieving revision 1.665
diff -u -r1.665 ChangeLog
--- bison/ChangeLog     3 May 2002 17:55:00 -0000       1.665
+++ bison/ChangeLog     3 May 2002 17:59:50 -0000
@@ -1,3 +1,10 @@
+2002-05-03  Florian Krohm  <address@hidden>
+
+       * configure.in (AC_FUNC_FORK): Added
+       * lib/readpipe.c: Rewritten to be more portable
+       * lib/readpipe.h: New
+       * src/output.c (output_skeleton): Adapted for new read_pipe.
+
 2002-05-03  Paul Eggert  <address@hidden>
 
        * data/bison.simple (b4_token_defines): Also define YYTOKENTYPE
Index: bison/configure.in
===================================================================
RCS file: /cvsroot/bison/bison/configure.in,v
retrieving revision 1.64
diff -u -r1.64 configure.in
--- bison/configure.in  3 May 2002 15:52:53 -0000       1.64
+++ bison/configure.in  3 May 2002 17:59:50 -0000
@@ -91,6 +91,7 @@
 AC_FUNC_OBSTACK
 AC_FUNC_ERROR_AT_LINE
 AC_FUNC_STRNLEN
+AC_FUNC_FORK
 UTILS_FUNC_MKSTEMP
 AC_CHECK_FUNCS(setlocale)
 AC_CHECK_DECLS([free, stpcpy, strchr, strspn, strnlen,
Index: bison/lib/readpipe.c
===================================================================
RCS file: /cvsroot/bison/bison/lib/readpipe.c,v
retrieving revision 1.1
diff -u -r1.1 readpipe.c
--- bison/lib/readpipe.c        5 Feb 2002 10:14:20 -0000       1.1
+++ bison/lib/readpipe.c        3 May 2002 17:59:50 -0000
@@ -1,5 +1,5 @@
-/* Open a pipe to read from a program without intermediary sh.
-   Copyright (C) 1992, 1997 Free Software Foundation, Inc.
+/* Open a pipe to read from a program.
+   Copyright (C) 1992, 1997, 2002 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -15,82 +15,122 @@
    along with this program; if not, write to the Free Software Foundation,
    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-/* Written by David MacKenzie.  */
+/* Based on code written by David MacKenzie.  */
 
 #if HAVE_CONFIG_H
 # include <config.h>
 #endif
 
-#include <stdio.h>
-
-#if __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
 #if HAVE_UNISTD_H
+# include <sys/types.h>
 # include <unistd.h>
 #endif
 
-/* Open a pipe to read from a program without intermediary sh.  Checks
-   PATH.  Sample use:
-
-   stream = readpipe ("progname", "arg1", "arg2", (char *) 0);
-
-   Return 0 on error.  */
+#ifndef _POSIX_VERSION
+# ifndef STDOUT_FILENO
+#  define STDOUT_FILENO 1
+# endif
+#endif
 
-#if __STDC__
-FILE *
-readpipe (char *progname, ...)
+#if STDC_HEADERS
+# include <string.h>
 #else
-FILE *
-readpipe (va_alist)
+# if HAVE_STRINGS_G
+#  include <strings.h>
+# endif
 #endif
+
+#include <errno.h>
+#include "quotearg.h"
+#include "xalloc.h"
+#include "readpipe.h"
+
+/* Open a pipe to read from a program. ARGV represents the argument list of the
+   invoked program and must be NULL-terminated. On error, the function returns
+   NULL and errno can be queried for the specific cause of failure. */
+FILE *
+read_pipe (const char **argv)
 {
-#if ! __STDC__
-  char *progname;
-#endif
+  FILE *fp;
+
+#if HAVE_WORKING_FORK || HAVE_WORKING_VFORK
+
   int fds[2];
-  va_list ap;
-  char *args[100];
-  int argno = 0;
-
-  /* Copy arguments into `args'. */
-#if __STDC__
-  va_start (ap, progname);
-#else
-  va_start (ap);
-  progname = va_arg (ap, char *);
-#endif
-  args[argno++] = progname;
-  while ((args[argno++] = va_arg (ap, char *)) != NULL)
-    ;
-  va_end (ap);
+  pid_t pid;
+
+  if (pipe (fds) != 0)
+    return NULL;
 
-  if (pipe (fds) == -1)
-    return 0;
+  pid = vfork ();
 
-  switch (fork ())
+  if (pid == -1)
+    return NULL;
+
+  if (pid == 0)
     {
-    case 0:                    /* Child.  Write to pipe. */
-      close (fds[0]);          /* Not needed. */
-      if (fds[1] != 1)         /* Redirect 1 (stdout) only if needed.  */
+      /* Child */
+      close (fds[0]);    /* Close read end */
+      if (fds[1] != STDOUT_FILENO)
        {
-         close (1);            /* We don't want the old stdout. */
-         if (dup (fds[1]) == 0)/* Maybe stdin was closed. */
-           {
-             dup (fds[1]);     /* Guaranteed to dup to 1 (stdout). */
-             close (0);
-           }
-         close (fds[1]);       /* No longer needed. */
+         if (dup2 (fds[1], STDOUT_FILENO) != STDOUT_FILENO)
+           return NULL;
+         
+         close (fds[1]);
        }
-      execvp (args[0], args);
-      _exit (2);               /* 2 for `cmp'. */
-    case -1:                   /* Error. */
-      return 0;
-    default:                   /* Parent.  Read from pipe. */
-      close (fds[1]);          /* Not needed. */
-      return fdopen (fds[0], "r");
+      
+      /* The cast to (char **) is needed for portability to older
+        hosts with a nonstandard prototype for execvp.  */
+      execvp (argv[0], (char **)argv);
+       
+      _exit (errno == ENOEXEC ? 126 : 127);
+    }
+  
+    /* Parent */
+  close (fds[1]);    /* Close write end */
+  
+  fp = fdopen (fds[0], "r");
+
+#else 
+
+  /* Open pipe using popen. Since popen invokes a shell under the covers
+     we need to escape the arguments. */
+  char *command, *s, *quoted;
+  const char **p;
+  unsigned buf_size;
+
+  buf_size = 0;
+  for (p = argv; *p; ++p) 
+    {
+      buf_size += strlen (quotearg_style (shell_quoting_style, *p)) + 1;
+    }
+    
+  command = s = xmalloc (buf_size);
+  quoted = quotearg_style (shell_quoting_style, argv[0]);
+  strcpy (s, quoted);
+  s += strlen (quoted);
+               
+  for (p = argv + 1; *p; ++p) 
+    {
+      *s++ = ' ';
+      quoted = quotearg_style (shell_quoting_style, *p);
+      strcpy (s, quoted);
+      s += strlen (quoted);
     }
+  *s = '\0';
+
+  fp = popen (command, "r");
+  free (command);
+#endif
+
+  return fp;
+}
+
+void
+close_pipe (FILE *fp)
+{
+#if HAVE_WORKING_FORK || HAVE_WORKING_VFORK
+  fclose (fp);
+#else
+  pclose (fp);
+#endif
 }
Index: bison/src/output.c
===================================================================
RCS file: /cvsroot/bison/bison/src/output.c,v
retrieving revision 1.150
diff -u -r1.150 output.c
--- bison/src/output.c  3 May 2002 08:42:48 -0000       1.150
+++ bison/src/output.c  3 May 2002 17:59:50 -0000
@@ -103,9 +103,7 @@
 #include "symtab.h"
 #include "conflicts.h"
 #include "muscle_tab.h"
-
-/* From lib/readpipe.h.  */
-FILE *readpipe PARAMS ((const char *, ...));
+#include "readpipe.h"
 
 /* From src/scan-skel.l. */
 int skel_lex PARAMS ((void));
@@ -1004,6 +1002,7 @@
 
   /* Invoke m4 on the definition of the muscles, and the skeleton. */
   {
+    const char *argv[7];
     const char *bison_pkgdatadir = getenv ("BISON_PKGDATADIR");
     const char *m4 = getenv ("M4");
     if (!m4)
@@ -1014,15 +1013,21 @@
       fprintf (stderr,
               "running: %s -I %s m4sugar/m4sugar.m4 %s %s\n",
               m4, bison_pkgdatadir, tempfile, skeleton);
-    skel_in = readpipe (m4,
-                       "-I", bison_pkgdatadir,
-                       "m4sugar/m4sugar.m4",
-                       tempfile,
-                       skeleton,
-                       NULL);
+    argv[0] = m4;
+    argv[1] = "-I";
+    argv[2] = bison_pkgdatadir;
+    argv[3] = "m4sugar/m4sugar.m4";
+    argv[4] = tempfile;
+    argv[5] = skeleton;
+    argv[6] = NULL;
+
+    skel_in = read_pipe (argv);
+
     if (!skel_in)
       error (EXIT_FAILURE, errno, "cannot run m4");
     skel_lex ();
+
+    close_pipe (skel_in);
 
     /* If `debugging', keep this file alive. */
     if (!trace_flag)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]