示例#1
0
文件: fuse.cpp 项目: looncraz/haiku
static int
fuse_readdir(const char* path, void* buf, fuse_fill_dir_t filler,
	off_t offset, struct fuse_file_info* fi)
{
	PRINTD("##readdir\n");
	int dfp = _kern_open_dir(-1, path);
	if (dfp < FSSH_B_OK)
		return _ERR(dfp);

	fssh_ssize_t entriesRead = 0;
	struct fssh_stat f_st;
	struct stat st;
	char buffer[sizeof(fssh_dirent) + FSSH_B_FILE_NAME_LENGTH];
	fssh_dirent* dirEntry = (fssh_dirent*)buffer;
	while ((entriesRead = _kern_read_dir(dfp, dirEntry,
			sizeof(buffer), 1)) == 1) {
		fssh_memset(&st, 0, sizeof(st));
		fssh_memset(&f_st, 0, sizeof(f_st));
		fssh_status_t status = _kern_read_stat(dfp, dirEntry->d_name,
			false, &f_st, sizeof(f_st));
		if (status >= FSSH_B_OK) {
			fromFsshStatToStat(&f_st, &st);
			if (filler(buf, dirEntry->d_name, &st, 0))
				break;
		}
	}
	_kern_close(dfp);
	//TODO: check _kern_close
	return 0;
}
示例#2
0
文件: fssh.cpp 项目: mariuz/haiku
static fssh_status_t
command_ls(int argc, const char* const* argv)
{
	const char* const currentDirFiles[] = { ".", NULL };
	const char* const* files;
	if (argc >= 2)
		files = argv + 1;
	else
		files = currentDirFiles;

	for (; *files; files++) {
		const char* file = *files;
		// stat file
		struct fssh_stat st;
		fssh_status_t error = _kern_read_stat(-1, file, false, &st, sizeof(st));
		if (error != FSSH_B_OK) {
			fprintf(stderr, "Error: Failed to stat() \"%s\": %s\n", file,
				fssh_strerror(error));
			continue;
		}

		// if it is a directory, print its entries
		if (FSSH_S_ISDIR(st.fssh_st_mode)) {
			printf("%s:\n", file);

			// open dir
			int fd = _kern_open_dir(-1, file);
			if (fd < 0) {
				fprintf(stderr, "Error: Failed to open dir \"%s\": %s\n",
					file, fssh_strerror(fd));
				continue;
			}

			// iterate through the entries
			char buffer[sizeof(fssh_dirent) + FSSH_B_FILE_NAME_LENGTH];
			fssh_dirent* entry = (fssh_dirent*)buffer;
			fssh_ssize_t entriesRead = 0;
			while ((entriesRead = _kern_read_dir(fd, entry, sizeof(buffer), 1))
					== 1) {
				list_entry(file, entry->d_name);
			}

			if (entriesRead < 0) {
				fprintf(stderr, "Error: reading dir \"%s\" failed: %s\n",
					file, fssh_strerror(entriesRead));
			}

			// close dir
			error = _kern_close(fd);
			if (error != FSSH_B_OK) {
				fprintf(stderr, "Error: Closing dir \"%s\" (fd: %d) failed: "
					"%s\n", file, fd, fssh_strerror(error));
				continue;
			}
		} else
			list_entry(file);
	}

	return FSSH_B_OK;
}
示例#3
0
/*! \brief Re-initializes the BDirectory to the directory referred to by the
	supplied BEntry.
	\param entry the BEntry referring to the directory
	\return
	- \c B_OK: Everything went fine.
	- \c B_BAD_VALUE: \c NULL \a entry.
	- \c B_ENTRY_NOT_FOUND: Directory not found.
	- \c B_PERMISSION_DENIED: Directory permissions didn't allow operation.
	- \c B_NO_MEMORY: Insufficient memory for operation.
	- \c B_LINK_LIMIT: Indicates a cyclic loop within the file system.
	- \c B_BUSY: A node was busy.
	- \c B_FILE_ERROR: A general file error.
	- \c B_NO_MORE_FDS: The application has run out of file descriptors.
*/
status_t
BDirectory::SetTo(const BEntry* entry)
{
	if (!entry) {
		Unset();
		return (fCStatus = B_BAD_VALUE);
	}

	// open node
	status_t error = _SetTo(entry->fDirFd, entry->fName, true);
	if (error != B_OK)
		return error;

	// open dir
	fDirFd = _kern_open_dir(entry->fDirFd, entry->fName);
	if (fDirFd < 0) {
		status_t error = fDirFd;
		Unset();
		return (fCStatus = error);
	}

	// set close on exec flag on dir FD
	fcntl(fDirFd, F_SETFD, FD_CLOEXEC);

	return B_OK;
}
示例#4
0
DIR*
fdopendir(int fd)
{
	DIR* dir;

	// Since our standard file descriptors can't be used as directory file
	// descriptors, we have to open a fresh one explicitly.
	int dirFD = _kern_open_dir(fd, NULL);
	if (dirFD < 0) {
		__set_errno(dirFD);
		return NULL;
	}

	// Since applications are allowed to use the file descriptor after a call
	// to fdopendir() without changing its state (like for other *at()
	// functions), we cannot close it now.
	// We dup2() the new FD to the previous location instead.
	if (dup2(dirFD, fd) == -1)
		close(fd);
	else {
		close(dirFD);
		dirFD = fd;
		fcntl(dirFD, F_SETFD, FD_CLOEXEC);
			// reset close-on-exec which is cleared by dup()
	}

	dir = __create_dir_struct(dirFD);
	if (dir == NULL) {
		close(dirFD);
		return NULL;
	}

	return dir;
}
示例#5
0
DIR*
opendir(const char* path)
{
	DIR* dir;

	int fd = _kern_open_dir(-1, path);
	if (fd < 0) {
		__set_errno(fd);
		return NULL;
	}

	// allocate the DIR structure
	if ((dir = __create_dir_struct(fd)) == NULL) {
		_kern_close(fd);
		return NULL;
	}

	return dir;
}
示例#6
0
文件: fssh.cpp 项目: mariuz/haiku
static fssh_status_t
command_ioctl(int argc, const char* const* argv)
{
	if (argc != 2) {
		fprintf(stderr, "Usage: %s <opcode>\n", argv[0]);
		return FSSH_B_BAD_VALUE;
	}

	int rootDir = _kern_open_dir(-1, "/myfs");
	if (rootDir < 0)
		return rootDir;

	fssh_status_t status = _kern_ioctl(rootDir, atoi(argv[1]), NULL, 0);
	if (status != FSSH_B_OK) {
		fprintf(stderr, "Error: ioctl failed: %s\n", fssh_strerror(status));
		return status;
	}

	return FSSH_B_OK;
}
示例#7
0
/*! \brief Re-initializes the BDirectory to the directory referred to by the
	supplied path name.
	\param path the directory's path name
	\return
	- \c B_OK: Everything went fine.
	- \c B_BAD_VALUE: \c NULL \a path.
	- \c B_ENTRY_NOT_FOUND: Directory not found.
	- \c B_PERMISSION_DENIED: Directory permissions didn't allow operation.
	- \c B_NO_MEMORY: Insufficient memory for operation.
	- \c B_NAME_TOO_LONG: The supplied path name (\a path) is too long.
	- \c B_LINK_LIMIT: Indicates a cyclic loop within the file system.
	- \c B_BUSY: A node was busy.
	- \c B_FILE_ERROR: A general file error.
	- \c B_NO_MORE_FDS: The application has run out of file descriptors.
	- \c B_NOT_A_DIRECTORY: \a path includes a non-directory.
*/
status_t
BDirectory::SetTo(const char* path)
{
	// open node
	status_t error = _SetTo(-1, path, true);
	if (error != B_OK)
		return error;

	// open dir
	fDirFd = _kern_open_dir(-1, path);
	if (fDirFd < 0) {
		status_t error = fDirFd;
		Unset();
		return (fCStatus = error);
	}

	// set close on exec flag on dir FD
	fcntl(fDirFd, F_SETFD, FD_CLOEXEC);

	return B_OK;
}
示例#8
0
文件: fssh.cpp 项目: mariuz/haiku
static fssh_status_t
remove_dir_contents(int parentDir, const char *name, bool force)
{
	// open the dir
	int dir = _kern_open_dir(parentDir, name);
	if (dir < 0) {
		fprintf(stderr, "Error: Failed to open dir \"%s\": %s\n", name,
			fssh_strerror(dir));
		return dir;
	}

	fssh_status_t error = FSSH_B_OK;

	// iterate through the entries
	fssh_ssize_t numRead;
	char buffer[sizeof(fssh_dirent) + FSSH_B_FILE_NAME_LENGTH];
	fssh_dirent *entry = (fssh_dirent*)buffer;
	while ((numRead = _kern_read_dir(dir, entry, sizeof(buffer), 1)) > 0) {
		// skip "." and ".."
		if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
			continue;

		error = remove_entry(dir, entry->d_name, true, force);
		if (error != FSSH_B_OK)
			break;
	}

	if (numRead < 0) {
		fprintf(stderr, "Error: Failed to read directory \"%s\": %s\n", name,
			fssh_strerror(numRead));
		error = numRead;
	}

	// close
	_kern_close(dir);

	return error;
}
示例#9
0
/*! \brief Re-initializes the BDirectory to the directory referred to by the
	supplied path name relative to the specified BDirectory.
	\param dir the BDirectory, relative to which the directory's path name is
		   given
	\param path the directory's path name relative to \a dir
	\return
	- \c B_OK: Everything went fine.
	- \c B_BAD_VALUE: \c NULL \a dir or \a path, or \a path is absolute.
	- \c B_ENTRY_NOT_FOUND: Directory not found.
	- \c B_PERMISSION_DENIED: Directory permissions didn't allow operation.
	- \c B_NO_MEMORY: Insufficient memory for operation.
	- \c B_NAME_TOO_LONG: The supplied path name (\a path) is too long.
	- \c B_LINK_LIMIT: Indicates a cyclic loop within the file system.
	- \c B_BUSY: A node was busy.
	- \c B_FILE_ERROR: A general file error.
	- \c B_NO_MORE_FDS: The application has run out of file descriptors.
	- \c B_NOT_A_DIRECTORY: \a path includes a non-directory.
*/
status_t
BDirectory::SetTo(const BDirectory* dir, const char* path)
{
	if (!dir || !path || BPrivate::Storage::is_absolute_path(path)) {
		Unset();
		return (fCStatus = B_BAD_VALUE);
	}

	int dirFD = dir->fDirFd;
	if (dir == this) {
		// prevent that our file descriptor goes away in _SetTo()
		fDirFd = -1;
	}

	// open node
	status_t error = _SetTo(dirFD, path, true);
	if (error != B_OK)
		return error;

	// open dir
	fDirFd = _kern_open_dir(dirFD, path);
	if (fDirFd < 0) {
		status_t error = fDirFd;
		Unset();
		return (fCStatus = error);
	}

	if (dir == this) {
		// cleanup after _SetTo()
		_kern_close(dirFD);
	}

	// set close on exec flag on dir FD
	fcntl(fDirFd, F_SETFD, FD_CLOEXEC);

	return B_OK;
}
示例#10
0
文件: fssh.cpp 项目: mariuz/haiku
static fssh_status_t
command_mv(int argc, const char* const* argv)
{
	bool force = false;

	// parse parameters
	int argi = 1;
	for (argi = 1; argi < argc; argi++) {
		const char *arg = argv[argi];
		if (arg[0] != '-')
			break;

		if (arg[1] == '\0') {
			fprintf(stderr, "Error: Invalid option \"-\"\n");
			return FSSH_B_BAD_VALUE;
		}

		for (int i = 1; arg[i]; i++) {
			switch (arg[i]) {
				case 'f':
					force = true;
					break;
				default:
					fprintf(stderr, "Error: Unknown option \"-%c\"\n", arg[i]);
					return FSSH_B_BAD_VALUE;
			}
		}
	}

	// check params
	int count = argc - 1 - argi;
	if (count <= 0) {
		fprintf(stderr, "Usage: %s [-f] <file>... <target>\n", argv[0]);
		return FSSH_B_BAD_VALUE;
	}

	const char* target = argv[argc - 1];

	// stat the target
	struct fssh_stat st;
	fssh_status_t status = _kern_read_stat(-1, target, true, &st, sizeof(st));
	if (status != FSSH_B_OK && count != 1) {
		fprintf(stderr, "Error: Failed to stat target \"%s\": %s\n", target,
			fssh_strerror(status));
		return status;
	}

	if (status == FSSH_B_OK && FSSH_S_ISDIR(st.fssh_st_mode)) {
		// move several entries
		int targetDir = _kern_open_dir(-1, target);
		if (targetDir < 0) {
			fprintf(stderr, "Error: Failed to open dir \"%s\": %s\n", target,
				fssh_strerror(targetDir));
			return targetDir;
		}

		// move loop
		for (; argi < argc - 1; argi++) {
			status = move_entry(-1, argv[argi], targetDir, argv[argi], force);
			if (status != FSSH_B_OK) {
				_kern_close(targetDir);
				return status;
			}
		}

		_kern_close(targetDir);
		return FSSH_B_OK;
	}

	// rename single entry
	return move_entry(-1, argv[argi], -1, target, force);
}