upgrade busybox to v1.11.2 and add current upstream fixes
[openwrt-10.03/.git] / package / busybox / patches / 902-crontab_vi.patch
1 --- a/editors/vi.c
2 +++ b/editors/vi.c
3 @@ -147,10 +147,10 @@
4  #endif
5  
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
16 @@ -623,7 +623,7 @@
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)
22                 ) {
23                         start_new_cmd_q(c);
24                 }
25 @@ -645,8 +645,8 @@
26         }
27         //-------------------------------------------------------------------
28  
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
33         cookmode();
34  #undef cur_line
35  }
36 @@ -2009,9 +2009,9 @@
37  {
38         // get buffer for new cmd
39         // if there is a current cmd count put it in the buffer first
40 -       if (cmdcnt > 0)
41 +       if (cmdcnt > 0) {
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;
46                 lmc_len = 1;
47         }
48 @@ -2247,18 +2247,20 @@
49  
50         fflush(stdout);
51         n = chars_to_parse;
52 -       // get input from User- are there already input chars in Q?
53 +       // get input from User - are there already input chars in Q?
54         if (n <= 0) {
55                 // the Q is empty, wait for a typed char
56 + again:
57                 n = safe_read(STDIN_FILENO, readbuffer, sizeof(readbuffer));
58 -               if (n < 0) {
59 -                       if (errno == EBADF || errno == EFAULT || errno == EINVAL
60 -                        || errno == EIO)
61 -                               editing = 0; // want to exit
62 -                       errno = 0;
63 -               }
64 -               if (n <= 0)
65 -                       return 0;       // error
66 +               if (n <= 0) {
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");
71 +               }
72 +               /* elsewhere we can get very confused by NULs */
73 +               if (readbuffer[0] == '\0')
74 +                       goto again;
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
80 @@ -93,6 +93,7 @@
81         char *new_fname;
82         char *user_name;  /* -u USER */
83         int fd;
84 +       int src_fd;
85         int opt_ler;
86  
87         /* file [opts]     Replace crontab from file
88 @@ -144,15 +145,15 @@
89                 bb_show_usage();
90  
91         /* Read replacement file under user's UID/GID/group vector */
92 +       src_fd = STDIN_FILENO;
93         if (!opt_ler) { /* Replace? */
94                 if (!argv[0])
95                         bb_show_usage();
96                 if (NOT_LONE_DASH(argv[0])) {
97 -                       fd = open_as_user(pas, argv[0]);
98 -                       if (fd < 0)
99 +                       src_fd = open_as_user(pas, argv[0]);
100 +                       if (src_fd < 0)
101                                 bb_error_msg_and_die("user %s cannot read %s",
102                                                 pas->pw_name, argv[0]);
103 -                       xmove_fd(fd, STDIN_FILENO);
104                 }
105         }
106  
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);
117                 if (fd >= 0) {
118 -                       bb_copyfd_eof(fd, STDIN_FILENO);
119 +                       bb_copyfd_eof(fd, src_fd);
120                         close(fd);
121 +                       xlseek(src_fd, 0, SEEK_SET);
122                 }
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);
126                 /* fall through */
127  
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);
131                 if (fd >= 0) {
132 -                       bb_copyfd_eof(STDIN_FILENO, fd);
133 +                       bb_copyfd_eof(src_fd, fd);
134                         close(fd);
135                         xrename(new_fname, pas->pw_name);
136                 } else {