[comp.lang.c] access

lfk@mbio.med.upenn.edu (Lee Kolakowski) (02/09/89)

What does ANSI say about the filename argument passed to the access()
function? Especially with regard to directorys.

For example, in RCS there are statements like
	access("./RCS/", 000)

But under a supposedly ANSI compiler (MSC 5.1) these lines return an
error that says RCS/ does not exist when RCS/ is fine.

If the filename is "RCS" everything is just fine, and the proper
response is returned.

Is this the correct behavior?

Thanks!

--

Frank Kolakowski 
____________________________________________________________________________
|lfk@mbio.med.upenn.edu                         ||      Lee F. Kolakowski   |
|kolakowski@mscf.med.upenn.                     ||	Univ. of Penna.     |
|c/o jes@eniac.seas.upenn.edu			||	Dept of Chemistry   |
|kolakowski%c.chem.upenn.edu@relay.upenn.edu	||	231 South 34th St.  |
|kolakowski%d.chem.upenn.edu@relay.upenn.edu    ||	Phila, PA 19104     |
|bcooperman.kolakowski@bionet-20.arpa		||--------------------------|
|AT&T:	1-215-898-2927				||      One-Liner Here!     |
=============================================================================

gwyn@smoke.BRL.MIL (Doug Gwyn ) (02/09/89)

In article <LFK.89Feb8170836@mbio.med.upenn.edu> lfk@mbio.med.upenn.edu (Lee Kolakowski) writes:
>What does ANSI say about the filename argument passed to the access()
>function? Especially with regard to directorys.
>For example, in RCS there are statements like
>	access("./RCS/", 000)
>But under a supposedly ANSI compiler (MSC 5.1) these lines return an
>error that says RCS/ does not exist when RCS/ is fine.
>If the filename is "RCS" everything is just fine, and the proper
>response is returned.
>Is this the correct behavior?

This is not an ANSI C issue; interpretation and validity of strings
used as filenames is up to the implementation.

Your operating system apparently thinks that "RCS/" is not a valid
pathname.  I seem to recall that the SVID requires this behavior.
7th Edition UNIX interpreted that string as denoting file "" in
directory "RCS", and took "" to mean the current directory (same as
".").  One would guess that RCS was developed on a 7th-Ed.-derived
system, probably 4.somethingBSD.  The simplest fix is to append "."
to such strings.

guy@auspex.UUCP (Guy Harris) (02/09/89)

>What does ANSI say about the filename argument passed to the access()
>function? Especially with regard to directorys.

ANSI sayeth not Bugger All about it, for it is a UNIX function and not a
C function.

POSIX, however, sayeth:

	"pathname".  A string that is used to identify a *file*.  It
	consists of, at most, {PATH_MAX} bytes, including the
	terminating null character.  It has an optional beginning
	*slash*, followed by zero or more *filenames* separated by
	*slashes*.  If the *pathname* refers to a *directory*, it may
	also have one or more trailing *slashes*.

(*word* here indicates that "word" appears in italics in the original).

I read this as saying that anything claiming POSIX conformance had
better allow trailing slashes; I presume this means "foo/" is equivalent
to "foo", if "foo" is a directory.

 >For example, in RCS there are statements like
 >	access("./RCS/", 000)
 >
 >But under a supposedly ANSI compiler (MSC 5.1) these lines return an
 >error that says RCS/ does not exist when RCS/ is fine.
 >
 >If the filename is "RCS" everything is just fine, and the proper
 >response is returned.
 >
 >Is this the correct behavior?

Well, It Depends.  I suspect MSC 5.1 does not claim POSIX conformance,
so in that sense the behavior is at least permissible; it may be
undesirable, and whether it's "correct" or not depends on your
definition of "correct".

The intent of the MSC library is presumably to provide some level of
UNIX compatibility.  There are a number of different standards that
purport to define various levels of UNIX compatibility; they say
different things about trailing slashes.  The System V Interface
Definition, for example, seems to indicate that trailing slashes are not
valid in pathnames, so a SVID-compliant implementation of "access" need
not handle them as you would like.  POSIX indicates, as I read it, that
they are valid in pathnames, so a POSIX-compliant implementation must
handle them as you would like.

In any case, I think you should remove trailing slashes where possible,
in case you run across an implementation that doesn't handle them as
you'd like; I also think you have some claim that MSC should handle
them, and should note this to Microsoft.

henry@utzoo.uucp (Henry Spencer) (02/10/89)

In article <LFK.89Feb8170836@mbio.med.upenn.edu> lfk@mbio.med.upenn.edu (Lee Kolakowski) writes:
>...For example, in RCS there are statements like
>	access("./RCS/", 000)

Well, the immediate problem comes from the interpretation of the null
component at the end of the pathname, something that was never very well
nailed down in the old days.  ("Nailed down" in this context means in the
documentation, not the code.)  The quick fix is to remove the trailing
slash or add a '.' after it.

There is also a deeper problem in that RCS, like a good many other pieces
of code, probably should not be using access() at all, since it *probably*
wants to check against the effective uid/gid, not the real ones.
-- 
Allegedly heard aboard Mir: "A |     Henry Spencer at U of Toronto Zoology
toast to comrade Van Allen!!"  | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

