#include <string.h>
#include <errno.h>
#include <assert.h>
+#include <unistd.h>
#include <sys/param.h>
-#include <sys/queue.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/queue.h>
#include "sysio.h"
#include "mount.h"
struct intent *intnt,
const char *path)
{
- struct pnode *pno;
int err;
+ struct pnode *pno;
if (!parent->p_base->pb_ino)
return -ENOTDIR;
+ err = _sysio_permitted(parent->p_base->pb_ino, X_OK);
+ if (err)
+ return err;
+
/*
* Short-circuit `.' and `..'; We don't cache those.
*/
parent = nd->nd_root;
}
+#if DEFER_INIT_CWD
+ if (!parent) {
+ const char *icwd;
+
+ if (!_sysio_init_cwd)
+ abort();
+
+ /*
+ * Finally have to set the curretn working directory. We can
+ * not tolerate errors here or else risk leaving the process
+ * in a very unexpected location. We abort then unless all goes
+ * well.
+ */
+ icwd = _sysio_init_cwd;
+ _sysio_init_cwd = NULL;
+ if (_sysio_namei(NULL, icwd, 0, NULL, &parent) != 0 ||
+ _sysio_p_chdir(parent) != 0)
+ abort();
+ }
+#endif
+
/*
* (Re)Validate the parent.
*/
*/
for (;;) {
ino = nd->nd_pno->p_base->pb_ino;
- if (S_ISLNK(ino->i_mode) &&
+ if (S_ISLNK(ino->i_stbuf.st_mode) &&
(next.len || !(nd->nd_flags & ND_NOFOLLOW))) {
char *lpath;
ssize_t cc;
}
#ifdef AUTOMOUNT_FILE_NAME
else if (ino &&
- S_ISDIR(ino->i_mode) &&
+ S_ISDIR(ino->i_stbuf.st_mode) &&
(nd->nd_pno->p_mount->mnt_flags & MOUNT_F_AUTO) &&
nd->nd_amcnt < MAX_MOUNT_DEPTH &&
- ino->i_mode & S_ISUID) {
+ ino->i_stbuf.st_mode & S_ISUID) {
struct pnode *pno;
/*
/*
* Parent must be a directory.
*/
- if (ino && !S_ISDIR(ino->i_mode)) {
+ if (ino && !S_ISDIR(ino->i_stbuf.st_mode)) {
err = -ENOTDIR;
break;
}
* Make sure the last processed component was a directory. The
* trailing slashes are illegal behind anything else.
*/
- if (!(err || S_ISDIR(nd->nd_pno->p_base->pb_ino->i_mode)))
+ if (!(err ||
+ S_ISDIR(nd->nd_pno->p_base->pb_ino->i_stbuf.st_mode)))
err = -ENOTDIR;
}