From nobody@FreeBSD.org  Sun Sep 14 05:16:45 2008
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id C5BA2106564A
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 14 Sep 2008 05:16:45 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id BC2158FC13
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 14 Sep 2008 05:16:45 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.2/8.14.2) with ESMTP id m8E5GiwL066530
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 14 Sep 2008 05:16:44 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.2/8.14.1/Submit) id m8E5GiXZ066529;
	Sun, 14 Sep 2008 05:16:44 GMT
	(envelope-from nobody)
Message-Id: <200809140516.m8E5GiXZ066529@www.freebsd.org>
Date: Sun, 14 Sep 2008 05:16:44 GMT
From: Andrei Lavreniyuk <andy.lavr@reactor-xg.kiev.ua>
To: freebsd-gnats-submit@FreeBSD.org
Subject: sh -c 'exit -1' fails with "Illegal number: -1", instead of exiting with a code of 255
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         127370
>Category:       bin
>Synopsis:       [patch] sh(1): sh -c 'exit -1' fails with "Illegal number: -1", instead of exiting with a code of 255
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Sep 14 05:20:01 UTC 2008
>Closed-Date:    Mon Sep 15 00:05:26 UTC 2008
>Last-Modified:  Mon Sep 15 00:05:26 UTC 2008
>Originator:     Andrei Lavreniyuk
>Release:        7.1-PRERELEASE
>Organization:
Technica-03, Inc.
>Environment:
FreeBSD datacenter.technica-03.local 7.1-PRERELEASE FreeBSD 7.1-PRERELEASE #0: Fri Sep 12 21:28:43 UTC 2008     root@datacenter.technica-03.local:/usr/obj/usr/src/sys/SMP-DATACENTER  i386
>Description:

(c) Garrett Cooper (misc_124748)
----------------------------------------

Bourne shell (/bin/sh), as it stands, doesn't parse numbers properly, even though bash does:

[gcooper@optimus /devel/ncvs/src/bin/sh]$ sh -c 'exit -1'
exit: Illegal number: -1
[gcooper@optimus /devel/ncvs/src/bin/sh]$ sh -c 'exit +1'
exit: Illegal number: +1

These are valid numbers though, which are merely red herrings; the patch attached does fix this behavior though, according to the following gamut of tests:

[gcooper@optimus /devel/ncvs/src/bin/sh]$ cat number_test.sh
#!/bin/sh

for shell in sh $@; do
        for i in -1 1 +1; do
                echo "$shell -c \"exit $i\""
                $shell -c "exit $i"; echo $?
        done;
done
# End of test
[gcooper@optimus /devel/ncvs/src/bin/sh]$ ./number_test.sh bash ./sh
sh -c "exit -1"
exit: Illegal number: -1
2
sh -c "exit 1"
1
sh -c "exit +1"
exit: Illegal number: +1
2
bash -c "exit -1"
255
bash -c "exit 1"
1
bash -c "exit +1"
1
./sh -c "exit -1"
255
./sh -c "exit 1"
1
./sh -c "exit +1"
1

>How-To-Repeat:

(c) Garrett Cooper (misc_124748)
----------------------

/bin/sh -c "exit -1"
/bin/sh -c "exit +1"

>Fix:

(c) Garrett Cooper (misc_124748)
-----------------

