summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Gregory <andrew.gregory.8@gmail.com>2017-02-18 17:09:50 -0500
committerAllan McRae <allan@archlinux.org>2017-04-04 12:04:16 +1000
commitd9908fc1f272a2859b525c3bd92d9f3e8a2a6293 (patch)
treec77b561f1e796e64e8a602b587c0ff4dc24e4f22
parenta138db3c07553cfd252495a3c406e11457075e79 (diff)
parse stdin as newline-separated
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> Signed-off-by: Allan McRae <allan@archlinux.org>
-rw-r--r--src/pacman/pacman.c55
1 files changed, 23 insertions, 32 deletions
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index a66bf585..fe96cb3b 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -1100,7 +1100,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();
@@ -1148,44 +1147,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));