apply post-1.11.2 fixes, bump version to 1.11.3 1_11_stable 1_11_3
authorDenis Vlasenko <vda.linux@googlemail.com>
Sun, 28 Sep 2008 16:40:02 +0000 (16:40 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Sun, 28 Sep 2008 16:40:02 +0000 (16:40 -0000)
Makefile
console-tools/kbd_mode.c
editors/vi.c
include/usage.h
libbb/lineedit.c
miscutils/crontab.c
miscutils/taskset.c

index fc9b3c1da0cb6643f59bb69008524264cac549e9..190d14e2edb360c69b56181e381603f707fff0df 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 11
-SUBLEVEL = 2
+SUBLEVEL = 3
 EXTRAVERSION =
 NAME = Unnamed
 
index f40ee6403305a008b293f006cb4375f1dd34a50d..2137d9f47e4f05bb151d84218dd1bf5011457285 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Mini kbd_mode implementation for busybox
  *
- * Copyright (C) 2007 Loïc Grenié <loic.grenie@gmail.com>
+ * Copyright (C) 2007 Loic Grenie <loic.grenie@gmail.com>
  *   written using Andries Brouwer <aeb@cwi.nl>'s kbd_mode from
  *   console-utils v0.2.3, licensed under GNU GPLv2
  *
@@ -46,6 +46,7 @@ int kbd_mode_main(int ATTRIBUTE_UNUSED argc, char **argv)
                printf("The keyboard is in %s mode\n", mode);
        } else {
                opt = opt & UNICODE ? 3 : opt >> 1;
+               /* double cast prevents warnings about widening conversion */
                xioctl(fd, KDSKBMODE, (void*)(ptrdiff_t)opt);
        }
 
index 81baa890f7e080463dbc166545095deb8c230b6e..1985be7db921cf8fa8b3b91cea8883edaf650bdd 100644 (file)
@@ -147,10 +147,10 @@ struct globals {
 #endif
 
        smallint editing;        // >0 while we are editing a file
-                                // [code audit says "can be 0 or 1 only"]
+                                // [code audit says "can be 0, 1 or 2 only"]
        smallint cmd_mode;       // 0=command  1=insert 2=replace
        int file_modified;       // buffer contents changed (counter, not flag!)
-       int last_file_modified; // = -1;
+       int last_file_modified;  // = -1;
        int fn_start;            // index of first cmd line file name
        int save_argc;           // how many file names on cmd line
        int cmdcnt;              // repetition count
@@ -623,7 +623,7 @@ static void edit_file(char *fn)
                // These are commands that change text[].
                // Remember the input for the "." command
                if (!adding2q && ioq_start == NULL
-                && strchr(modifying_cmds, c)
+                && c != '\0' && strchr(modifying_cmds, c)
                ) {
                        start_new_cmd_q(c);
                }
@@ -645,8 +645,8 @@ static void edit_file(char *fn)
        }
        //-------------------------------------------------------------------
 
-       place_cursor(rows, 0, FALSE);   // go to bottom of screen
-       clear_to_eol();         // Erase to end of line
+       place_cursor(rows - 1, 0, FALSE); // go to bottom of screen
+       clear_to_eol(); // erase to end of line
        cookmode();
 #undef cur_line
 }
