Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

keep track of file (fdesc) types, properly fill stat st_mode #580

Merged
merged 1 commit into from
Mar 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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