dhesi@bsu-cs.UUCP (Rahul Dhesi) (02/10/89)

In article <979@auspex.UUCP> guy@auspex.UUCP (Guy Harris) quotes POSIX:
     "pathname".  A string that is used to identify a *file*...It has
     an optional beginning *slash*, followed by zero or more
     *filenames* separated by *slashes*.

Hmmm...as I understand it, this disallows pathnames of the form
"//filename" and is ambiguous about pathnames of the form
"filename//filename".

This is not very UNIX-like.
-- 
Rahul Dhesi         UUCP:  <backbones>!{iuvax,pur-ee}!bsu-cs!dhesi
                    ARPA:  bsu-cs!dhesi@iuvax.cs.indiana.edu

gwyn@smoke.BRL.MIL (Doug Gwyn ) (02/10/89)

In article <5615@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes:
>Hmmm...as I understand it, this disallows pathnames of the form
>"//filename" and is ambiguous about pathnames of the form
>"filename//filename".

The first form has special meaning in some network-extended implementations.

A null path component is not accepted by UNIX System V, as I recall.

>This is not very UNIX-like.

Hey, these days UNIX isn't very UNIX-like.

guy@auspex.UUCP (Guy Harris) (02/11/89)

>Hmmm...as I understand it, this disallows pathnames of the form
>"//filename" and is ambiguous about pathnames of the form
>"filename//filename".

Well, what it says after that is:

	Multiple successive *slashes* are considered the same as one
	*slash*.  A pathname that begins with two successive *slashes*
	may be interpreted in an implementation-defined manner, although
	more than two leading *slashes* shall be treated as a single
	*slash*.

So it doesn't disallow "//filename", although it indicates that it may
not do what you think it does, and explicitly indicates that
"filename//filename" is the same as "filename/filename".

>This is not very UNIX-like.

No, but it *is* somewhat Aegis-like; it permits
"//nodename/filename/filename..." to mean "file '/filename/filename...'
on node "nodename" (or whatever it means on Aegis/DOMAIN/OS).  I'm quite
able to live with that trivial restriction in my applications. 

greywolf@unisoft.UUCP (The Grey Wolf) (02/06/91)

In article <15051@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
/*
 * ... one is said to have access for execution when in fact an attempt to
 * execute cannot succeed.
 *
 * There are other problems, but that should be enough to discourage use of
 * access(). It is usually simpler and more reliable to simply attempt the
 * desired operation and see whether it succeeds.
 */

Sometimes, we only want to verify that a file exists, in which case it
is more tended to use access() for this.  We may not do anything with it
-- it may be a lock file.  creat() doesn't work for this; open with
O_CREAT|O_EXCL set is a more expensive call, after which we might not
want to do anything with the file descriptor we get back.

[ I was going to argue that an access(dirpath, X_OK) is faster than
chdir(dirpath);, but my argument is kind of null since, generally, if
one wishes to verify that a directory is executable (searchable/
residable), one will probably be performing a chdir() to it rather
soon afterwards. ]

-- 
thought:  I ain't so damb dumn!	| Your brand new kernel just dump core on you
war: Invalid argument		| And fsck can't find root inode 2
				| Don't worry -- be happy...
...!{ucbvax,acad,uunet,amdahl,pyramid}!unisoft!greywolf

gwyn@smoke.brl.mil (Doug Gwyn) (02/07/91)

In article <3345@unisoft.UUCP> greywolf@unisoft.UUCP (The Grey Wolf) writes:
>Sometimes, we only want to verify that a file exists, in which case it
>is more tended to use access() for this.

Yeah, well often it doesn't work, because the wrong permissions are
checked for the path components.  The safest way to test for file
existence (on UNIX) is to stat() the presumed pathname and see if
it succeeds.

mtr@ukc.ac.uk (M.T.Russell) (02/07/91)

In article <15103@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:
>                                  The safest way to test for file
>existence (on UNIX) is to stat() the presumed pathname and see if
>it succeeds.

On BSD systems lstat() is often better, as stat() will return
a wrong negative result for a symbolic link that points to a
non-existent file.

Mark

rburgess@milton.u.washington.edu (Rick Burgess) (04/12/91)

Is the routine "access(char *file_spec, int mode);" standard?  My VAX/VMS C
manual tells me it indicates existence and protection of files.  One of the
other programmers on campus told me of its existence on a compiler on the
dynix system here, but I was not able to find the routine in the 2nd edition
of K&R C Book.

If this is not a standard, can anyone recommend a standard way of doing this
or a recommended clear good right way to do it.

Also:

Does anyone wish to recommend any good supplement to ANSI C besides K&R 2nd
edition?  (if so please recommend away)

Also:

Neither was I able to find the "symbolic constants" (possibly VAX/VMSpeak) such
as EPERM, ENOENT, ESRCH, EINTR, EIO,... which according to my VAX/VMS C manual
reside in errno.h.  Are these Ansi standard, or at least common?