delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2002/06/11/07:32:29

Date: Tue, 11 Jun 2002 12:13:08 +0100
From: "Richard Dawe" <rich AT phekda DOT freeserve DOT co DOT uk>
Sender: rich AT phekda DOT freeserve DOT co DOT uk
To: djgpp-workers AT delorie DOT com
X-Mailer: Emacs 21.3.50 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.6
Subject: /dev/zero, /dev/full: Bugfixes, add support for llseek, fchown
Message-Id: <E17HjUA-0000ao-00@phekda.freeserve.co.uk>
Reply-To: djgpp-workers AT delorie DOT com

Hello.

Below is a patch that does the following for /dev/zero and /dev/full:

* Some FSEXT functions that take file descriptors did not check that
  the file descriptor was valid, before using it: ioctl, lseek (IIRC).
  This has been fixed.

* Support for llseek has been added. This works like lseek.

* Support for fchown has been added. This works like fchown does
  on regular files - it always succeeds.

OK to commit?

Thanks, bye, Rich =]

Index: src/libc/fsext/fse_zero.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/fsext/fse_zero.c,v
retrieving revision 1.1
diff -p -u -3 -r1.1 fse_zero.c
--- src/libc/fsext/fse_zero.c	2002/02/08 21:22:54	1.1
+++ src/libc/fsext/fse_zero.c	2002/06/11 11:03:11
@@ -176,22 +176,26 @@ match_dev_path (const char *filename, co
 static int
 dev_fsext (__FSEXT_Fnumber n, int *rv, va_list args)
 {
-  int          emul       = 0; /* Emulated call? 1 => yes, 0 = no. */
-  int          fd         = 0;
-  DEV_DATA    *data       = NULL;
-  char        *filename   = NULL;
-  int          open_mode  = 0;
-  int          perm       = 0;
-  mode_t       creat_mode = 0;  
-  void        *buf        = NULL;
-  size_t       buflen     = 0;
-  off_t        offset     = 0;
-  int          whence     = 0;
-  struct stat *sbuf       = NULL;
-  int          cmd        = 0;
-  int          iparam     = 0;
+  int          emul         = 0; /* Emulated call? 1 => yes, 0 = no. */
+  int          fd           = 0;
+  DEV_DATA    *data         = NULL;
+  char        *filename     = NULL;
+  char        *new_filename = NULL;
+  int          open_mode    = 0;
+  int          perm         = 0;
+  mode_t       creat_mode   = 0;  
+  void        *buf          = NULL;
+  size_t       buflen       = 0;
+  off_t        offset       = 0;
+  offset_t     lloffset     = 0;
+  uid_t        owner        = 0;
+  gid_t        group        = 0;
+  int          whence       = 0;
+  struct stat *sbuf         = NULL;
+  int          cmd          = 0;
+  int          iparam       = 0;
 #ifdef DJGPP_SUPPORTS_FIONBIO_NOW
-  int         *piparam    = NULL;
+  int         *piparam      = NULL;
 #endif /* DJGPP_SUPPORTS_FIONBIO_NOW */
 
   switch(n) {
@@ -478,6 +482,14 @@ dev_fsext (__FSEXT_Fnumber n, int *rv, v
     /* This must be emulated, since the FSEXT has been called. */
     emul = 1;    
 
+    /* Get context */
+    data = (DEV_DATA *) __FSEXT_get_data(fd);
+    if (data == NULL) {
+      errno = EBADF;
+      *rv   = -1;
+      break;
+    }
+
     switch(cmd) {
       /* */
 #ifdef DJGPP_SUPPORTS_FIONBIO_NOW
@@ -502,15 +514,68 @@ dev_fsext (__FSEXT_Fnumber n, int *rv, v
   case __FSEXT_lseek:
     fd     = va_arg(args, int);
     offset = va_arg(args, off_t);
-    whence = va_arg(args, int);    
+    whence = va_arg(args, int);
+
+    /* This must be emulated, since the FSEXT has been called. */
+    emul = 1;
+
+    /* Get context */
+    data = (DEV_DATA *) __FSEXT_get_data(fd);
+    if (data == NULL) {
+      errno = EBADF;
+      *rv   = -1;
+      break;
+    }
+
+    /* Seek is meaningless */
+    *rv = 0;
+    break;
+
+  case __FSEXT_llseek:
+    fd       = va_arg(args, int);
+    lloffset = va_arg(args, offset_t);
+    whence   = va_arg(args, int);    
+
+    /* This must be emulated, since the FSEXT has been called. */
+    emul = 1;
+
+    /* Get context */
+    data = (DEV_DATA *) __FSEXT_get_data(fd);
+    if (data == NULL) {
+      errno = EBADF;
+      *rv   = -1;
+      break;
+    }
+
+    /* Seek is meaningless */
+    *rv = 0;
+    break;
 
+  case __FSEXT_fchown:
+    fd    = va_arg(args, int);
+    owner = va_arg(args, uid_t);
+    group = va_arg(args, gid_t);
+
     /* This must be emulated, since the FSEXT has been called. */
     emul = 1;
 
+    /* Get context */
+    data = (DEV_DATA *) __FSEXT_get_data(fd);
+    if (data == NULL) {
+      errno = EBADF;
+      *rv   = -1;
+      break;
+    }
+
+    /* Behave like fchown() does on a regular file - succeed whatever
+     * the uid, gid are. */
     *rv = 0;
     break;
 
   case __FSEXT_link:
+    filename     = va_arg(args, char *);
+    new_filename = va_arg(args, char *);
+
     /* This must be emulated, since the FSEXT has been called. */
     emul = 1;
 
@@ -518,8 +583,10 @@ dev_fsext (__FSEXT_Fnumber n, int *rv, v
     errno = EPERM;
     *rv   = -1;
     break;
+
+  case __FSEXT_unlink:
+    filename = va_arg(args, char *);
 
-  case __FSEXT_unlink:    
     /* This must be emulated, since the FSEXT has been called. */
     emul = 1;
 
@@ -534,6 +601,14 @@ dev_fsext (__FSEXT_Fnumber n, int *rv, v
 
     /* This must be emulated, since the FSEXT has been called. */
     emul = 1;
+
+    /* Get context */
+    data = (DEV_DATA *) __FSEXT_get_data(fd);
+    if (data == NULL) {
+      errno = EBADF;
+      *rv   = -1;
+      break;
+    }
 
     /* Done */
     *rv = internal_dup(fd);
Index: tests/libc/fsext/tzero.c
===================================================================
RCS file: /cvs/djgpp/djgpp/tests/libc/fsext/tzero.c,v
retrieving revision 1.1
diff -p -u -3 -r1.1 tzero.c
--- tests/libc/fsext/tzero.c	2002/02/08 21:22:54	1.1
+++ tests/libc/fsext/tzero.c	2002/06/11 11:03:11
@@ -108,15 +108,20 @@ main (int argc, char *argv[])
 {
   char           buf[32768];
   char           filename[PATH_MAX];
-  int            fd         = 0;
-  int            new_fd     = 0;
+  int            fd           = 0;
+  int            new_fd       = 0;
   fd_set         readfds, writefds;
   struct timeval tv;
   struct stat    sbuf;
-  off_t          offset     = 0;
-  off_t          ret_offset = 0;
-  int            n          = 0;
-  size_t         i          = 0;
+  off_t          offset       = 0;
+  offset_t       lloffset     = 0;
+  off_t          ret_offset   = 0;
+  offset_t       ret_lloffset = 0;
+  uid_t          owner        = 0;
+  gid_t          group        = 0;
+  int            ret          = 0;
+  int            n            = 0;
+  size_t         i            = 0;
 
   if (!__install_dev_zero()) {
     fprintf(stderr, "__install_dev_zero() failed\n");
@@ -386,6 +391,62 @@ main (int argc, char *argv[])
 
   close(fd);
 
+  /* - Check llseek() - */
+  fd = open(DEV_ZERO_PATH, O_RDWR);
+  if (fd == -1) {
+    fprintf(stderr,
+	    "Unable to open %s: %s\n", DEV_ZERO_PATH, strerror(errno));
+    return(EXIT_FAILURE);
+  }
+
+  for (i = 0; i < 1000; i++) {
+    lloffset     = (offset_t) random();
+    ret_lloffset = llseek(fd, offset, SEEK_SET);
+
+    if (ret_lloffset < 0)
+      fprintf(stderr, "llseek() to position %Lu failed\n", lloffset);
+  }
+
+  close(fd);
+
+  /* - Check fchown() - */
+
+  /* fchown() should behave the same way for /dev/zero as it does for
+   * regular files - it should always succeed. */
+  fd = open(DEV_ZERO_PATH, O_RDWR);
+  if (fd == -1) {
+    fprintf(stderr,
+	    "Unable to open %s: %s\n", DEV_ZERO_PATH, strerror(errno));
+    return(EXIT_FAILURE);
+  }
+
+  /* Try the current uid, gid. */
+  owner = getuid();
+  group = getgid();
+
+  ret = fchown(fd, owner, group);
+  if (ret < 0) {
+    fprintf(stderr,
+	    "fchown() on %s failed unexpectedly, when changing ownership "
+	    "to current owner: %s\n", DEV_ZERO_PATH, strerror(errno));
+    close(fd);
+    return(EXIT_FAILURE);
+  }
+
+  /* Try a non-existent uid, gid. */
+  owner *= 2, group *= 2;
+
+  ret = fchown(fd, owner, group);
+  if (ret < 0) {
+    fprintf(stderr,
+	    "fchown() on %s failed unexpectedly, when changing ownership: "
+	    "%s\n", DEV_ZERO_PATH, strerror(errno));
+    close(fd);
+    return(EXIT_FAILURE);
+  }
+
+  close(fd);
+
   /* - Check dup works - */
 #ifdef DJGPP_SUPPORTS_FSEXT_DUP_NOW
   fd = open(DEV_ZERO_PATH, O_RDWR);
@@ -532,6 +593,9 @@ main (int argc, char *argv[])
   /* - Check fstat() works - */
   test_fstat(DEV_ZERO_PATH);
   test_fstat(DEV_FULL_PATH);
+
+  /* Success!*/
+  printf("SUCCESS\n");
 
   return(EXIT_SUCCESS);
 }

- Raw text -


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