Date: Wed, 12 Jun 1996 15:11:21 +0200 (IST) From: Eli Zaretskii To: j DOT aldrich6 AT genie DOT com Cc: djgpp AT delorie DOT com, Charles Sandmann Subject: Re: Printer error Message-Id: Mime-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII On Sun, 9 Jun 1996 j DOT aldrich6 AT genie DOT com wrote: > encountered another problem. If I told the program to output to stdprn > when my printer was not turned on, then the first call to fprintf using > stdprn would cause a SIGSEGV. [snip] > --- Under DOS w/CWSDPMI --- > > C:\CPROGS>test2 > Exiting due to signal SIGSEGV > Page fault at eip=00006168, error=0006 This is a bug in the library function `_flsbuf'. It doesn't allocate a buffer for line-buffered standard streams, and `stdprn' is the only standard stream that is defined by default to be line-buffered. So `_flsbuf' boldly dereferences a NULL pointer, and CWSDPMI promptly catches that. Below I post a patch for this problem. I also want to reiterate the following passage from the DJGPP FAQ list (section 9.1): **Q*: My v2.0 program crashes, but only under CWSDPMI; it runs OK under other DPMI hosts like Windows, OS/2 or QDPMI. Is this a bug in CWSDPMI?* [snip] Another possible cause of problems will most probably be seen under CWSDPMI. Unlike other DPMI hosts, CWSDPMI supports some DPMI 1.0 extensions which allow DJGPP to capture and disallow illegal dereference of pointers which point to addresses less than 1000h (aka "NULL pointer protection"). This feature may be disabled by setting the `_CRT0_FLAG_NULLOK' bit in `_crt0_startup_flags'; if this makes SIGSEGV crashes to go away, your program is using such illegal pointers. Now, how the heck, I wonder, did that FAQ author know that in advance?... Here is that patch I promised. After you install it, CWSDPMI and Windows make `fprintf' fail when the printer is OFF, and under QDPMI you will crash (the well-known QDPMI bug in handling Int 24h). ----------------------------- cut here --------------------------------- *** src/libc/ansi/stdio/flsbuf.c~0 Fri Jun 16 08:59:52 1995 --- src/libc/ansi/stdio/flsbuf.c Wed Jun 12 13:44:44 1996 *************** _flsbuf(int c, FILE *f) *** 24,30 **** if ((f->_flag&_IOWRT)==0) return EOF; ! tryagain: if (f->_flag&_IOLBF) { base = f->_base; --- 24,48 ---- if ((f->_flag&_IOWRT)==0) return EOF; ! if ((base = f->_base) == NULL && (f->_flag & _IONBF) == 0) ! { ! size = _go32_info_block.size_of_transfer_buffer; ! if ((f->_base = base = malloc (size)) == NULL) ! f->_flag |= _IONBF; ! else ! { ! f->_flag |= _IOMYBUF; ! f->_bufsiz = size; ! if (f == stdout && isatty (fileno (stdout))) ! f->_flag |= _IOLBF; ! else ! rn = n = 0; ! ! f->_ptr = base; ! f->_cnt = f->_bufsiz; ! } ! } ! if (f->_flag&_IOLBF) { base = f->_base; *************** _flsbuf(int c, FILE *f) *** 51,76 **** } else { ! if ((base=f->_base)==NULL) ! { ! size = _go32_info_block.size_of_transfer_buffer; ! if ((f->_base=base=malloc(size)) == NULL) ! { ! f->_flag |= _IONBF; ! goto tryagain; ! } ! f->_flag |= _IOMYBUF; ! f->_bufsiz = size; ! if (f==stdout && isatty(fileno(stdout))) ! { ! f->_flag |= _IOLBF; ! f->_ptr = base; ! goto tryagain; ! } ! rn = n = 0; ! } ! else ! rn = f->_ptr - base; f->_ptr = base; f->_cnt = f->_bufsiz; } --- 69,75 ---- } else { ! rn = f->_ptr - base; f->_ptr = base; f->_cnt = f->_bufsiz; }