struct stat s;
char new[PATH_MAX];
char *source = (char *)orig_source;
- int fd;
+ int fd, ret = 0;
bool is_bind = (orig_mountflags & MS_BIND);
bool is_mask = (source == (void *)(-1));
unsigned long mountflags = orig_mountflags;
+ assert(!(inner && is_mask));
+ assert(!(inner && !orig_source));
+
if (source && is_bind && stat(source, &s)) {
ERROR("stat(%s) failed: %m\n", source);
return error;
}
- if (!is_mask && orig_source && inner) {
+ if (inner)
if (asprintf(&source, "%s%s", root, orig_source) < 0)
return ENOMEM;
- }
snprintf(new, sizeof(new), "%s%s", root, target?target:source);
return 0; /* doesn't exists, nothing to mask */
if (S_ISDIR(s.st_mode)) {/* use empty 0-sized tmpfs for directories */
- if (mount(NULL, new, "tmpfs", MS_RDONLY | MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_NOATIME, "size=0,mode=000"))
+ if (mount("none", new, "tmpfs", MS_RDONLY | MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_NOATIME, "size=0,mode=000"))
return error;
} else {
/* mount-bind 0-sized file having mode 000 */
} else if (is_bind && source) {
mkdir_p(dirname(new), 0755);
snprintf(new, sizeof(new), "%s%s", root, target?target:source);
- fd = creat(new, 0644);
- if (fd == -1) {
- ERROR("creat(%s) failed: %m\n", new);
- return error;
+ fd = open(new, O_CREAT|O_WRONLY|O_TRUNC|O_EXCL, 0644);
+ if (fd >= 0)
+ close(fd);
+
+ if (error && fd < 0 && errno != EEXIST) {
+ ERROR("failed to create mount target %s: %m\n", new);
+
+ ret = errno;
+ goto free_source_out;
}
- close(fd);
}
if (is_bind) {
if (error)
ERROR("failed to mount -B %s %s: %m\n", source, new);
- if (inner)
- free(source);
-
- return error;
+ ret = error;
+ goto free_source_out;
}
mountflags |= MS_REMOUNT;
}
if (error)
ERROR("failed to mount %s %s: %m\n", source, new);
- if (inner)
- free(source);
-
- return error;
+ ret = error;
+ goto free_source_out;
}
DEBUG("mount %s%s %s (%s)\n", (mountflags & MS_BIND)?"-B ":"", source, new,
if (error)
ERROR("failed to mount --make-... %s \n", new);
- if (inner)
- free(source);
-
- return error;
+ ret = error;
}
+free_source_out:
if (inner)
free(source);
- return 0;
+ return ret;
}
static int _add_mount(const char *source, const char *target, const char *filesystemtype,
return _add_mount(source, target, filesystemtype, mountflags, propflags, optstr, error, true);
}
-int add_mount_bind(const char *path, int readonly, int error)
+static int _add_mount_bind(const char *path, const char *path2, int readonly, int error)
{
unsigned long mountflags = MS_BIND;
if (readonly)
mountflags |= MS_RDONLY;
- return add_mount(path, path, NULL, mountflags, 0, NULL, error);
+ return add_mount(path, path2, NULL, mountflags, 0, NULL, error);
+}
+
+int add_mount_bind(const char *path, int readonly, int error)
+{
+ return _add_mount_bind(path, path, readonly, error);
}
enum {
if (len) {
*mount_data = calloc(len + 1, sizeof(char));
- if (!mount_data)
+ if (!(*mount_data))
return ENOMEM;
len = 0;
int fd;
fd = creat(UJAIL_NOAFILE, 0000);
- if (fd == -1)
+ if (fd < 0)
return;
close(fd);
return add_path_and_deps(buf, 1, -1, 0);
}
-int add_path_and_deps(const char *path, int readonly, int error, int lib)
+int add_2paths_and_deps(const char *path, const char *path2, int readonly, int error, int lib)
{
assert(path != NULL);
+ assert(path2 != NULL);
if (lib == 0 && path[0] != '/') {
ERROR("%s is not an absolute path\n", path);
char *map = NULL;
int fd, ret = -1;
if (path[0] == '/') {
- if (avl_find(&mounts, path))
+ if (avl_find(&mounts, path2))
return 0;
fd = open(path, O_RDONLY|O_CLOEXEC);
- if (fd == -1)
+ if (fd < 0)
return error;
- add_mount_bind(path, readonly, error);
+ _add_mount_bind(path, path2, readonly, error);
} else {
if (avl_find(&libraries, path))
return 0;
char *fullpath;
fd = lib_open(&fullpath, path);
- if (fd == -1)
+ if (fd < 0)
return error;
if (fullpath) {
alloc_library(fullpath, path);