delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2000/12/26/12:22:24

Date: Tue, 26 Dec 2000 18:45:39 +0200
From: "Eli Zaretskii" <eliz AT is DOT elta DOT co DOT il>
Sender: halo1 AT zahav DOT net DOT il
To: rich AT phekda DOT freeserve DOT co DOT uk
Message-Id: <9003-Tue26Dec2000184539+0200-eliz@is.elta.co.il>
X-Mailer: Emacs 20.6 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.6
CC: djgpp-workers AT delorie DOT com
In-reply-to: <3A489766.349B3C71@bigfoot.com> (message from Richard Dawe on
Tue, 26 Dec 2000 13:04:38 +0000)
Subject: Re: An implementation of /dev/zero for DJGPP
References: <Pine DOT SUN DOT 3 DOT 91 DOT 1001225105646 DOT 18547E-100000 AT is> <3A489766 DOT 349B3C71 AT bigfoot DOT com>
Reply-To: djgpp-workers AT delorie DOT com
Errors-To: nobody AT delorie DOT com
X-Mailing-List: djgpp-workers AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

> Date: Tue, 26 Dec 2000 13:04:38 +0000
> From: Richard Dawe <richdawe AT bigfoot DOT com>
> 
> Eli Zaretskii wrote:
> > If whatever link, fcntl, and ioctl will do with the null device is
> > appropriate for /dev/zero, you can simply leave these functions
> > unhandled.  Does the man page for /dev/zero say what these functions
> > yield?
> 
> Unfortunately /dev/zero's man page (FYI zero(4)) does not mention these
> functions.

Well, you could write a short test program to see what GNU/Linux
does.  We could also say we don't care ;-)

> BTW there's a device call /dev/full on Linux, which returns zeroes when
> read, but returns ENOSPC when written to. This could easily be added to
> the /dev/zero framework. If there are any good uses for /dev/full, then
> I'll add this.

I don't know about any good uses.  It's up to you.

> > > Why would we get called for a handle that isn't ours? Should we not
> > > inform the caller that something has gone wrong?
> > 
> > I don't know.  What if some other FSEXT hooked the same handle for
> > some purpose?  For example, the debug support does that.
> 
> AFAICT you can only have one hook per fd.

True; and that is one of the main disadvantages of using FSEXT in a
library.

But my point was more general than the current limitations: I don't
think that the fact that the handle doesn't have any data is a reason
to fail the call.  I don't think other FSEXT uses I saw were so
invasive; I think they just punt when they see something like that.

>     save old function and data pointer for fd
>     call __FSEXT_set_data(fd, NULL) to remove association
>         between fd & old data
>     hook fd with debug FSEXT
> 
> Then in the handler:
> 
>     set data to old data
>     call old handler
>     remove association between fd & old data
> 
> Does the debug FSEXT work like this? Or does it leave the fd's data
> pointer alone?

It does much worse: it simply ignores any possibility that someone
else might have hooked the handle.  Here's an excerpt from dbgcom.c:

	case __FSEXT_open:
	  filename = va_arg(_args,const char *);
	  oflag = va_arg(_args,int);
	  in_dbg_fsext++;
	  retval = _open(filename,oflag);
    #ifdef DEBUG_DBGCOM_FILES
	  fprintf(stderr,"_open(%s) => %d\n",filename,retval);
    #endif
	  in_dbg_fsext--;
	  if (retval != -1)
	  {
	    handles[retval] = retval;
	    __FSEXT_set_function(retval,dbg_fsext);
	  }
	  break;
	case __FSEXT_close:
	  handle = va_arg(_args,int);
	  in_dbg_fsext++;
    #ifdef DEBUG_DBGCOM_FILES
	  fprintf(stderr,"_close(%d)\n",handle);
    #endif
	  retval = _close(handle);
	  in_dbg_fsext--;
	  if (retval == 0)
	  {
	    handles[handle] = 0xff;
	    __FSEXT_set_function(handle,NULL);
	  }
	  break;

Btw, since the debug support hooks the handle at startup (its
initialization routine is declared "__attribute__((constructor))"), it
is actually the /dev/zero FSEXT which will cause trouble, unless you
add special code to chain to the previous hook.

> > > > If buflen is declared size_t, why do you start failing at INT_MAX?
> > > > memset would work for up to UINT_MAX, no?
> > >
> > > Because 'rv' is an int, we shouldn't overflow the return value.
> > 
> > ??? But the same problem exists with `_read' and `read', and we still
> > let DOS do whatever it can.  On FAT32 systems, you can potentially
> > read more than 2^31-1 bytes, right?
> >
> > The problem with the return value being signed is a nuisance each
> > programmer needs to deal with, regardless of FSEXT: a program should
> > test for the return value being -1; any other value should be cast to
> > size_t.
> 
> Hmmm, I'm not sure we should allow overflow. I seem to recall that some
> programs I've seen test for failure by checking that the return value is
> less than zero.

Those programs are buggy.

> read() does not have to return the number of bytes asked for.

It doesn't?  I've seen gobs of programs which depend on the fact it
does.

> So, when >= INT_MAX is requested, it will
> return INT_MAX. Since the programmer should be aware that read() may not
> return everything asked for, this avoids the overflow problem.

I don't think it's a good idea.  I also don't see any reason for such
a drastic change in behavior, just to prevent buggy programs from
getting what they asked for.

> BTW I just discovered I should be checking for SSIZE_MAX, rather than
> INT_MAX.

Sure, but they are identical in DJGPP.

- Raw text -


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