mirror of
https://gitlab.com/procps-ng/procps.git
synced 2024-11-23 18:14:15 +08:00
watch: my_getwc(): errors when char signed/unsigned, off-by-one in ungetc(), ...
Signed-off-by: Craig Small <csmall@dropbear.xyz>
This commit is contained in:
parent
03aa5d371c
commit
67284cb719
82
src/watch.c
82
src/watch.c
@ -446,34 +446,31 @@ static watch_usec_t get_time_usec()
|
|||||||
|
|
||||||
#ifdef WITH_WATCH8BIT
|
#ifdef WITH_WATCH8BIT
|
||||||
/* read a wide character from a popen'd stream */
|
/* read a wide character from a popen'd stream */
|
||||||
wint_t my_getwc(FILE * s)
|
wint_t my_getwc(FILE *s)
|
||||||
{
|
{
|
||||||
char i[MB_CUR_MAX];
|
int c;
|
||||||
int byte = 0;
|
unsigned char i[MB_CUR_MAX];
|
||||||
int convert;
|
uint8_t byte = 0;
|
||||||
wchar_t rval;
|
wchar_t rval;
|
||||||
while (1) {
|
mbstate_t mbstate;
|
||||||
i[byte] = getc(s);
|
|
||||||
if (i[byte] == EOF) {
|
memset(&mbstate, 0, sizeof(mbstate));
|
||||||
return WEOF;
|
|
||||||
}
|
while ((c = getc(s)) != EOF) {
|
||||||
byte++;
|
i[byte] = c;
|
||||||
errno = 0;
|
if (mbrtowc(&rval, i+byte, 1, &mbstate) <= 1)
|
||||||
mbtowc(NULL, NULL, 0);
|
/* legal conversion, may be L'\0' */
|
||||||
convert = mbtowc(&rval, i, byte);
|
|
||||||
if (convert > 0) {
|
|
||||||
/* legal conversion */
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
if (++byte == MB_CUR_MAX) {
|
||||||
if (byte == MB_CUR_MAX) {
|
while (byte)
|
||||||
while (byte > 1) {
|
|
||||||
/* at least *try* to fix up */
|
/* at least *try* to fix up */
|
||||||
ungetc(i[--byte], s);
|
ungetc(i[--byte], s);
|
||||||
}
|
errno = EILSEQ;
|
||||||
errno = -EILSEQ;
|
break;
|
||||||
return WEOF;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return WEOF;
|
||||||
}
|
}
|
||||||
#endif /* WITH_WATCH8BIT */
|
#endif /* WITH_WATCH8BIT */
|
||||||
|
|
||||||
@ -814,6 +811,7 @@ int main(int argc, char *argv[])
|
|||||||
char *command;
|
char *command;
|
||||||
char **command_argv;
|
char **command_argv;
|
||||||
int command_length = 0; /* not including final \0 */
|
int command_length = 0; /* not including final \0 */
|
||||||
|
int command_exit;
|
||||||
watch_usec_t last_run = 0;
|
watch_usec_t last_run = 0;
|
||||||
watch_usec_t next_loop = 0; /* next loop time in us, used for precise time
|
watch_usec_t next_loop = 0; /* next loop time in us, used for precise time
|
||||||
* keeping only */
|
* keeping only */
|
||||||
@ -838,7 +836,7 @@ int main(int argc, char *argv[])
|
|||||||
{"equexit", required_argument, 0, 'q'},
|
{"equexit", required_argument, 0, 'q'},
|
||||||
{"exec", no_argument, 0, 'x'},
|
{"exec", no_argument, 0, 'x'},
|
||||||
{"precise", no_argument, 0, 'p'},
|
{"precise", no_argument, 0, 'p'},
|
||||||
{"no-rerun", no_argument, 0, 'r'},
|
{"no-rerun", no_argument, 0, 'r'},
|
||||||
{"no-title", no_argument, 0, 't'},
|
{"no-title", no_argument, 0, 't'},
|
||||||
{"no-wrap", no_argument, 0, 'w'},
|
{"no-wrap", no_argument, 0, 'w'},
|
||||||
{"version", no_argument, 0, 'v'},
|
{"version", no_argument, 0, 'v'},
|
||||||
@ -885,9 +883,9 @@ int main(int argc, char *argv[])
|
|||||||
flags |= WATCH_EQUEXIT;
|
flags |= WATCH_EQUEXIT;
|
||||||
max_cycles = strtod_nol_or_err(optarg, _("failed to parse argument"));
|
max_cycles = strtod_nol_or_err(optarg, _("failed to parse argument"));
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
flags |= WATCH_NORERUN;
|
flags |= WATCH_NORERUN;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
show_title = 0;
|
show_title = 0;
|
||||||
break;
|
break;
|
||||||
@ -1003,25 +1001,23 @@ int main(int argc, char *argv[])
|
|||||||
output_header(command, interval);
|
output_header(command, interval);
|
||||||
#endif /* WITH_WATCH8BIT */
|
#endif /* WITH_WATCH8BIT */
|
||||||
|
|
||||||
if (!(flags & WATCH_NORERUN) ||
|
if (!(flags & WATCH_NORERUN) ||
|
||||||
get_time_usec() - last_run > interval * USECS_PER_SEC) {
|
get_time_usec() - last_run > interval * USECS_PER_SEC) {
|
||||||
last_run = get_time_usec();
|
last_run = get_time_usec();
|
||||||
int exit = run_command(command, command_argv);
|
command_exit = run_command(command, command_argv);
|
||||||
|
|
||||||
if (flags & WATCH_EQUEXIT) {
|
if (flags & WATCH_EQUEXIT) {
|
||||||
if (cycle_count == max_cycles && exit) {
|
if (cycle_count == max_cycles && command_exit)
|
||||||
break;
|
break;
|
||||||
} else if (exit) {
|
else if (command_exit)
|
||||||
cycle_count++;
|
cycle_count++;
|
||||||
} else {
|
else
|
||||||
cycle_count = 0;
|
cycle_count = 0;
|
||||||
}
|
}
|
||||||
} else if (exit) {
|
} else if (command_exit)
|
||||||
break;
|
break;
|
||||||
}
|
else
|
||||||
} else {
|
refresh();
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (precise_timekeeping) {
|
if (precise_timekeeping) {
|
||||||
watch_usec_t cur_time = get_time_usec();
|
watch_usec_t cur_time = get_time_usec();
|
||||||
|
Loading…
Reference in New Issue
Block a user