I have successfully used both stat()
& access()
separately to determine if a user has either read or read/write access to a directory.
These two code snippets are not identical and will produce materially different results.
Firstly, your stat call only checks the owner's permission bits. If the user running this code does not own the file in question, this is not the right set of bits to check.
Secondly, even if we assume the calling user is the owner, we also need to figure out what we mean by "calling user." As far as open(2)
and its friends are concerned, the calling user is the number returned by geteuid(2), that is, the effective user ID. This is what open uses to determine whether to allow opening a file. As far as access(2)
is concerned, the calling user is the number returned by getuid(2)
, that is, the real user ID. This is what access uses to determine whether to report success. The real and effective UIDs can differ, particularly when running a binary with the setuid bit enabled or when the programmer is doing something particularly clever (and probably ill-advised IMHO).
(Meanwhile, stat()
doesn't care about the calling user one way or the other, except insofar as it needs execute permission on the containing directory to do its job. For that purpose it checks the EUID).
Finally, as has been pointed out in multiple answers, both code snippets may be vulnerable to TOCTTOU bugs, depending on what you do with the results. All in all, the safest way to determine whether an action is permitted is to attempt that action and check whether it failed.