nrg@nsscb.UUCP (G.Narotham Reddy) (12/10/89)
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
main(argc,argv)
int argc;
char *argv[];
{
struct stat nfile;
stat(argv[1], &nfile);
if (nfile.st_mode & S_IFMT == S_IFREG)
printf("%s regular file\n", argv[1]);
else if (nfile.st_mode & S_IFMT == S_IEXEC)
printf("%s executable\n", argv[1]);
else if (nfile.st_mode & S_IFMT == S_IWRITE)
printf("%s writable\n", argv[1]);
else if (nfile.st_mode & S_IFMT == S_IREAD)
printf("%s readable\n", argv[1]);
else if (nfile.st_mode & S_IFMT == S_IFDIR)
printf("%s dir\n", argv[1]);
}
Thanks
--
_________________________________________________________________________
Narotham Reddy reddy@attctc.Dallas.TX.US reddy@nucleus.mi.org
reddy@pooh.att.com
-------------------------------------------------------------------------
jxh@phobos.cis.ksu.edu (James Hu) (12/10/89)
In article <1156@nsscb.UUCP> nrg@nsscb.UUCP (G.Narotham Reddy) writes: [...] >stat(argv[1], &nfile); >if (nfile.st_mode & S_IFMT == S_IFREG) >printf("%s regular file\n", argv[1]); [...] The problem is in the order of precedence of the == and & operation. Just add parentheses : if ((nfile.st_mode & S_IFMT) == S_IFREG) ... -- | James Hu | jxh@phobos.cis.ksu.edu | Kansas State University | | 642 Haymaker Hall | SIRIUS@KSUVM.BITNET | Dept. of Computing and | | Manhattan, KS 66502 | ...!phobos.cis.ksu.edu!jxh | Information Sciences | `-----------------------------------------------------------------------------'
lint@mimsy.umd.edu (The Lint Program) (12/11/89)
In article <1156@nsscb.UUCP> nrg@nsscb.UUCP (G.Narotham Reddy) writes: main(argc,argv) int argc; char *argv[]; { struct stat nfile; stat(argv[1], &nfile); if (nfile.st_mode & S_IFMT == S_IFREG) printf("%s regular file\n", argv[1]); else if (nfile.st_mode & S_IFMT == S_IEXEC) printf("%s executable\n", argv[1]); else if (nfile.st_mode & S_IFMT == S_IWRITE) printf("%s writable\n", argv[1]); else if (nfile.st_mode & S_IFMT == S_IREAD) printf("%s readable\n", argv[1]); else if (nfile.st_mode & S_IFMT == S_IFDIR) printf("%s dir\n", argv[1]); } t.c(11): warning: constant in conditional context t.c(11): warning: null effect t.c(13): warning: constant in conditional context t.c(13): warning: null effect t.c(15): warning: constant in conditional context t.c(15): warning: null effect t.c(17): warning: constant in conditional context t.c(17): warning: null effect t.c(19): warning: constant in conditional context t.c(19): warning: null effect t.c(6): warning: argument argc unused in function main stat returns value which is always ignored printf returns value which is always ignored
desj@idacrd.UUCP (David desJardins) (12/11/89)
From article <1156@nsscb.UUCP>, by nrg@nsscb.UUCP (G.Narotham Reddy):
> if (nfile.st_mode & S_IFMT == S_IFREG)
What is wrong with this code is that, in this as in so many other
examples, C has the world's stupidest precedence for its operators.
-- David desJardins
darcy@druid.uucp (D'Arcy J.M. Cain) (12/11/89)
In article <1156@nsscb.UUCP> nrg@nsscb.UUCP (G.Narotham Reddy) writes: > >#include <stdio.h> >#include <sys/types.h> >#include <sys/stat.h> > >main(argc,argv) >int argc; >char *argv[]; >{ >struct stat nfile; >stat(argv[1], &nfile); >if (nfile.st_mode & S_IFMT == S_IFREG) >printf("%s regular file\n", argv[1]); >else if (nfile.st_mode & S_IFMT == S_IEXEC) >printf("%s executable\n", argv[1]); >else if (nfile.st_mode & S_IFMT == S_IWRITE) >printf("%s writable\n", argv[1]); >else if (nfile.st_mode & S_IFMT == S_IREAD) >printf("%s readable\n", argv[1]); >else if (nfile.st_mode & S_IFMT == S_IFDIR) >printf("%s dir\n", argv[1]); >} > You forgot to put a smiley in this message (I hope). In case this is a serious question here is my $0.02 1: There is no indentation. 2: There isn't enough white space. 3: It's inefficient. 4: It's rather useless. P.S: :-) -- D'Arcy J.M. Cain (darcy@druid) | "You mean druid wasn't taken yet???" D'Arcy Cain Consulting | - Everybody - West Hill, Ontario, Canada | No disclaimers. I agree with me |
dold@mitisft.Convergent.COM (Clarence Dold) (12/11/89)
in article <1156@nsscb.UUCP>, nrg@nsscb.UUCP (G.Narotham Reddy) says: Oh, so judgemental! Who says it's stupid precedence? True, we do need a couple of parens to make it work, "it" being this one line, but don't we also need some logic in the program? > if (nfile.st_mode & S_IFMT == S_IFREG) > else if (nfile.st_mode & S_IFMT == S_IEXEC) all these "else if" are self-defeating. Might argv[1] not point to a file that satisfies more than one? How will any of them ever display, if we else if the permissions against S_IFREG to begin with? (only for a special). 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(...); ... -- --- Clarence A Dold - dold@tsmiti.Convergent.COM (408) 435-5293 ...pyramid!ctnews!tsmiti!dold FAX (408) 435-3105 P.O.Box 6685, San Jose, CA 95150-6685 MS#10-007
chris@mimsy.umd.edu (Chris Torek) (12/12/89)
It has come to my attention that people are not reading their news carefully. (Big surprise, eh?) In article <21198@mimsy.umd.edu> lint@mimsy.umd.edu (The Lint Program) quoted someone else's faulty C program, and included the lint output as a lesson in `use lint before posting to USENET'. Unfortunately, many of you are replying to Dr. Lint via the good graces of the Wonder Dog, and to put it simply, the Wonder Dog's good graces have run out. Now, this is not something you would want to happen to *you*. This dog, for instance, thinks that -20 degree weather is `just right'. He eats squirrels more or less whole. He has *very* strong teeth. *Big* teeth. You might even call them `fangs'. Dogs do not harbour grudges, so you can get those good graces back by not replying any more. This has been a private service annoucement. (Well, it can hardly be called `public service', now can it?) Thank you. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris
jws@hpcljws.HP.COM (John Stafford) (12/14/89)
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.
dold@mitisft.Convergent.COM (Clarence Dold) (12/16/89)
in article <660067@hpcljws.HP.COM>, jws@hpcljws.HP.COM (John Stafford) says: Clarence Dold writes... > For that matter, we don't need to mask type against S_IFMT. - 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_IFLNK 0120000 /* symbolic link */ - #define S_IFSOCK 0140000/* socket */ Notice when I said 'we' I used lower case, not the big We :-( My SysV doesn't have any cases of needing S_IFMT, but then it doesn't have symbolic links either. I got e-mail chastising me, but no explanation. - choice, it doesn't hurt that much. Thank you for your support. Thanks, and you're welcome to my support. -- --- Clarence A Dold - dold@tsmiti.Convergent.COM (408) 435-5293 ...pyramid!ctnews!tsmiti!dold FAX (408) 435-3105 P.O.Box 6685, San Jose, CA 95150-6685 MS#10-007
guy@auspex.UUCP (Guy Harris) (12/17/89)
(What's wrong with the original code is an error in using C; what's wrong with the reply to which I'm following up is an error in using UNIX - a real doozy at that, and one that I see all too often - so I'm moving that particular thread of the discussion to "comp.unix.questions".) >> if (nfile.st_mode & S_IFMT == S_IFREG) >> else if (nfile.st_mode & S_IFMT == S_IEXEC) > >Additionally, we don't want to mask permissions against S_IFMT. That is true, but: >For that matter, we don't need to mask type against S_IFMT. Bzzzt! Sorry, wrong answer. You *do* 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(...); No, we don't - not one bit (no pun intended :-)). From the SunOS 4.0.3 <sys/stat.h>, the values in which reflect those in every other AT&T-derived UNIX I know of (except possibly for some of the newer mode bits, but I suspect that S_IFLNK is the same in S5R4 and 4.xBSD....) #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_IFLNK 0120000 /* symbolic link */ #define S_IFSOCK 0140000/* socket */ #define S_IFIFO 0010000 /* fifo */ The astute reader will note that if (nfile.st_mode & S_IFREG) will test whether the 0100000 bit is on in "st_mode". The astute reader will *also* note that this bit is on in the following values: S_IFLNK S_IFSOCK so the test above will say "true" for symbolic links and "socket files". They don't count as regular files in *my* book.... The astute reader will further node that else if (nfile.st_mode & S_IFDIR) will test whether the 004000 bit is on in "st_mode", and that said bit is on in the following values: S_IFBLK S_IFSOCK and will, in addition, note that a block special file is *not* a directory. Folks, the S_IF... values are *NOT* flag bits! They are values for a bit field, said bit field being defined by the S_IFMT value. You must *NOT* test whether a file is of type S_IFXXX by doing if (xxx.st_mode & S_IFXXX) because you run the risk of getting false positives. You must test whether a file is of type S_IFXXX by doing if ((xxx.st_mode & S_IFMT) == S_IFXXX)