Mail Archives: djgpp-workers/2000/12/24/13:30:22
> Date: Sun, 24 Dec 2000 14:43:31 +0000
> From: Richard Dawe <richdawe AT bigfoot DOT com>
>
> Please find below an implementation of /dev/zero for DJGPP.
Thanks!
> Currently unimplemented are:
>
> - fcntl() support
> - ioctl() support
> - link() support
How hard is it to add a trivial support for these functions that does
nothing and returns a success (or failure, as the case may be)
indication?
I'm worried that the lack of support for some of the FSEXT types could
break some application that uses /dev/zero if it is available.
> dup() and dup2() on /dev/zero will be supported when FSEXT is supported by
> those functions.
It's okay to leave these two out, since dup/dup2 are always supported
for FSEXT handles. (Hmm, perhaps the same ``trick'' will work for
fcntl and friends?)
> If this code looks sane, I'd like it to incorporated into DJGPP. So, where
> is the best place to put this source? src/libc/fsext?
Why not?
> Where should
> init_dev_zero_handler() be called from in the libc startup sequence?
This actually raises a more serious problem: how does an application
requests that /dev/zero support to be linked in?
If we always link it in, then simply call the initialization function
from the startup code. (Please do that even if the program was dumped
and restarted, by checking the value of __bss_count, like
e.g. putenv.c does. Otherwise, it will break in Emacs.)
If you want the seupport to be linked in only when an application
wants that, I don't see what mechanism do you suggest for that.
> #define DEV_ZERO_PATH "/dev/zero"
I think static "const char DEV_ZERO_PATH[]" is better.
> if (strcmp(filename, DEV_ZERO_PATH) != 0)
> break;
Should we support "/DEV/ZERO" as well? What about "x:/dev/zero"?
> case __FSEXT_read:
> fd = va_arg(args, int);
> buf = va_arg(args, void *);
> buflen = va_arg(args, size_t);
>
> /* This must be emulated, since the FSEXT has been called. */
> emul = 1;
>
> /* Get context */
> data = (DEV_ZERO_DATA *) __FSEXT_get_data(fd);
> if (data == NULL) {
> errno = EBADF; /* TODO: Right error? */
> *rv = -1;
> break;
> }
I don't the last snippet is right: this condition can happen if we
somehow are called for a handle that isn't ours. So I think you
should simply return without handling the call; failing the call seems
a bit too drastic.
> /* Is the specified length bigger than the max return value? */
> if (buflen > INT_MAX) {
> errno = EINVAL; /* TODO: Right error? */
> *rv = -1;
> break;
> }
If buflen is declared size_t, why do you start failing at INT_MAX?
memset would work for up to UINT_MAX, no?
> /* Update access time */
> time(&dev_zero_atime);
Shouldn't the open hook also update the access time? (I'm not sure
which Unix system calls update atime.)
- Raw text -