aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-07-28 12:13:58 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2018-07-28 12:13:58 +0200
commitaa449c927d1d84092f9654e45ab9f68847e81226 (patch)
tree3ae7ea620aa9498cac9d8f2efac73a90ecdf52a6
parent4b70c926bcbfaf6df6e21c98ea096b0db8629095 (diff)
downloadbusybox-w32-aa449c927d1d84092f9654e45ab9f68847e81226.tar.gz
busybox-w32-aa449c927d1d84092f9654e45ab9f68847e81226.tar.bz2
busybox-w32-aa449c927d1d84092f9654e45ab9f68847e81226.zip
hush: make "set -x" output don't redirectable when fd#2 redirected
function old new delta x_mode_print_optionally_squoted - 120 +120 x_mode_flush - 68 +68 save_fd_on_redirect 208 243 +35 x_mode_prefix - 27 +27 x_mode_addblock - 23 +23 x_mode_addchr - 17 +17 dump_cmd_in_x_mode 110 85 -25 run_pipe 1919 1890 -29 print_optionally_squoted 145 - -145 ------------------------------------------------------------------------------ (add/remove: 5/1 grow/shrink: 1/2 up/down: 290/-199) Total: 91 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/hush.c129
1 files changed, 84 insertions, 45 deletions
diff --git a/shell/hush.c b/shell/hush.c
index ac8467fb4..9676819fa 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -955,9 +955,6 @@ struct globals {
955# endif 955# endif
956 struct function *top_func; 956 struct function *top_func;
957#endif 957#endif
958#if ENABLE_HUSH_MODE_X
959 unsigned x_mode_depth;
960#endif
961 /* Signal and trap handling */ 958 /* Signal and trap handling */
962#if ENABLE_HUSH_FAST 959#if ENABLE_HUSH_FAST
963 unsigned count_SIGCHLD; 960 unsigned count_SIGCHLD;
@@ -993,6 +990,15 @@ struct globals {
993#if ENABLE_HUSH_MEMLEAK 990#if ENABLE_HUSH_MEMLEAK
994 unsigned long memleak_value; 991 unsigned long memleak_value;
995#endif 992#endif
993#if ENABLE_HUSH_MODE_X
994 unsigned x_mode_depth;
995 /* "set -x" output should not be redirectable with subsequent 2>FILE.
996 * We dup fd#2 to x_mode_fd when "set -x" is executed, and use it
997 * for all subsequent output.
998 */
999 int x_mode_fd;
1000 o_string x_mode_buf;
1001#endif
996#if HUSH_DEBUG 1002#if HUSH_DEBUG
997 int debug_indent; 1003 int debug_indent;
998#endif 1004#endif
@@ -1660,6 +1666,12 @@ static int move_HFILEs_on_redirect(int fd, int avoid_fd)
1660 } 1666 }
1661 fl = fl->next_hfile; 1667 fl = fl->next_hfile;
1662 } 1668 }
1669#if ENABLE_HUSH_MODE_X
1670 if (G.x_mode_fd > 0 && fd == G.x_mode_fd) {
1671 G.x_mode_fd = xdup_CLOEXEC_and_close(fd, avoid_fd);
1672 return 1; /* "found and moved" */
1673 }
1674#endif
1663 return 0; /* "not in the list" */ 1675 return 0; /* "not in the list" */
1664} 1676}
1665#if ENABLE_FEATURE_SH_STANDALONE && BB_MMU 1677#if ENABLE_FEATURE_SH_STANDALONE && BB_MMU
@@ -2903,6 +2915,11 @@ static void o_addstr(o_string *o, const char *str)
2903 o_addblock(o, str, strlen(str)); 2915 o_addblock(o, str, strlen(str));
2904} 2916}
2905 2917
2918static void o_addstr_with_NUL(o_string *o, const char *str)
2919{
2920 o_addblock(o, str, strlen(str) + 1);
2921}
2922
2906#if !BB_MMU 2923#if !BB_MMU
2907static void nommu_addchr(o_string *o, int ch) 2924static void nommu_addchr(o_string *o, int ch)
2908{ 2925{
@@ -2913,10 +2930,36 @@ static void nommu_addchr(o_string *o, int ch)
2913# define nommu_addchr(o, str) ((void)0) 2930# define nommu_addchr(o, str) ((void)0)
2914#endif 2931#endif
2915 2932
2916static void o_addstr_with_NUL(o_string *o, const char *str) 2933#if ENABLE_HUSH_MODE_X
2934static void x_mode_addchr(int ch)
2917{ 2935{
2918 o_addblock(o, str, strlen(str) + 1); 2936 o_addchr(&G.x_mode_buf, ch);
2919} 2937}
2938static void x_mode_addstr(const char *str)
2939{
2940 o_addstr(&G.x_mode_buf, str);
2941}
2942static void x_mode_addblock(const char *str, int len)
2943{
2944 o_addblock(&G.x_mode_buf, str, len);
2945}
2946static void x_mode_prefix(void)
2947{
2948 int n = G.x_mode_depth;
2949 do x_mode_addchr('+'); while (--n >= 0);
2950}
2951static void x_mode_flush(void)
2952{
2953 int len = G.x_mode_buf.length;
2954 if (len <= 0)
2955 return;
2956 if (G.x_mode_fd > 0) {
2957 G.x_mode_buf.data[len] = '\n';
2958 full_write(G.x_mode_fd, G.x_mode_buf.data, len + 1);
2959 }
2960 G.x_mode_buf.length = 0;
2961}
2962#endif
2920 2963
2921/* 2964/*
2922 * HUSH_BRACE_EXPANSION code needs corresponding quoting on variable expansion side. 2965 * HUSH_BRACE_EXPANSION code needs corresponding quoting on variable expansion side.
@@ -8030,31 +8073,26 @@ static void execvp_or_die(char **argv)
8030} 8073}
8031 8074
8032#if ENABLE_HUSH_MODE_X 8075#if ENABLE_HUSH_MODE_X
8033static void print_optionally_squoted(FILE *fp, const char *str) 8076static void x_mode_print_optionally_squoted(const char *str)
8034{ 8077{
8035 unsigned len; 8078 unsigned len;
8036 const char *cp; 8079 const char *cp;
8037 8080
8038 cp = str; 8081 cp = str;
8039 if (str[0] != '{' && str[0] != '(') for (;;) { 8082
8040 if (!*cp) { 8083 /* the set of chars which-cause-string-to-be-squoted mimics bash */
8041 /* string has no special chars */ 8084 /* test a char with: bash -c 'set -x; echo "CH"' */
8042 fputs(str, fp); 8085 if (str[strcspn(str, "\\\"'`$(){}[]<>;#&|~*?!^"
8043 return; 8086 " " "\001\002\003\004\005\006\007"
8044 } 8087 "\010\011\012\013\014\015\016\017"
8045 if (*cp == '\\') break; 8088 "\020\021\022\023\024\025\026\027"
8046 if (*cp == '\'') break; 8089 "\030\031\032\033\034\035\036\037"
8047 if (*cp == '"') break; 8090 )
8048 if (*cp == '$') break; 8091 ] == '\0'
8049 if (*cp == '!') break; 8092 ) {
8050 if (*cp == '*') break; 8093 /* string has no special chars */
8051 if (*cp == '[') break; 8094 x_mode_addstr(str);
8052 if (*cp == ']') break; 8095 return;
8053#if ENABLE_HUSH_TICK
8054 if (*cp == '`') break;
8055#endif
8056 if (isspace(*cp)) break;
8057 cp++;
8058 } 8096 }
8059 8097
8060 cp = str; 8098 cp = str;
@@ -8062,13 +8100,16 @@ static void print_optionally_squoted(FILE *fp, const char *str)
8062 /* print '....' up to EOL or first squote */ 8100 /* print '....' up to EOL or first squote */
8063 len = (int)(strchrnul(cp, '\'') - cp); 8101 len = (int)(strchrnul(cp, '\'') - cp);
8064 if (len != 0) { 8102 if (len != 0) {
8065 fprintf(fp, "'%.*s'", len, cp); 8103 x_mode_addchr('\'');
8104 x_mode_addblock(cp, len);
8105 x_mode_addchr('\'');
8066 cp += len; 8106 cp += len;
8067 } 8107 }
8068 if (*cp == '\0') 8108 if (*cp == '\0')
8069 break; 8109 break;
8070 /* string contains squote(s), print them as \' */ 8110 /* string contains squote(s), print them as \' */
8071 fprintf(fp, "\\'"); 8111 x_mode_addchr('\\');
8112 x_mode_addchr('\'');
8072 cp++; 8113 cp++;
8073 } 8114 }
8074} 8115}
@@ -8078,19 +8119,19 @@ static void dump_cmd_in_x_mode(char **argv)
8078 unsigned n; 8119 unsigned n;
8079 8120
8080 /* "+[+++...][ cmd...]\n\0" */ 8121 /* "+[+++...][ cmd...]\n\0" */
8081 n = G.x_mode_depth; 8122 x_mode_prefix();
8082 do bb_putchar_stderr('+'); while ((int)(--n) >= 0);
8083 n = 0; 8123 n = 0;
8084 while (argv[n]) { 8124 while (argv[n]) {
8085 if (argv[n][0] == '\0') 8125 x_mode_addchr(' ');
8086 fputs(" ''", stderr); 8126 if (argv[n][0] == '\0') {
8087 else { 8127 x_mode_addchr('\'');
8088 bb_putchar_stderr(' '); 8128 x_mode_addchr('\'');
8089 print_optionally_squoted(stderr, argv[n]); 8129 } else {
8130 x_mode_print_optionally_squoted(argv[n]);
8090 } 8131 }
8091 n++; 8132 n++;
8092 } 8133 }
8093 bb_putchar_stderr('\n'); 8134 x_mode_flush();
8094 } 8135 }
8095} 8136}
8096#else 8137#else
@@ -8885,17 +8926,14 @@ static NOINLINE int run_pipe(struct pipe *pi)
8885#if ENABLE_HUSH_MODE_X 8926#if ENABLE_HUSH_MODE_X
8886 if (G_x_mode) { 8927 if (G_x_mode) {
8887 char *eq; 8928 char *eq;
8888 if (i == 0) { 8929 if (i == 0)
8889 unsigned n = G.x_mode_depth; 8930 x_mode_prefix();
8890 do 8931 x_mode_addchr(' ');
8891 bb_putchar_stderr('+');
8892 while ((int)(--n) >= 0);
8893 }
8894 eq = strchrnul(p, '='); 8932 eq = strchrnul(p, '=');
8895 fprintf(stderr, " %.*s=", (int)(eq - p), p); 8933 if (*eq) eq++;
8896 if (*eq) 8934 x_mode_addblock(p, (eq - p));
8897 print_optionally_squoted(stderr, eq + 1); 8935 x_mode_print_optionally_squoted(eq);
8898 bb_putchar_stderr('\n'); 8936 x_mode_flush();
8899 } 8937 }
8900#endif 8938#endif
8901 debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p); 8939 debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p);
@@ -9691,6 +9729,7 @@ static int set_mode(int state, char mode, const char *o_opt)
9691 break; 9729 break;
9692 case 'x': 9730 case 'x':
9693 IF_HUSH_MODE_X(G_x_mode = state;) 9731 IF_HUSH_MODE_X(G_x_mode = state;)
9732 IF_HUSH_MODE_X(if (G.x_mode_fd <= 0) G.x_mode_fd = dup_CLOEXEC(2, 10);)
9694 break; 9733 break;
9695 case 'o': 9734 case 'o':
9696 if (!o_opt) { 9735 if (!o_opt) {