Skip to content

Commit

Permalink
keep track of file (fdesc) types, properly fill stat st_mode (#580)
Browse files Browse the repository at this point in the history
  • Loading branch information
wjhun authored Mar 5, 2019
1 parent 9667afb commit 04607fa
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 32 deletions.
2 changes: 1 addition & 1 deletion src/net/netsyscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ static int allocate_sock(process p, int type, u32 flags, sock * rs)
unix_cache_free(get_unix_heaps(), socket, s);
return -EMFILE;
}
fdesc_init(&s->f);
fdesc_init(&s->f, FDESC_TYPE_SOCKET);
heap h = heap_general(get_kernel_heaps());
s->f.read = closure(h, socket_read, s);
s->f.write = closure(h, socket_write, s);
Expand Down
4 changes: 2 additions & 2 deletions src/unix/pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,15 +276,15 @@ int do_pipe2(int fds[2], int flags)

pipe_file reader = &pipe->files[PIPE_READ];
reader->fd = fds[PIPE_READ] = allocate_fd(pipe->p, reader);
fdesc_init(&reader->f);
fdesc_init(&reader->f, FDESC_TYPE_PIPE);
reader->ns = allocate_notify_set(pipe->h);
reader->bq = allocate_blockq(pipe->h, "pipe read", PIPE_BLOCKQ_LEN, 0);
reader->f.read = closure(pipe->h, pipe_read, reader);
reader->f.close = closure(pipe->h, pipe_close, reader);
reader->f.check = closure(pipe->h, pipe_read_check, reader);

pipe_file writer = &pipe->files[PIPE_WRITE];
fdesc_init(&writer->f);
fdesc_init(&writer->f, FDESC_TYPE_PIPE);
writer->fd = fds[PIPE_WRITE] = allocate_fd(pipe->p, writer);
writer->ns = allocate_notify_set(pipe->h);
writer->bq = allocate_blockq(pipe->h, "pipe write", PIPE_BLOCKQ_LEN, 0);
Expand Down
2 changes: 1 addition & 1 deletion src/unix/poll.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ sysreturn epoll_create(u64 flags)
rv = -EMFILE;
goto out_cache_free;
}
fdesc_init(&e->f);
fdesc_init(&e->f, FDESC_TYPE_EPOLL);
e->f.close = closure(h, epoll_close, e);
list_init(&e->blocked_head);
e->events = allocate_vector(h, 8);
Expand Down
72 changes: 49 additions & 23 deletions src/unix/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,16 @@ static boolean file_check(file f, fsfile fsf, u32 eventmask, u32 * last, event_h
return true;
}

static int file_type_from_tuple(tuple n)
{
if (is_dir(n))
return FDESC_TYPE_DIRECTORY;
else if (is_special(n))
return FDESC_TYPE_SPECIAL;
else
return FDESC_TYPE_REGULAR;
}

sysreturn open_internal(tuple root, char *name, int flags, int mode)
{
heap h = heap_general(get_kernel_heaps());
Expand All @@ -692,29 +702,34 @@ sysreturn open_internal(tuple root, char *name, int flags, int mode)
thread_log(current, "\"%s\" - not found", name);
return set_syscall_error(current, ENOENT);
}

u64 length = 0;
fsfile fsf = 0;
if (!is_dir(n) && !is_special(n)) {

int type = file_type_from_tuple(n);
if (type == FDESC_TYPE_REGULAR) {
fsf = fsfile_from_node(current->p->fs, n);
if (!fsf) {
length = 0;
} else {
length = fsfile_get_length(fsf);
}
}
// might be functional, or be a directory

file f = unix_cache_alloc(uh, file);
if (f == INVALID_ADDRESS) {
thread_log(current, "failed to allocate struct file");
return set_syscall_error(current, ENOMEM);
}

int fd = allocate_fd(current->p, f);
if (fd == INVALID_PHYSICAL) {
thread_log(current, "failed to allocate fd");
unix_cache_free(uh, file, f);
return set_syscall_error(current, EMFILE);
}
fdesc_init(&f->f);

fdesc_init(&f->f, type);
f->f.read = closure(h, file_read, f, fsf);
f->f.write = closure(h, file_write, f, fsf);
f->f.close = closure(h, file_close, f, fsf);
Expand Down Expand Up @@ -1034,42 +1049,50 @@ sysreturn openat(int dirfd, char *name, int flags, int mode)
return open_internal(f->n, name, flags, mode);
}

