Example #1
0
static int
recursive_remove_internal(const char *path, int missing_ok, int cwd)
{
	DIR *dir;
	struct dirent *de;
	const char *sub_path;
	char *subdir;
	int did_chdir, rv;

	/*
	 * If the argument is longer than PATH_MAX, long_remove
	 * will try to shorten it using chdir.  So before returning,
	 * make sure to fchdir back to the original cwd.
	 */
	sub_path = path;
	if (long_remove(&sub_path, missing_ok, &did_chdir) == 0)
		rv = 0;
	else if (errno != ENOTEMPTY) /* Other errors are terminal. */
		rv = -1;
	else
		rv = 1;

	if (rv != 1) {
		if (did_chdir && safe_fchdir(cwd) == -1 && rv == 0)
			rv = -1;
		return rv;
	}

	if ((dir = opendir(sub_path)) == NULL) {
		if (errno == EMFILE)
			warn("opendir failed");
		return -1;
	}

	if (did_chdir && fchdir(cwd) == -1)
		return -1;

	rv = 0;

	while ((de = readdir(dir)) != NULL) {
		if (strcmp(de->d_name, ".") == 0)
			continue;
		if (strcmp(de->d_name, "..") == 0)
			continue;
		subdir = xasprintf("%s/%s", path, de->d_name);
		rv = recursive_remove_internal(subdir, 1, cwd);
		free(subdir);
	}

	closedir(dir);

	safe_fchdir(cwd);

	rv |= long_remove(&path, missing_ok, &did_chdir);

	if (did_chdir && safe_fchdir(cwd) == -1 && rv == 0)
		rv = -1;

	return rv;
}
Example #2
0
static void
add_dir(struct sfs_fs *sfs, struct cache_inode *parent, const char *dirname, int curfd, int fd, ino_t real) {
    assert(search_cache_inode(sfs, real) == NULL);
    struct cache_inode *current = alloc_cache_inode(sfs, real, 0, SFS_TYPE_DIR);
    safe_fchdir(fd), subpath_push(sfs, dirname);
    open_dir(sfs, current, parent);
    safe_fchdir(curfd), subpath_pop(sfs);
    add_entry(sfs, parent, current, dirname);
}
Example #3
0
int
create_img(struct sfs_fs *sfs, const char *home) {
    int curfd, homefd;
    if ((curfd = open(".", O_RDONLY)) < 0) {
        bug("get current fd failed.\n");
    }
    if ((homefd = open(home, O_RDONLY | O_NOFOLLOW)) < 0) {
        bug("open home directory '%s' failed.\n", home);
    }
    safe_fchdir(homefd);
    open_dir(sfs, sfs->root, sfs->root);
    safe_fchdir(curfd);
    close(curfd), close(homefd);
    close_sfs(sfs);
    return 0;
}