From f9a0d6d4395d5377bd1c41bebbd2190e0971beb9 Mon Sep 17 00:00:00 2001 From: Matt Weber Date: Thu, 12 Sep 2019 15:04:35 -0500 Subject: [PATCH] notice read and write errors on input and output Quoting from the bug report: bc (1.06-19ubuntu1) dapper; urgency=low * Make dc notice read and write errors on its input and output. I grepped for mentions of the strings `putc', `print', `getc', `FILE', `stdin', `stdout' and `stderr' and added calls to new error-checking functions unless it was clear from the immediately-surrounding code that the program was exiting nonzero, or would exit nonzero if the call failed. I ignored hits in lib/getopt*, which seems to pervasively ignore write errors when printing usage messages, in the hope that these were correct. I _think_ I got them all. -iwj. -- Ian Jackson Tue, 4 Apr 2006 17:21:02 +0100 Upstream: https://sources.debian.org/patches/bc/1.07.1-2/05_notice_read_write_errors.diff/ [Reformatted to GIT for 1.0.7.1 by Matt W] Updated by Ryan Kavanagh for 1.0.7.1 on 26 July 2017. Author: Ian Jackson Origin: other Bug-Debian: http://bugs.debian.org/488735 Signed-off-by: Matthew Weber Signed-off-by: Bernd Kuhls [Bernd: Updated to incorporate changes by Matthias Klose on 2024-03-13 that fix Debian bug https://bugs.debian.org/1065375] [dario: update patch for 1.08.2] Signed-off-by: Dario Binacchi --- bc/execute.c | 10 +++++++++- bc/main.c | 3 +++ bc/sbc.y | 2 ++ bc/scan.c | 2 ++ bc/scan.l | 3 +++ bc/util.c | 15 +++++++++++++-- dc/dc.c | 4 ++++ dc/eval.c | 2 ++ dc/misc.c | 3 +++ dc/numeric.c | 5 +++++ dc/stack.c | 2 ++ dc/string.c | 3 +++ h/number.h | 10 ++++++---- lib/number.c | 24 ++++++++++++++++++++++++ 14 files changed, 81 insertions(+), 7 deletions(-) diff --git a/bc/execute.c b/bc/execute.c index e653a9d75979..3374a38e5fb6 100644 --- a/bc/execute.c +++ b/bc/execute.c @@ -105,6 +105,7 @@ execute (void) } out_char ('\n'); } + checkferror_output(stdout); } #endif @@ -225,6 +226,7 @@ execute (void) } } fflush (stdout); + checkferror_output(stdout); break; case 'R' : /* Return from function */ @@ -260,6 +262,7 @@ execute (void) if (inst == 'W') out_char ('\n'); store_var (4); /* Special variable "last". */ fflush (stdout); + checkferror_output(stdout); pop (); break; @@ -343,6 +346,7 @@ execute (void) case 'w' : /* Write a string to the output. */ while ((ch = byte(&pc)) != '"') out_schar (ch); fflush (stdout); + checkferror_output(stdout); break; case 'x' : /* Exchange Top of Stack with the one under the tos. */ @@ -550,7 +554,10 @@ execute (void) { signal (SIGINT, use_quit); if (had_sigint) - printf ("\ninterrupted execution.\n"); + { + printf ("\ninterrupted execution.\n"); + checkferror_output(stdout); + } } } @@ -585,6 +592,7 @@ input_char (void) out_col = 0; /* Saw a new line */ } } + checkferror_input(stdin); /* Classify and preprocess the input character. */ if (isdigit(in_ch)) diff --git a/bc/main.c b/bc/main.c index b388e17b55bf..ab662dd10fc7 100644 --- a/bc/main.c +++ b/bc/main.c @@ -358,6 +358,9 @@ use_quit (int sig) errno = save; #else write (1, "\n(interrupt) Exiting bc.\n", 26); +#ifdef READLINE + rl_initialize (); /* Clear readline buffer */ +#endif bc_exit(0); #endif } diff --git a/bc/sbc.y b/bc/sbc.y index 586686b4b71f..921ab1e13144 100644 --- a/bc/sbc.y +++ b/bc/sbc.y @@ -86,7 +86,9 @@ program : /* empty */ if (interactive && !quiet) { show_bc_version (); + checkferror_output(stdout); welcome (); + checkferror_output(stdout); } } | program input_item diff --git a/bc/scan.c b/bc/scan.c index e208c8e7b3ba..5ac4c80fd732 100644 --- a/bc/scan.c +++ b/bc/scan.c @@ -776,6 +776,7 @@ bcel_input (char *buf, int *result, int max) if (bcel_len != 0) history (hist, &histev, H_ENTER, bcel_line); fflush (stdout); + checkferror_output(stdout); } if (bcel_len <= max) @@ -848,6 +849,7 @@ rl_input (char *buf, int *result, int max) add_history (rl_line); rl_line[rl_len-1] = '\n'; fflush (stdout); + checkferror_output(stdout); } if (rl_len <= max) diff --git a/bc/scan.l b/bc/scan.l index 958538d6fed0..009f8b196a5e 100644 --- a/bc/scan.l +++ b/bc/scan.l @@ -100,6 +100,7 @@ bcel_input (char *buf, int *result, int max) if (bcel_len != 0) history (hist, &histev, H_ENTER, bcel_line); fflush (stdout); + checkferror_output(stdout); } if (bcel_len <= max) @@ -172,6 +173,7 @@ rl_input (char *buf, int *result, int max) add_history (rl_line); rl_line[rl_len-1] = '\n'; fflush (stdout); + checkferror_output(stdout); } if (rl_len <= max) @@ -296,6 +298,7 @@ limits return(Limits); if (c == EOF) { fprintf (stderr,"EOF encountered in a comment.\n"); + checkferror_output(stderr); break; } } diff --git a/bc/util.c b/bc/util.c index 7abc2a0af309..ce7cc404fb0b 100644 --- a/bc/util.c +++ b/bc/util.c @@ -248,9 +248,10 @@ init_gen (void) continue_label = 0; next_label = 1; out_count = 2; - if (compile_only) + if (compile_only) { printf ("@i"); - else + checkferror_output(stdout); + } else init_load (); had_error = FALSE; did_gen = FALSE; @@ -273,6 +274,7 @@ generate (const char *str) printf ("\n"); out_count = 0; } + checkferror_output(stdout); } else load_code (str); @@ -290,6 +292,7 @@ run_code(void) if (compile_only) { printf ("@r\n"); + checkferror_output(stdout); out_count = 0; } else @@ -327,6 +330,7 @@ out_char (int ch) } putchar (ch); } + checkferror_output(stdout); } /* Output routines: Write a character CH to the standard output. @@ -356,6 +360,7 @@ out_schar (int ch) } putchar (ch); } + checkferror_output(stdout); } @@ -640,6 +645,7 @@ limits(void) #ifdef OLD_EQ_OP printf ("Old assignment operatiors are valid. (=-, =+, ...)\n"); #endif + checkferror_output(stdout); } /* bc_malloc will check the return value so all other places do not @@ -704,6 +710,7 @@ yyerror (str, va_alist) fprintf (stderr,"%s %d: ",name,line_no); vfprintf (stderr, str, args); fprintf (stderr, "\n"); + checkferror_output(stderr); had_error = TRUE; va_end (args); } @@ -744,6 +751,7 @@ ct_warn (mesg, va_alist) fprintf (stderr,"%s %d: Error: ",name,line_no); vfprintf (stderr, mesg, args); fprintf (stderr, "\n"); + checkferror_output(stderr); had_error = TRUE; } else @@ -756,6 +764,7 @@ ct_warn (mesg, va_alist) fprintf (stderr,"%s %d: (Warning) ",name,line_no); vfprintf (stderr, mesg, args); fprintf (stderr, "\n"); + checkferror_output(stderr); } va_end (args); } @@ -790,6 +799,7 @@ rt_error (mesg, va_alist) va_end (args); fprintf (stderr, "\n"); + checkferror_output(stderr); runtime_error = TRUE; } @@ -824,6 +834,7 @@ rt_warn (const char *mesg) va_end (args); fprintf (stderr, "\n"); + checkferror_output(stderr); } /* bc_exit: Make sure to reset the edit state. */ diff --git a/dc/dc.c b/dc/dc.c index 92a843cbdcdc..c5ea5753c91e 100644 --- a/dc/dc.c +++ b/dc/dc.c @@ -36,6 +36,7 @@ #endif #include "../h/getopt.h" #include "dc.h" +#include "../h/number.h" const char *progname; /* basename of program invocation */ unsigned int max_recursion_depth=0; @@ -44,6 +45,7 @@ static void bug_report_info(void) { printf("Email bug reports to: bug-dc@gnu.org .\n"); + checkferror_output(stdout); } static void @@ -54,6 +56,7 @@ show_version(void) This is free software; see the source for copying conditions. There is NO\n\ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,\n\ to the extent permitted by law.\n", DC_COPYRIGHT); + checkferror_output(stdout); } /* your generic usage function */ @@ -71,6 +74,7 @@ Usage: %s [OPTION] [file ...]\n\ \n\ ", progname); bug_report_info(); + checkferror_output(f); } /* returns a pointer to one past the last occurrence of c in s, diff --git a/dc/eval.c b/dc/eval.c index 30d0a20381d1..26e6d21256f9 100644 --- a/dc/eval.c +++ b/dc/eval.c @@ -33,6 +33,7 @@ # include /* isatty */ #endif #include "dc.h" +#include "../h/number.h" typedef enum { DC_OKAY, //no further intervention needed for this command @@ -421,6 +422,7 @@ dc_nextcmd(void) || tmpint < 2 || DC_IBASE_MAX < tmpint) { fprintf(stderr, "%s: input base must be a number " "between 2 and %d (inclusive)\n", progname, DC_IBASE_MAX); + checkferror_output(stderr); break; } dc_discard_TOS(); diff --git a/dc/misc.c b/dc/misc.c index e64f62aca1e9..17e337792a84 100644 --- a/dc/misc.c +++ b/dc/misc.c @@ -31,12 +31,14 @@ #include #include "dc.h" #include "../config.h" +#include "../h/number.h" /* print a simple warning message */ void dc_warn(const char *msg) { fprintf(stderr, "%s: %s\n", progname, msg); + checkferror_output(stderr); } /* print an "out of memory" diagnostic and exit program */ @@ -71,6 +73,7 @@ dc_show_id(FILE *fp, int id, const char *suffix) fprintf(fp, "'%c' (%#o)%s", (unsigned int) id, id, suffix); else fprintf(fp, "%#o%s", (unsigned int) id, suffix); + checkferror_output(fp); } diff --git a/dc/numeric.c b/dc/numeric.c index 556c5bd6478f..887688b0d64f 100644 --- a/dc/numeric.c +++ b/dc/numeric.c @@ -408,6 +408,7 @@ dc_dump_num(dc_num dcvalue) for (cur=top_of_stack; cur; cur=next) { putchar(cur->digit); + checkferror_output(stdout); next = cur->link; free(cur); } @@ -493,6 +494,8 @@ out_char (int ch) out_col = 1; } putchar(ch); + checkferror_output(stdout); + checkferror_output(stderr); } } @@ -516,6 +519,7 @@ rt_error(const char *mesg, ...) vfprintf(stderr, mesg, args); va_end(args); fprintf(stderr, "\n"); + checkferror_output(stderr); } @@ -533,6 +537,7 @@ rt_warn(const char *mesg, ...) vfprintf(stderr, mesg, args); va_end(args); fprintf(stderr, "\n"); + checkferror_output(stderr); } diff --git a/dc/stack.c b/dc/stack.c index 35f8ee7cc876..36755e42a87d 100644 --- a/dc/stack.c +++ b/dc/stack.c @@ -28,6 +28,7 @@ #include #include "dc.h" #include "dc-regdef.h" +#include "../h/number.h" /* an oft-used error message: */ #define Empty_Stack dc_warn("stack empty") @@ -388,6 +389,7 @@ dc_register_pop(int stackid, dc_data *result) r = dc_register[stackid]; if (!r || r->value.dc_type==DC_UNINITIALIZED){ fprintf(stderr, "%s: stack register ", progname); + checkferror_output(stderr); dc_show_id(stderr, stackid, " is empty\n"); return DC_FAIL; } diff --git a/dc/string.c b/dc/string.c index 41b578c130d2..bc8cac8248df 100644 --- a/dc/string.c +++ b/dc/string.c @@ -26,6 +26,7 @@ #include #include /* memcpy */ #include "dc.h" +#include "../h/number.h" /* here is the completion of the dc_string type: */ struct dc_string { @@ -71,6 +72,7 @@ void dc_out_str(dc_str value, dc_discard discard_flag) { fwrite(value->s_ptr, value->s_len, sizeof *value->s_ptr, stdout); + checkferror_output(stdout); if (discard_flag == DC_TOSS) dc_free_str(&value); } @@ -155,6 +157,7 @@ dc_readstring(int (*input)(void), int ldelim, int rdelim, const char *augment) } *p++ = c; } + if (c==EOF && p==line_buf) return dc_makestring(NULL, 0, NULL); return dc_makestring(line_buf, (size_t)(p-line_buf), augment); diff --git a/h/number.h b/h/number.h index b2d9f9eae46a..f6fc880de920 100644 --- a/h/number.h +++ b/h/number.h @@ -23,10 +23,10 @@ You may contact the author by: e-mail: philnelson@acm.org us-mail: Philip A. Nelson - Computer Science Department, 9062 - Western Washington University - Bellingham, WA 98226-9062 - + Computer Science Department, 9062 + Western Washington University + Bellingham, WA 98226-9062 + *************************************************************************/ #ifndef _NUMBER_H_ @@ -142,6 +142,8 @@ void bc_out_num (bc_num num, int o_base, void (* out_char)(int), void bc_out_long (long val, int size, int space, void (*out_char)(int)); +void checkferror_input (FILE*); +void checkferror_output (FILE*); /* function prototypes for callbacks from the library which * need to be provided by the application diff --git a/lib/number.c b/lib/number.c index f84f4fc87336..9d4553a14b37 100644 --- a/lib/number.c +++ b/lib/number.c @@ -1714,6 +1714,7 @@ static void out_char (int c) { putchar(c); + checkferror_output(stdout); } @@ -1722,6 +1723,7 @@ pn (bc_num num) { bc_out_num (num, 10, out_char, 0); out_char ('\n'); + checkferror_output(stdout); } @@ -1733,6 +1735,28 @@ pv (char *name, unsigned char *num, int len) printf ("%s=", name); for (i=0; i