Path: utzoo!mnetor!uunet!lll-winken!lll-tis!mordor!sri-spam!sri-unix!quintus!ok From: ok@quintus.UUCP (Richard A. O'Keefe) Newsgroups: comp.unix.wizards Subject: Re: access(2) (was: Writing to A NON-Existing File in "C") Message-ID: <893@cresswell.quintus.UUCP> Date: 23 Apr 88 01:18:29 GMT References: <9654@jplgodo.UUCP> <14020030@hpisod2.HP.COM> <579@vsi.UUCP> Organization: Quintus Computer Systems, Mountain View, CA Lines: 32 Summary: a positive reason not to use access(2) Recently we've heard again the negative reason not to use access(2): it doesn't do what you'd expect if a program runs set[ug]id, and any useful program might be run as a tool by a set[ug]id suite. There is also a positive reason why it is better to use stat(2). While you _can_ read a directory in UNIX, it usually doesn't make sense. (Some versions of UNIX now support only the BSD directory(3) routines.) And of course write access to a directory doesn't mean that you can _write_ on it. So if you want to know whether a given path name identifies a _file_ that you can read/write/whatever, you have to call stat(2) _anyway_ in order to find out what sort of thing the path name identifies. When I first ran into the access(2) problem, I wrote two functions eaccess(char *path, int mode) /* "effective" access */ saccess(struct stat *stat_buf, int mode) /* "stat" access */ and was chagrined to discover that saccess() was the one I almost always wanted, so using access(2) had been costing me an extra system call to no good purpose. I have wondered about posting this code to comp.sources.unix, but it strikes me that it might be better still to extend the specification slightly: if the S_IFDIR bit were set in the mode, the path would have to identify a directory, or if the S_IFREG bit were set in the mode, the path would have to identify something other than a directory. The test would be if ((stat_buf->st_mode & S_IFMT) == S_IFDIR) { if (mode & S_IFREG) { errno = EISDIR; return -1; } } else { if (mode & S_IFDIR) { errno = ENOTDIR; return -1; } } What do you think?