www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/06/12/08:16:30

Date: Wed, 12 Jun 1996 15:11:21 +0200 (IST)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
To: j DOT aldrich6 AT genie DOT com
Cc: djgpp AT delorie DOT com, Charles Sandmann <sandmann AT clio DOT rice DOT edu>
Subject: Re: Printer error
Message-Id: <Pine.SUN.3.91.960612145344.7239A-100000@is>
Mime-Version: 1.0

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;
      }

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019