bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Bash 2.05 strange behavior with exit statuses above 255


From: Paul Eggert
Subject: Bash 2.05 strange behavior with exit statuses above 255
Date: Tue, 1 May 2001 17:18:28 -0700 (PDT)

From: eggert
To: bug-bash@gnu.org
Subject: [50 character or so descriptive subject here (for reference)]

Configuration Information [Automatically generated, do not change]:
Machine: sparc
OS: solaris2.7
Compiler: cc -xarch=v9
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='sparc' 
-DCONF_OSTYPE='solaris2.7' -DCONF_MACHTYPE='sparc-sun-solaris2.7' 
-DCONF_VENDOR='sun' -DSHELL  -DHAVE_CONFIG_H  -D_LARGEFILE_SOURCE 
-D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -I.  -I.. -I../include -I../lib 
-I/tmp/prefix/include -g
uname output: SunOS sic.twinsun.com 5.7 Generic_106541-15 sun4u sparc 
SUNW,UltraSPARC-IIi-Engine
Machine Type: sparc-sun-solaris2.7

Bash Version: 2.05
Patch Level: 0
Release Status: release

Description:
        Bash reserves exit statuses outside the range 0-255 for
        internal use, but it doesn't enforce this restriction.  This
        leads to strange behavior in some cases.  It would be better
        if Bash simply enforced the 0-255 rule for exit statuses
        generated by the "return", "exit", and "logout" builtins.

Repeat-By:
        $ f() { return $1; }
        $ g() { f $1; echo f $1 returned $?; }
        $ g 0
        f 0 returned 0
        $ g 255
        f 255 returned 255
        $ g 256
        f 256 returned 256
        $ g 257
        f 257 returned 1
        $ g 258
        f 258 returned 2
        $ g 259
        f 259 returned 1
        $ g 260
        f 260 returned 1
        $ g 2147483647
        f 2147483647 returned 1
        $ g 2147483648
        f 2147483648 returned -2147483648
        $ g 4294967295
        f 4294967295 returned -1
        $ g 4294967296
        f 4294967296 returned 0
        $ g 9223372036854775807
        f 9223372036854775807 returned -1

Fix:

2001-05-01  Paul Eggert  <eggert@twinsun.com>

        * builtins/common.c, builtins/common.h (get_exit_status):
        New function.
        * builtins/exit.def (exit_or_logout): Check that arg is a
        valid exit status.
        * builtins/return.def (return_builtin): Likewise.
        * doc/bashref.texi: Document restriction on exit status.

===================================================================
RCS file: builtins/common.c,v
retrieving revision 2.5.0.2
retrieving revision 2.5.0.3
diff -pu -r2.5.0.2 -r2.5.0.3
--- builtins/common.c   2001/05/01 01:06:58     2.5.0.2
+++ builtins/common.c   2001/05/02 00:10:18     2.5.0.3
@@ -362,6 +362,20 @@ get_numeric_arg (list, fatal)
   return (count);
 }
 
+/* Read an exit status for a shell builtin.  */
+int
+get_exit_status (list)
+     WORD_LIST *list;
+{
+  intmax_t status = get_numeric_arg (list, 1);
+  if (! (0 <= status && status < EX_SHERRBASE))
+    {
+      builtin_error ("exit status `%s' out of range", list->word->word);
+      throw_to_top_level ();
+    }
+  return status;
+}
+
 /* Return the octal number parsed from STRING, or -1 to indicate
    that the string contained a bad number. */
 int
===================================================================
RCS file: builtins/common.h,v
retrieving revision 2.5.0.2
retrieving revision 2.5.0.3
diff -pu -r2.5.0.2 -r2.5.0.3
--- builtins/common.h   2001/05/01 01:06:58     2.5.0.2
+++ builtins/common.h   2001/05/02 00:10:18     2.5.0.3
@@ -50,6 +50,7 @@ extern void set_dollar_vars_unchanged __
 extern void set_dollar_vars_changed __P((void));
 
 extern intmax_t get_numeric_arg __P((WORD_LIST *, int));
+extern int get_exit_status __P((WORD_LIST *));
 extern int read_octal __P((char *));
 
 /* Keeps track of the current working directory. */
===================================================================
RCS file: builtins/exit.def,v
retrieving revision 2.5
retrieving revision 2.5.0.1
diff -pu -r2.5 -r2.5.0.1
--- builtins/exit.def   1999/08/05 11:42:05     2.5
+++ builtins/exit.def   2001/05/02 00:10:18     2.5.0.1
@@ -119,7 +119,7 @@ exit_or_logout (list)
 
   /* Get return value if present.  This means that you can type
      `logout 5' to a shell, and it returns 5. */
-  exit_value = list ? get_numeric_arg (list, 1) : last_command_exit_value;
+  exit_value = list ? get_exit_status (list) : last_command_exit_value;
 
   /* Run our `~/.bash_logout' file if it exists, and this is a login shell. */
   if (login_shell && sourced_logout++ == 0)
===================================================================
RCS file: builtins/return.def,v
retrieving revision 2.5
retrieving revision 2.5.0.1
diff -pu -r2.5 -r2.5.0.1
--- builtins/return.def 1999/09/08 16:56:25     2.5
+++ builtins/return.def 2001/05/02 00:10:18     2.5.0.1
@@ -52,7 +52,7 @@ int
 return_builtin (list)
      WORD_LIST *list;
 {
-  return_catch_value = list ? get_numeric_arg (list, 1) : 
last_command_exit_value;
+  return_catch_value = list ? get_exit_status (list) : last_command_exit_value;
 
   if (return_catch_flag)
     longjmp (return_catch, 1);
===================================================================
RCS file: doc/bashref.texi,v
retrieving revision 2.5.0.1
retrieving revision 2.5.0.2
diff -pu -r2.5.0.1 -r2.5.0.2
--- doc/bashref.texi    2001/04/10 19:15:14     2.5.0.1
+++ doc/bashref.texi    2001/05/02 00:10:18     2.5.0.2
@@ -268,6 +268,7 @@ or one of the following:
 @item exit status
 @cindex exit status
 The value returned by a command to its caller.
+It is a nonnegative integer that is at most 255.
 
 @item field
 @cindex field
@@ -2538,6 +2539,8 @@ return status is zero; otherwise the ret
 exit [@var{n}]
 @end example
 Exit the shell, returning a status of @var{n} to the shell's parent.
+The optional argument @var{n} must be an unsigned decimal integer
+that does not exceed 255.
 If @var{n} is omitted, the exit status is that of the last command executed.
 Any trap on @code{EXIT} is executed before the shell terminates.
 
@@ -2665,13 +2668,15 @@ or the @option{-f} option is supplied wi
 return [@var{n}]
 @end example
 Cause a shell function to exit with the return value @var{n}.
+The optional argument @var{n} must be an unsigned decimal integer
+that does not exceed 255.
 If @var{n} is not supplied, the return value is the exit status of the
 last command executed in the function.
 This may also be used to terminate execution of a script being executed
 with the @code{.} (or @code{source}) builtin, returning either @var{n} or
 the exit status of the last command executed within the script as the exit
 status of the script.
-The return status is false if @code{return} is used outside a function
+The return status is non-zero if @code{return} is used outside a function
 and not during the execution of a script by @code{.} or @code{source}.
 
 @item shift



reply via email to

[Prev in Thread] Current Thread [Next in Thread]