]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
fix error return from wait builtin in a subshell when there are no children of this...
authorChet Ramey <chet.ramey@case.edu>
Mon, 10 Feb 2025 14:27:45 +0000 (09:27 -0500)
committerChet Ramey <chet.ramey@case.edu>
Mon, 10 Feb 2025 14:27:45 +0000 (09:27 -0500)
CWRU/CWRU.chlog
builtins/umask.def
doc/bash.1
examples/loadables/cat.c
examples/shellmath/shellmath.sh
jobs.c
lib/readline/doc/readline.3
lib/readline/doc/rluser.texi
lib/sh/zgetline.c

index 9824a366eb54d913db8bc6b5bef19a0aa8645d9e..632e93d7a5374e7ff53cfb4e9eb54ea73b246516 100644 (file)
@@ -10921,3 +10921,11 @@ lib/readline/rltty.c
          executing in a signal handler context and handling SIGTSTP and the
          application has indicated that it doesn't want the environment
          variables LINES and COLUMNS to have priority (rl_prefer_env_winsize)
+
+                                  1/30
+                                  ----
+jobs.c
+       - wait_for_single_pid: if wait_for returns -1/ECHILD, make sure to
+         return 257 just as if the child was not found, optionally printing
+         an error message if JWAIT_PERROR is supplied
+         From a discussion with Ian <saturns_rings@protonmail.com>
index d3488bf903ce4acdc8d2523dd19012543a50095e..2172d5a8f8748585a2cad3866619f920ef1e621b 100644 (file)
@@ -283,7 +283,11 @@ start_op:
              perm |= S_IWUGO;
              break;
            case 'X':
-             /* for chmod, this includes S_ISDIR but that doesn't make sense here */
+             /* for chmod, this includes S_ISDIR but that doesn't make sense for umask */
+#if defined (S_IFDIR)
+             if (this_shell_builtin != umask_builtin && (initial_bits & S_IFDIR) == 0)
+               break;
+#endif
              if ((initial_bits & S_IXUGO) == 0)
                break;          /* no-op if original mask doesn't include execute bits */
              /* FALLTHROUGH */
index 7061d59b06705e4d8d93731aeb6115f187c02fbe..fd86b83583184d5d307bacef50dc58daea96afb0 100644 (file)
@@ -7483,7 +7483,7 @@ leaving the current line at the top of the screen.
 Clear the screen,
 then redraw the current line,
 leaving the current line at the top of the screen.
-With an argument, refresh the current line without clearing the
+With a numeric argument, refresh the current line without clearing the
 screen.
 .TP
 .B redraw\-current\-line
