From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/12285 Path: news.gmane.org!.POSTED!not-for-mail From: Markus Wichmann Newsgroups: gmane.linux.lib.musl.general Subject: Conformance problem in system() Date: Fri, 29 Dec 2017 10:48:48 +0100 Message-ID: <20171229094848.lfunfbqvjc4gln5u@voyager> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="nfkp7s45licfjd5t" X-Trace: blaine.gmane.org 1514540841 8728 195.159.176.226 (29 Dec 2017 09:47:21 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 29 Dec 2017 09:47:21 +0000 (UTC) User-Agent: NeoMutt/20170609 (1.8.3) To: musl@lists.openwall.com Original-X-From: musl-return-12301-gllmg-musl=m.gmane.org@lists.openwall.com Fri Dec 29 10:47:17 2017 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1eUrG0-0001pM-NX for gllmg-musl@m.gmane.org; Fri, 29 Dec 2017 10:47:16 +0100 Original-Received: (qmail 20387 invoked by uid 550); 29 Dec 2017 09:49:15 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 20352 invoked from network); 29 Dec 2017 09:49:15 -0000 Content-Disposition: inline X-Provags-ID: V03:K0:vHn2c81clmszpIyjVLiM2AAqTgVGeGSna8Dz3VsbtieYicB5uiw kWfKJ+p8EwfTcPMQKspLh1BhKVZd8NZBDQ9YZhuTQqoayloHoG0owKZb4Lpjoo9IY134glv 9jc/ezYwh4ifcSPt5Upsi+EvlKQBc1ACZWYNv1O6Kezu0RKvG+GjNBkjmJsjuw/4knTKkP0 3NeIYziiHE4x/jinIz2Iw== X-UI-Out-Filterresults: notjunk:1;V01:K0:ECNoMESm48I=:vxCNkfVfaOdQRUntSnNUK/ vV8yaAl2OMx21+UhmUMyXgy9krklb9ewIYW0DuBGv3FVXXtNwCKazxNV+z1w9Rdxf1VX20p6K 1EHRSc1WPeAFSgeT2TPyVeYAqMpJQbrjVO1aBcniL2vdN9dagorXOvBT39nBDkochjVyvL6Zb 0pwKbrXBAKYELgQcS4BiUahiU/uP5i7yWrF8Nr+qjLMOjEnlzRSfXbSYzwC8wpBNrYkwC0eyT /2z0RYBpOLOhWCBRM1wio1NkKWfinN9p/IKIlGA8bMOgT1tL8FWf9u1KjR2Jxmz0R0+dnNJ+V 9ih+tE035uLcd2WKR9qLB54EiZlZYzfL651cHbKGihC3lwxxU+QRVlu0Dj/7r4L7VLMkOwLy0 KzzRNkcg04jkUCZDm/pbk8Wy7onyewksQqeDZSpFsiKESQLkcZXHyll+mljEAhG9j4WyAEb0m i8Ah0QadLF9wG6VcS7+D5/MyWFb9rijkwe32mcvc/mO6f2Tme7UO1WZlAnPPXwLuYRZ52o00H D6RUhvvKfzV1aDMOPxdHL38hEBsSPXnmoaozMudv6mWMp+zlj9hHo6lN//lhed0EAPNg7JFDu p0yxI3Xn3lKp4sS9+nfLpsX03CtjVUNiL4n0NIrzkzKvXGEm7zokmt2jtjWHI78VAKvvJ+J16 mVaQ2+nEDdapHSGS67C12RjQjTH21AH9wxOUV32KYHJe5hJNDreQEjvaH+moTwK5UbPzx7+tU B3nmlTXufaV3XfRkFacTdAwHgponRodf8Hcho+BJiKuFoIuZEdJNeeBqhyT0S1JyKtfbyqU1 Xref: news.gmane.org gmane.linux.lib.musl.general:12285 Archived-At: --nfkp7s45licfjd5t Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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 #include #include 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 --nfkp7s45licfjd5t Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0002-Correctly-handle-failing-waitpid-in-system.patch" >From a2a4e552e617af76f6352bd280a042af621ffcf4 Mon Sep 17 00:00:00 2001 From: Markus Wichmann 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 --nfkp7s45licfjd5t--