summaryrefslogtreecommitdiffstats
path: root/fs/fs.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fs.c')
-rw-r--r--fs/fs.c113
1 files changed, 48 insertions, 65 deletions
diff --git a/fs/fs.c b/fs/fs.c
index 1901c94ad1..9cb15738b0 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -435,57 +435,6 @@ static int dir_is_empty(const char *pathname)
return ret;
}
-#define S_UB_IS_EMPTY (1 << 31)
-#define S_UB_EXISTS (1 << 30)
-#define S_UB_DOES_NOT_EXIST (1 << 29)
-
-/*
- * Helper function to check the prerequisites of a path given
- * to fs functions. Besides the flags above S_IFREG and S_IFDIR
- * can be passed in.
- */
-static int path_check_prereq(const char *path, unsigned int flags)
-{
- struct stat s;
- unsigned int m;
- int ret = 0;
-
- if (lstat(path, &s)) {
- if (flags & S_UB_DOES_NOT_EXIST)
- goto out;
- ret = -ENOENT;
- goto out;
- }
-
- if (flags & S_UB_DOES_NOT_EXIST) {
- ret = -EEXIST;
- goto out;
- }
-
- if (flags == S_UB_EXISTS)
- goto out;
-
- m = s.st_mode;
-
- if (S_ISDIR(m)) {
- if (flags & S_IFREG) {
- ret = -EISDIR;
- goto out;
- }
- if ((flags & S_UB_IS_EMPTY) && !dir_is_empty(path)) {
- ret = -ENOTEMPTY;
- goto out;
- }
- }
- if ((flags & S_IFDIR) && S_ISREG(m)) {
- ret = -ENOTDIR;
- goto out;
- }
-
-out:
- return ret;
-}
-
static int parent_check_directory(const char *path)
{
struct stat s;
@@ -515,12 +464,17 @@ int chdir(const char *pathname)
{
char *p = normalise_path(pathname);
int ret;
+ struct stat s;
-
- ret = path_check_prereq(p, S_IFDIR);
+ ret = stat(p, &s);
if (ret)
goto out;
+ if (!S_ISDIR(s.st_mode)) {
+ ret = -ENOTDIR;
+ goto out;
+ }
+
automount_mount(p, 0);
strcpy(cwd, p);
@@ -542,10 +496,14 @@ int unlink(const char *pathname)
char *p = normalise_path(pathname);
char *freep = p;
int ret;
+ struct stat s;
- ret = path_check_prereq(pathname, S_IFREG);
- if (ret) {
- ret = -EINVAL;
+ ret = lstat(pathname, &s);
+ if (ret)
+ goto out;
+
+ if (S_ISDIR(s.st_mode)) {
+ ret = -EISDIR;
goto out;
}
@@ -1071,11 +1029,17 @@ int readlink(const char *pathname, char *buf, size_t bufsiz)
char *p = normalise_path(pathname);
char *freep = p;
int ret;
+ struct stat s;
- ret = path_check_prereq(pathname, S_IFLNK);
+ ret = lstat(pathname, &s);
if (ret)
goto out;
+ if (!S_ISLNK(s.st_mode)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
fsdev = get_fs_device_and_root_path(&p);
if (!fsdev) {
ret = -ENODEV;
@@ -1274,15 +1238,21 @@ int mount(const char *device, const char *fsname, const char *_path,
device, path, fsname, fsoptions);
if (fs_dev_root) {
+ struct stat s;
+
fsdev = get_fsdevice_by_path(path);
if (fsdev != fs_dev_root) {
printf("sorry, no nested mounts\n");
ret = -EBUSY;
goto err_free_path;
}
- ret = path_check_prereq(path, S_IFDIR);
+ ret = lstat(path, &s);
if (ret)
goto err_free_path;
+ if (!S_ISDIR(s.st_mode)) {
+ ret = -ENOTDIR;
+ goto err_free_path;
+ }
} else {
/* no mtab, so we only allow to mount on '/' */
if (*path != '/' || *(path + 1)) {
@@ -1420,11 +1390,17 @@ DIR *opendir(const char *pathname)
char *p = normalise_path(pathname);
char *freep = p;
int ret;
+ struct stat s;
- ret = path_check_prereq(pathname, S_IFDIR);
+ ret = stat(pathname, &s);
if (ret)
goto out;
+ if (!S_ISDIR(s.st_mode)) {
+ ret = -ENOTDIR;
+ goto out;
+ }
+
fsdev = get_fs_device_and_root_path(&p);
if (!fsdev) {
ret = -ENOENT;
@@ -1564,14 +1540,17 @@ int mkdir (const char *pathname, mode_t mode)
char *p = normalise_path(pathname);
char *freep = p;
int ret;
+ struct stat s;
ret = parent_check_directory(p);
if (ret)
goto out;
- ret = path_check_prereq(pathname, S_UB_DOES_NOT_EXIST);
- if (ret)
+ ret = stat(pathname, &s);
+ if (!ret) {
+ ret = -EEXIST;
goto out;
+ }
fsdev = get_fs_device_and_root_path(&p);
if (!fsdev) {
@@ -1601,16 +1580,20 @@ int rmdir (const char *pathname)
char *p = normalise_path(pathname);
char *freep = p;
int ret;
+ struct stat s;
- ret = path_check_prereq(pathname, S_IFLNK);
- if (!ret) {
+ ret = lstat(pathname, &s);
+ if (ret)
+ goto out;
+ if (!S_ISDIR(s.st_mode)) {
ret = -ENOTDIR;
goto out;
}
- ret = path_check_prereq(pathname, S_IFDIR | S_UB_IS_EMPTY);
- if (ret)
+ if (!dir_is_empty(pathname)) {
+ ret = -ENOTEMPTY;
goto out;
+ }
fsdev = get_fs_device_and_root_path(&p);
if (!fsdev) {