[pacman-dev] [PATCH] Support reading package args from stdin
Dan McGee
dpmcgee at gmail.com
Fri Nov 5 02:43:43 CET 2010
On Thu, Nov 4, 2010 at 3:05 PM, 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.
>
> Signed-off-by: Dave Reisner <d at falconindy.com>
> ---
> Resending as per Allan's request with modifications from the origin 7/24
> submission.
>
> Changes:
> * Check return value of freopen
> * Assign '\0' instead of 0 to null terminate
> * Use post-increment instead of pre-increment
> * Check for buffer overflow condition (not convinced my method is reasonable)
> * Dynamically find stdin's FD instead of assuming it's 1
> * Use PATH_MAX instead of BUFSIZ
>
> Concerns:
> * The verbiage I've used in the new strings is probably not ideal.
>
> src/pacman/pacman.c | 33 +++++++++++++++++++++++++++++++++
> 1 files changed, 33 insertions(+), 0 deletions(-)
>
> diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
> index 15abecc..e078aab 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,38 @@ int main(int argc, char *argv[])
> cleanup(ret);
> }
>
> + /* read package arguments from stdin if we have none yet */
> + if(!pm_targets && !isatty(fileno(stdin))) {
We talked on IRC, but probably can kill the pm_targets check- why
limit people if we are going to allow this?
> + char line[PATH_MAX];
> + int i = 0;
> + while(i < PATH_MAX && (line[i] = fgetc(stdin)) != EOF) {
> + if(isspace((unsigned char)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++;
> + }
> + }
> + /* check for buffer overflow */
> + if (i >= PATH_MAX) {
> + pm_printf(PM_LOG_ERROR, _("buffer overflow detected in arg parsing\n"));
How about "could not process stdin: argument greater than %d
characters\n" or something (obv passing PATH_MAX along to the printf
function)?
> + cleanup(EXIT_FAILURE);
> + }
> +
> + /* end of stream -- check for data still in line buffer */
> + if(i > 0) {
Do we know line is going to end in a ptr to a null char? Or do you
have to do that here too like you did above.
> + 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));
If it is a true error, should we cleanup() here too? Otherwise make
this a PM_LOG_WARN probably.
> + }
> + }
> +
> /* parse the config file */
> ret = parseconfig(config->configfile);
> if(ret != 0) {
> --
Otherwise, this + documentation in pacman man page would be kickass
and ready to commit.
-Dan
More information about the pacman-dev
mailing list