Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATH_MAX vs. _PC_PATH_MAX vs. POSIX (was Re: PATCH: tail-dropping in files module mkdir)

> The definition of pathconf(dir, _PC_PATH_MAX) is inherently incompatible
> with the definition of the PATH_MAX constant.  The latter is the maximum
> length of an absolute path from the root [*], the former approximates the
> same constant minus the length of [the equivalent of] realpath(dir).

Well, I've seen two or three manpages that list _PC_PATH_MAX as being
"relative path from cwd", and nothing that claims that PATH_MAX is anything
more meaningful than "maximum path length".

FreeBSD doesn't make the relative claim; it just says

             The maximum number of bytes in a pathname.

But, it will actually go to the directory in the first argument, determine
it's filesystem, and ask the filesystem driver's pathconf() for a value.

As usual, I don't have access to POSIX (and it seems all the old drafts
that were available online have been recalled), but SUSv2 says

         Maximum number of bytes in a pathname, including the terminating
null character. Minimum Acceptable Value: _POSIX_PATH_MAX 

On the other hand, SUSv2 pathconf(),
which is "derived from POSIX-1.1988", both links PATH_MAX with _PC_PATH_MAX,
but it also has the same notes we saw in either HP/UX or Solaris.  Those
would be

4.If path or fildes does not refer to a directory, it is unspecified whether
an implementation supports an association of the variable name with the
specified file. 

5.If path or fildes refers to a directory, the value returned is the maximum
length of a relative pathname when the specified directory is the working

> Suppose pathconf() returns a constant value == _POSIX_PATH_MAX no matter
> what its directory argument is.  Comparing strlen(realpath(dir)) to that
> constant tells you if the filesystem will ultimately reject the name, but
> comparing strlen(dir) tells you nothing.
> Now suppose pathconf() returns a differing amount depending on the length
> of realpath(dir).  In this case comparing strlen(realpath(dir)) to that
> value is entirely wrong, because pathconf() has already accounted for the
> real path!  Even comparing strlen(dir) doesn't tell you anything, because
> what the value reflects is how much *more* path space you have left after
> you already have used whatever it takes to get to realpath(dir), whereas
> strlen(dir) gives some fraction of the already-used path space.

Back to the pathconf() manpage from SUSv2, we have

|If the variable corresponding to name has no limit for the path or file
|descriptor, both pathconf() and fpathconf() return -1 without changing
|errno. If the implementation needs to use path to determine the value
|of name and the implementation does not support the association of name
|with the file specified by path, or if the process did not have
|appropriate privileges to query the file specified by path, or path does
|not exist, pathconf() returns -1 and errno is set to indicate the error. 

So it appears that the implementation has the option of caring about
the first argument or completely ignoring it.

> If somebody with access to the POSIX spec can refute that last paragraph,
> I'll be thrilled.

I hope they've made some clarifications since 1988.

> In the meantime, we have to detect the constant-valued pathconf() in order
> to determine whether we should do a comparison, because comparing to a
> context-dependent pathconf() value is wrong.

It could be an autoconf check if you can think of a path guaranteed to
be invalid.

> Hard to say.  It's going to take a LOT of rewriting; it might be better
> not even to pretend to support pathconf() until that rewriting is done.
> [*] Or at least zsh has always treated it as if that's the definition.

It seems to me as though, at least according to what I understood of some
X/Open specs, it's intended as a maximum argument length to library functions.

Messages sorted by: Reverse Date, Date, Thread, Author