Exemplo n.º 1
0
int
dup(int oldfn)
{
	filedesc *newfd = filedesc_alloc();
	if (!newfd)
		return -1;
	return dup2(oldfn, newfd - files->fd);
}
Exemplo n.º 2
0
FILE *
fopen(const char *path, const char *mode)
{
	// Find an unused file descriptor and use it for the open
	FILE *fd = filedesc_alloc();
	if (fd == NULL)
		return NULL;

	return freopen(path, mode, fd);
}
Exemplo n.º 3
0
// Find or create and open a file, optionally using a given file descriptor.
// The argument 'fd' must point to a currently unused file descriptor,
// or may be NULL, in which case this function finds an unused file descriptor.
// The 'openflags' determines whether the file is created, truncated, etc.
// Returns the opened file descriptor on success,
// or returns NULL and sets errno on failure.
filedesc *
filedesc_open(filedesc *fd, const char *path, int openflags, mode_t mode)
{
	if (!fd && !(fd = filedesc_alloc()))
		return NULL;
	assert(fd->ino == FILEINO_NULL);

	// Determine the complete file mode if it is to be created.
	mode_t createmode = (openflags & O_CREAT) ? S_IFREG | (mode & 0777) : 0;

	// Walk the directory tree to find the desired directory entry,
	// creating an entry if it doesn't exist and O_CREAT is set.
	int ino = dir_walk(path, createmode);
	if (ino < 0)
		return NULL;
	assert(fileino_exists(ino));

	// Refuse to open conflict-marked files;
	// the user needs to resolve the conflict and clear the conflict flag,
	// or just delete the conflicted file.
	if (files->fi[ino].mode & S_IFCONF) {
		errno = ECONFLICT;
		return NULL;
	}

	// Truncate the file if we were asked to
	if (openflags & O_TRUNC) {
		if (!(openflags & O_WRONLY)) {
			warn("filedesc_open: can't truncate non-writable file");
			errno = EINVAL;
			return NULL;
		}
		if (fileino_truncate(ino, 0) < 0)
			return NULL;
	}

	// Initialize the file descriptor
	fd->ino = ino;
	fd->flags = openflags;
	fd->ofs = (openflags & O_APPEND) ? files->fi[ino].size : 0;
	fd->err = 0;

	assert(filedesc_isopen(fd));
	return fd;
}