Bug#719692: Make run-parts useful for running hook scripts

2019-09-02 Thread Dmitry Bogatov


control: tags -1 +patch

[2019-08-19 11:28] Dmitry Bogatov 
> [2019-08-16 17:35] Clint Adams 
> > On Thu, Aug 15, 2019 at 09:24:46PM +, Dmitry Bogatov wrote:
> > > I want this feature too. Dear maintainer, are you interested? Will you
> > > accept patch?
> >
> > Sure.  Would you read all of stdin into memory or would you
> > do something else?
>
> I use temporary file. Do you foresee problems with it? Here is patch.
> Note, it uses Linux-only (I believe) O_TMPFILE. I can make it
> posix-compliant if you want.
> [...]

Ping?
-- 
Note, that I send and fetch email in batch, once in a few days.
Please, mention in body of your reply when you add or remove recepients.



Bug#719692: Make run-parts useful for running hook scripts

2019-08-19 Thread Dmitry Bogatov


[2019-08-16 17:35] Clint Adams 
> On Thu, Aug 15, 2019 at 09:24:46PM +, Dmitry Bogatov wrote:
> > I want this feature too. Dear maintainer, are you interested? Will you
> > accept patch?
>
> Sure.  Would you read all of stdin into memory or would you
> do something else?

I use temporary file. Do you foresee problems with it? Here is patch.
Note, it uses Linux-only (I believe) O_TMPFILE. I can make it
posix-compliant if you want.

From 0d5c423d5305092be9b28cc3dcd55604af24827d Mon Sep 17 00:00:00 2001
From: Dmitry Bogatov 
Date: Sat, 17 Aug 2019 05:38:10 +
Subject: [PATCH] run-parts: add option to multiplex stdin for children

Closes: #719692
---
 run-parts.c | 71 +
 1 file changed, 71 insertions(+)

diff --git a/run-parts.c b/run-parts.c
index 9a80229..64022f8 100644
--- a/run-parts.c
+++ b/run-parts.c
@@ -11,6 +11,7 @@
  * Based on run-parts.pl version 0.2, Copyright (C) 1994 Ian Jackson.
  *
  */
+#define _GNU_SOURCE
 
 #include 
 #include 
@@ -44,6 +45,9 @@ int exitstatus = 0;
 int regex_mode = 0;
 int exit_on_error_mode = 0;
 int new_session_mode = 0;
+int stdin_mode = 0;
+int stdin_fd = -1; // initialized in run_parts() if {stdin_mode} != 0
+
 
 int argcount = 0, argsize = 0;
 char **args = 0;
@@ -95,6 +99,7 @@ void usage()
  "  --reverse   reverse execution order of scripts.\n"
  "  --exit-on-error exit as soon as a script returns with a 
non-zero exit\n"
  "  code.\n"
+ "  --stdin multiplex stdin to scripts being run, using 
temporary file\n"
  "  --lsbsysinitvalidate filenames based on LSB sysinit 
specs.\n"
  "  --new-session   run each script in a separate process 
session\n"
  "  --regex=PATTERN validate filenames based on POSIX ERE pattern 
PATTERN.\n"
@@ -184,6 +189,17 @@ void run_part(char *progname)
 restore_signals();
 if (new_session_mode)
   setsid();
