[pacman-dev] [PATCH] Support reading package args from stdin
Dave Reisner
d at falconindy.com
Thu Nov 4 16:27:28 CET 2010
On Thu, Nov 04, 2010 at 09:40:46AM -0500, Dan McGee wrote:
> On Thu, Nov 4, 2010 at 9:20 AM, Dave Reisner <d at falconindy.com> 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.
> >
> > Revised from the original 7/24 submission at Allan's request to check
> > the return value of freopen().
> >
> > 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)) {
> isatty(fileno(stdin)) is technically more correct, no? It also would
> handle the case where someone reassigned stdin.
>
> > + char line[BUFSIZ];
> Another constant for a buffer size? If there is one in our codebase
> I'd rather we use that, and of course it would be even better to not
> have an arbitrary limit on this at all. See later comment.
>
BUFSIZ is provided by stdlib.h and is supposed to be tuned to be
architecture specific. I believe POSIX guarnatees it to be a minimum of
256. PATH_MAX seems to make a fairly common appearance throughout the
code -- would you prefer I use that instead?
> > + int i = 0;
> > + while((line[i] = fgetc(stdin)) != EOF) {
> > + if(isspace(line[i])) {
> > + line[i] = 0;
> Use '\0' please, this is a char, not an int.
>
> > + /* 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;
> i++; we don't use the pre-increment operator anywhere and it makes no
> difference so we should style-match.
>
> > + }
> > + }
> Uhhhhh- buffer overflow condition?
>
What should the behavior be if an overflow is detected? Truncate the
argument and fast forward to the next delimeter? Restart parsing right
after the truncated argument? Fail entirely?
> > + /* 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)) {
> > + pm_printf(PM_LOG_ERROR, _("failed to reopen stdin for reading: (%s)\n"),
> > + strerror(errno));
> > + }
> > + }
> > +
> So the other thing I'm thinking here is it breaks anyone that might
> have piped into pacman before. I'm not sure if we care, but using
> /usr/bin/yes did work before. Is it worth guarding this functionality
> behind an option (--use-stdin or something) instead of the isatty()
> check (which would take place on the freopen() call instead)?
>
I hadn't considered that, but it's certainly a valid concern. My opinion
is that having to specify an extra flag to read from stdin makes this a
lot less appealing. I'd be personally patching that _out_ if that were
deemed to be the desirable path. Just an opinion, though.
> > /* parse the config file */
> > ret = parseconfig(config->configfile);
> > if(ret != 0) {
> > --
> > 1.7.3.2
> >
> >
> >
>
More information about the pacman-dev
mailing list