[pacman-dev] [PATCH 2/2] parse stdin as newline-separated
Andrew Gregory
andrew.gregory.8 at gmail.com
Sat Feb 18 22:39:46 UTC 2017
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 at 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
More information about the pacman-dev
mailing list