ccan.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: Kevin Locke <kevin@kevinlocke.name>
Cc: ccan@lists.ozlabs.org
Subject: Re: [PATCH v2 02/13] configurator: Reimplement run using popen
Date: Tue, 27 Sep 2016 14:52:15 +1000	[thread overview]
Message-ID: <20160927045215.GJ30322@umbus.fritz.box> (raw)
In-Reply-To: <bd664ad818923efca7c5ca72a6f71abdc7e7af9e.1474600863.git.kevin@kevinlocke.name>


[-- Attachment #1.1: Type: text/plain, Size: 4906 bytes --]

On Thu, Sep 22, 2016 at 09:33:05PM -0600, Kevin Locke wrote:
> Rather than using fork+pipe+system+waitpid, most of which are only
> available on POSIX-like systems, use popen which is also available on
> Windows (under the name _popen).
> 
> Changes since v1:
> - Create fread_noeintr to avoid EINTR in fread without reading any data.
> - Handle short reads from fread.  This can happen with non-conformant
>   libc or if EINTR occurs after reading some data.

Hrm.  Have you actually confirmed this problem with EINTR?  My
previous objections to not handling short read were based entirely on
not realizing that fread() wasn't supposed to do that, rather than
thinking of some edge case you hadn't.

Unless we have a confirmed case where fread() can give a short read
that won't have feof() or ferror() set afterwards, I'm inclined to go
back to your initial implementation.

> - Define _POSIX_C_SOURCE for popen/pclose with strict implementations
>   which require it (e.g. gcc with -std=c11).
> 
> Signed-off-by: Kevin Locke <kevin@kevinlocke.name>
> ---
>  tools/configurator/configurator.c | 90 +++++++++++++++++++--------------------
>  1 file changed, 44 insertions(+), 46 deletions(-)
> 
> diff --git a/tools/configurator/configurator.c b/tools/configurator/configurator.c
> index e322c76..4eed188 100644
> --- a/tools/configurator/configurator.c
> +++ b/tools/configurator/configurator.c
> @@ -21,17 +21,20 @@
>   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
>   * THE SOFTWARE.
>   */
> +#define _POSIX_C_SOURCE 200809L		/* For pclose, popen, strdup */
> +
> +#include <errno.h>
>  #include <stdio.h>
>  #include <stdbool.h>
>  #include <stdlib.h>
> -#include <unistd.h>
>  #include <err.h>
> -#include <sys/types.h>
> -#include <sys/wait.h>
> -#include <sys/stat.h>
> -#include <fcntl.h>
>  #include <string.h>
>  
> +#ifdef _MSC_VER
> +#define popen _popen
> +#define pclose _pclose
> +#endif
> +
>  #define DEFAULT_COMPILER "cc"
>  #define DEFAULT_FLAGS "-g3 -ggdb -Wall -Wundef -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wold-style-definition"
>  
> @@ -367,20 +370,33 @@ static struct test tests[] = {
>  	},
>  };
>  
> -static char *grab_fd(int fd)
> +static size_t fread_noeintr(void *ptr, size_t size, size_t nitems,
> +		FILE *stream)
> +{
> +	size_t ret;
> +
> +	do {
> +		errno = 0;
> +		ret = fread(ptr, size, nitems, stream);
> +	} while (ret == 0 && errno == EINTR);
> +
> +	return ret;
> +}
> +
> +static char *grab_stream(FILE *file)
>  {
> -	int ret;
> -	size_t max, size = 0;
> +	size_t max, ret, size = 0;
>  	char *buffer;
>  
> -	max = 16384;
> -	buffer = malloc(max+1);
> -	while ((ret = read(fd, buffer + size, max - size)) > 0) {
> +	max = BUFSIZ;
> +	buffer = malloc(max);
> +	while ((ret = fread_noeintr(buffer + size, 1, max - size, file)) > 0) {
>  		size += ret;
>  		if (size == max)
>  			buffer = realloc(buffer, max *= 2);
>  	}
> -	if (ret < 0)
> +	size += ret;
> +	if (ferror(file))
>  		err(1, "reading from command");
>  	buffer[size] = '\0';
>  	return buffer;
> @@ -388,43 +404,25 @@ static char *grab_fd(int fd)
>  
>  static char *run(const char *cmd, int *exitstatus)
>  {
> -	pid_t pid;
> -	int p[2];
> +	static const char redir[] = " 2>&1";
> +	size_t cmdlen;
> +	char *cmdredir;
> +	FILE *cmdout;
>  	char *ret;
> -	int status;
>  
> -	if (pipe(p) != 0)
> -		err(1, "creating pipe");
> -
> -	pid = fork();
> -	if (pid == -1)
> -		err(1, "forking");
> -
> -	if (pid == 0) {
> -		if (dup2(p[1], STDOUT_FILENO) != STDOUT_FILENO
> -		    || dup2(p[1], STDERR_FILENO) != STDERR_FILENO
> -		    || close(p[0]) != 0
> -		    || close(STDIN_FILENO) != 0
> -		    || open("/dev/null", O_RDONLY) != STDIN_FILENO)
> -			exit(128);
> -
> -		status = system(cmd);
> -		if (WIFEXITED(status))
> -			exit(WEXITSTATUS(status));
> -		/* Here's a hint... */
> -		exit(128 + WTERMSIG(status));
> -	}
> +	cmdlen = strlen(cmd);
> +	cmdredir = malloc(cmdlen + sizeof(redir));
> +	memcpy(cmdredir, cmd, cmdlen);
> +	memcpy(cmdredir + cmdlen, redir, sizeof(redir));
> +
> +	cmdout = popen(cmdredir, "r");
> +	if (!cmdout)
> +		err(1, "popen \"%s\"", cmdredir);
> +
> +	free(cmdredir);
>  
> -	close(p[1]);
> -	ret = grab_fd(p[0]);
> -	/* This shouldn't fail... */
> -	if (waitpid(pid, &status, 0) != pid)
> -		err(1, "Failed to wait for child");
> -	close(p[0]);
> -	if (WIFEXITED(status))
> -		*exitstatus = WEXITSTATUS(status);
> -	else
> -		*exitstatus = -WTERMSIG(status);
> +	ret = grab_stream(cmdout);
> +	*exitstatus = pclose(cmdout);
>  	return ret;
>  }
>  

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 127 bytes --]

_______________________________________________
ccan mailing list
ccan@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/ccan

  reply	other threads:[~2016-09-27  5:20 UTC|newest]

Thread overview: 78+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-19  0:51 [PATCH 0/9] configurator: Support for Windows and MSVC Kevin Locke
2016-09-19  0:51 ` [PATCH 1/9] configurator: Replace unlink with remove Kevin Locke
2016-09-20  4:50   ` David Gibson
2016-09-19  0:51 ` [PATCH 2/9] configurator: Reimplement run using popen Kevin Locke
2016-09-20  5:00   ` David Gibson
2016-09-20  6:22     ` Kevin Locke
2016-09-20 13:28       ` David Gibson
2016-09-19  0:52 ` [PATCH 3/9] configurator: Inline err.h functions from musl libc Kevin Locke
2016-09-20  5:03   ` David Gibson
2016-09-27  6:11     ` Rusty Russell
2016-09-19  0:52 ` [PATCH 4/9] configurator: Use native directory separator Kevin Locke
2016-09-20  5:04   ` David Gibson
2016-09-19  0:52 ` [PATCH 5/9] configurator: Mark non-Windows tests MAY_NOT_COMPILE Kevin Locke
2016-09-20  5:06   ` David Gibson
2016-09-19  0:52 ` [PATCH 6/9] configurator: Print test source without cat Kevin Locke
2016-09-20  5:09   ` David Gibson
2016-09-19  0:52 ` [PATCH 7/9] configurator: Fix compiler warning with compare Kevin Locke
2016-09-20  5:09   ` David Gibson
2016-09-19  0:52 ` [PATCH 8/9] configurator: Pass output cflag to configurator Kevin Locke
2016-09-20  5:23   ` David Gibson
2016-09-20  6:22     ` Kevin Locke
2016-09-20 13:32       ` David Gibson
2016-09-19  0:52 ` [PATCH 9/9] configurator: DEFAULT_{COMPILER, FLAGS} for MSVC Kevin Locke
2016-09-20  4:48 ` [PATCH 0/9] configurator: Support for Windows and MSVC David Gibson
2016-09-20  6:21   ` Kevin Locke
2016-09-20 12:25     ` David Gibson
2016-09-20 14:16       ` Daniel Burke
2016-09-22  2:00         ` David Gibson
2016-09-23  3:33 ` [PATCH v2 00/13] " Kevin Locke
2016-09-23  3:33   ` [PATCH v2 01/13] configurator: Replace unlink with remove Kevin Locke
2016-09-27  4:50     ` David Gibson
2016-09-23  3:33   ` [PATCH v2 02/13] configurator: Reimplement run using popen Kevin Locke
2016-09-27  4:52     ` David Gibson [this message]
2016-09-28  5:29       ` [PATCH v3 2/13] " Kevin Locke
2016-09-23  3:33   ` [PATCH v2 03/13] configurator: Inline err.h functions from musl libc Kevin Locke
2016-09-27  5:01     ` David Gibson
2016-09-28  5:35       ` [PATCH v3 3/13] configurator: Inline err.h functions Kevin Locke
2016-09-23  3:33   ` [PATCH v2 04/13] configurator: Use native directory separator Kevin Locke
2016-09-27  5:05     ` David Gibson
2016-09-23  3:33   ` [PATCH v2 05/13] configurator: Mark non-Windows tests MAY_NOT_COMPILE Kevin Locke
2016-09-27  5:05     ` David Gibson
2016-09-23  3:33   ` [PATCH v2 06/13] configurator: Print test source without cat Kevin Locke
2016-09-27  5:06     ` David Gibson
2016-09-28  5:38       ` Kevin Locke
2016-09-23  3:33   ` [PATCH v2 07/13] configurator: Fix compiler warning with compare Kevin Locke
2016-09-27  5:09     ` David Gibson
2016-09-23  3:33   ` [PATCH v2 08/13] configurator: Add output cflag option and macro Kevin Locke
2016-09-27  5:17     ` David Gibson
2016-09-23  3:33   ` [PATCH v2 09/13] configurator: DEFAULT_{COMPILER, FLAGS} for MSVC Kevin Locke
2016-09-27  5:17     ` David Gibson
2016-09-23  3:33   ` [PATCH v2 10/13] configurator: Fix warning in HAVE_FOR_LOOP_DECLARATION Kevin Locke
2016-09-27  5:10     ` David Gibson
2016-09-23  3:33   ` [PATCH v2 11/13] configurator: Return pointer difference as ptrdiff_t Kevin Locke
2016-09-27  5:10     ` David Gibson
2016-09-23  3:33   ` [PATCH v2 12/13] Makefile: Define CFLAGS_FORCE_C_SOURCE macro Kevin Locke
2016-09-27  5:18     ` David Gibson
2016-09-27  6:18       ` Rusty Russell
2016-09-28  2:01         ` David Gibson
2016-10-26  2:49           ` Rusty Russell
2016-09-23  3:33   ` [PATCH v2 13/13] Add appveyor.yml Kevin Locke
2016-09-27  5:20     ` David Gibson
2016-09-28  6:01       ` [PATCH v3 " Kevin Locke
2016-09-27  5:23   ` [PATCH v2 00/13] configurator: Support for Windows and MSVC David Gibson
2016-09-27  6:20     ` Rusty Russell
2016-09-28  6:32       ` Kevin Locke
2016-09-28  6:28     ` Kevin Locke
2016-09-29  0:21       ` David Gibson
2016-09-29  0:44         ` [PATCH v3 0/7] " Kevin Locke
2016-09-29  0:44           ` [PATCH v3 1/7] configurator: Reimplement run using popen Kevin Locke
2016-09-29  0:44           ` [PATCH v3 2/7] configurator: Inline err.h functions Kevin Locke
2016-09-29  0:44           ` [PATCH v3 3/7] configurator: Print test source without cat Kevin Locke
2016-09-29  0:44           ` [PATCH v3 4/7] configurator: Add output cflag option and macro Kevin Locke
2016-09-29  0:44           ` [PATCH v3 5/7] configurator: DEFAULT_{COMPILER, FLAGS} for MSVC Kevin Locke
2016-09-29  0:44           ` [PATCH v3 6/7] Makefile: Define CFLAGS_FORCE_C_SOURCE macro Kevin Locke
2016-09-29  0:44           ` [PATCH v3 7/7] Add appveyor.yml Kevin Locke
2016-09-30 15:08           ` [PATCH v3 0/7] configurator: Support for Windows and MSVC David Gibson
2016-10-03  3:14             ` Kevin Locke
2016-12-02 20:23               ` AppVeyor custom Git URL support (was Re: [PATCH v3 0/7] configurator: Support for Windows and MSVC) Kevin Locke

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160927045215.GJ30322@umbus.fritz.box \
    --to=david@gibson.dropbear.id.au \
    --cc=ccan@lists.ozlabs.org \
    --cc=kevin@kevinlocke.name \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).