* PATCH: Handle ENOENT/ENOTDIR in zpathmax()
@ 2000-08-05 5:51 Bart Schaefer
2000-08-05 6:24 ` Bart Schaefer
0 siblings, 1 reply; 2+ messages in thread
From: Bart Schaefer @ 2000-08-05 5:51 UTC (permalink / raw)
To: zsh-workers
When I commit this, I'm going to also back out 12541 and 12533.
Index: Src/compat.c
===================================================================
@@ -118,21 +118,52 @@
* some other flag value) in order to determine that the resource is *
* unlimited. What use is leaving errno unchanged? Instead, define *
* a wrapper that resets errno to 0 and returns 0 for "the system *
- * does not have a limit." *
+ * does not have a limit," so that -1 always means a real error. *
* *
- * This is replaced by a macro from system.h if not HAVE_PATHCONF. */
+ * This is replaced by a macro from system.h if not HAVE_PATHCONF. *
+ *
+ * Note that the length of a relative path is compared without first *
+ * prepending the current directory, if pathconf() does not return *
+ * an error. This is for consistency with the macro and with older *
+ * zsh behavior; it may be problematic in the ENOENT/ENOTDIR cases. */
/**/
mod_export long
zpathmax(char *dir)
{
long pathmax;
+
+ if (!dir || !*dir)
+ dir = ".";
errno = 0;
if ((pathmax = pathconf(dir, _PC_PATH_MAX)) >= 0) {
+ /* This code is redundant if pathconf works correctly, but *
+ * some versions of glibc pathconf return a hardwired value. */
if (strlen(dir) < pathmax)
return pathmax;
else
errno = ENAMETOOLONG;
+ } else if (errno == ENOENT || errno == ENOTDIR) {
+ /* Work backward to find a directory, until we run out of path. */
+ char *tail = strrchr(dir, '/');
+ while (tail > dir && tail[-1] == '/')
+ --tail;
+ if (tail > dir) {
+ *tail = 0;
+ pathmax = zpathmax(dir);
+ *tail = '/';
+ if (pathmax > 0) {
+ if (strlen(dir) < pathmax)
+ return pathmax;
+ else
+ errno = ENAMETOOLONG;
+ }
+ }
+ /* else *
+ * Either we're at the root (tail == dir) or we're on the first *
+ * component of a relative path (tail == NULL). Either way we *
+ * have nothing to do here, the error from pathconf() is real. *
+ * Perhaps our current working directory has been removed? */
}
if (errno)
return -1;
--
Bart Schaefer Brass Lantern Enterprises
http://www.well.com/user/barts http://www.brasslantern.com
Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: PATCH: Handle ENOENT/ENOTDIR in zpathmax()
2000-08-05 5:51 PATCH: Handle ENOENT/ENOTDIR in zpathmax() Bart Schaefer
@ 2000-08-05 6:24 ` Bart Schaefer
0 siblings, 0 replies; 2+ messages in thread
From: Bart Schaefer @ 2000-08-05 6:24 UTC (permalink / raw)
To: zsh-workers
On Aug 5, 5:51am, Bart Schaefer wrote:
} + /* else *
} + * Either we're at the root (tail == dir) or we're on the first *
} + * component of a relative path (tail == NULL). Either way we *
} + * have nothing to do here, the error from pathconf() is real. *
} + * Perhaps our current working directory has been removed? */
I just realized that the above mishandles base cases of the recursion.
(I have the stupid hardwired glibc pathconf so I can't easily test that
branch.) That is, I suspect `mkdir notadir' or `mkdir /notadir' would
fail with 12547 and a working pathconf().
So the below might call pathconf() twice if dir = "." and the current
directory has been removed, or if pathconf("/") fails, but I figured both
of those are rare enough not to be worth a special-case test in the code.
I also decided to go back to letting pathconf() choke on NULL or "" if it
wants to.
Index: Src/compat.c
===================================================================
@@ -133,8 +133,6 @@
{
long pathmax;
- if (!dir || !*dir)
- dir = ".";
errno = 0;
if ((pathmax = pathconf(dir, _PC_PATH_MAX)) >= 0) {
/* This code is redundant if pathconf works correctly, but *
@@ -152,18 +150,19 @@
*tail = 0;
pathmax = zpathmax(dir);
*tail = '/';
- if (pathmax > 0) {
- if (strlen(dir) < pathmax)
- return pathmax;
- else
- errno = ENAMETOOLONG;
- }
+ } else {
+ errno = 0;
+ if (tail)
+ pathmax = pathconf("/", _PC_PATH_MAX);
+ else
+ pathmax = pathconf(".", _PC_PATH_MAX);
}
- /* else *
- * Either we're at the root (tail == dir) or we're on the first *
- * component of a relative path (tail == NULL). Either way we *
- * have nothing to do here, the error from pathconf() is real. *
- * Perhaps our current working directory has been removed? */
+ if (pathmax > 0) {
+ if (strlen(dir) < pathmax)
+ return pathmax;
+ else
+ errno = ENAMETOOLONG;
+ }
}
if (errno)
return -1;
--
Bart Schaefer Brass Lantern Enterprises
http://www.well.com/user/barts http://www.brasslantern.com
Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2000-08-05 6:25 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-08-05 5:51 PATCH: Handle ENOENT/ENOTDIR in zpathmax() Bart Schaefer
2000-08-05 6:24 ` Bart Schaefer
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).