Mail Archives: djgpp-workers/2002/06/11/07:32:29
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 -