mailing list of musl libc
 help / color / mirror / code / Atom feed
* Conformance problem in system()
@ 2017-12-29  9:48 Markus Wichmann
  2017-12-30 22:22 ` Rich Felker
  0 siblings, 1 reply; 4+ messages in thread
From: Markus Wichmann @ 2017-12-29  9:48 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 1747 bytes --]

Hi all,

I was testing system() while SIGCHLD is ignored just now, and noticed a
difference between glibc and musl. That in itself is not alarming, but
it prompted me to look this function up in the standard, to see which
behavior was conforming better (or maybe both are).

The program was this:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    if (signal(SIGCHLD, SIG_IGN) == SIG_ERR)
        perror("signal");
    int i = system("sleep 1");
    if (i != 0)
        fprintf(stderr, "system() == %d, %m\n", i);
    return i;
}

Glibc returns -1 from system() while musl returns 32512. errno is the
same in both cases, ECHILD. Which is also what waitpid() is returning.

SUSv4 specifies for system()'s return value:

| [...][I]f the termination status for the command language interpreter
| cannot be obtained, system() shall return -1 and set errno to indicate
| the error.

So, it turns out, glibc is conforming to the standard, and musl is not.
If waitpid() fails, then the status cannot be retrieved.

I don't know about other system calls, but I tend to view pointer
arguments to system calls as undefined after a failed call. The kernel
might deposit something in those variables, or it might not. In this
case, it does not, so the status returned is the value status was
initialized to at the start of system(), which is 0x7f00, the value I
observed. I think you were hoping to land under the umbrella of

| If command is not a null pointer, system() shall return the termination
| status of the command language interpreter in the format specified by
| waitpid().

But a failing waitpid() does not fetch the status at all.

I have attached a patch to correct this behavior, for your perusal.

Ciao,
Markus

[-- Attachment #2: 0002-Correctly-handle-failing-waitpid-in-system.patch --]
[-- Type: text/x-diff, Size: 1194 bytes --]

From a2a4e552e617af76f6352bd280a042af621ffcf4 Mon Sep 17 00:00:00 2001
From: Markus Wichmann <nullplan@gmx.net>
Date: Fri, 29 Dec 2017 10:45:58 +0100
Subject: [PATCH 2/2] Correctly handle failing waitpid() in system()

---
 src/process/system.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/process/system.c b/src/process/system.c
index 8cbdda06..a62ff26e 100644
--- a/src/process/system.c
+++ b/src/process/system.c
@@ -14,7 +14,7 @@ int system(const char *cmd)
 	pid_t pid;
 	sigset_t old, reset;
 	struct sigaction sa = { .sa_handler = SIG_IGN }, oldint, oldquit;
-	int status = 0x7f00, ret;
+	int status = 0x7f00, ret, wr = 0;
 	posix_spawnattr_t attr;
 
 	pthread_testcancel();
@@ -37,11 +37,12 @@ int system(const char *cmd)
 		(char *[]){"sh", "-c", (char *)cmd, 0}, __environ);
 	posix_spawnattr_destroy(&attr);
 
-	if (!ret) while (waitpid(pid, &status, 0)<0 && errno == EINTR);
+	if (!ret) while ((wr = waitpid(pid, &status, 0))<0 && errno == EINTR);
 	sigaction(SIGINT, &oldint, NULL);
 	sigaction(SIGQUIT, &oldquit, NULL);
 	sigprocmask(SIG_SETMASK, &old, NULL);
 
 	if (ret) errno = ret;
+        if (wr) status = wr;
 	return status;
 }
-- 
2.14.2


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-01-09 18:03 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-29  9:48 Conformance problem in system() Markus Wichmann
2017-12-30 22:22 ` Rich Felker
2017-12-30 23:23   ` Markus Wichmann
2018-01-09 18:03     ` Rich Felker

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

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).