@@ -2009,9 +2009,9 @@ static void start_new_cmd_q(char c)
 {
        // get buffer for new cmd
        // if there is a current cmd count put it in the buffer first
-       if (cmdcnt > 0)
+       if (cmdcnt > 0) {
                lmc_len = sprintf(last_modifying_cmd, "%d%c", cmdcnt, c);
-       else { // just save char c onto queue
+       else { // just save char c onto queue
                last_modifying_cmd[0] = c;
                lmc_len = 1;
        }
@@ -2247,18 +2247,20 @@ static char readit(void)        // read (maybe cursor) key from stdin
 
        fflush(stdout);
        n = chars_to_parse;
-       // get input from User- are there already input chars in Q?
+       // get input from User - are there already input chars in Q?
        if (n <= 0) {
                // the Q is empty, wait for a typed char
+ again:
                n = safe_read(STDIN_FILENO, readbuffer, sizeof(readbuffer));
-               if (n < 0) {
-                       if (errno == EBADF || errno == EFAULT || errno == EINVAL
-                        || errno == EIO)
-                               editing = 0; // want to exit
-                       errno = 0;
-               }
-               if (n <= 0)
-                       return 0;       // error
+               if (n <= 0) {
+                       place_cursor(rows - 1, 0, FALSE); // go to bottom of screen
+                       clear_to_eol(); // erase to end of line
+                       cookmode(); // terminal to "cooked"
+                       bb_error_msg_and_die("can't read user input");
+               }
+               /* elsewhere we can get very confused by NULs */
+               if (readbuffer[0] == '\0')
+                       goto again;
                if (readbuffer[0] == 27) {
                        // This is an ESC char. Is this Esc sequence?
                        // Could be bare Esc key. See if there are any
index dcb6e344e77ff0438fd0deac7bdb379ac02115c6..1165ad615643cca99b70626fc5d65a1adc74ac6d 100644 (file)
        "[OPTIONS] [-S|-K] ... [-- arguments...]"
 #define start_stop_daemon_full_usage "\n\n" \
        "Search for matching processes, and then\n" \
-       "-S: stop all matching processes.\n" \
-       "-K: start a process unless a matching process is found.\n" \
+       "-S: start a process unless a matching process is found.\n" \
+       "-K: stop all matching processes.\n" \
        USE_GETOPT_LONG( \
      "\nProcess matching:" \
      "\n       -u,--user USERNAME|UID  Match only this user's processes" \
      "\n                               in /proc/PID/cmdline" \
      "\n       -p,--pidfile FILE       Match a process with PID from the file" \
      "\n       All specified conditions must match" \
-     "\n-K only:" \
+     "\n-S only:" \
      "\n       -x,--exec EXECUTABLE    Program to run" \
      "\n       -a,--startas NAME       Zeroth argument" \
      "\n       -b,--background         Background" \
        ) \
      "\n       -c,--chuid USER[:[GRP]] Change to user/group" \
      "\n       -m,--make-pidfile       Write PID to the pidfile specified by -p" \
-     "\n-S only:" \
+     "\n-K only:" \
      "\n       -s,--signal SIG         Signal to send" \
      "\n       -t,--test               Match only, exit with 0 if a process is found" \
      "\nOther:" \
      "\n                       command in /proc/PID/cmdline" \
      "\n       -p FILE         Match a process with PID from the file" \
      "\n       All specified conditions must match" \
-     "\n-K only:" \
+     "\n-S only:" \
      "\n       -x EXECUTABLE   Program to run" \
      "\n       -a NAME         Zeroth argument" \
      "\n       -b              Background" \
        ) \
      "\n       -c USER[:[GRP]] Change to user/group" \
      "\n       -m              Write PID to the pidfile specified by -p" \
-     "\n-S only:" \
+     "\n-K only:" \
      "\n       -s SIG          Signal to send" \
      "\n       -t              Match only, exit with 0 if a process is found" \
      "\nOther:" \
index fb595c01085bae3b33697ff7c39bc6886c9c65ed..b3f4f532760a19963c1319e3a8c780019ec16f68 100644 (file)
@@ -953,24 +953,33 @@ static void input_tab(smallint *lastWasTab)
 
 #if MAX_HISTORY > 0
 
+static void save_command_ps_at_cur_history(void)
+{
+       if (command_ps[0] != '\0') {
+               int cur = state->cur_history;
+               free(state->history[cur]);
+               state->history[cur] = xstrdup(command_ps);
+       }
+}
+
 /* state->flags is already checked to be nonzero */
-static void get_previous_history(void)
+static int get_previous_history(void)
 {
-       if (command_ps[0] != '\0' || state->history[state->cur_history] == NULL) {
-               free(state->history[state->cur_history]);
-               state->history[state->cur_history] = xstrdup(command_ps);
+       if ((state->flags & DO_HISTORY) && state->cur_history) {
+               save_command_ps_at_cur_history();
+               state->cur_history--;
+               return 1;
        }
-       state->cur_history--;
+       beep();
+       return 0;
 }
 
 static int get_next_history(void)
 {
        if (state->flags & DO_HISTORY) {
-               int ch = state->cur_history;
-               if (ch < state->cnt_history) {
-                       get_previous_history(); /* save the current history line */
-                       state->cur_history = ch + 1;
-                       return state->cur_history;
+               if (state->cur_history < state->cnt_history) {
+                       save_command_ps_at_cur_history(); /* save the current history line */
+                       return ++state->cur_history;
                }
        }
        beep();
@@ -992,6 +1001,7 @@ static void load_history(const char *fromfile)
                for (hi = state->cnt_history; hi > 0;) {
                        hi--;
                        free(state->history[hi]);
+                       state->history[hi] = NULL;
                }
 
                for (hi = 0; hi < MAX_HISTORY;) {
@@ -1003,14 +1013,14 @@ static void load_history(const char *fromfile)
                        l = strlen(hl);
                        if (l >= MAX_LINELEN)
                                hl[MAX_LINELEN-1] = '\0';
-                       if (l == 0 || hl[0] == ' ') {
+                       if (l == 0) {
                                free(hl);
                                continue;
                        }
                        state->history[hi++] = hl;
                }
                fclose(fp);
-               state->cur_history = state->cnt_history = hi;
+               state->cnt_history = hi;
        }
 }
 
@@ -1040,19 +1050,27 @@ static void remember_in_history(const char *str)
 
        if (!(state->flags & DO_HISTORY))
                return;
-
+       if (str[0] == '\0')
+               return;
        i = state->cnt_history;
-       free(state->history[MAX_HISTORY]);
-       state->history[MAX_HISTORY] = NULL;
-       /* After max history, remove the oldest command */
+       /* Don't save dupes */
+       if (i && strcmp(state->history[i-1], str) == 0)
+               return;
+
+       free(state->history[MAX_HISTORY]); /* redundant, paranoia */
+       state->history[MAX_HISTORY] = NULL; /* redundant, paranoia */
+
+       /* If history[] is full, remove the oldest command */
+       /* we need to keep history[MAX_HISTORY] empty, hence >=, not > */
        if (i >= MAX_HISTORY) {
                free(state->history[0]);
                for (i = 0; i < MAX_HISTORY-1; i++)
                        state->history[i] = state->history[i+1];
+               /* i == MAX_HISTORY-1 */
        }
-// Maybe "if (!i || strcmp(history[i-1], command) != 0) ..."
-// (i.e. do not save dups?)
+       /* i <= MAX_HISTORY-1 */
        state->history[i++] = xstrdup(str);
+       /* i <= MAX_HISTORY */
        state->cur_history = i;
        state->cnt_history = i;
 #if ENABLE_FEATURE_EDITING_SAVEHISTORY
@@ -1394,6 +1412,7 @@ int read_line_input(const char *prompt, char *command, int maxsize, line_input_t
        if ((state->flags & SAVE_HISTORY) && state->hist_file)
                load_history(state->hist_file);
 #endif
+       state->cur_history = state->cnt_history;
 
        /* prepare before init handlers */
        cmdedit_y = 0;  /* quasireal y, not true if line > xt*yt */
@@ -1429,6 +1448,13 @@ int read_line_input(const char *prompt, char *command, int maxsize, line_input_t
                }
        }
 #endif
+
+#if 0
+       for (ic = 0; ic <= MAX_HISTORY; ic++)
+               bb_error_msg("history[%d]:'%s'", ic, state->history[ic]);
+       bb_error_msg("cur_history:%d cnt_history:%d", state->cur_history, state->cnt_history);
+#endif
+
        /* Print out the command prompt */
        parse_and_put_prompt(prompt);
 
@@ -1537,11 +1563,8 @@ int read_line_input(const char *prompt, char *command, int maxsize, line_input_t
                vi_case(CTRL('P')|vbit:)
                vi_case('k'|vbit:)
                        /* Control-p -- Get previous command from history */
-                       if ((state->flags & DO_HISTORY) && state->cur_history > 0) {
-                               get_previous_history();
+                       if (get_previous_history())
                                goto rewrite_line;
-                       }
-                       beep();
                        break;
 #endif
 
@@ -1730,10 +1753,8 @@ int read_line_input(const char *prompt, char *command, int maxsize, line_input_t
 #if MAX_HISTORY > 0
                        case 'A':
                                /* Up Arrow -- Get previous command from history */
-                               if ((state->flags & DO_HISTORY) && state->cur_history > 0) {
-                                       get_previous_history();
+                               if (get_previous_history())
                                        goto rewrite_line;
-                               }
                                beep();
                                break;
                        case 'B':
@@ -1743,7 +1764,7 @@ int read_line_input(const char *prompt, char *command, int maxsize, line_input_t
  rewrite_line:
                                /* Rewrite the line with the selected history item */
                                /* change command */
-                               command_len = strlen(strcpy(command, state->history[state->cur_history]));
+                               command_len = strlen(strcpy(command, state->history[state->cur_history] ? : ""));
                                /* redraw and go to eol (bol, in vi */
                                redraw(cmdedit_y, (state->flags & VI_MODE) ? 9999 : 0);
                                break;
index dc3179dac20add33b8464041321d9433e8e7a246..38933cf4acec2852de15fe8bc2f7e2b63390342b 100644 (file)
@@ -93,6 +93,7 @@ int crontab_main(int argc ATTRIBUTE_UNUSED, char **argv)
        char *new_fname;
        char *user_name;  /* -u USER */
        int fd;
+       int src_fd;
        int opt_ler;
 
        /* file [opts]     Replace crontab from file
@@ -144,15 +145,15 @@ int crontab_main(int argc ATTRIBUTE_UNUSED, char **argv)
                bb_show_usage();
 
        /* Read replacement file under user's UID/GID/group vector */
+       src_fd = STDIN_FILENO;
        if (!opt_ler) { /* Replace? */
                if (!argv[0])
                        bb_show_usage();
                if (NOT_LONE_DASH(argv[0])) {
-                       fd = open_as_user(pas, argv[0]);
-                       if (fd < 0)
+                       src_fd = open_as_user(pas, argv[0]);
+                       if (src_fd < 0)
                                bb_error_msg_and_die("user %s cannot read %s",
                                                pas->pw_name, argv[0]);
-                       xmove_fd(fd, STDIN_FILENO);
                }
        }
 
@@ -180,23 +181,23 @@ int crontab_main(int argc ATTRIBUTE_UNUSED, char **argv)
                tmp_fname = xasprintf("%s.%u", crontab_dir, (unsigned)getpid());
                /* No O_EXCL: we don't want to be stuck if earlier crontabs
                 * were killed, leaving stale temp file behind */
-               fd = xopen3(tmp_fname, O_RDWR|O_CREAT|O_TRUNC, 0600);
-               xmove_fd(fd, STDIN_FILENO);
-               fchown(STDIN_FILENO, pas->pw_uid, pas->pw_gid);
+               src_fd = xopen3(tmp_fname, O_RDWR|O_CREAT|O_TRUNC, 0600);
+               fchown(src_fd, pas->pw_uid, pas->pw_gid);
                fd = open(pas->pw_name, O_RDONLY);
                if (fd >= 0) {
-                       bb_copyfd_eof(fd, STDIN_FILENO);
+                       bb_copyfd_eof(fd, src_fd);
                        close(fd);
+                       xlseek(src_fd, 0, SEEK_SET);
                }
+               close_on_exec_on(src_fd); /* don't want editor to see this fd */
                edit_file(pas, tmp_fname);
-               xlseek(STDIN_FILENO, 0, SEEK_SET);
                /* fall through */
 
        case 0: /* Replace (no -l, -e, or -r were given) */
                new_fname = xasprintf("%s.new", pas->pw_name);
                fd = open(new_fname, O_WRONLY|O_CREAT|O_TRUNC|O_APPEND, 0600);
                if (fd >= 0) {
-                       bb_copyfd_eof(STDIN_FILENO, fd);
+                       bb_copyfd_eof(src_fd, fd);
                        close(fd);
                        xrename(new_fname, pas->pw_name);
                } else {
index 708abd9f275ac29c9d5fd30e1eb398683d4c8935..973f94ac3d76b1c380dee2bf132520864d20ce93 100644 (file)
@@ -35,7 +35,8 @@ static char *__from_cpuset(cpu_set_t *mask)
 #define TASKSET_PRINTF_MASK "%x"
 /* (void*) cast is for battling gcc: */
 /* "dereferencing type-punned pointer will break strict-aliasing rules" */
-#define from_cpuset(mask) (*(unsigned*)(void*)&(mask))
+#define from_cpuset(mask) ({ void *__vp = &(mask); *(unsigned*)__vp; })
+/* gcc 4.3.0 still complains: #define from_cpuset(mask) (*(unsigned*)(void*)&(mask)) */
 #endif