delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2000/12/24/19:18:34

Sender: richdawe AT bigfoot DOT com
Message-ID: <3A468DFE.79156B94@bigfoot.com>
Date: Sun, 24 Dec 2000 23:59:58 +0000
From: Richard Dawe <richdawe AT bigfoot DOT com>
X-Mailer: Mozilla 4.51 [en] (X11; I; Linux 2.2.17 i586)
X-Accept-Language: de,fr
MIME-Version: 1.0
To: djgpp-workers AT delorie DOT com
Subject: Re: An implementation of /dev/zero for DJGPP
References: <3A460B93 DOT 2347528B AT bigfoot DOT com> <2110-Sun24Dec2000202824+0200-eliz AT is DOT elta DOT co DOT il>
Reply-To: djgpp-workers AT delorie DOT com

Hello.

Eli Zaretskii wrote:
> > 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 not too sure about link(). fcntl() and ioctl() probably wouldn't be
too hard. I will do that for the patch to DJGPP.
 
> 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.

I admit that the usage by 'dd' is the only case I have considered. If
anyone has any pointers on others, please tell me.

> > 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?)

Currently link(), fcntl(), ioctl() are just passed through unprocessed.
Will the pass through will work OK (perhaps), because these calls end up
being applied to the NUL device (since __FSEXT_alloc_fd() returns an fd
linked to NUL)?

> > 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?

OK: src/libc/fsext/fse_zero.c

> > 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?
[snip]
> 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.

I admit that I thought /dev/zero support would always be linked in. Since
both you and DJ seem to be against bloating libc with this
infrequently-used device, I suggest the following:

* /dev/zero will be initialised using the __FSEXT_install_dev_zero()
function. This will be declared in sys/fsext.h.

* No code in libc will reference __FSEXT_install_dev_zero().

* Applications wanting /dev/zero will have to call
__FSEXT_install_dev_zero().

Of course, this would all be described in the docs for
__FSEXT_install_dev_zero(). ;) How does this sound?

> > #define DEV_ZERO_PATH "/dev/zero"
> 
> I think static "const char DEV_ZERO_PATH[]" is better.

OK, fixed.

> >     if (strcmp(filename, DEV_ZERO_PATH) != 0)
> >       break;
> 
> Should we support "/DEV/ZERO" as well?  What about "x:/dev/zero"?

Good point. I've fixed it for those cases.

> >   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.

Why would we get called for a handle that isn't ours? Should we not inform
the caller that something has gone wrong? E.g. memory corruption, bad
code?

> >     /* 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?

Because 'rv' is an int, we shouldn't overflow the return value.

> >     /* 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.)

FYI here's what the stat(2) man page says on RedHat Linux 6.2 (man-pages
1.28-6):

  "Not all of the Linux filesystems implement all of the time
   fields.   Traditionally,  st_atime is changed by mknod(2),
   utime(2), read(2), write(2), and truncate(2).

   Traditionally, st_mtime is changed by mknod(2),  utime(2),
   and  write(2).  The st_mtime is not changed for changes in
   owner, group, hard link count, or mode.

   Traditionally, st_ctime is changed by writing or  by  set-
   ting  inode  information  (i.e., owner, group, link count,
   mode, etc.)."

Unix98 says that st_*time fields should have a meaningful value, but
doesn't describe them any further than this on the sys/stat.h page:

  "time_t    st_atime   time of last access
   time_t    st_mtime   time of last data modification
   time_t    st_ctime   time of last status change"

Bye, Rich =]

-- 
Richard Dawe
[ mailto:richdawe AT bigfoot DOT com | http://www.bigfoot.com/~richdawe/ ]

- Raw text -


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