6 smallint editing; // >0 while we are editing a file
7 - // [code audit says "can be 0 or 1 only"]
8 + // [code audit says "can be 0, 1 or 2 only"]
9 smallint cmd_mode; // 0=command 1=insert 2=replace
10 int file_modified; // buffer contents changed (counter, not flag!)
11 - int last_file_modified; // = -1;
12 + int last_file_modified; // = -1;
13 int fn_start; // index of first cmd line file name
14 int save_argc; // how many file names on cmd line
15 int cmdcnt; // repetition count
17 // These are commands that change text[].
18 // Remember the input for the "." command
19 if (!adding2q && ioq_start == NULL
20 - && strchr(modifying_cmds, c)
21 + && c != '\0' && strchr(modifying_cmds, c)
27 //-------------------------------------------------------------------
29 - place_cursor(rows, 0, FALSE); // go to bottom of screen
30 - clear_to_eol(); // Erase to end of line
31 + place_cursor(rows - 1, 0, FALSE); // go to bottom of screen
32 + clear_to_eol(); // erase to end of line
38 // get buffer for new cmd
39 // if there is a current cmd count put it in the buffer first
42 lmc_len = sprintf(last_modifying_cmd, "%d%c", cmdcnt, c);
43 - else { // just save char c onto queue
44 + } else { // just save char c onto queue
45 last_modifying_cmd[0] = c;
48 @@ -2247,18 +2247,20 @@
52 - // get input from User- are there already input chars in Q?
53 + // get input from User - are there already input chars in Q?
55 // the Q is empty, wait for a typed char
57 n = safe_read(STDIN_FILENO, readbuffer, sizeof(readbuffer));
59 - if (errno == EBADF || errno == EFAULT || errno == EINVAL
61 - editing = 0; // want to exit
67 + place_cursor(rows - 1, 0, FALSE); // go to bottom of screen
68 + clear_to_eol(); // erase to end of line
69 + cookmode(); // terminal to "cooked"
70 + bb_error_msg_and_die("can't read user input");
72 + /* elsewhere we can get very confused by NULs */
73 + if (readbuffer[0] == '\0')
75 if (readbuffer[0] == 27) {
76 // This is an ESC char. Is this Esc sequence?
77 // Could be bare Esc key. See if there are any
78 --- a/miscutils/crontab.c
79 +++ b/miscutils/crontab.c
82 char *user_name; /* -u USER */
87 /* file [opts] Replace crontab from file
91 /* Read replacement file under user's UID/GID/group vector */
92 + src_fd = STDIN_FILENO;
93 if (!opt_ler) { /* Replace? */
96 if (NOT_LONE_DASH(argv[0])) {
97 - fd = open_as_user(pas, argv[0]);
99 + src_fd = open_as_user(pas, argv[0]);
101 bb_error_msg_and_die("user %s cannot read %s",
102 pas->pw_name, argv[0]);
103 - xmove_fd(fd, STDIN_FILENO);
107 @@ -180,23 +181,23 @@
108 tmp_fname = xasprintf("%s.%u", crontab_dir, (unsigned)getpid());
109 /* No O_EXCL: we don't want to be stuck if earlier crontabs
110 * were killed, leaving stale temp file behind */
111 - fd = xopen3(tmp_fname, O_RDWR|O_CREAT|O_TRUNC, 0600);
112 - xmove_fd(fd, STDIN_FILENO);
113 - fchown(STDIN_FILENO, pas->pw_uid, pas->pw_gid);
114 + src_fd = xopen3(tmp_fname, O_RDWR|O_CREAT|O_TRUNC, 0600);
115 + fchown(src_fd, pas->pw_uid, pas->pw_gid);
116 fd = open(pas->pw_name, O_RDONLY);
118 - bb_copyfd_eof(fd, STDIN_FILENO);
119 + bb_copyfd_eof(fd, src_fd);
121 + xlseek(src_fd, 0, SEEK_SET);
123 + close_on_exec_on(src_fd); /* don't want editor to see this fd */
124 edit_file(pas, tmp_fname);
125 - xlseek(STDIN_FILENO, 0, SEEK_SET);
128 case 0: /* Replace (no -l, -e, or -r were given) */
129 new_fname = xasprintf("%s.new", pas->pw_name);
130 fd = open(new_fname, O_WRONLY|O_CREAT|O_TRUNC|O_APPEND, 0600);
132 - bb_copyfd_eof(STDIN_FILENO, fd);
133 + bb_copyfd_eof(src_fd, fd);
135 xrename(new_fname, pas->pw_name);