Message ID | 20170218220950.4734-2-andrew.gregory.8@gmail.com |
---|---|
State | Accepted, archived |
Headers | show |
Series | [pacman-dev,1/2] add alpm_list_append_strdup | expand |
On 02/18/17 at 05:09pm, Andrew Gregory wrote: > Newline-separated input is more reliable because most of the arguments > we accept over stdin can validly contain spaces but not newlines. > > Resolves FS#52992 > > Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com> > --- > src/pacman/pacman.c | 55 ++++++++++++++++++++++------------------------------- > 1 file changed, 23 insertions(+), 32 deletions(-) > > diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c > index a459cf00..7651df3c 100644 > --- a/src/pacman/pacman.c > +++ b/src/pacman/pacman.c > @@ -1094,7 +1094,6 @@ static void cl_to_log(int argc, char *argv[]) > int main(int argc, char *argv[]) > { > int ret = 0; > - size_t i; > uid_t myuid = getuid(); > > install_segv_handler(); > @@ -1142,44 +1141,36 @@ int main(int argc, char *argv[]) > if(alpm_list_find_str(pm_targets, "-")) { > if(!isatty(fileno(stdin))) { > int target_found = 0; > - size_t current_size = PATH_MAX; > - char *vdata, *line = malloc(current_size); > - int c; > + char *vdata, *line = NULL; > + size_t line_size = 0; > + ssize_t nread; > > /* remove the '-' from the list */ > pm_targets = alpm_list_remove_str(pm_targets, "-", &vdata); > free(vdata); > > - i = 0; > - do { > - c = fgetc(stdin); > - if(c == EOF || isspace(c)) { > - /* avoid adding zero length arg when multiple spaces separate args */ > - if(i > 0) { > - line[i] = '\0'; > - pm_targets = alpm_list_add(pm_targets, strdup(line)); > - target_found = 1; > - i = 0; > - } > - } else { > - line[i++] = (char)c; > - /* we may be at the end of our allocated buffer now */ > - if(i >= current_size) { > - char *new = realloc(line, current_size * 2); > - if(new) { > - line = new; > - current_size *= 2; > - } else { > - free(line); > - pm_printf(ALPM_LOG_ERROR, > - _("memory exhausted in argument parsing\n")); > - cleanup(EXIT_FAILURE); > - } > - } > + while((nread = getline(&line, &line_size, stdin)) != -1) { > + if(line[nread - 1] == '\n') { > + /* remove trailing newline */ > + line[nread - 1] = '\0'; > } > - } while(c != EOF); > - > + if(line[0] == '\0') { > + /* skip empty lines */ > + continue; > + } > + if(!alpm_list_append_strdup(&pm_targets, line)) { > + break; > + } > + target_found = 1; > + } > free(line); > + > + if(ferror(stdin)) { > + pm_printf(ALPM_LOG_ERROR, > + _("failed to read arguments from stdin: (%s)\n"), strerror(errno)); > + cleanup(EXIT_FAILURE); > + } This, of course, won't catch errors from appending to pm_targets. Switched to using errno for error detection in my repo. > + > if(!freopen(ctermid(NULL), "r", stdin)) { > pm_printf(ALPM_LOG_ERROR, _("failed to reopen stdin for reading: (%s)\n"), > strerror(errno)); > -- > 2.11.1
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index a459cf00..7651df3c 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -1094,7 +1094,6 @@ static void cl_to_log(int argc, char *argv[]) int main(int argc, char *argv[]) { int ret = 0; - size_t i; uid_t myuid = getuid(); install_segv_handler(); @@ -1142,44 +1141,36 @@ int main(int argc, char *argv[]) if(alpm_list_find_str(pm_targets, "-")) { if(!isatty(fileno(stdin))) { int target_found = 0; - size_t current_size = PATH_MAX; - char *vdata, *line = malloc(current_size); - int c; + char *vdata, *line = NULL; + size_t line_size = 0; + ssize_t nread; /* remove the '-' from the list */ pm_targets = alpm_list_remove_str(pm_targets, "-", &vdata); free(vdata); - i = 0; - do { - c = fgetc(stdin); - if(c == EOF || isspace(c)) { - /* avoid adding zero length arg when multiple spaces separate args */ - if(i > 0) { - line[i] = '\0'; - pm_targets = alpm_list_add(pm_targets, strdup(line)); - target_found = 1; - i = 0; - } - } else { - line[i++] = (char)c; - /* we may be at the end of our allocated buffer now */ - if(i >= current_size) { - char *new = realloc(line, current_size * 2); - if(new) { - line = new; - current_size *= 2; - } else { - free(line); - pm_printf(ALPM_LOG_ERROR, - _("memory exhausted in argument parsing\n")); - cleanup(EXIT_FAILURE); - } - } + while((nread = getline(&line, &line_size, stdin)) != -1) { + if(line[nread - 1] == '\n') { + /* remove trailing newline */ + line[nread - 1] = '\0'; } - } while(c != EOF); - + if(line[0] == '\0') { + /* skip empty lines */ + continue; + } + if(!alpm_list_append_strdup(&pm_targets, line)) { + break; + } + target_found = 1; + } free(line); + + if(ferror(stdin)) { + pm_printf(ALPM_LOG_ERROR, + _("failed to read arguments from stdin: (%s)\n"), strerror(errno)); + cleanup(EXIT_FAILURE); + } + if(!freopen(ctermid(NULL), "r", stdin)) { pm_printf(ALPM_LOG_ERROR, _("failed to reopen stdin for reading: (%s)\n"), strerror(errno));
Newline-separated input is more reliable because most of the arguments we accept over stdin can validly contain spaces but not newlines. Resolves FS#52992 Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com> --- src/pacman/pacman.c | 55 ++++++++++++++++++++++------------------------------- 1 file changed, 23 insertions(+), 32 deletions(-)