From 2bf70477093d42ce7436cb0f786e2a87d486d94f Mon Sep 17 00:00:00 2001 From: Nick Briggs Date: Tue, 29 Mar 2022 18:15:21 -0700 Subject: [PATCH] Correct usage of stat.st_mode result for testing S_IFREG and S_IFDIR (#421) stat.st_mode cannot be tested for whether a node is S_IFDIR with if (stat.st_mode & S_IFDIR) ... since S_IFDIR bit (0040000) is a subset of S_IFSOCK (0140000) bits. A correct check is if ((stat.st_mode & S_IFMT) == S_IFDIR) ... or alternatively, since the convenience macros are defined on all modern systems if (S_ISDIR(stat.st_mode)) ... --- src/dir.c | 16 ++++++++-------- src/dsk.c | 12 ++++++------ src/ufs.c | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/dir.c b/src/dir.c index 71d603a..54afd6e 100644 --- a/src/dir.c +++ b/src/dir.c @@ -522,7 +522,7 @@ static int enum_dsk_prop(char *dir, char *name, char *ver, FINFO **finfo_buf) } strcpy(namebuf, dirp.name); - if (sbuf.st_mode & S_IFDIR) { + if (S_ISDIR(sbuf.st_mode)) { nextp->dirp = 1; quote_dname(namebuf); strcpy(nextp->lname, namebuf); @@ -659,7 +659,7 @@ static int enum_dsk_prop(char *dir, char *name, char *ver, FINFO **finfo_buf) } strcpy(namebuf, dp->d_name); - if (sbuf.st_mode & S_IFDIR) { + if (S_ISDIR(sbuf.st_mode)) { nextp->dirp = 1; quote_dname(namebuf); strcpy(nextp->lname, namebuf); @@ -800,7 +800,7 @@ static int enum_dsk(char *dir, char *name, char *ver, FINFO **finfo_buf) } strcpy(namebuf, dirp.name); /* moved from below 2/26/93 */ - if (sbuf.st_mode & S_IFDIR) { + if (S_ISDIR(sbuf.st_mode)) { nextp->dirp = 1; quote_dname(namebuf); strcpy(nextp->lname, namebuf); @@ -922,7 +922,7 @@ static int enum_dsk(char *dir, char *name, char *ver, FINFO **finfo_buf) } strcpy(namebuf, dp->d_name); - if (sbuf.st_mode & S_IFDIR) { + if (S_ISDIR(sbuf.st_mode)) { nextp->dirp = 1; quote_dname(namebuf); strcpy(nextp->lname, namebuf); @@ -1025,7 +1025,7 @@ static int enum_ufs_prop(char *dir, char *name, char *ver, FINFO **finfo_buf) } strcpy(namebuf, dirp.name); - if (sbuf.st_mode & S_IFDIR) { + if (S_ISDIR(sbuf.st_mode)) { nextp->dirp = 1; quote_dname(namebuf); strcpy(nextp->lname, namebuf); @@ -1117,7 +1117,7 @@ static int enum_ufs_prop(char *dir, char *name, char *ver, FINFO **finfo_buf) } strcpy(namebuf, dp->d_name); - if (sbuf.st_mode & S_IFDIR) { + if (S_ISDIR(sbuf.st_mode)) { nextp->dirp = 1; quote_dname(namebuf); strcpy(nextp->lname, namebuf); @@ -1224,7 +1224,7 @@ static int enum_ufs(char *dir, char *name, char *ver, FINFO **finfo_buf) } strcpy(namebuf, dirp.name); - if (sbuf.st_mode & S_IFDIR) { + if (S_ISDIR(sbuf.st_mode)) { nextp->dirp = 1; quote_dname(namebuf); strcpy(nextp->lname, namebuf); @@ -1300,7 +1300,7 @@ static int enum_ufs(char *dir, char *name, char *ver, FINFO **finfo_buf) } strcpy(namebuf, dp->d_name); - if (sbuf.st_mode & S_IFDIR) { + if (S_ISDIR(sbuf.st_mode)) { nextp->dirp = 1; quote_dname(namebuf); strcpy(nextp->lname, namebuf); diff --git a/src/dsk.c b/src/dsk.c index 3f3b333..6871366 100644 --- a/src/dsk.c +++ b/src/dsk.c @@ -407,7 +407,7 @@ LispPTR COM_openfile(register LispPTR *args) if (dskp) { TIMEOUT(rval = stat(file, &sbuf)); if (rval == 0) { - if ((sbuf.st_mode & S_IFMT) != S_IFREG) { + if (!S_ISREG(sbuf.st_mode)) { /* * The Lisp code handles this case as same as "file table * overflow" error. Final error message is "File won't @@ -513,7 +513,7 @@ LispPTR COM_openfile(register LispPTR *args) *bufp = ToLispTime(sbuf.st_mtime); bufp = (int *)(Addr68k_from_LADDR(args[4])); - if (!dskp && ((sbuf.st_mode & S_IFMT) != S_IFREG) && ((sbuf.st_mode & S_IFMT) != S_IFDIR)) { + if (!dskp && (!S_ISREG(sbuf.st_mode)) && (!S_ISDIR(sbuf.st_mode))) { /* * Not a regular file or directory file. Put on a marker. */ @@ -617,7 +617,7 @@ LispPTR COM_closefile(register LispPTR *args) /* Just close. */ TIMEOUT(rval = close(fd)); if (rval == -1) { - if (!dskp && errno == EPERM && (sbuf.st_mode & S_IFREG) == 0) { + if (!dskp && errno == EPERM && !S_ISREG(sbuf.st_mode)) { /* * On {UNIX} device, closing a special file we are not * the owner of it. Although I don't think close fails @@ -745,7 +745,7 @@ LispPTR COM_closefile(register LispPTR *args) /* Just close. */ TIMEOUT(rval = close(fd)); if (rval == -1) { - if (!dskp && errno == EPERM && (sbuf.st_mode & S_IFREG) == 0) { + if (!dskp && errno == EPERM && !S_ISREG(sbuf.st_mode)) { /* * On {UNIX} device, closing a special file we are not * the owner of it. Although I don't think close fails @@ -1945,7 +1945,7 @@ LispPTR COM_readpage(register LispPTR *args) return (NIL); } - if ((sbuf.st_mode & S_IFREG) != 0) { + if (S_ISREG(sbuf.st_mode)) { /* * The request file is a regular file. We have to make sure that * next byte read is at the beginning of the requested page of the @@ -2096,7 +2096,7 @@ LispPTR COM_truncatefile(register LispPTR *args) return (NIL); } - if ((sbuf.st_mode & S_IFREG) == 0) { + if (!S_ISREG(sbuf.st_mode)) { /* * The request file is not a regular file. We don't need to * truncate such file. diff --git a/src/ufs.c b/src/ufs.c index a701a12..71626a9 100644 --- a/src/ufs.c +++ b/src/ufs.c @@ -271,7 +271,7 @@ LispPTR UFS_deletefile(LispPTR *args) * On UNIX device, all we have to do is just to unlink the file * or directory */ - if ((sbuf.st_mode & S_IFMT) == S_IFDIR) { + if (S_ISDIR(sbuf.st_mode)) { TIMEOUT(rval = rmdir(file)); } else { TIMEOUT(rval = unlink(file)); @@ -409,7 +409,7 @@ LispPTR UFS_directorynamep(LispPTR *args) return (NIL); } - if ((sbuf.st_mode & S_IFMT) != S_IFDIR) return (NIL); + if (!S_ISDIR(sbuf.st_mode)) return (NIL); /* Convert Unix file naming convention to Xerox Lisp one. */ if (lisppathname(fullname, dirname, 1, 0) == 0) return (NIL);