[pacman-dev] [PATCH] Support reading package args from stdin

Dave Reisner d at falconindy.com
Thu Nov 4 16:36:43 CET 2010


On Fri, Nov 05, 2010 at 12:42:54AM +1000, Allan McRae wrote:
> On 05/11/10 00:20, Dave Reisner wrote:
> >Only occurs if no arguments were provided directly. Arguments can be
> >separated by any amount of valid whitespace. This allows for piping into
> >pacman from other programs or from itself, e.g.:
> >
> >   pacman -Qdtq | pacman -Rs
> >
> >This is better than using xargs, as xargs will not reconnect stdin to
> >the terminal. The above operation performed using xargs would require
> >the --noconfirm flag to be passed to pacman.
> 
> Dan: this sold the patch to me.
> 
> >Revised from the original 7/24 submission at Allan's request to check
> >the return value of freopen().
> 
> FYI, comments like this can go below the "---" two lines down.  That
> way they do not get included in the actual git commit.
> 
Cool beans. I should really look at the man page for git-send-email one
of these days.

> >Signed-off-by: Dave Reisner<d at falconindy.com>
> >---
> >  src/pacman/pacman.c |   27 +++++++++++++++++++++++++++
> >  1 files changed, 27 insertions(+), 0 deletions(-)
> >
> >diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
> >index 15abecc..6f40a97 100644
> >--- a/src/pacman/pacman.c
> >+++ b/src/pacman/pacman.c
> >@@ -26,6 +26,7 @@
> >  #define PACKAGE_VERSION GIT_VERSION
> >  #endif
> >
> >+#include<ctype.h>  /* isspace */
> >  #include<stdlib.h>  /* atoi */
> >  #include<stdio.h>
> >  #include<limits.h>
> >@@ -1305,6 +1306,32 @@ int main(int argc, char *argv[])
> >  		cleanup(ret);
> >  	}
> >
> >+	/* read package arguments from stdin if we have none yet */
> >+	if(!pm_targets&&  !isatty(0)) {
> >+		char line[BUFSIZ];
> >+		int i = 0;
> >+		while((line[i] = fgetc(stdin)) != EOF) {
> >+			if(isspace(line[i])) {
> >+				line[i] = 0;
> >+				/* avoid adding zero length arg when multiple spaces separate args */
> >+				if(i>  0) {
> >+					pm_targets = alpm_list_add(pm_targets, strdup(line));
> >+					i = 0;
> >+				}
> >+			} else {
> >+				++i;
> >+			}
> >+		}
> >+		/* end of stream -- check for data still in line buffer */
> >+		if(i>  0) {
> >+			pm_targets = alpm_list_add(pm_targets, strdup(line));
> >+		}
> >+		if (!freopen(ctermid(NULL), "r", stdin)) {
> 
> Two things here.  The HACKING file says to use if(foo() == 0) rather
> than if(!foo()).  But freopen returns a FILE*.  So we really should
> be checking if that == NULL?   Also, does the FILE* that freopen
> returns need closed here or is that fine as is?  I get slight
> confused...
> 
Just above where my patch falls in, is this chunk (line 1275):

  if(!isatty()) {
    config->noprogressbar = 1;
  }

The reopened stdin should be closed as usual by the kernel on exit.

We only need to check for the presence of a FILE* being returned. When
successful, the function just returns the value of the third argument --
stdin in this case.

> >+			pm_printf(PM_LOG_ERROR, _("failed to reopen stdin for reading: (%s)\n"),
> >+					strerror(errno));
> >+		}
> >+	}
> >+
> >  	/* parse the config file */
> >  	ret = parseconfig(config->configfile);
> >  	if(ret != 0) {
> 
> 


More information about the pacman-dev mailing list