The whole bc package is terrible at checking for read and write
errors. For another example:
-anarres:~> echo '1' | bc >/dev/full ; echo $?
0
-anarres:~> echo '1 p' | dc >/dev/full ; echo $?
0
-anarres:~>
The attached patch fixes these problems.
(FYI, this bug was also reported by an Ubuntu user at
https://launchpad.net/distros/ubuntu/+source/bc/+bug/18917
and I have just uploaded a fixed bc into Ubuntu Dapper.)
Ian.
diff -u bc-1.06/bc/scan.c bc-1.06/bc/scan.c
--- bc-1.06/bc/scan.c
+++ bc-1.06/bc/scan.c
@@ -699,6 +699,7 @@
if (bcel_len != 0)
history (hist, &histev, H_ENTER, bcel_line);
fflush (stdout);
+ checkferror_output(stdout);
}
if (bcel_len <= max)
@@ -777,6 +778,7 @@
add_history (rl_line);
rl_line[rl_len-1] = '\n';
fflush (stdout);
+ checkferror_output(stdout);
}
if (rl_len <= max)
diff -u bc-1.06/bc/scan.l bc-1.06/bc/scan.l
--- bc-1.06/bc/scan.l
+++ bc-1.06/bc/scan.l
@@ -111,6 +111,7 @@
if (bcel_len != 0)
history (hist, &histev, H_ENTER, bcel_line);
fflush (stdout);
+ checkferror_output(stdout);
}
if (bcel_len <= max)
@@ -189,6 +190,7 @@
add_history (rl_line);
rl_line[rl_len-1] = '\n';
fflush (stdout);
+ checkferror_output(stdout);
}
if (rl_len <= max)
@@ -311,6 +313,7 @@
if (c == EOF)
{
fprintf (stderr,"EOF encountered in a comment.\n");
+ checkferror_output(stderr);
break;
}
}
diff -u bc-1.06/bc/load.c bc-1.06/bc/load.c
--- bc-1.06/bc/load.c
+++ bc-1.06/bc/load.c
@@ -217,6 +217,7 @@
if (label_no > 65535L)
{ /* Better message? */
fprintf (stderr,"Program too big.\n");
+ checkferror_output(stderr);
exit(1);
}
addbyte ( (char) (label_no & 0xFF));
diff -u bc-1.06/dc/dc.c bc-1.06/dc/dc.c
--- bc-1.06/dc/dc.c
+++ bc-1.06/dc/dc.c
@@ -59,6 +59,7 @@
bug_report_info DC_DECLVOID()
{
printf("Email bug reports to: [EMAIL PROTECTED] .\n");
+ checkferror_output(stdout);
}
static void
@@ -69,6 +70,7 @@
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 */
@@ -86,6 +88,7 @@
\n\
", progname);
bug_report_info();
+ checkferror_output(f);
}
/* returns a pointer to one past the last occurance of c in s,
diff -u bc-1.06/dc/eval.c bc-1.06/dc/eval.c
--- bc-1.06/dc/eval.c
+++ bc-1.06/dc/eval.c
@@ -92,12 +92,15 @@
static int
input_fil DC_DECLVOID()
{
+ int c;
if (input_pushback != EOF){
- int c = input_pushback;
+ c = input_pushback;
input_pushback = EOF;
return c;
}
- return getc(input_fil_fp);
+ c = getc(input_fil_fp);
+ checkferror_input(input_fil_fp);
+ return c;
}
/* passed as an argument to dc_getnum */
@@ -275,12 +278,13 @@
tmpint = 0;
if (datum.dc_type == DC_NUMBER)
tmpint = dc_num2int(datum.v.number, DC_TOSS);
- if ( ! (2 <= tmpint && tmpint <= DC_IBASE_MAX) )
+ if ( ! (2 <= tmpint && tmpint <= DC_IBASE_MAX) ) {
fprintf(stderr,
"%s: input base must be a
number \
between 2 and %d (inclusive)\n",
progname, DC_IBASE_MAX);
- else
+ checkferror_output(stderr);
+ } else
dc_ibase = tmpint;
}
break;
@@ -289,11 +293,12 @@
tmpint = -1;
if (datum.dc_type == DC_NUMBER)
tmpint = dc_num2int(datum.v.number, DC_TOSS);
- if ( ! (tmpint >= 0) )
+ if ( ! (tmpint >= 0) ) {
fprintf(stderr,
"%s: scale must be a
nonnegative number\n",
progname);
- else
+ checkferror_output(stderr);
+ } else
dc_scale = tmpint;
}
break;
@@ -317,11 +322,12 @@
tmpint = 0;
if (datum.dc_type == DC_NUMBER)
tmpint = dc_num2int(datum.v.number, DC_TOSS);
- if ( ! (tmpint > 1) )
+ if ( ! (tmpint > 1) ) {
fprintf(stderr,
"%s: output base must be a
number greater than 1\n",
progname);
- else
+ checkferror_output(stderr);
+ } else
dc_obase = tmpint;
}
break;
@@ -362,6 +368,7 @@
fprintf(stderr,
"%s: square root of nonnumeric
attempted\n",
progname);
+ checkferror_output(stderr);
}else if (dc_sqrt(datum.v.number, dc_scale, &tmpnum) ==
DC_SUCCESS){
dc_free_num(&datum.v.number);
datum.v.number = tmpnum;
@@ -433,6 +440,7 @@
fprintf(stderr,
"%s: Q command requires a number >=
1\n",
progname);
+ checkferror_output(stderr);
}
break;
#if 0
@@ -479,11 +487,12 @@
if (datum.dc_type == DC_NUMBER)
tmpint = dc_num2int(datum.v.number, DC_TOSS);
if (dc_pop(&datum) == DC_SUCCESS){
- if (tmpint < 0)
+ if (tmpint < 0) {
fprintf(stderr,
"%s: array index must
be a nonnegative integer\n",
progname);
- else
+ checkferror_output(stderr);
+ } else
dc_array_set(peekc, tmpint, datum);
}
}
@@ -495,17 +504,19 @@
tmpint = -1;
if (datum.dc_type == DC_NUMBER)
tmpint = dc_num2int(datum.v.number, DC_TOSS);
- if (tmpint < 0)
+ if (tmpint < 0) {
fprintf(stderr,
"%s: array index must be a
nonnegative integer\n",
progname);
- else
+ checkferror_output(stderr);
+ } else
dc_push(dc_array_get(peekc, tmpint));
}
return DC_EATONE;
default: /* What did that user mean? */
fprintf(stderr, "%s: ", progname);
+ checkferror_output(stderr);
dc_show_id(stdout, c, " unimplemented\n");
break;
}
@@ -533,6 +544,7 @@
fprintf(stderr,
"%s: eval called with non-string argument\n",
progname);
+ checkferror_output(stderr);
return DC_OKAY;
}
s = dc_str2charp(string->v.string);
@@ -591,6 +603,7 @@
case DC_EVALREG:
if (peekc == EOF){
fprintf(stderr, "%s: unexpected EOS\n",
progname);
+ checkferror_output(stderr);
return DC_OKAY;
}else{
dc_data evalstr;
@@ -601,6 +614,7 @@
fprintf(stderr,
"%s: eval
called with non-string argument\n",
progname);
+
checkferror_output(stderr);
return DC_OKAY;
}
dc_free_str(&string->v.string);
@@ -621,6 +635,7 @@
case DC_EOF_ERROR:
fprintf(stderr, "%s: unexpected EOS\n", progname);
+ checkferror_output(stderr);
return DC_OKAY;
}
}
@@ -645,6 +660,7 @@
stdin_lookahead = EOF;
for (c=getc(fp); c!=EOF; c=peekc){
peekc = getc(fp);
+ checkferror_input(stdin);
/*
* The following if() is the only place where
``stdin_lookahead''
* might be set to other than EOF:
@@ -667,8 +683,11 @@
fprintf(stderr,
"%s: Q command argument exceeded string
execution depth\n",
progname);
- if (stdin_lookahead != peekc && fp == stdin)
+ checkferror_output(stderr);
+ if (stdin_lookahead != peekc && fp == stdin) {
peekc = getc(fp);
+ checkferror_input(stdin);
+ }
break;
case DC_INT:
@@ -709,15 +728,18 @@
if (unwind_noexit != DC_TRUE)
return DC_SUCCESS;
fprintf(stderr, "%s: Q command argument
exceeded string execution depth\n", progname);
+ checkferror_output(stderr);
}
}
break;
case DC_EOF_ERROR:
fprintf(stderr, "%s: unexpected EOF\n", progname);
+ checkferror_output(stderr);
return DC_FAIL;
}
}
+ checkferror_input(fp);
return DC_SUCCESS;
}
diff -u bc-1.06/debian/changelog bc-1.06/debian/changelog
--- bc-1.06/debian/changelog
+++ bc-1.06/debian/changelog
@@ -1,3 +1,16 @@
+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 <[EMAIL PROTECTED]> Tue, 4 Apr 2006 17:21:02 +0100
+
bc (1.06-19) unstable; urgency=low
* Fixed libreadline dependency.
only in patch2:
unchanged:
--- bc-1.06.orig/lib/number.c
+++ bc-1.06/lib/number.c
@@ -1767,6 +1767,7 @@
out_char (int c)
{
putchar(c);
+ checkferror_output(stdout);
}
@@ -1776,6 +1777,7 @@
{
bc_out_num (num, 10, out_char, 0);
out_char ('\n');
+ checkferror_output(stdout);
}
@@ -1790,4 +1792,27 @@
printf ("%s=", name);
for (i=0; i<len; i++) printf ("%c",BCD_CHAR(num[i]));
printf ("\n");
+ checkferror_output(stdout);
+}
+
+
+/* check ferror() status and if so die */
+void
+checkferror_input (fp)
+ FILE *fp;
+{
+ if (ferror(fp)) {
+ perror("dc: could not read input file");
+ exit(EXIT_FAILURE);
+ }
+}
+
+void
+checkferror_output (fp)
+ FILE *fp;
+{
+ if (ferror(fp)) {
+ perror("dc: could not write output file");
+ exit(EXIT_FAILURE);
+ }
}
only in patch2:
unchanged:
--- bc-1.06.orig/lib/testmul.c
+++ bc-1.06/lib/testmul.c
@@ -57,6 +57,7 @@
va_end (args);
fprintf (stderr, "Runtime error: %s\n", error_mesg);
+ checkferror_output(stderr);
}
/* A runtime warning tells of some action taken by the processor that
@@ -90,12 +91,14 @@
va_end (args);
fprintf (stderr, "Runtime warning: %s\n", error_mesg);
+ checkferror_output(stderr);
}
void
out_char (int ch)
{
putchar (ch);
+ checkferror_output(stdout);
}
/* Time stuff !!! */
@@ -147,21 +150,28 @@
bc_init_num (&big);
bc_int2num (&ten, 10);
- if (debug)
+ if (debug) {
fprintf (stderr, "Timings are for %d multiplies\n"
"Minimum time is %d seconds\n", test_n,
test_time/CLOCKS_PER_SEC);
+ checkferror_output(stderr);
+ }
/* Two of the same size */
min = 10;
max = 500;
- if (debug)
+ if (debug) {
fprintf (stderr, "Testing numbers of the same length.\n");
+ checkferror_output(stderr);
+ }
while (min < max) {
mid = (min+max)/2;
- if (debug) fprintf (stderr,"Checking %d...\n", mid);
+ if (debug) {
+ fprintf (stderr,"Checking %d...\n", mid);
+ checkferror_output(stderr);
+ }
bc_int2num (&expo, mid);
bc_raise (ten, expo, &num, 0);
@@ -183,12 +193,16 @@
if (debug) {
fprintf (stderr, "n1 = %d :: n2 = %d\n", n1, n2);
fprintf (stderr, "p1 = %f :: p2 = %f\n", permul1, permul2);
+ checkferror_output(stderr);
}
}
- if (debug)
+ if (debug) {
fprintf (stderr, "Base digits crossover at %d digits\n", min);
+ checkferror_output(stderr);
+ }
printf ("#define MUL_BASE_DIGITS %d\n", 2*min);
+ checkferror_output(stdout);
#if 0
@@ -204,12 +218,17 @@
min = min / 2;
max = 500;
- if (debug)
+ if (debug) {
fprintf (stderr, "Testing numbers of the different length.\n");
+ checkferror_output(stderr);
+ }
while (min < max) {
mid = (min+max)/2;
- if (debug) fprintf (stderr, "Checking %d...\n", mid);
+ if (debug) {
+ fprintf (stderr, "Checking %d...\n", mid);
+ checkferror_output(stderr);
+ }
bc_int2num (&expo, mid-smallsize);
bc_raise (ten, expo, &num, 0);
@@ -231,12 +250,16 @@
if (debug) {
fprintf (stderr, "n1 = %d :: n2 = %d\n", n1, n2);
fprintf (stderr, "p1 = %f :: p2 = %f\n", permul1, permul2);
+ checkferror_output(stderr);
}
}
- if (debug)
+ if (debug) {
fprintf (stderr, "Non equal digits crossover at %d total digits\n", min);
+ checkferror_output(stderr);
+ }
printf ("#define MUL_SMALL_DIGITS = %d\n", min);
+ checkferror_output(stdout);
#endif
only in patch2:
unchanged:
--- bc-1.06.orig/bc/execute.c
+++ bc-1.06/bc/execute.c
@@ -44,6 +44,7 @@
{
had_sigint = TRUE;
printf ("\n");
+ checkferror_output(stdout);
rt_error ("interrupted execution");
}
@@ -110,6 +111,7 @@
}
out_char ('\n');
}
+ checkferror_output(stdout);
}
#endif
@@ -224,6 +226,7 @@
}
}
fflush (stdout);
+ checkferror_output(stdout);
break;
case 'R' : /* Return from function */
@@ -259,6 +262,7 @@
if (inst == 'W') out_char ('\n');
store_var (4); /* Special variable "last". */
fflush (stdout);
+ checkferror_output(stdout);
pop ();
break;
@@ -335,6 +339,7 @@
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. */
@@ -541,8 +546,10 @@
if (interactive)
{
signal (SIGINT, use_quit);
- if (had_sigint)
+ if (had_sigint) {
printf ("Interruption completed.\n");
+ checkferror_output(stdout);
+ }
}
}
@@ -575,6 +582,7 @@
if (in_ch == '\n')
in_ch = getchar();
}
+ checkferror_input(stdin);
/* Classify and preprocess the input character. */
if (isdigit((int)in_ch))
only in patch2:
unchanged:
--- bc-1.06.orig/bc/util.c
+++ bc-1.06/bc/util.c
@@ -248,9 +248,10 @@
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 @@
printf ("\n");
out_count = 0;
}
+ checkferror_output(stdout);
}
else
load_code (str);
@@ -290,6 +292,7 @@
if (compile_only)
{
printf ("@r\n");
+ checkferror_output(stdout);
out_count = 0;
}
else
@@ -328,6 +331,7 @@
}
putchar (ch);
}
+ checkferror_output(stdout);
}
/* Output routines: Write a character CH to the standard output.
@@ -358,6 +362,7 @@
}
putchar (ch);
}
+ checkferror_output(stdout);
}
@@ -636,6 +641,7 @@
{
printf ("This is free software with ABSOLUTELY NO WARRANTY.\n");
printf ("For details type `warranty'. \n");
+ checkferror_output(stdout);
}
/* Print out the version information. */
@@ -643,6 +649,7 @@
show_bc_version()
{
printf("%s %s\n%s\n", PACKAGE, VERSION, BC_COPYRIGHT);
+ checkferror_output(stdout);
}
@@ -668,6 +675,7 @@
" The Free Software Foundation, Inc.\n"
" 59 Temple Place, Suite 330\n"
" Boston, MA 02111, USA.\n\n");
+ checkferror_output(stdout);
}
/* Print out the limits of this program. */
@@ -684,6 +692,7 @@
#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
@@ -748,6 +757,7 @@
fprintf (stderr,"%s %d: ",name,line_no);
vfprintf (stderr, str, args);
fprintf (stderr, "\n");
+ checkferror_output(stderr);
had_error = TRUE;
va_end (args);
}
@@ -788,6 +798,7 @@
fprintf (stderr,"%s %d: ",name,line_no);
vfprintf (stderr, mesg, args);
fprintf (stderr, "\n");
+ checkferror_output(stderr);
had_error = TRUE;
}
else
@@ -800,6 +811,7 @@
fprintf (stderr,"%s %d: (Warning) ",name,line_no);
vfprintf (stderr, mesg, args);
fprintf (stderr, "\n");
+ checkferror_output(stderr);
}
va_end (args);
}
@@ -834,6 +846,7 @@
va_end (args);
fprintf (stderr, "\n");
+ checkferror_output(stderr);
runtime_error = TRUE;
}
@@ -870,4 +883,5 @@
va_end (args);
fprintf (stderr, "\n");
+ checkferror_output(stderr);
}
only in patch2:
unchanged:
--- bc-1.06.orig/bc/sbc.y
+++ bc-1.06/bc/sbc.y
@@ -85,8 +85,9 @@
if (interactive)
{
printf ("s%s\n", BC_VERSION);
- welcome();
- }
+ checkferror_output(stdout);
+ welcome();
+ }
}
| program input_item
;
only in patch2:
unchanged:
--- bc-1.06.orig/dc/misc.c
+++ bc-1.06/dc/misc.c
@@ -91,6 +91,7 @@
fprintf(fp, "'%c' (%#o)%s", id, id, suffix);
else
fprintf(fp, "%#o%s", id, suffix);
+ checkferror_output(fp);
}
only in patch2:
unchanged:
--- bc-1.06.orig/dc/stack.c
+++ bc-1.06/dc/stack.c
@@ -38,7 +38,10 @@
#include "dc-regdef.h"
/* an oft-used error message: */
-#define Empty_Stack fprintf(stderr, "%s: stack empty\n", progname)
+#define Empty_Stack do{ \
+ fprintf(stderr, "%s: stack empty\n", progname); \
+ checkferror_output(stderr); \
+ }while(0)
/* simple linked-list implementaion suffices: */
@@ -93,6 +96,7 @@
if (dc_stack->value.dc_type!=DC_NUMBER
|| dc_stack->link->value.dc_type!=DC_NUMBER){
fprintf(stderr, "%s: non-numeric value\n", progname);
+ checkferror_output(stderr);
return;
}
(void)dc_pop(&b);
@@ -133,6 +137,7 @@
if (dc_stack->value.dc_type!=DC_NUMBER
|| dc_stack->link->value.dc_type!=DC_NUMBER){
fprintf(stderr, "%s: non-numeric value\n", progname);
+ checkferror_output(stderr);
return;
}
(void)dc_pop(&b);
@@ -171,6 +176,7 @@
if (dc_stack->value.dc_type!=DC_NUMBER
|| dc_stack->link->value.dc_type!=DC_NUMBER){
fprintf(stderr, "%s: non-numeric value\n", progname);
+ checkferror_output(stderr);
return 0;
}
(void)dc_pop(&b);
@@ -206,6 +212,7 @@
|| dc_stack->link->value.dc_type!=DC_NUMBER
|| dc_stack->link->link->value.dc_type!=DC_NUMBER){
fprintf(stderr, "%s: non-numeric value\n", progname);
+ checkferror_output(stderr);
return;
}
(void)dc_pop(&c);
@@ -324,6 +331,7 @@
r = dc_register[regid];
if ( ! r ){
fprintf(stderr, "%s: register ", progname);
+ checkferror_output(stderr);
dc_show_id(stderr, regid, " is empty\n");
return DC_FAIL;
}
@@ -398,6 +406,7 @@
r = dc_register[stackid];
if (!r){
fprintf(stderr, "%s: stack register ", progname);
+ checkferror_output(stderr);
dc_show_id(stderr, stackid, " is empty\n");
return DC_FAIL;
}
only in patch2:
unchanged:
--- bc-1.06.orig/dc/numeric.c
+++ bc-1.06/dc/numeric.c
@@ -116,6 +116,7 @@
bc_init_num((bc_num *)result);
if (bc_divide(CastNum(a), CastNum(b), (bc_num *)result, kscale)){
fprintf(stderr, "%s: divide by zero\n", progname);
+ checkferror_output(stderr);
return DC_DOMAIN_ERROR;
}
return DC_SUCCESS;
@@ -138,6 +139,7 @@
if (bc_divmod(CastNum(a), CastNum(b),
(bc_num *)quotient, (bc_num
*)remainder, kscale)){
fprintf(stderr, "%s: divide by zero\n", progname);
+ checkferror_output(stderr);
return DC_DOMAIN_ERROR;
}
return DC_SUCCESS;
@@ -156,6 +158,7 @@
bc_init_num((bc_num *)result);
if (bc_modulo(CastNum(a), CastNum(b), (bc_num *)result, kscale)){
fprintf(stderr, "%s: remainder by zero\n", progname);
+ checkferror_output(stderr);
return DC_DOMAIN_ERROR;
}
return DC_SUCCESS;
@@ -172,8 +175,10 @@
bc_init_num((bc_num *)result);
if (bc_raisemod(CastNum(base), CastNum(expo), CastNum(mod),
(bc_num *)result, kscale)){
- if (bc_is_zero(CastNum(mod)))
+ if (bc_is_zero(CastNum(mod))) {
fprintf(stderr, "%s: remainder by zero\n", progname);
+ checkferror_output(stderr);
+ }
return DC_DOMAIN_ERROR;
}
return DC_SUCCESS;
@@ -208,6 +213,7 @@
tmp = bc_copy_num(CastNum(value));
if (!bc_sqrt(&tmp, kscale)){
fprintf(stderr, "%s: square root of negative number\n",
progname);
+ checkferror_output(stderr);
bc_free_num(&tmp);
return DC_DOMAIN_ERROR;
}
@@ -400,8 +406,10 @@
{
out_char('\0'); /* clear the column counter */
bc_out_num(CastNum(value), obase, out_char, 0);
- if (newline_p == DC_WITHNL)
+ if (newline_p == DC_WITHNL) {
putchar ('\n');
+ checkferror_output(stdout);
+ }
if (discard_p == DC_TOSS)
dc_free_num(&value);
}
@@ -446,6 +454,7 @@
for (cur=top_of_stack; cur; cur=next) {
putchar(cur->digit);
+ checkferror_output(stdout);
next = cur->link;
free(cur);
}
@@ -525,6 +534,7 @@
out_col = 1;
}
putchar (ch);
+ checkferror_output(stdout);
}
}
@@ -564,6 +574,7 @@
vfprintf (stderr, mesg, args);
va_end (args);
fprintf (stderr, "\n");
+ checkferror_output(stderr);
}
@@ -597,4 +608,5 @@
vfprintf (stderr, mesg, args);
va_end (args);
fprintf (stderr, "\n");
+ checkferror_output(stderr);
}
only in patch2:
unchanged:
--- bc-1.06.orig/dc/string.c
+++ bc-1.06/dc/string.c
@@ -101,6 +101,7 @@
fwrite(value->s_ptr, value->s_len, sizeof *value->s_ptr, stdout);
if (newline == DC_WITHNL)
putchar('\n');
+ checkferror_output(stdout);
if (discard_flag == DC_TOSS)
dc_free_str(&value);
}
@@ -176,6 +177,7 @@
}
*p++ = c;
}
+ checkferror_input(fp);
return dc_makestring(line_buf, (size_t)(p-line_buf));
}
only in patch2:
unchanged:
--- bc-1.06.orig/h/number.h
+++ bc-1.06/h/number.h
@@ -150,4 +150,7 @@
_PROTOTYPE(void bc_out_num, (bc_num num, int o_base, void (* out_char)(int),
int leading_zero));
+_PROTOTYPE(void checkferror_input, (FILE*));
+_PROTOTYPE(void checkferror_output, (FILE*));
+
#endif