Beispiel #1
0
int
fflush(FILE *f)
{
	if (f == NULL) {	// flush all open streams
		for (f = &files->fd[0]; f < &files->fd[OPEN_MAX]; f++)
			if (filedesc_isopen(f))
				fflush(f);
		return 0;
	}

	assert(filedesc_isopen(f));
	return fileino_flush(f->ino);
}
Beispiel #2
0
int
dup2(int oldfn, int newfn)
{
	filedesc *oldfd = &files->fd[oldfn];
	filedesc *newfd = &files->fd[newfn];
	assert(filedesc_isopen(oldfd));
	assert(filedesc_isvalid(newfd));

	if (filedesc_isopen(newfd))
		close(newfn);

	*newfd = *oldfd;

	return newfn;
}
Beispiel #3
0
int
feof(FILE *fd)
{
	assert(filedesc_isopen(fd));
	fileinode *fi = &files->fi[fd->ino];
	return fd->ofs >= fi->size && !(fi->mode & S_IFPART);
}
Beispiel #4
0
int
isatty(int fn)
{
	assert(filedesc_isopen(&files->fd[fn]));
	return files->fd[fn].ino == FILEINO_CONSIN
		|| files->fd[fn].ino == FILEINO_CONSOUT;
}
Beispiel #5
0
void
filedesc_close(filedesc *fd)
{
	assert(filedesc_isopen(fd));
	assert(fileino_isvalid(fd->ino));

	fd->ino = FILEINO_NULL;		// mark the fd free
}
Beispiel #6
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;
}
Beispiel #7
0
// Scan an open directory filedesc and return the next entry.
// Returns a pointer to the next matching file inode's 'dirent' struct,
// or NULL if the directory being scanned contains no more entries.
struct dirent *readdir(DIR *dir)
{
#if SOL >= 4
	assert(filedesc_isopen(dir));
	int ino;
	while ((ino = dir->ofs++) < FILE_INODES) {
		if (!fileino_exists(ino) || files->fi[ino].dino != dir->ino)
			continue;
		return &files->fi[ino].de;	// Return inode's dirent
	}
	return NULL;	// End of directory
#else	// ! SOL >= 4
	// Lab 4: insert your directory scanning code here.
	// Hint: a fileinode's 'dino' field indicates
	// what directory the file is in;
	// this function shouldn't return entries from other directories!
	warn("readdir() not implemented");
	return NULL;
#endif	// ! SOL >= 4
}
Beispiel #8
0
// Seek the given file descriptor to a specificied position,
// which may be relative to the file start, end, or corrent position,
// depending on 'whence' (SEEK_SET, SEEK_CUR, or SEEK_END).
// Returns the resulting absolute file position,
// or returns -1 and sets errno appropriately on error.
off_t filedesc_seek(filedesc *fd, off_t offset, int whence)
{
	assert(filedesc_isopen(fd));
	assert(whence == SEEK_SET || whence == SEEK_CUR || whence == SEEK_END);
	fileinode *fi = &files->fi[fd->ino];

#if SOL >= 4
	off_t newofs = offset;
	if (whence == SEEK_CUR)
		newofs += fd->ofs;
	else if (whence == SEEK_END)
		newofs += fi->size;
	assert(newofs >= 0);

	fd->ofs = newofs;
	return newofs;
#else	// ! SOL >= 4
	// Lab 4: insert your file descriptor seek implementation here.
	warn("filedesc_seek() not implemented");
	errno = EINVAL;
	return -1;
#endif	// ! SOL >= 4
}
Beispiel #9
0
FILE *
freopen(const char *path, const char *mode, FILE *fd)
{
	assert(filedesc_isvalid(fd));
	if (filedesc_isopen(fd))
		fclose(fd);

	// Parse the open mode string
	int flags;
	switch (*mode++) {
	case 'r':	flags = O_RDONLY; break;
	case 'w':	flags = O_WRONLY | O_CREAT | O_TRUNC; break;
	case 'a':	flags = O_WRONLY | O_CREAT | O_APPEND; break;
	default:	panic("freopen: unknown file mode '%c'\n", *--mode);
	}
	if (*mode == 'b')	// binary flag - compatibility only
		mode++;
	if (*mode == '+')
		flags |= O_RDWR;

	if (filedesc_open(fd, path, flags, 0666) != fd)
		return NULL;
	return fd;
}
Beispiel #10
0
int
fileno(FILE *fd)
{
	assert(filedesc_isopen(fd));
	return fd - files->fd;
}
Beispiel #11
0
void
clearerr(FILE *fd)
{
	assert(filedesc_isopen(fd));
	fd->err = 0;
}
Beispiel #12
0
int
ferror(FILE *fd)
{
	assert(filedesc_isopen(fd));
	return fd->err;
}
Beispiel #13
0
long
ftell(FILE *fd)
{
	assert(filedesc_isopen(fd));
	return fd->ofs;
}
Beispiel #14
0
int
fsync(int fn)
{
	assert(filedesc_isopen(&files->fd[fn]));
	return fileino_flush(files->fd[fn].ino);
}
Beispiel #15
0
int
fstat(int fn, struct stat *statbuf)
{
	assert(filedesc_isopen(&files->fd[fn]));
	return fileino_stat(files->fd[fn].ino, statbuf);
}
Beispiel #16
0
int
ftruncate(int fn, off_t newlength)
{
	assert(filedesc_isopen(&files->fd[fn]));
	return fileino_truncate(files->fd[fn].ino, newlength);
}