What is wrong with this code ?

John Stafford jws at hpcljws.HP.COM
Thu Dec 14 14:18:04 AEST 1989


Clarence Dold writes...
 .
 .
 .
> Additionally, we don't want to mask permissions against S_IFMT.
> For that matter, we don't need to mask type against S_IFMT.
> 
> Don't we really want
> if (nfile.st_mode & S_IFREG) 
> 	printf(...);
> else if (nfile.st_mode & S_IFDIR)
> 	printf(...);
> 
> followed by several
> if (nfile.st_mode & S_IWRITE) 
> 	printf(...);
> if (nfile.st_mode & S_IREAD) 
> 	printf(...);

I've seen this mistake in two fairly professionally written pieces of
code, written by well meaning folks who simply aren't that familiar with
Unix.

The problem is that the various S_...  items have, in some cases, more
than one bit on.  Guess what happens if one of the S_...  items has a
bit on that is also in one of the other items?  For example on my
system...

#define	S_IFMT	0170000		/* type of file */
#define		S_IFDIR	0040000	/* directory */
#define		S_IFCHR	0020000	/* character special */
#define		S_IFBLK	0060000	/* block special */
#define		S_IFREG	0100000	/* regular */
#define		S_IFIFO	0010000	/* fifo */
#define		S_IFNWK 0110000 /* network special */
#define		S_IFLNK	0120000	/* symbolic link */
#define		S_IFSOCK 0140000/* socket */

Hence (nfile.st_mode & S_IFDIR) will be true for directories, block
special files, and sockets.  This is likely to lead to incorrect program
results.

Please mask with S_IFMT and compare for equality with the S_...  of your
choice, it doesn't hurt that much.  Thank you for your support.



More information about the Comp.lang.c mailing list