mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
pwd(1): De-obfuscate, style(9)
In getcwd_logical(), test for a '.' or '..' component in one of the most
straightforward and intelligible ways possible.
In particular, this removes a superfluous re-test of the the component's
first character being '.' when the first one did not pass and, more
importantly, prevents the second test from relying on a side-effect in
the first.
While here, for better clarity, replace the loop that searches for '/'
with a simple call to strchrnul().
Add high-level comments about what is going on.
While here, test explicitly that pointed 'char' values are not 0 ('\0')
(style(9)).
While here, separate the successive steps of getcwd_logical() with blank
lines.
No functional change (intended).
Discussed with: emaste
Fixes: 2df923c5d2 ("pwd: Clean up and adopt POSIX semantics")
MFC after: 3 days
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D59709
This commit is contained in:
1 file changed
+14
-7
+14
-7
@@ -33,33 +33,40 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static char *
|
||||
getcwd_logical(void)
|
||||
{
|
||||
struct stat log, phy;
|
||||
char *pwd, *p, *q;
|
||||
char *pwd, *s, *e;
|
||||
|
||||
/* $PWD is set and absolute */
|
||||
if ((pwd = getenv("PWD")) == NULL || *pwd != '/')
|
||||
return (NULL);
|
||||
|
||||
/* $PWD does not contain /./ or /../ */
|
||||
for (p = pwd; *p; p = q) {
|
||||
for (q = ++p; *q && *q != '/'; q++)
|
||||
/* nothing */;
|
||||
if ((*p == '.' && q == ++p) ||
|
||||
(*p == '.' && q == ++p))
|
||||
e = pwd;
|
||||
do {
|
||||
assert(*e == '/');
|
||||
s = e + 1; /* Beginning of next component (may point to NUL). */
|
||||
/* Search for the component's end. */
|
||||
e = strchrnul(s, '/');
|
||||
if (s[0] == '.' && (s + 1 == e || (s[1] == '.' && s + 2 == e)))
|
||||
return (NULL);
|
||||
}
|
||||
} while (*e != '\0');
|
||||
|
||||
/* $PWD refers to the current directory */
|
||||
if (stat(pwd, &log) != 0 || stat(".", &phy) != 0 ||
|
||||
log.st_dev != phy.st_dev || log.st_ino != phy.st_ino)
|
||||
return (NULL);
|
||||
|
||||
return (pwd);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user