Browse Source

dpkg: Add new --status-logger option

This option works in a similar way to --status-fd, the main difference
is that we invoke the provided command and pass the status information
to its standard input instead.

Suggested-by: Raphaël Hertzog <hertzog@debian.org>
Guillem Jover 15 years ago
parent
commit
73dab65273
3 changed files with 45 additions and 2 deletions
  1. 3 0
      debian/changelog
  2. 7 1
      man/dpkg.1
  3. 35 1
      src/main.c

+ 3 - 0
debian/changelog

@@ -8,6 +8,9 @@ dpkg (1.16.0) UNRELEASED; urgency=low
     warn otherwise.
   * Update dpkg(1) to note that --status-fd output does not contain newlines
     in error messages anymore (this was fixed in 1.15.0).
+  * Add a new --status-logger option to dpkg, similar to --status-fd but
+    instead invoke the command ourselves and feed the status information
+    to its standard input. Suggested by Raphaël Hertzog.
 
   [ Raphaël Hertzog ]
   * Fail properly when debian/source/format is empty. Closes: #600854

+ 7 - 1
man/dpkg.1

@@ -1,4 +1,4 @@
-.TH dpkg 1 "2010-11-04" "Debian Project" "dpkg suite"
+.TH dpkg 1 "2010-11-05" "Debian Project" "dpkg suite"
 .SH NAME
 dpkg \- package manager for Debian
 .
@@ -588,6 +588,12 @@ Sent just before a processing stage starts. \fIstage\fR is one of
 .BR configure ", " trigproc  ", " disappear ", " remove  ", " purge .
 .RE
 .TP
+\fB\-\-status\-logger\fR=\fIcommand\fR
+Send machine-readable package status and progress information to the
+shell \fIcommand\fR's standard input. This option can be specified
+multiple times. The output format used is the same as in \fB\-\-status\-fd.
+.RE
+.TP
 \fB\-\-log=\fP\fIfilename\fP
 Log status change updates and actions to \fIfilename\fP, instead of
 the default \fI/var/log/dpkg.log\fP. If this option is given multiple

+ 35 - 1
src/main.c

@@ -46,6 +46,7 @@
 #include <dpkg/i18n.h>
 #include <dpkg/dpkg.h>
 #include <dpkg/dpkg-db.h>
+#include <dpkg/subproc.h>
 #include <dpkg/command.h>
 #include <dpkg/myopt.h>
 
@@ -336,6 +337,8 @@ struct invoke_hook *pre_invoke_hooks = NULL;
 struct invoke_hook **pre_invoke_hooks_tail = &pre_invoke_hooks;
 struct invoke_hook *post_invoke_hooks = NULL;
 struct invoke_hook **post_invoke_hooks_tail = &post_invoke_hooks;
+struct invoke_hook *status_loggers = NULL;
+struct invoke_hook **status_loggers_tail = &status_loggers;
 
 static void
 set_invoke_hook(const struct cmdinfo *cip, const char *value)
@@ -373,6 +376,34 @@ run_invoke_hooks(const char *action, struct invoke_hook *hook_head)
   unsetenv("DPKG_HOOK_ACTION");
 }
 
+static void
+run_status_loggers(struct invoke_hook *hook_head)
+{
+  struct invoke_hook *hook;
+
+  for (hook = hook_head; hook; hook = hook->next) {
+    pid_t pid;
+    int p[2];
+
+    m_pipe(p);
+
+    pid = subproc_fork();
+    if (pid == 0) {
+      /* Setup stdin and stdout. */
+      m_dup2(p[0], 0);
+      close(1);
+
+      close(p[0]);
+      close(p[1]);
+
+      command_shell(hook->command, _("status logger"));
+    }
+    close(p[0]);
+
+    statusfd_add(p[1]);
+  }
+}
+
 static void setforce(const struct cmdinfo *cip, const char *value) {
   const char *comma;
   size_t l;
@@ -487,6 +518,7 @@ static const struct cmdinfo cmdinfos[]= {
   { "post-invoke",       0,   1, NULL,          NULL,      set_invoke_hook, 0, &post_invoke_hooks_tail },
   { "path-exclude",      0,   1, NULL,          NULL,      setfilter,     0 },
   { "path-include",      0,   1, NULL,          NULL,      setfilter,     1 },
+  { "status-logger",     0,   1, NULL,          NULL,      set_invoke_hook, 0, &status_loggers_tail },
   { "status-fd",         0,   1, NULL,          NULL,      setpipe, 0 },
   { "log",               0,   1, NULL,          &log_file, NULL,    0 },
   { "pending",           'a', 0, &f_pending,    NULL,      NULL,    1 },
@@ -673,8 +705,10 @@ int main(int argc, const char *const *argv) {
 
   setvbuf(stdout, NULL, _IONBF, 0);
 
-  if (is_invoke_action(cipaction->arg))
+  if (is_invoke_action(cipaction->arg)) {
     run_invoke_hooks(cipaction->olong, pre_invoke_hooks);
+    run_status_loggers(status_loggers);
+  }
 
   filesdbinit();