From 13784570c7741768a382427bd0a1fdcee03ace63 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 29 Dec 2015 20:11:50 +0000 Subject: [PATCH] opendir_r: shuffle structures about, implement and use opendir_r --- Applications/util/chmod.c | 12 +++++----- Applications/util/df.c | 10 ++++----- Applications/util/du.c | 8 +++---- Applications/util/ll.c | 23 ++++++++----------- Applications/util/prtroot.c | 6 ++--- Applications/util/tar.c | 22 +++++++++--------- Library/include/dirent.h | 45 +++++++++++++++++++------------------ Library/libs/Makefile.6809 | 9 ++++---- Library/libs/closedir.c | 11 +++++---- Library/libs/closedir_r.c | 21 +++++++++++++++++ Library/libs/opendir.c | 21 +++++------------ Library/libs/opendir_r.c | 24 ++++++++++++++++++++ Library/libs/readdir.c | 21 +++++++++-------- Library/libs/rewinddir.c | 7 +++--- Library/libs/seekdir.c | 7 +++--- Library/libs/telldir.c | 5 ++--- 16 files changed, 140 insertions(+), 112 deletions(-) create mode 100644 Library/libs/closedir_r.c create mode 100644 Library/libs/opendir_r.c diff --git a/Applications/util/chmod.c b/Applications/util/chmod.c index c6cb8975..82effc70 100644 --- a/Applications/util/chmod.c +++ b/Applications/util/chmod.c @@ -210,17 +210,17 @@ int main(int argc, char *argv[]) int do_change(char *name) { mode_t m; - DIR *dirp; + DIR dir; struct dirent *entp; char *namp; if (lstat(name, &st)) { perror(name); - return (1); + return 1; } if (S_ISLNK(st.st_mode) && rflag) - return (0); /* Note: violates POSIX. */ + return 0; /* Note: violates POSIX. */ if (!symbolic) m = new_mode; @@ -235,7 +235,7 @@ int do_change(char *name) } if (S_ISDIR(st.st_mode) && rflag) { - if (!(dirp = opendir(name))) { + if (!opendir_r(&dir, name)) { perror(name); return (1); } @@ -243,14 +243,14 @@ int do_change(char *name) strcpy(path, name); namp = path + strlen(path); *namp++ = '/'; - while (entp = readdir(dirp)) + while (entp = readdir(&dir)) if (entp->d_name[0] != '.' || (entp->d_name[1] && (entp->d_name[1] != '.' || entp->d_name[2]))) { strcpy(namp, entp->d_name); errors |= do_change(path); } - closedir(dirp); + closedir_r(&dir); *--namp = '\0'; } return (errors); diff --git a/Applications/util/df.c b/Applications/util/df.c index d92feb6d..5ef983a6 100644 --- a/Applications/util/df.c +++ b/Applications/util/df.c @@ -143,13 +143,13 @@ void df_all(void) const char *devname(dev_t devno) { - DIR *dp; + DIR dp; struct dirent *entry; struct stat fstat; static char namebuf[sizeof(DEV_PATH) + MAXNAMLEN + 2]; - if ((dp = opendir(DEV_PATH)) != (DIR *) NULL) { - while ((entry = readdir(dp)) != (struct dirent *) NULL) { + if (opendir_r(&dp, DEV_PATH) != (DIR *) NULL) { + while ((entry = readdir(&dp)) != (struct dirent *) NULL) { sprintf(namebuf, "%s/%s", DEV_PATH, entry->d_name); if (stat(namebuf, &fstat) != 0) continue; @@ -157,11 +157,11 @@ const char *devname(dev_t devno) continue; if (fstat.st_rdev != devno) continue; - closedir(dp); + closedir_r(&dp); return namebuf; } } - closedir(dp); + closedir_r(&dp); sprintf(namebuf, "%d", devno); return namebuf; diff --git a/Applications/util/du.c b/Applications/util/du.c index b19ef852..2ab2ed0a 100644 --- a/Applications/util/du.c +++ b/Applications/util/du.c @@ -129,7 +129,7 @@ long dodir(char *d, int thislev, dev_t dev) int maybe_print; struct stat s; long total; - DIR *dp; + DIR dir; struct dirent *entry; static char dent[LINELEN]; @@ -155,8 +155,8 @@ long dodir(char *d, int thislev, dev_t dev) * directory should not already have been done. */ maybe_print = !silent; - if ((dp = opendir(d)) == NULL) break; - while ((entry = readdir(dp)) != NULL) { + if (opendir_r(&dir, d) == NULL) break; + while ((entry = readdir(&dir)) != NULL) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; @@ -164,7 +164,7 @@ long dodir(char *d, int thislev, dev_t dev) continue; total += dodir(dent, thislev - 1, s.st_dev); } - closedir(dp); + closedir_r(&dir); break; case S_IFBLK: diff --git a/Applications/util/ll.c b/Applications/util/ll.c index cfc955ae..52101515 100644 --- a/Applications/util/ll.c +++ b/Applications/util/ll.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -28,16 +29,11 @@ void prmode(int mode) printf("-"); } -/* FIXME: use readdir */ -struct _uzidirent { - uint16_t ino; - char d_name[30]; -}; - int ls(char *path) { - int d, st; - struct _uzidirent buf; + int st; + struct dirent *d; + DIR dp; struct stat statbuf; static char dname[512]; @@ -46,15 +42,14 @@ int ls(char *path) return -1; } - d = open(path, O_RDONLY); - if (d < 0) { + if (opendir_r(&dp, path) < 0) { printf ("ls: can't open %s\n", path); return -1; } /* FIXME: use readdir etc */ - while (read(d, (char *)&buf, 32) == 16) { - if (buf.d_name[0] == '\0') + while (d = readdir(&dp)) { + if (d->d_name[0] == '\0') continue; if (path[0] != '.' || path[1]) { @@ -64,7 +59,7 @@ int ls(char *path) dname[0] = '\0'; } - strlcat(dname, buf.d_name, sizeof(dname)); + strlcat(dname, d->d_name, sizeof(dname)); if (stat(dname, &statbuf) != 0) { printf("ls: can't stat %s\n", dname); @@ -117,7 +112,7 @@ int ls(char *path) printf(" %-30s\n", dname); } - close (d); + closedir_r(&dp); return 0; } diff --git a/Applications/util/prtroot.c b/Applications/util/prtroot.c index 2d7a7339..431daacc 100644 --- a/Applications/util/prtroot.c +++ b/Applications/util/prtroot.c @@ -59,7 +59,7 @@ void done(const char *name, int status) int main(int argc, const char *argv[]) { - DIR *dp; + DIR dp; int i; struct dirent *entry; struct stat filestat, rootstat; @@ -73,8 +73,8 @@ int main(int argc, const char *argv[]) } if (stat(ROOT, &rootstat) == 0 - && (dp = opendir(DEV_PATH)) != (DIR *) NULL) { - while ((entry = readdir(dp)) != (struct dirent *) NULL) { + && opendir_r(&dp,DEV_PATH) != (DIR *) NULL) { + while ((entry = readdir(&dp)) != (struct dirent *) NULL) { strcpy(namebuf, DEV_PATH); strlcat(namebuf, entry->d_name, sizeof(namebuf)); if (stat(namebuf, &filestat) != 0) diff --git a/Applications/util/tar.c b/Applications/util/tar.c index c20a6c80..453c6fba 100644 --- a/Applications/util/tar.c +++ b/Applications/util/tar.c @@ -245,7 +245,7 @@ static void storedir( char *name){ struct stat s; int fd; int ret; - DIR *dirstream; + DIR dirstream; struct dirent *dir; char cname[100]; uint32_t count; @@ -342,12 +342,11 @@ static void storedir( char *name){ break; case S_IFDIR: /* open the directory */ - dirstream = opendir( name ); - if( ret < 0 ){ + if (opendir_r(&dirstream, name) == NULL) { pname(); break; } - while( dir = readdir( dirstream ) ){ + while( dir = readdir(&dirstream ) ){ /* dont arch .. or . */ if( !strcmp( dir->d_name, "." ) || !strcmp( dir->d_name, ".." ) @@ -357,23 +356,26 @@ static void storedir( char *name){ strncat( cname, dir->d_name, 100 ); { /* save state of files */ - uint32_t tell=telldir( dirstream ); - closedir( dirstream ); + uint32_t tell=telldir( &dirstream ); + closedir_r( &dirstream ); /* recursive call to this dir */ storedir( cname ); /* restore state of files */ - dirstream=opendir( name ); - seekdir( dirstream, tell ); + if (opendir_r(&dirstream, name) == NULL) { + pname(); + break; + } + seekdir(&dirstream, tell ); } } - closedir( dirstream ); + closedir_r( &dirstream ); break; } } /* list all the files in an archive */ -static void list( ){ +static void list(void){ int x; int zcount=2; diff --git a/Library/include/dirent.h b/Library/include/dirent.h index bfb9e7ea..a6c4f1b6 100644 --- a/Library/include/dirent.h +++ b/Library/include/dirent.h @@ -7,12 +7,28 @@ #define MAXNAMLEN 30 +struct dirent { + long d_ino; /* Try to be iBCS2 like */ + off_t d_off; + unsigned short d_reclen; + char d_name[31]; +}; + +/* Internal directory structure */ +struct _dir { + struct dirent de; + uint8_t buf[512]; + uint8_t next; + uint8_t last; +}; + /* Directory stream type. */ typedef struct { int dd_fd; /* file descriptor */ int dd_loc; /* offset in buffer */ int dd_size; /* # of valid entries in buffer */ struct dirent *dd_buf; /* -> directory buffer */ + struct _dir _priv; } DIR; /* stream data from opendir() */ @@ -20,35 +36,20 @@ typedef int (*__dir_select_fn_t) __P ((struct dirent *)); typedef int (*__dir_compar_fn_t) __P ((struct dirent **, struct dirent **)); -struct dirent { - long d_ino; /* Try to be iBCS2 like */ - off_t d_off; - unsigned short d_reclen; - char d_name[31]; -}; - /* Kernel directory format off disk */ struct __dirent { ino_t d_ino; char d_name[30]; }; - -/* Internal directory structure */ -struct _dir { - DIR d; - struct dirent de; - uint8_t buf[512]; - uint8_t next; - uint8_t last; -}; - extern DIR *opendir __P ((char *__name)); -extern int closedir __P ((DIR * __dirp)); -extern struct dirent *readdir __P ((DIR * __dirp)); -extern void rewinddir __P ((DIR * __dirp)); +extern DIR *opendir_r __P ((DIR *__dirp, char *__name)); +extern int closedir __P ((DIR *__dirp)); +extern int closedir_r __P ((DIR *__dirp)); +extern struct dirent *readdir __P ((DIR *__dirp)); +extern void rewinddir __P ((DIR *__dirp)); -extern void seekdir __P ((DIR * __dirp, off_t __pos)); -extern off_t telldir __P ((DIR * __dirp)); +extern void seekdir __P ((DIR *__dirp, off_t __pos)); +extern off_t telldir __P ((DIR *__dirp)); /* Scan the directory DIR, calling SELECT on each directory entry. Entries for which SELECT returns nonzero are individually malloc'd, diff --git a/Library/libs/Makefile.6809 b/Library/libs/Makefile.6809 index 67314d5c..193f8456 100644 --- a/Library/libs/Makefile.6809 +++ b/Library/libs/Makefile.6809 @@ -12,9 +12,9 @@ OBJ_CRT0 = $(SRC_CRT0:.s=.o) SRC_ASM = setjmp_6809.s ashlsi3_6809.s OBJ_ASM = $(SRC_ASM:.s=.o) SRC_C = __argv.c abort.c asctime.c assert.c atexit.c -SRC_C += bcmp.c bcopy.c bsearch.c bzero.c calloc.c cfree.c clock.c closedir.c -SRC_C += clock_gettime.c clock_getres.c clock_settime.c -SRC_C += creat.c crypt.c ctermid.c ctime.c cuserid.c +SRC_C += bcmp.c bcopy.c bsearch.c bzero.c calloc.c cfree.c +SRC_C += clock.c clock_gettime.c clock_getres.c clock_settime.c +SRC_C += closedir.c closedir_r.c creat.c crypt.c ctermid.c ctime.c cuserid.c SRC_C += difftime.c err.c errno.c error.c SRC_C += execl.c execv.c execvp.c exit.c SRC_C += fclose.c fflush.c fgetc.c fgetgrent.c fgetpwent.c @@ -26,7 +26,8 @@ SRC_C += getpw.c __getpwent.c getpwnam.c getpwuid.c gets.c gettimeofday.c SRC_C += getw.c gmtime.c gmtime_r.c grent.c index.c isatty.c killpg.c SRC_C += libintl.c SRC_C += localtim.c localtim_r.c lseek.c lsearch.c lstat.c ltoa.c ltostr.c -SRC_C += malloc.c mkfifo.c mkstemps.c nanosleep.c opendir.c pause.c perror.c +SRC_C += malloc.c mkfifo.c mkstemps.c nanosleep.c opendir.c opendir_r.c +SRC_C += pause.c perror.c SRC_C += popen.c printf.c putenv.c putchar.c putpwent.c putw.c pwent.c qsort.c SRC_C += raise.c rand.c readdir.c readlink.c realloc.c regerror.c SRC_C += regsub.c remove.c rewind.c rewinddir.c rindex.c seekdir.c setbuffer.c setenv.c diff --git a/Library/libs/closedir.c b/Library/libs/closedir.c index efcf3777..a2d34d35 100644 --- a/Library/libs/closedir.c +++ b/Library/libs/closedir.c @@ -9,15 +9,14 @@ #include #include -int closedir(DIR * dirp) +int closedir(DIR * dir) { - struct _dir *dir = (struct _dir *)dirp; - if (dir == NULL || dir->d.dd_fd == -1) { - errno = EFAULT; + if (dir == NULL || dir->dd_fd == -1) { + errno = EBADF; return -1; } - close(dir->d.dd_fd); - dir->d.dd_fd = -1; + close(dir->dd_fd); + dir->dd_fd = -1; free(dir); return 0; } diff --git a/Library/libs/closedir_r.c b/Library/libs/closedir_r.c new file mode 100644 index 00000000..09209eb7 --- /dev/null +++ b/Library/libs/closedir_r.c @@ -0,0 +1,21 @@ +/* closedir_r.c closedir_r implementation + * + */ +#include +#include +#include +#include +#include +#include +#include + +int closedir_r(DIR * dir) +{ + if (dir == NULL || dir->dd_fd == -1) { + errno = EBADF; + return -1; + } + close(dir->dd_fd); + dir->dd_fd = -1; + return 0; +} diff --git a/Library/libs/opendir.c b/Library/libs/opendir.c index fc9126be..b64c31f4 100644 --- a/Library/libs/opendir.c +++ b/Library/libs/opendir.c @@ -9,24 +9,13 @@ DIR *opendir(char *path) { struct stat statbuf; - struct _dir *dir; - - if (stat(path, &statbuf) != 0) - return NULL; - - if ((statbuf.st_mode & S_IFDIR) == 0) { - errno = ENOTDIR; - return NULL; - } - if ((dir = calloc(1, sizeof(struct _dir))) == NULL) { + DIR *dir = calloc(1, sizeof(DIR)); + if (dir == NULL) { errno = ENOMEM; return NULL; } - if ((dir->d.dd_fd = open(path, O_RDONLY | O_CLOEXEC)) < 0) { + dir = opendir_r(dir, path); + if (dir == NULL) free(dir); - return NULL; - } - - dir->d.dd_loc = 0; - return (DIR *)dir; + return dir; } diff --git a/Library/libs/opendir_r.c b/Library/libs/opendir_r.c new file mode 100644 index 00000000..9fe3d9ae --- /dev/null +++ b/Library/libs/opendir_r.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include +#include +#include +#include + +DIR *opendir_r(DIR *dir, char *path) +{ + struct stat statbuf; + + if (stat(path, &statbuf) != 0) + return NULL; + + if ((statbuf.st_mode & S_IFDIR) == 0) { + errno = ENOTDIR; + return NULL; + } + if ((dir->dd_fd = open(path, O_RDONLY | O_CLOEXEC)) < 0) + return NULL; + dir->dd_loc = 0; + return dir; +} diff --git a/Library/libs/readdir.c b/Library/libs/readdir.c index 9a403082..8e53184a 100644 --- a/Library/libs/readdir.c +++ b/Library/libs/readdir.c @@ -9,26 +9,25 @@ #include #include -static struct __dirent *dnext(struct _dir *dir) +static struct __dirent *dnext(DIR *dir) { - if (dir->next == dir->last) { - int l = read(dir->d.dd_fd, dir->buf, sizeof(dir->buf)); + if (dir->_priv.next == dir->_priv.last) { + int l = read(dir->dd_fd, dir->_priv.buf, sizeof(dir->_priv.buf)); if (l <= 0) return NULL; l /= 32; - dir->last = l; - dir->next = 0; + dir->_priv.last = l; + dir->_priv.next = 0; } - return (struct __dirent *)(dir->buf + 32 * dir->next++); + return (struct __dirent *)(dir->_priv.buf + 32 * dir->_priv.next++); } -struct dirent *readdir(DIR * dirp) +struct dirent *readdir(DIR * dir) { - struct _dir *dir = (struct _dir *)dirp; struct __dirent *direntry; register struct dirent *buf; - if (dir == NULL || dir->d.dd_fd == -1) { + if (dir == NULL) { errno = EFAULT; return NULL; } @@ -39,11 +38,11 @@ struct dirent *readdir(DIR * dirp) return NULL; } while (direntry->d_name[0] == 0); - buf = &dir->de; + buf = &dir->_priv.de; buf->d_ino = direntry->d_ino; buf->d_off = -1; /* FIXME */ buf->d_reclen = 31; - dir->d.dd_loc += (buf->d_reclen + 1); + dir->dd_loc += (buf->d_reclen + 1); strncpy(buf->d_name, (char *) direntry->d_name, 31); buf->d_name[30] = 0; return buf; diff --git a/Library/libs/rewinddir.c b/Library/libs/rewinddir.c index 910be84b..f4399e1d 100644 --- a/Library/libs/rewinddir.c +++ b/Library/libs/rewinddir.c @@ -1,9 +1,8 @@ #include #include -void rewinddir(DIR *dirp) +void rewinddir(DIR *dir) { - struct _dir *dir = (struct _dir *)dirp; - lseek(dir->d.dd_fd, dir->d.dd_loc = 0, SEEK_SET); - dir->next = dir->last = 0; + lseek(dir->dd_fd, dir->dd_loc = 0, SEEK_SET); + dir->_priv.next = dir->_priv.last = 0; } diff --git a/Library/libs/seekdir.c b/Library/libs/seekdir.c index 25e7813d..db82950b 100644 --- a/Library/libs/seekdir.c +++ b/Library/libs/seekdir.c @@ -1,9 +1,8 @@ #include #include -void seekdir (DIR * dirp, off_t pos) +void seekdir(DIR *dir, off_t pos) { - struct _dir *dir = (struct _dir *)dirp; - lseek(dir->d.dd_fd, dir->d.dd_loc = pos, SEEK_SET); - dir->next = dir->last = 0; + lseek(dir->dd_fd, dir->dd_loc = pos, SEEK_SET); + dir->_priv.next = dir->_priv.last = 0; } diff --git a/Library/libs/telldir.c b/Library/libs/telldir.c index 5e13e28f..ab570f9d 100644 --- a/Library/libs/telldir.c +++ b/Library/libs/telldir.c @@ -1,7 +1,6 @@ #include -off_t telldir(DIR * dirp) +off_t telldir(DIR * dir) { - struct _dir *dir = (struct _dir *)dirp; - return dir->d.dd_loc; + return dir->dd_loc; } -- 2.34.1