Patch attached (also fixes histcmd.c and trap.c -- strange thing is that I can't seem to test that builtin cmd), and maintains proper compatibility with builtin jobs:

[gcooper@optimus /devel/ncvs/src/bin/sh]$ sh -c 'builtin histcmd'
histcmd: not found

Patch attached with submission follows:

Index: exec.c
===================================================================
RCS file: /home/ncvs/src/bin/sh/exec.c,v
retrieving revision 1.31
diff -r1.31 exec.c
40a41
> #include <string.h>
361c362
<                       if (prefix("builtin", pathopt)) {
---
>                       if (strncmp(BUILTIN, pathopt, strlen(BUILTIN)) == 0) {
Index: histedit.c
===================================================================
RCS file: /home/ncvs/src/bin/sh/histedit.c,v
retrieving revision 1.29
diff -r1.29 histedit.c
425,426d424
<       if (*s == '-')
<               s++;
Index: jobs.c
===================================================================
RCS file: /home/ncvs/src/bin/sh/jobs.c,v
retrieving revision 1.72
diff -r1.72 jobs.c
534c534
<               return (jp);
---
>               return jp;
540c540,544
<                       jobno = number(name + 1);
---
>                       /*
>                        * Don't use number() here. This breaks existing
>                        * jobs(1) compatibility.
>                        */
>                       jobno = atoi(name + 1);
560c564
<                                       if (found)
---
>                                       if (found != NULL)
571,572c575,576
<                                && prefix(name + 1, jp->ps[0].cmd)) {
<                                       if (found)
---
>                                && strncmp(name+1, jp->ps[0].cmd, strlen(name+1))) {
>                                       if (found != NULL)
577,578c581,582
<                       if (found)
<                               return found;
---
>                       if (found != NULL)
>                               return (found);
581c585,586
<               pid = (pid_t)number(name);
---
>               /* no need to run is_number() again with number() */
>               pid = (pid_t)atoi(name);
Index: main.h
===================================================================
RCS file: /home/ncvs/src/bin/sh/main.h,v
retrieving revision 1.8
diff -r1.8 main.h
38a39,40
> #define BUILTIN "builtin"
>
Index: mystring.c
===================================================================
RCS file: /home/ncvs/src/bin/sh/mystring.c,v
retrieving revision 1.13
diff -r1.13 mystring.c
56a57,59
> #if DEBUG
> #include <stdio.h>
> #endif
123a127,135
>       /* Is this the first index? */
>       int iter = 0;
>
> #if DEBUG
> #define PRINT_DEBUG fprintf(stderr, "%d: %c\n", iter, *p)
> #else
> #define PRINT_DEBUG
> #endif
>
125c137,154
<               if (! is_digit(*p))
---
>               /*
>                * Account for signs in front of numbers.
>                */
>
>               /*
>                * XXX: does POSIX bourne shell allow for '+' prefixed
>                * numbers?
>                */
>
>               /*
>                * The string defined by *p isn't a number, unless:
>                *      1. It's a digit.
>                *      2. The 0'th index is either a + or -.
>                */
>               if (!(is_digit(*p) ||
>                    (iter == 0 && (*p == '-' || *p == '+')))
>               ) {
>                       PRINT_DEBUG;
126a156,163
>               }
>
>               PRINT_DEBUG;
>
> #undef PRINT_DEBUG
>
>               iter++;
>

------------------------------


(c) Garrett Cooper (misc_124748) 

  



>Release-Note:
>Audit-Trail:

From: Christoph Mallon <christoph.mallon@gmx.de>
To: bug-followup@FreeBSD.org, andy.lavr@reactor-xg.kiev.ua
Cc:  
Subject: Re: bin/127370: [patch] sh(1): sh -c 'exit -1' fails with "Illegal
 number: -1", instead of exiting with a code of 255
Date: Sun, 14 Sep 2008 22:32:14 +0200

 > Bourne shell (/bin/sh), as it stands, doesn't parse numbers properly, even though bash does:
 > 
 > [gcooper at optimus /devel/ncvs/src/bin/sh]$ sh -c 'exit -1'
 > exit: Illegal number: -1
 > [gcooper at optimus /devel/ncvs/src/bin/sh]$ sh -c 'exit +1'
 > exit: Illegal number: +1
 > 
 > These are valid numbers though, which are merely red herrings;
 
 The standard (SUSv2, chapter Shell Command Language, 
 http://www.opengroup.org/onlinepubs/7990989775/xcu/chap2.html#tag_001_014_007) 
 is pretty clear in this respect:
 "The exit utility causes the shell to exit with the exit status 
 specified by the unsigned decimal integer n. If n is specified, but its 
 value is not between 0 and 255 inclusively, the exit status is undefined."
 
 It clearly states that the exit status must be an *unsigned* decimal 
 integer.  The changes, which you propose, are clearly bashisms and 
 should not be part of sh.
 
 Regards
 	Christoph
State-Changed-From-To: open->closed 
State-Changed-By: linimon 
State-Changed-When: Mon Sep 15 00:05:11 UTC 2008 
State-Changed-Why:  
Apparently working as designed. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=127370 
>Unformatted:
