903-ash.patch 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. --- a/shell/ash.c
  2. +++ b/shell/ash.c
  3. @@ -1569,14 +1569,14 @@
  4. static char *optptr; /* used by nextopt */
  5. /*
  6. - * XXX - should get rid of. have all builtins use getopt(3). the
  7. - * library getopt must have the BSD extension static variable "optreset"
  8. - * otherwise it can't be used within the shell safely.
  9. + * XXX - should get rid of. Have all builtins use getopt(3).
  10. + * The library getopt must have the BSD extension static variable
  11. + * "optreset", otherwise it can't be used within the shell safely.
  12. *
  13. - * Standard option processing (a la getopt) for builtin routines. The
  14. - * only argument that is passed to nextopt is the option string; the
  15. - * other arguments are unnecessary. It return the character, or '\0' on
  16. - * end of input.
  17. + * Standard option processing (a la getopt) for builtin routines.
  18. + * The only argument that is passed to nextopt is the option string;
  19. + * the other arguments are unnecessary. It returns the character,
  20. + * or '\0' on end of input.
  21. */
  22. static int
  23. nextopt(const char *optstring)
  24. @@ -1587,13 +1587,20 @@
  25. p = optptr;
  26. if (p == NULL || *p == '\0') {
  27. + /* We ate entire "-param", take next one */
  28. p = *argptr;
  29. - if (p == NULL || *p != '-' || *++p == '\0')
  30. + if (p == NULL)
  31. + return '\0';
  32. + if (*p != '-')
  33. + return '\0';
  34. + if (*++p == '\0') /* just "-" ? */
  35. return '\0';
  36. argptr++;
  37. - if (LONE_DASH(p)) /* check for "--" */
  38. + if (LONE_DASH(p)) /* "--" ? */
  39. return '\0';
  40. + /* p => next "-param" */
  41. }
  42. + /* p => some option char in the middle of a "-param" */
  43. c = *p++;
  44. for (q = optstring; *q != c;) {
  45. if (*q == '\0')
  46. @@ -1602,8 +1609,11 @@
  47. q++;
  48. }
  49. if (*++q == ':') {
  50. - if (*p == '\0' && (p = *argptr++) == NULL)
  51. - ash_msg_and_raise_error("no arg for -%c option", c);
  52. + if (*p == '\0') {
  53. + p = *argptr++;
  54. + if (p == NULL)
  55. + ash_msg_and_raise_error("no arg for -%c option", c);
  56. + }
  57. optionarg = p;
  58. p = NULL;
  59. }
  60. @@ -7428,8 +7438,10 @@
  61. else if (c != 'p')
  62. abort();
  63. #endif
  64. - if (verify)
  65. + /* Mimic bash: just "command -v" doesn't complain, it's a nop */
  66. + if (verify && (*argptr != NULL)) {
  67. return describe_command(*argptr, verify - VERIFY_BRIEF);
  68. + }
  69. return 0;
  70. }
  71. @@ -7788,16 +7800,33 @@
  72. static void
  73. evaltree(union node *n, int flags)
  74. {
  75. +
  76. + struct jmploc *volatile savehandler = exception_handler;
  77. + struct jmploc jmploc;
  78. int checkexit = 0;
  79. void (*evalfn)(union node *, int);
  80. - unsigned isor;
  81. int status;
  82. +
  83. if (n == NULL) {
  84. TRACE(("evaltree(NULL) called\n"));
  85. - goto out;
  86. + goto out1;
  87. }
  88. TRACE(("pid %d, evaltree(%p: %d, %d) called\n",
  89. getpid(), n, n->type, flags));
  90. +
  91. + exception_handler = &jmploc;
  92. + {
  93. + int err = setjmp(jmploc.loc);
  94. + if (err) {
  95. + /* if it was a signal, check for trap handlers */
  96. + if (exception == EXSIG)
  97. + goto out;
  98. + /* continue on the way out */
  99. + exception_handler = savehandler;
  100. + longjmp(exception_handler->loc, err);
  101. + }
  102. + }
  103. +
  104. switch (n->type) {
  105. default:
  106. #if DEBUG
  107. @@ -7843,19 +7872,20 @@
  108. goto calleval;
  109. case NAND:
  110. case NOR:
  111. - case NSEMI:
  112. + case NSEMI: {
  113. +
  114. #if NAND + 1 != NOR
  115. #error NAND + 1 != NOR
  116. #endif
  117. #if NOR + 1 != NSEMI
  118. #error NOR + 1 != NSEMI
  119. #endif
  120. - isor = n->type - NAND;
  121. + unsigned is_or = n->type - NAND;
  122. evaltree(
  123. n->nbinary.ch1,
  124. - (flags | ((isor >> 1) - 1)) & EV_TESTED
  125. + (flags | ((is_or >> 1) - 1)) & EV_TESTED
  126. );
  127. - if (!exitstatus == isor)
  128. + if (!exitstatus == is_or)
  129. break;
  130. if (!evalskip) {
  131. n = n->nbinary.ch2;
  132. @@ -7866,6 +7896,7 @@
  133. break;
  134. }
  135. break;
  136. + }
  137. case NIF:
  138. evaltree(n->nif.test, EV_TESTED);
  139. if (evalskip)
  140. @@ -7886,8 +7917,11 @@
  141. exitstatus = status;
  142. break;
  143. }
  144. +
  145. out:
  146. - if ((checkexit & exitstatus))
  147. + exception_handler = savehandler;
  148. + out1:
  149. + if (checkexit & exitstatus)
  150. evalskip |= SKIPEVAL;
  151. else if (pendingsig && dotrap())
  152. goto exexit;