Date: Tue, 26 Dec 2000 18:45:39 +0200 From: "Eli Zaretskii" 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: <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 Precedence: bulk > Date: Tue, 26 Dec 2000 13:04:38 +0000 > From: Richard Dawe > > 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.