index 5ce2c9a48706ddb5c68c92415da0ef3d059ceb8e..3499755bde4b5f639d63ac2d165a839fb77951f3 100644 (file)
@@ -72,17 +72,18 @@ fcopy(int fd, char *fn)
 int
 cat_main (int argc, char **argv)
 {
-       int     i, fd, r;
+       int     i, fd, r, closefd;
        char    *s;
 
        if (argc == 1)
                return (fcopy(0, "standard input"));
 
-       for (i = r = 1; i < argc; i++) {
+       for (i = 1, r = 0; i < argc; i++) {
                QUIT;
-               if (argv[i][0] == '-' && argv[i][1] == '\0')
+               if (argv[i][0] == '-' && argv[i][1] == '\0') {
                        fd = 0;
-               else {
+                       closefd = 0;
+               } else {
                        fd = open(argv[i], O_RDONLY, 0666);
                        if (fd < 0) {
                                s = strerror(errno);
@@ -91,11 +92,13 @@ cat_main (int argc, char **argv)
                                write(2, ": ", 2);
                                write(2, s, strlen(s));
                                write(2, "\n", 1);
+                               r++;
                                continue;
                        }
+                       closefd = 1;
                }
-               r = fcopy(fd, argv[i]);
-               if (fd != 0)
+               r += fcopy(fd, argv[i]);
+               if (closefd)
                        close(fd);
        }
        QUIT;
@@ -113,7 +116,7 @@ cat_builtin(WORD_LIST *list)
        r = cat_main(c, v);
        free(v);
 
-       return r;
+       return r;       /* relies on EXECUTION_SUCCESS being 0 */
 }
 
 char *cat_doc[] = {
index 5804ad2aede444432feee4270ac0297dcefa54e7..074aa9949b53ce3714e78f032973f5e4c280b840 100644 (file)
@@ -88,7 +88,7 @@ function _shellmath_handleError()
     
     # Display error msg, making parameter substitutions as needed
     msgParameters="$*"
-    printf  "$msgTemplate" "${msgParameters[@]}"
+    printf '%s ' "$msgTemplate" "${msgParameters[@]}"; printf '\n'
 
     if ((returnDontExit)); then
         return "$returnCode"
@@ -442,7 +442,7 @@ function _shellmath_add()
         ((isNegative2)) && ((integerPart2*=-1))
         local sum=$((integerPart1 + integerPart2))
         if (( (!isSubcall) && (isScientific1 || isScientific2) )); then
-            _shellmath_numToScientific $sum "" 
+            _shellmath_numToScientific $sum ""
             _shellmath_getReturnValue sum
         fi
         _shellmath_setReturnValue $sum
@@ -485,17 +485,11 @@ function _shellmath_add()
     # Summing the fractional parts is tricky: We need to override the shell's
     # default interpretation of leading zeros, but the operator for doing this
     # (the "10#" operator) cannot work directly with negative numbers. So we
-    # break it all down.
-    if ((isNegative1)); then
-        ((fractionalSum += (-1) * 10#${fractionalPart1:1}))
-    else
-        ((fractionalSum += 10#$fractionalPart1))
-    fi
-    if ((isNegative2)); then
-        ((fractionalSum += (-1) * 10#${fractionalPart2:1}))
-    else
-        ((fractionalSum += 10#$fractionalPart2))
-    fi
+    # use parameter expansions to separate the \+/-\ signs from the numbers.
+
+    ((fractionalSum =
+        ${fractionalPart1//[^-]}10#${fractionalPart1//[^0-9]} +
+        ${fractionalPart2//[^-]}10#${fractionalPart2//[^0-9]}))
 
     unsignedFracSumLength=${#fractionalSum}
     if [[ "$fractionalSum" =~ ^[-] ]]; then
@@ -515,7 +509,9 @@ function _shellmath_add()
     fi
 
     # Carry a digit from fraction to integer if required
-    if ((10#$fractionalSum!=0 && unsignedFracSumLength > unsignedFracLength)); then
+    if (( ${fractionalSum//[^-]}10#${fractionalSum//[^0-9]} !=0 )) &&
+        ((unsignedFracSumLength > unsignedFracLength))
+    then
         local carryAmount
         ((carryAmount = isNegative1?-1:1))
         ((integerSum += carryAmount))
@@ -527,34 +523,43 @@ function _shellmath_add()
     # pair (-2,3) is not -2.3 but rather (-2)+(0.3), i.e. -1.7 so we want to
     # transform (-2,3) to (-1,7). This transformation is meaningful when
     # the two parts have opposite signs, so that's what we look for.
-    if ((integerSum < 0 && 10#$fractionalSum > 0)); then
+    if ((integerSum < 0)) &&
+        (( ${fractionalSum//[^-]}10#${fractionalSum//[^0-9]} > 0))
+    then
         ((integerSum += 1))
-        ((fractionalSum = 10#$fractionalSum - 10**unsignedFracSumLength))
-    elif ((integerSum > 0 && 10#$fractionalSum < 0)); then
+        ((fractionalSum = ${fractionalSum//[^-]}10#${fractionalSum//[^0-9]} -
+            10**unsignedFracSumLength))
+    elif ((integerSum > 0)) &&
+        (( ${fractionalSum//[^-]}10#${fractionalSum//[^0-9]} < 0))
+    then
         ((integerSum -= 1))
-        ((fractionalSum = 10**unsignedFracSumLength + 10#$fractionalSum))
+        ((fractionalSum = 10**unsignedFracSumLength +
+            ${fractionalSum//[^-]}10#${fractionalSum//[^0-9]} ))
     fi
     # This last case needs to function either as an "else" for the above,
     # or as a coda to the "if" clause when integerSum is -1 initially.
-    if ((integerSum == 0 && 10#$fractionalSum < 0)); then
+    if ((integerSum == 0)) &&
+        (( ${fractionalSum//[^-]}10#${fractionalSum//[^0-9]} < 0))
+    then
         integerSum="-"$integerSum
         ((fractionalSum *= -1))
     fi
 
     # Touch up the numbers for display
     local sum
-    ((10#$fractionalSum < 0)) && fractionalSum=${fractionalSum:1}
+    (( ${fractionalSum//[^-]}10#${fractionalSum//[^0-9]}< 0)) &&
+        fractionalSum=${fractionalSum//[-]}
     if (( (!isSubcall) && (isScientific1 || isScientific2) )); then
         _shellmath_numToScientific "$integerSum" "$fractionalSum"
         _shellmath_getReturnValue sum
-    elif ((10#$fractionalSum)); then
+    elif (( ${fractionalSum//[^-]}10#${fractionalSum//[^0-9]} )); then
         printf -v sum "%s.%s" "$integerSum" "$fractionalSum"
     else
         sum=$integerSum
     fi
 
     # Note the result, print if running "normally", and return
-    _shellmath_setReturnValue $sum
+    _shellmath_setReturnValue "$sum"
     if (( isVerbose && ! isSubcall )); then
         echo "$sum"
     fi
@@ -660,9 +665,9 @@ function _shellmath_reduceOuterPairs()
         fi
 
         # Discard the least-significant digits or move them past the decimal point
-        value1=${value1%${tail1}}
+        value1=${value1%"${tail1}"}
         [[ -n "$subvalue1" ]] && subvalue1=${tail1}${subvalue1%0}  # remove placeholder zero
-        value2=${value2%${tail2}}
+        value2=${value2%"${tail2}"}
         [[ -n "$subvalue2" ]] && subvalue2=${tail2}${subvalue2%0}
     else
         # Signal the caller that no rescaling was actually done
@@ -733,7 +738,7 @@ function _shellmath_round()
 
     number=${number:0:digitCount}
     if ((nextDigit >= 5)); then
-        printf -v number "%0*d" "$digitCount" $((10#$number + 1))
+        printf -v number "%0*d" "$digitCount" $((${number//[^-]}10#${number//[^0-9]} + 1))
     fi
 
     _shellmath_setReturnValue "$number"
@@ -818,11 +823,15 @@ function _shellmath_multiply()
 
     # Overflow / underflow detection and accommodation
     local rescalingFactor=0
-    if ((${#integerPart1} + ${#integerPart2} + ${#fractionalPart1} + ${#fractionalPart2} >= ${__shellmath_precision})); then
+    if ((${#integerPart1} + ${#integerPart2} + ${#fractionalPart1} + ${#fractionalPart2} >= __shellmath_precision)); then
         _shellmath_reduceOuterPairs "$integerPart1" "$integerPart2" "$fractionalPart1" "$fractionalPart2"
         _shellmath_getReturnValues integerPart1 integerPart2 fractionalPart1 fractionalPart2 rescalingFactor
-        if ((10#$fractionalPart1)); then type1=${__shellmath_numericTypes[DECIMAL]}; fi
-        if ((10#$fractionalPart2)); then type2=${__shellmath_numericTypes[DECIMAL]}; fi
+        if ((${fractionalPart1//[^-]}10#${fractionalPart1//[^0-9]})); then
+            type1=${__shellmath_numericTypes[DECIMAL]}
+        fi
+        if ((${fractionalPart2//[^-]}10#${fractionalPart2//[^0-9]})); then
+            type2=${__shellmath_numericTypes[DECIMAL]}
+        fi
 
         _shellmath_reduceCrossPairs "$integerPart1" "$integerPart2" "$fractionalPart1" "$fractionalPart2"
         _shellmath_getReturnValues fractionalPart1 fractionalPart2
@@ -841,7 +850,7 @@ function _shellmath_multiply()
             _shellmath_getReturnValue product
         fi
         if (( (!isSubcall) && (isScientific1 || isScientific2) )); then
-            _shellmath_numToScientific $product "" 
+            _shellmath_numToScientific $product ""
             _shellmath_getReturnValue product
         fi
         _shellmath_setReturnValue $product
@@ -862,14 +871,16 @@ function _shellmath_multiply()
     fractionalWidth1=${#fractionalPart1}
     fractionalWidth2=${#fractionalPart2}
     ((floatWidth = fractionalWidth1 + fractionalWidth2))
-    ((floatProduct = 10#$fractionalPart1 * 10#$fractionalPart2))
+    ((floatProduct =
+        ${fractionalPart1//[^-]}10#${fractionalPart1//[^0-9]} *
+        ${fractionalPart2//[^-]}10#${fractionalPart2//[^0-9]}))
     if ((${#floatProduct} < floatWidth)); then
         printf -v floatProduct "%0*d" "$floatWidth" "$floatProduct"
     fi
 
     # Compute the inner products: First integer-multiply, then rescale
-    ((innerProduct1 = integerPart1 * 10#$fractionalPart2))
-    ((innerProduct2 = integerPart2 * 10#$fractionalPart1))
+    ((innerProduct1 = integerPart1 * ${fractionalPart2//[^-]}10#${fractionalPart2//[^0-9]}))
+    ((innerProduct2 = integerPart2 * ${fractionalPart1//[^-]}10#${fractionalPart1//[^0-9]}))
 
     # Rescale the inner products back to decimals so we can shellmath_add() them
     if ((fractionalWidth2 <= ${#innerProduct1})); then
@@ -979,7 +990,9 @@ function _shellmath_divide()
     fi
 
     # Throw error on divide by zero
-    if ((integerPart2 == 0 && 10#$fractionalPart2 == 0)); then
+    if ((integerPart2 == 0)) &&
+        (( ${fractionalPart2//[^-]}10#${fractionalPart2//[^0-9]} == 0 ))
+    then
         _shellmath_warn  "${__shellmath_returnCodes[DIVIDE_BY_ZERO]}"  "$n2"
         return $?
     fi
@@ -1002,11 +1015,13 @@ function _shellmath_divide()
     # Rescale and rewrite the fraction to be computed, and compute it
     numerator=${integerPart1}${fractionalPart1}${zeroTail}
     denominator=${integerPart2}${fractionalPart2}
-    ((quotient = 10#$numerator / 10#$denominator))
+    ((quotient = ${numerator//[^-]}10#${numerator//[^0-9]} /
+        ${denominator//[^-]}10#${denominator//[^0-9]}))
 
     # For greater precision, re-divide by the remainder to get the next digits of the quotient
     local remainder quotient_2
-    ((remainder = 10#$numerator % 10#$denominator))   # cannot exceed numerator or thus, maxValue
+    ((remainder = ${numerator//[^-]}10#${numerator//[^0-9]} %
+        ${denominator//[^-]}10#${denominator//[^0-9]})) # cant exceed numerator or thus, maxValue
     ((zeroCount = __shellmath_precision - ${#remainder}))
     if ((zeroCount > 0)); then
         printf -v zeroTail "%0*d" "$zeroCount" 0
@@ -1015,7 +1030,8 @@ function _shellmath_divide()
     fi
     # Derive the new numerator from the remainder. Do not change the denominator.
     numerator=${remainder}${zeroTail}
-    ((quotient_2 = 10#$numerator / 10#$denominator))
+    ((quotient_2 = ${numerator//[^-]}10#${numerator//[^0-9]} /
+        ${denominator//[^-]}10#${denominator//[^0-9]}))
     quotient=${quotient}${quotient_2}
     ((rescaleFactor += ${#quotient_2}))
 
@@ -1027,12 +1043,12 @@ function _shellmath_divide()
             printf -v zeroPrefix "%0*d" "$((rescaleFactor - ${#quotient}))" 0
         fi
         fractionalPart=${zeroPrefix}${quotient}
-        _shellmath_round "$fractionalPart" $__shellmath_precision
+        _shellmath_round "$fractionalPart" "$__shellmath_precision"
         _shellmath_getReturnValue fractionalPart
         quotient="0."${fractionalPart}
     else
         fractionalPart=${quotient:(-$rescaleFactor)}
-        _shellmath_round "$fractionalPart" $__shellmath_precision
+        _shellmath_round "$fractionalPart" "$__shellmath_precision"
         _shellmath_getReturnValue fractionalPart
         quotient=${quotient:0:(-$rescaleFactor)}"."${fractionalPart}
     fi
@@ -1047,7 +1063,7 @@ function _shellmath_divide()
         if [[ "$quotient" =~ [\.].*0$ ]]; then
             # If the decimal point IMMEDIATELY precedes the 0s, remove that too
             [[ $quotient =~ [\.]?0+$ ]]
-            quotient=${quotient%${BASH_REMATCH[0]}}
+            quotient=${quotient%"${BASH_REMATCH[0]}"}
         fi
     fi
 
@@ -1065,4 +1081,3 @@ function _shellmath_divide()
 
     return "$__shellmath_SUCCESS"
 }
-
diff --git a/jobs.c b/jobs.c
index d93df3fc896c998c14f858947e8527968c7d2a2d..b73f75afc244700e220938752edbc1392769eb4a 100644 (file)
--- a/jobs.c
+++ b/jobs.c
@@ -2749,6 +2749,7 @@ wait_for_single_pid (pid_t pid, int flags)
 
   if (child == 0)
     {
+no_child:
       if (flags & JWAIT_PERROR)
        internal_error (_("wait: pid %ld is not a child of this shell"), (long)pid);
       return (257);
@@ -2758,6 +2759,8 @@ wait_for_single_pid (pid_t pid, int flags)
   do
     {
       r = wait_for (pid, 0);
+      if (r == -1 && errno == ECHILD)
+       goto no_child;
       if ((flags & JWAIT_FORCE) == 0)
        break;
 
index 3c1ef4838062772d7f14b5491b3847a438612635..f66e21a318daf1008d99026534e2d4c76af357c6 100644 (file)
@@ -1057,7 +1057,7 @@ leaving the current line at the top of the screen.
 Clear the screen,
 then redraw the current line,
 leaving the current line at the top of the screen.
-With an argument, refresh the current line without clearing the
+With a numeric argument, refresh the current line without clearing the
 screen.
 .TP
 .B redraw\-current\-line
index 27078b5e01324379c6aa042a6fae1bc5872eda02..704b88f2b0b82b123f530e27f0a6e274731c6869 100644 (file)
@@ -1388,6 +1388,8 @@ leaving the current line at the top of the screen.
 Clear the screen,
 then redraw the current line,
 leaving the current line at the top of the screen.
+If given a numeric argument, this refreshes the current line
+without clearing the screen.
 
 @item redraw-current-line ()
 Refresh the current line.  By default, this is unbound.
index 0bb10dfb522a686334ca69d168f8ec591f08160d..79db1ce15c0ce521343eab21e553da3664219401 100644 (file)
@@ -43,7 +43,7 @@ typedef ssize_t breadfunc_t (int, char *, size_t);
 typedef ssize_t creadfunc_t (int, char *);
 
 /* Initial memory allocation for automatic growing buffer in zreadlinec */
-#define GET_LINE_INITIAL_ALLOCATION 16
+#define GET_LINE_INITIAL_ALLOCATION 64
 
 /* Derived from GNU libc's getline.
    The behavior is almost the same as getline. See man getline.