+
+if (stdin_mode) {
+  if (dup2(stdin_fd, STDIN_FILENO) == -1) {
+error("dup2: %s", strerror(errno));
+exit(1);
+  }
+  if (lseek(STDIN_FILENO, 0, SEEK_SET) == (off_t) -1) {
+error("run-parts: failed to rewind temporary file: %s\n", 
strerror(errno));
+exit(1);
+  }
+}
 if (report_mode) {
   if (dup2(pout[1], STDOUT_FILENO) == -1 ||
  dup2(perr[1], STDERR_FILENO) == -1) {
@@ -370,6 +386,52 @@ static void restore_signals()
 sigprocmask(SIG_UNBLOCK, , NULL);
 }
 
+/* 
+ * Copy stdin into temporary read-write file, and return file descriptor to it.
+ */
+static int copy_stdin(void)
+{
+  int fd;
+  const char *tmpdir;
+  char buffer[4096];
+  ssize_t bytes;
+  
+  tmpdir = getenv("TMPDIR");
+  if (!tmpdir) {
+tmpdir = "/tmp";
+  };
+
+  fd = open(tmpdir, O_TMPFILE|O_RDWR|O_EXCL, S_IRUSR | S_IWUSR);
+  if (fd < 0) {
+return -1;
+  };
+
+  do {
+ssize_t rest;
+
+bytes = rest = read(STDIN_FILENO, buffer, sizeof(buffer));
+if (bytes < 0) {
+  error("run-parts: failed to read from stdin\n");
+  close(fd);
+  return -1;
+}
+
+while (rest > 0) {
+  ssize_t written;
+
+  written = write(fd, buffer, rest);
+  if (written < 0) {
+error("run-parts: failed to write to temporary file\n");
+close(fd);
+return -1;
+  }
+  rest -= written;
+}
+  } while (bytes > 0);
+
+  return fd;
+}
+
 /* Find the parts to run & call run_part() */
 void run_parts(char *dirname)
 {
@@ -397,6 +459,14 @@ void run_parts(char *dirname)
 exit(1);
   }
 
+  if (stdin_mode) {
+stdin_fd = copy_stdin();
+if (stdin_fd < 0) {
+  error("run-parts: failed to copy content of stdin\n");
+  exit(1);
+}
+  }
+
   i = reverse_mode ? 0 : entries;
   for (i = reverse_mode ? (entries - 1) : 0;
reverse_mode ? (i >= 0) : (i < entries); reverse_mode ? i-- : i++) {
@@ -497,6 +567,7 @@ int main(int argc, char *argv[])
   {"version", 0, 0, 'V'},
   {"lsbsysinit", 0, _mode, RUNPARTS_LSBSYSINIT},
   {"regex", 1, _mode, RUNPARTS_ERE},
+  {"stdin", 0, _mode, 1},
   {"exit-on-error", 0, _on_error_mode, 1},
   {"new-session", 0, _session_mode, 1},
   {0, 0, 0, 0}
-- 
Note, that I send and fetch email in batch, once in a few days.
Please, mention in body of your reply when you add or remove recepients.



Bug#719692: Make run-parts useful for running hook scripts

2019-08-16 Thread Clint Adams
On Thu, Aug 15, 2019 at 09:24:46PM +, Dmitry Bogatov wrote:
> I want this feature too. Dear maintainer, are you interested? Will you
> accept patch?

Sure.  Would you read all of stdin into memory or would you
do something else?



Bug#719692: Make run-parts useful for running hook scripts

2019-08-15 Thread Dmitry Bogatov


[2013-08-14 12:48] Michael Haggerty 
> Package: debianutils
> Version: 4.2.1
> Severity: wishlist
> [...]
> Just the thing for run-parts!
>
> But hook scripts are often fed some data on their stdin.  For example,
> the Git post-receive hook receives input that tells what references have
> been changed, one line per reference.  These data would be needed by
> *each* of the sub-hook scripts for them to run correctly.

I want this feature too. Dear maintainer, are you interested? Will you
accept patch?
-- 
Note, that I send and fetch email in batch, once in a few days.
Please, mention in body of your reply when you add or remove recepients.



Bug#719692: Make run-parts useful for running hook scripts

2013-08-14 Thread Michael Haggerty
Package: debianutils
Version: 4.2.1
Severity: wishlist

Managing hook scripts (e.g., githooks(5)) shares many of the problems of
managing startup scripts.  It is often useful for one hook script to
trigger multiple independent actions; for example, a Git post-receive
hook might want to send out email notifications, trigger an automated
build, etc.  It would be nice to organize these actions as separate
scripts in a subdirectory, like

.git/
hooks/
post-receive
post-receive.d/
10-send-email-notification
20-trigger-build
...

Just the thing for run-parts!

But hook scripts are often fed some data on their stdin.  For example,
the Git post-receive hook receives input that tells what references have
been changed, one line per reference.  These data would be needed by
*each* of the sub-hook scripts for them to run correctly.

Therefore, it would be useful if there were an option to make run-parts
multiplex its stdin to *each* of the programs that it runs:

= post-receive =
#! /bin/sh

run-parts --mux-stdin -- post-receive.d

In the general case this would require the stdin to be written to a
temporary file, though in most real-world cases it would probably be
fine to cache the input in RAM.

It is not hard to write a separate utility with this functionality, but
it seems to me that it is a feature that would fit in well with what
run-parts already does.


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org