static void fill_stat(tuple n, struct stat *s)
static void fill_stat(int type, tuple n, struct stat *s)
{
switch (type) {
case FDESC_TYPE_REGULAR:
s->st_mode = S_IFREG | 0644;
break;
case FDESC_TYPE_DIRECTORY:
s->st_mode = S_IFDIR | 0777;
break;
case FDESC_TYPE_SPECIAL:
s->st_mode = S_IFCHR; /* assuming only character devs now */
break;
case FDESC_TYPE_SOCKET:
s->st_mode = S_IFSOCK;
break;
case FDESC_TYPE_PIPE:
case FDESC_TYPE_STDIO:
s->st_mode = S_IFIFO;
break;
case FDESC_TYPE_EPOLL:
s->st_mode = S_IFCHR; /* XXX not clear - EBADF? */
break;
}
s->st_dev = 0;
s->st_ino = u64_from_pointer(n);
s->st_size = 0;
if (is_dir(n)) {
s->st_mode = S_IFDIR | 0777;
return;
} else if (!is_special(n)) {
if (type == FDESC_TYPE_REGULAR) {
fsfile f = fsfile_from_node(current->p->fs, n);
if (!f) {
s->st_size = 0;
} else {
if (f)
s->st_size = fsfile_get_length(f);
}
}
s->st_mode = S_IFREG | 0644; /* TODO */
thread_log(current, "st_ino %P, st_mode %P, st_size %P",
s->st_ino, s->st_mode, s->st_size);
}

static sysreturn fstat(int fd, struct stat *s)
{
thread_log(current, "fd %d, stat %p", fd, s);
file f = resolve_fd(current->p, fd);
fdesc f = resolve_fd(current->p, fd);
zero(s, sizeof(struct stat));
// take this from tuple space
if (fd == 0 || fd == 1 || fd == 2) {
s->st_mode = S_IFIFO;
return 0;
}
fill_stat(f->n, s);
fill_stat(f->type, ((file)f)->n, s);
return 0;
}


static sysreturn stat(char *name, struct stat *s)
{
thread_log(current, "name %s, stat %p", name, s);
Expand All @@ -1078,7 +1101,8 @@ static sysreturn stat(char *name, struct stat *s)
if (!(n = resolve_cstring(current->p->cwd, name))) {
return set_syscall_error(current, ENOENT);
}
fill_stat(n, s);

fill_stat(file_type_from_tuple(n), n, s);
return 0;
}

Expand All @@ -1103,7 +1127,8 @@ static sysreturn newfstatat(int dfd, char *name, struct stat *s, int flags)
if (!(n = resolve_cstring(children, name))) {
return set_syscall_error(current, ENOENT);
}
fill_stat(n, s);

fill_stat(file_type_from_tuple(n), n, s);
return 0;
}

Expand Down Expand Up @@ -1212,6 +1237,7 @@ sysreturn readlinkat(int dirfd, const char *pathname, char *buf, u64 bufsiz)

sysreturn close(int fd)
{
thread_log(current, "close: fd %d", fd);
fdesc f = resolve_fd(current->p, fd);
deallocate_fd(current->p, fd);

Expand Down
9 changes: 5 additions & 4 deletions src/unix/unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
#include <buffer.h>
#include <gdb.h>

void fdesc_init(fdesc f)
void fdesc_init(fdesc f, int type)
{
f->read = 0;
f->write = 0;
f->close = 0;
f->check = 0;
f->refcnt = 1;
f->type = type;
f->flags = 0;
}

Expand Down Expand Up @@ -85,11 +86,11 @@ static boolean create_stdfiles(unix_heaps uh, process p)

/* Writes to in, reads from out and err act as if handled by the
out and in files respectively. */
fdesc_init(&in->f);
fdesc_init(&in->f, FDESC_TYPE_STDIO);
in->f.close = closure(h, std_close, in);
fdesc_init(&out->f);
fdesc_init(&out->f, FDESC_TYPE_STDIO);
out->f.close = closure(h, std_close, out);
fdesc_init(&err->f);
fdesc_init(&err->f, FDESC_TYPE_STDIO);
err->f.close = closure(h, std_close, err);
in->f.write = out->f.write = err->f.write = closure(h, stdout);
in->f.read = out->f.read = err->f.read = closure(h, dummy_read);
Expand Down
11 changes: 10 additions & 1 deletion src/unix/unix_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,20 @@ typedef closure_type(io, sysreturn, void *, u64 length, u64 offset);

#include <notify.h>

#define FDESC_TYPE_REGULAR 1
#define FDESC_TYPE_DIRECTORY 2
#define FDESC_TYPE_SPECIAL 3
#define FDESC_TYPE_SOCKET 4
#define FDESC_TYPE_PIPE 5
#define FDESC_TYPE_STDIO 6
#define FDESC_TYPE_EPOLL 7

typedef struct fdesc {
io read, write;
closure_type(check, boolean, u32 eventmask, u32 * last, event_handler eh);
closure_type(close, sysreturn);
u64 refcnt;
int type;
int flags; /* F_GETFD/F_SETFD flags */
} *fdesc;

Expand Down Expand Up @@ -157,7 +166,7 @@ static inline kernel_heaps get_kernel_heaps()
#define unix_cache_alloc(uh, c) ({ heap __c = uh->c ## _cache; allocate(__c, __c->pagesize); })
#define unix_cache_free(uh, c, p) ({ heap __c = uh->c ## _cache; deallocate(__c, p, __c->pagesize); })

void fdesc_init(fdesc f);
void fdesc_init(fdesc f, int type);

u64 allocate_fd(process p, void *f);

Expand Down

0 comments on commit 04607fa

Please sign in to comment.