From patchwork Tue Jul 24 22:15:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geoff Levand X-Patchwork-Id: 948882 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Zt5N0yf4z9s2g for ; Wed, 25 Jul 2018 08:17:28 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=infradead.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="SVBDy5gp"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41Zt5M6YG4zDrTH for ; Wed, 25 Jul 2018 08:17:27 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=infradead.org Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="SVBDy5gp"; dkim-atps=neutral X-Original-To: Petitboot@lists.ozlabs.org Delivered-To: Petitboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (mailfrom) smtp.mailfrom=infradead.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=geoff@infradead.org; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=infradead.org Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="SVBDy5gp"; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41Zt3P6bPjzDrS7 for ; Wed, 25 Jul 2018 08:15:45 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=Date:Cc:To:Subject:From:References: In-Reply-To:Message-Id:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=aFJKzFBcprA33n0TeKUCkfggQsJrhBMa/4IKc7Zmy0k=; b=SVBDy5gpChFafZ2sHzPGoca07 rn/3Dc+JTb9c/faaJbWjM7B4ajMHvGXbWiSQkSUtcPx+WIhTeYCSQ43kKUpbiEL8COR/AvPbmYvnO Gzuy+MVTeBJcukhG+NzxX0oNbZJTxX3UGH9Bm0nkyGRpORJZnkMKcbOxQ5HlgSM9kFRaK5/rO1X+Z YNC27a6deAdBi991/X/JW+5FGVDxQnjCj8183GrnALXHKk9e7rzJ9d+qZXF3zpBUpLrlyPSqthA5D ZNS7Nj3obOpuolS/lZ9msk8FR6ErwsDU91nnClA3+FboJW3VlkPs7vBYXtYMgcBeB1l7B9+tF5JwB rGxn4n5sw==; Received: from geoff by merlin.infradead.org with local (Exim 4.90_1 #2 (Red Hat Linux)) id 1fi5an-0004ji-EP; Tue, 24 Jul 2018 22:15:41 +0000 Message-Id: <46b3f40fe91b725d6ca897709ebe0c353fb3a882.1532469861.git.geoff@infradead.org> In-Reply-To: References: From: Geoff Levand Patch-Date: Tue, 24 Jul 2018 15:03:16 -0700 Subject: [PATCH v1 13/30] lib/process: Add process_get_stdout To: Samuel Mendoza-Jonas Date: Tue, 24 Jul 2018 22:15:41 +0000 X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Ge Song , Petitboot@lists.ozlabs.org MIME-Version: 1.0 Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" Add a new structure 'struct process_stdout' and optional parameter 'stdout' to the process_run_simple functions to allow the caller to get a buffer filled with the stdout from the child process. Rename the process_run_simple functions to process_get_stdout and add wrappers for the old process_run_simple function names. Signed-off-by: Geoff Levand --- lib/process/process.c | 54 ++++++++++++++++++++++++++++++++++++++------------- lib/process/process.h | 26 ++++++++++++++++++++----- 2 files changed, 62 insertions(+), 18 deletions(-) diff --git a/lib/process/process.c b/lib/process/process.c index bc392dc..5f1f9d3 100644 --- a/lib/process/process.c +++ b/lib/process/process.c @@ -452,48 +452,76 @@ void process_stop_async_all(void) } } -int process_run_simple_argv(void *ctx, const char *argv[]) +int process_get_stdout_argv(void *ctx, struct process_stdout **stdout, + const char *argv[]) { - struct process *process; + struct process *p; int rc; - process = process_create(ctx); + p = process_create(NULL); + p->path = argv[0]; + p->argv = argv; - process->path = argv[0]; - process->argv = argv; + if (stdout) { + p->keep_stdout = true; + *stdout = NULL; + } - rc = process_run_sync(process); + rc = process_run_sync(p); if (!rc) - rc = process->exit_status; + rc = p->exit_status; + else { + pb_debug("%s: process_run_sync failed: %s.\n", __func__, + p->path); + if (*stdout) + pb_debug("%s: stdout: %s\n\n", __func__, p->stdout_buf); + goto exit; + } + + if (!stdout) + goto exit; + + *stdout = talloc(ctx, struct process_stdout); + + if (!*stdout) { + rc = -1; + goto exit; + } - process_release(process); + (*stdout)->len = p->stdout_len; + (*stdout)->buf = talloc_memdup(*stdout, p->stdout_buf, + p->stdout_len + 1); + (*stdout)->buf[p->stdout_len] = 0; +exit: + process_release(p); return rc; } -int process_run_simple(void *ctx, const char *name, ...) +int process_get_stdout(void *ctx, struct process_stdout **stdout, + const char *path, ...) { int rc, i, n_argv = 1; const char **argv; va_list ap; - va_start(ap, name); + va_start(ap, path); while (va_arg(ap, char *)) n_argv++; va_end(ap); argv = talloc_array(ctx, const char *, n_argv + 1); - argv[0] = name; + argv[0] = path; - va_start(ap, name); + va_start(ap, path); for (i = 1; i < n_argv; i++) argv[i] = va_arg(ap, const char *); va_end(ap); argv[i] = NULL; - rc = process_run_simple_argv(ctx, argv); + rc = process_get_stdout_argv(ctx, stdout, argv); talloc_free(argv); diff --git a/lib/process/process.h b/lib/process/process.h index 003ff8e..9473a0d 100644 --- a/lib/process/process.h +++ b/lib/process/process.h @@ -27,6 +27,11 @@ struct process_info; typedef void (*process_exit_cb)(struct process *); +struct process_stdout { + size_t len; + char *buf; +}; + struct process { /* caller-provided configuration */ const char *path; @@ -63,13 +68,24 @@ struct process *process_create(void *ctx); */ void process_release(struct process *process); -/* Synchronous interface. These functions will all block while waiting for - * the process to exit. +/* Synchronous interface. The process_run_sync, process_run_simple and + * process_get_stdout functions will all block while waiting for the child + * process to exit. Calls to the variadic versions must have a NULL terminating + * argument. For the process_get_stdout calls stderr will go to the log. */ int process_run_sync(struct process *process); -int process_run_simple_argv(void *ctx, const char *argv[]); -int process_run_simple(void *ctx, const char *name, ...) - __attribute__((sentinel(0))); +int process_get_stdout_argv(void *ctx, struct process_stdout **stdout, + const char *argv[]); +int process_get_stdout(void *ctx, struct process_stdout **stdout, + const char *path, ...) __attribute__((sentinel(0))); + +static inline int process_run_simple_argv(void *ctx, const char *argv[]) +{ + return process_get_stdout_argv(ctx, NULL, argv); +} +#define process_run_simple(_ctx, _path, args...) \ + process_get_stdout(_ctx, NULL, _path, args) + /* Asynchronous interface. When a process is run with process_run_async, the * function returns without wait()ing for the child process to exit. If the