diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | console-tools/kbd_mode.c | 3 | ||||
-rw-r--r-- | editors/vi.c | 34 | ||||
-rw-r--r-- | include/usage.h | 12 | ||||
-rw-r--r-- | libbb/lineedit.c | 73 | ||||
-rw-r--r-- | miscutils/crontab.c | 19 | ||||
-rw-r--r-- | miscutils/taskset.c | 3 |
7 files changed, 86 insertions, 60 deletions
@@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 11 -SUBLEVEL = 2 +SUBLEVEL = 3 EXTRAVERSION = NAME = Unnamed diff --git a/console-tools/kbd_mode.c b/console-tools/kbd_mode.c index f40ee6403..2137d9f47 100644 --- a/console-tools/kbd_mode.c +++ b/console-tools/kbd_mode.c @@ -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); } diff --git a/editors/vi.c b/editors/vi.c index 81baa890f..1985be7db 100644 --- a/editors/vi.c +++ b/editors/vi.c @@ -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 diff --git a/include/usage.h b/include/usage.h index dcb6e344e..1165ad615 100644 --- a/include/usage.h +++ b/include/usage.h @@ -3640,8 +3640,8 @@ "[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" \ @@ -3651,7 +3651,7 @@ "\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" \ @@ -3660,7 +3660,7 @@ ) \ "\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:" \ @@ -3679,7 +3679,7 @@ "\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" \ @@ -3688,7 +3688,7 @@ ) \ "\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:" \ diff --git a/libbb/lineedit.c b/libbb/lineedit.c index fb595c010..b3f4f5327 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -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; diff --git a/miscutils/crontab.c b/miscutils/crontab.c index dc3179dac..38933cf4a 100644 --- a/miscutils/crontab.c +++ b/miscutils/crontab.c @@ -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 { diff --git a/miscutils/taskset.c b/miscutils/taskset.c index 708abd9f2..973f94ac3 100644 --- a/miscutils/taskset.c +++ b/miscutils/taskset.c @@ -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 |