bug-cvs
[Top][All Lists]
Advanced

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

arguments limit


From: Jiri Moskovcak
Subject: arguments limit
Date: Fri, 12 Sep 2008 13:27:13 +0200
User-agent: Thunderbird 2.0.0.16 (X11/20080723)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,
I'm redhat cvs mainter and recently I've got this bugreport (feature
request) I've checked the patch and it seems ok to me and as it's quite
 critical for (at least our) kernel guys to tag many files and might be
useful for others also. I'd like to ask you to consider adding this
patch into upstream.

Thank you,
J. Moskovcak

Aristeu Rozanski wrote:
> Hello Jiri,
>       recently Don Zickus hit a CVS/kernel problem on cvs.devel.redhat.com
> while trying to release a new kernel. The problem consists of trying to tag
> the kernel package contents which now appears to contain too much patches with
> names too long, too much to be allowed as arguments. And on 
> cvs.devel.redhat.com
> we use several CVS hooks such as scripts before every tag operation and now
> that's failing because of the high volume of patches/patch names.
> I managed to cook a patch to allow hook files to accept commands that start by
> a |:
>       ALL     /usr/sbin/script1
>       ALL     |/usr/sbin/script2
> that would allow, when needed, to call an application passing all the 
> arguments
> by the standard input instead. I wrote the patch to be less intrusive as
> possible.
> I was wondering if you could comment on and submit it upstream for inclusion.
> The patch is based on the version present in RHEL-5 that is the latest stable.
> 
> Thanks
> 
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iEYEARECAAYFAkjKUhEACgkQWQVtHdDK37kGjACfUecY9qEvlS/aN8C8C55hcWoj
+DgAn1mBlZIB0klRXQySq1FNOFt43qso
=/Fwe
-----END PGP SIGNATURE-----
--- cvs-1.11.22.orig/src/cvs.h  2008-09-09 13:46:07.000000000 -0400
+++ cvs-1.11.22/src/cvs.h       2008-09-09 13:46:13.000000000 -0400
@@ -695,6 +695,8 @@ void sleep_past PROTO ((time_t desttime)
 #define        RUN_STDOUT_APPEND     0x0004    /* append to stdout, don't 
truncate */
 #define        RUN_STDERR_APPEND     0x0008    /* append to stderr, don't 
truncate */
 #define        RUN_SIGIGNORE         0x0010    /* ignore interrupts for 
command */
+#define        RUN_PIPE              0x0020    /* pass the arguments by stdin 
instead
+                                         * as arguments */
 #define        RUN_TTY               (char *)0 /* for the benefit of lint */
 
 void run_add_arg_p PROTO ((int *, size_t *, char ***, const char *s));
--- cvs-1.11.22.orig/src/run.c  2005-10-03 16:31:12.000000000 -0400
+++ cvs-1.11.22/src/run.c       2008-09-09 13:49:15.000000000 -0400
@@ -123,6 +123,8 @@ run_exec (stin, stout, sterr, flags)
     int rc = -1;
     int rerrno = 0;
     int pid, w;
+    int pipefd[2];
+    char *run_argv2[3] = { NULL, "-", NULL };
 
 #ifdef POSIX_SIGNALS
     sigset_t sigset_mask, sigset_omask;
@@ -163,7 +165,26 @@ run_exec (stin, stout, sterr, flags)
     mode_out |= ((flags & RUN_STDOUT_APPEND) ? O_APPEND : O_TRUNC);
     mode_err |= ((flags & RUN_STDERR_APPEND) ? O_APPEND : O_TRUNC);
 
-    if (stin && (shin = open (stin, O_RDONLY)) == -1)
+    if (*(run_argv[0]) == '|')
+    {
+        char *buf;
+
+        if (pipe(pipefd) == -1) {
+           rerrno = errno;
+           error (0, errno, "unable to open pipe");
+           goto out0;
+        }
+        flags |= RUN_PIPE;
+        shin = pipefd[0];
+        buf = strdup(run_argv[0] + 1); /* skip '|' */
+        if (buf == NULL) {
+            rc = ENOMEM;
+            error (0, errno, "unable to allocate memory");
+            goto out1;
+        }
+        run_argv2[0] = buf;
+    }
+    else if (stin && (shin = open (stin, O_RDONLY)) == -1)
     {
        rerrno = errno;
        error (0, errno, "cannot open %s for reading (prog %s)",
@@ -239,8 +260,14 @@ run_exec (stin, stout, sterr, flags)
 #endif
 
        /* dup'ing is done.  try to run it now */
-       (void) execvp (run_argv[0], run_argv);
-       error (0, errno, "cannot exec %s", run_argv[0]);
+        if (flags & RUN_PIPE) {
+            close(pipefd[1]);
+            (void) execvp (run_argv2[0], run_argv2);
+           error (0, errno, "cannot exec %s", run_argv2[0]);
+        } else {
+           (void) execvp (run_argv[0], run_argv);
+           error (0, errno, "cannot exec %s", run_argv[0]);
+        }
        _exit (127);
     }
     else if (pid == -1)
@@ -283,6 +310,39 @@ run_exec (stin, stout, sterr, flags)
 #endif
 #endif
 
+    /* write all the arguments in the stdout if requested */
+    if (flags & RUN_PIPE) {
+        int size, s;
+
+       close(pipefd[0]);
+        for (w = 0; run_argv[w] != NULL; w++) {
+             size = strlen(run_argv[w]);
+             s = 0;
+             while (s < size) {
+                 rc = write(pipefd[1], run_argv[w] + s, size - s);
+                 if (rc < 0 && errno != EINTR) {
+                     /* all other cases we'll just fail */
+                     rerrno = errno;
+                     error (0, errno, "unable to write to the application's 
stdin %s",
+                            run_argv2[0]);
+                     goto wait_for_process;
+                 } else if (rc > 0)
+                     s += rc;
+             }
+             do {
+                 rc = write(pipefd[1], "\n", 1);
+                 if (rc < 0 && errno != EINTR) {
+                     rerrno = errno;
+                     error (0, errno, "unable to write to the application's 
stdin %s",
+                            run_argv2[0]);
+                     goto wait_for_process;
+                 }
+             } while (rc != 1);
+        }
+wait_for_process:
+        close(pipefd[1]);
+        pipefd[1] = -1;
+    }
     /* wait for our process to die and munge return status */
 #ifdef POSIX_SIGNALS
     while ((w = waitpid (pid, &status, 0)) == -1 && errno == EINTR)
@@ -356,7 +416,14 @@ run_exec (stin, stout, sterr, flags)
         * relative to the protocol pipe
         */
        cvs_flushout();
+    if (flags & RUN_PIPE)
+        free(run_argv2[0]);
   out1:
+    if (flags & RUN_PIPE) {
+        shin = -1;
+        if (pipefd[1] != -1)
+            close(pipefd[1]);
+    }
     if (stin)
        (void) close (shin);

reply via email to

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