Merge branch 'master' of git.lfbs.rwth-aachen.de:metalsvm

This commit is contained in:
Stefan Lankes 2011-10-02 14:44:20 +02:00
commit 95488fee4d
3 changed files with 187 additions and 64 deletions

View file

@ -53,7 +53,9 @@ typedef struct
extern kb_buffer_t kb_buffer;
void kb_flush();
void kb_init(size_t size, tid_t tid);
void kb_finish(void);
#endif

View file

@ -36,7 +36,7 @@ void kb_init(size_t size, tid_t tid) {
return;
}
void kb_finish() {
void kb_finish(void) {
kfree(kb_buffer.buffer, (kb_buffer.maxsize * sizeof(char)));
kb_buffer.buffer = NULL;
kb_buffer.size = 0;

View file

@ -47,6 +47,11 @@ static int get_fildes(void)
task_t* curr_task = per_core(current_task);
int fd;
/*
* Seach the process specific file descriptor table for a free
* descriptor. The new descriptor returned by the call is the lowest
* numbered descriptor currently not in use by the process.
*/
for (fd = 0; fd < NR_OPEN; fd++) {
if (curr_task->fildes_table[fd] == NULL) {
/* Init Filedescriptor */
@ -60,32 +65,55 @@ static int get_fildes(void)
return -EMFILE;
}
static int sys_write(int fd, const char* buf, size_t len)
{
task_t* curr_task = per_core(current_task);
/* fd is negative or greater than the maximum allowable number */
if (BUILTIN_EXPECT((fd >= NR_OPEN) || (fd < 0), 0))
return -EBADF;
/* fd is not an active, valid file descriptor. */
if (curr_task->fildes_table[fd] == NULL)
return -EBADF;
return write_fs(curr_task->fildes_table[fd], (uint8_t*)buf, len);
}
static int sys_open(const char* name, int flags, int mode)
{
int fd, check;
fildes_t* file = NULL;
task_t* curr_task = per_core(current_task);
/* no name is given */
if (name == NULL)
return -EINVAL;
/* Get a free file descriptor */
fd = get_fildes();
/* validate the fd */
if (fd < 0)
return fd;
file = per_core(current_task)->fildes_table[fd];
file->mode = mode;
file->flags = flags;
file->count = 1;
check = open_fs(file, (char*) name);
/* fd is negative or greater than the maximum allowable number */
if (BUILTIN_EXPECT((fd >= NR_OPEN) || (fd < 0), 0))
return fd; /* in this case fd = errno */
/* init the whole file descriptor structure */
curr_task->fildes_table[fd]->mode = mode;
curr_task->fildes_table[fd]->flags = flags;
curr_task->fildes_table[fd]->count = 1;
check = open_fs(curr_task->fildes_table[fd], (char*) name);
/* file doesn't exist! */
if (check < 0) {
/* file doesn't exist! */
kfree(file, sizeof(fildes_t));
file = NULL;
/* tidy up the fildescriptor */
kfree(curr_task->fildes_table[fd], sizeof(fildes_t));
curr_task->fildes_table[fd] = NULL;
return check;
}
return fd;
}
static int sys_stat(const char* name, struct stat* st) {
static int sys_stat(const char* name, struct stat* st)
{
vfs_node_t* node;
node = findnode_fs(name);
@ -112,43 +140,102 @@ static int sys_stat(const char* name, struct stat* st) {
return 0;
}
static int sys_read(int fd, const char* buf, size_t len)
{
task_t* curr_task = per_core(current_task);
/* fd is negative or greater than the maximum allowable number */
if (BUILTIN_EXPECT((fd >= NR_OPEN) || (fd < 0), 0))
return -EBADF;
/* fd is not an active, valid file descriptor. */
if (curr_task->fildes_table[fd] == NULL)
return -EBADF;
return read_fs(curr_task->fildes_table[fd], (uint8_t*)buf, len);
}
#if defined(CONFIG_LWIP) && LWIP_SOCKET
static int sys_socket(int domain, int type, int protocol)
{
int fd;
fildes_t* file = NULL;
int fd, sock;
task_t* curr_task = per_core(current_task);
/* Get a free file descriptor */
fd = get_fildes();
/* validate the fd */
if (fd < 0)
return fd;
file = per_core(current_task)->fildes_table[fd];
file->offset = lwip_socket(domain, type, protocol);
file->node = findnode_fs("/dev/socket");
file->count = 1;
/* validate the file descriptor */
if (BUILTIN_EXPECT((fd >= NR_OPEN) || (fd < 0), 0))
return fd; /* in this case fd = errno */
/* Get a valid lwip descriptor */
sock = lwip_socket(domain, type, protocol);
/* validate the file descriptor */
if (BUILTIN_EXPECT(sock < 0, 0))
return sock; /* in this case sock = errno */
/*
* init the whole file descriptor structure.
* We use the offset to save the lwip descriptor
* TODO: find another solution or change the name 'offset'
*/
curr_task->fildes_table[fd]->offset = sock;
curr_task->fildes_table[fd]->count = 1;
curr_task->fildes_table[fd]->node = findnode_fs("/dev/socket");
/* file doesn't exist! */
if (curr_task->fildes_table[fd]->node == NULL) {
/* tidy up the fildescriptor */
kfree(curr_task->fildes_table[fd], sizeof(fildes_t));
curr_task->fildes_table[fd] = NULL;
return -ENOENT;
}
return fd;
}
static int sys_accept(int s, struct sockaddr* addr, socklen_t* addrlen)
{
int fd;
fildes_t* file = NULL;
int fd, sock2;
task_t* curr_task = per_core(current_task);
if (BUILTIN_EXPECT(s >= NR_OPEN, 0))
return -EINVAL;
/* validate the 'socket'-filedescriptor */
if (BUILTIN_EXPECT((s >= NR_OPEN) || (s < 0), 0))
return -EBADF;
/* validate the 'socket'-file descriptor object */
if (curr_task->fildes_table[s] == NULL)
return -EBADF;
/* Get a free file descriptor */
fd = get_fildes();
/* validate the fd */
if (fd < 0)
return fd;
file = per_core(current_task)->fildes_table[fd];
file->offset = lwip_accept(s, addr, addrlen);
file->node = findnode_fs("/dev/socket");
file->count = 1;
/* validate the file descriptor */
if (BUILTIN_EXPECT((fd >= NR_OPEN) || (fd < 0), 0))
return fd; /* in this case fd = errno */
/* Get a valid lwip descriptor */
sock2 = lwip_accept(s, addr, addrlen);
/* validate the file descriptor */
if (BUILTIN_EXPECT(sock2 < 0, 0))
return sock2; /* in this case sock = errno */
/*
* init the whole file descriptor structure.
* We use the offset to save the lwip descriptor
* TODO: find another solution or change the name 'offset'
*/
curr_task->fildes_table[fd]->offset = sock2;
curr_task->fildes_table[fd]->count = 1;
curr_task->fildes_table[fd]->node = findnode_fs("/dev/socket");
/* file doesn't exist! */
if (curr_task->fildes_table[fd]->node == NULL) {
/* tidy up the fildescriptor */
kfree(curr_task->fildes_table[fd], sizeof(fildes_t));
curr_task->fildes_table[fd] = NULL;
return -ENOENT;
}
return fd;
}
@ -157,13 +244,26 @@ static int sys_accept(int s, struct sockaddr* addr, socklen_t* addrlen)
static int sys_close(int fd)
{
int check;
task_t* curr_task = per_core(current_task);
if (BUILTIN_EXPECT(fd >= NR_OPEN, 0))
return -EINVAL;
/* fd is negative or greater than the maximum allowable number */
if (BUILTIN_EXPECT((fd >= NR_OPEN) || (fd < 0), 0))
return -EBADF;
/* fd is not an active, valid file descriptor. */
if (curr_task->fildes_table[fd] == NULL)
return -EBADF;
/*
* The close() call deletes a descriptor from the per-process object
* reference table. If this is the last reference to the underlying
* object, the object will be deactivated.
*/
if (curr_task->fildes_table[fd]->count == 1) {
close_fs(curr_task->fildes_table[fd]);
check = close_fs(curr_task->fildes_table[fd]);
/* close command failed -> return check = errno */
if (BUILTIN_EXPECT(check < 0, 0))
return check;
kfree(curr_task->fildes_table[fd], sizeof(fildes_t));
curr_task->fildes_table[fd] = NULL;
} else {
@ -178,30 +278,42 @@ static int sys_close(int fd)
static int sys_lseek(int fd, off_t pos, int origin)
{
int ret = -EINVAL;
fildes_t* file;
task_t* curr_task = per_core(current_task);
if (BUILTIN_EXPECT(fd >= NR_OPEN, 0))
return -EINVAL;
/* fd is negative or greater than the maximum allowable number */
if (BUILTIN_EXPECT((fd >= NR_OPEN) || (fd < 0), 0))
return -EBADF;
/* fd is not an active, valid file descriptor. */
if (curr_task->fildes_table[fd] == NULL)
return -EBADF;
file = per_core(current_task)->fildes_table[fd];
if (BUILTIN_EXPECT(!((file->node->type == FS_FILE)
|| (file->node->type == FS_CHARDEVICE)), 0))
return -EINVAL;
/* TODO: in case of Fildes is associated with a pipe, socket, or FIFO. return ESPIPE */
/* TODO: The seek location is too large to be stored in an object of type off_t. return EOVERFLOW*/
switch(origin)
{
{
case SEEK_SET: { /* set file offset to offset */
file->offset = pos;
ret = pos;
/* The seek location is negative. */
if (ret < 0)
return -EINVAL;
curr_task->fildes_table[fd]->offset = ret;
ret = 0;
break;
}
case SEEK_CUR: { /* set file offset to current plus offset */
ret = pos + file->offset;
ret = pos + curr_task->fildes_table[fd]->offset;
/* The seek location is negative. */
if (ret < 0)
return -EINVAL;
break;
}
case SEEK_END: { /* set file offset to EOF plus offset */
file->offset = pos + file->node->block_size;
ret = pos + curr_task->fildes_table[fd]->node->block_size;
/* The seek location is negative. */
if (ret < 0)
return -EINVAL;
curr_task->fildes_table[fd]->offset = ret;
ret = 0;
break;
}
@ -209,6 +321,7 @@ static int sys_lseek(int fd, off_t pos, int origin)
ret = -EINVAL;
break;
}
return ret;
}
@ -217,12 +330,19 @@ static int sys_dup(int fd)
task_t* curr_task = per_core(current_task);
int new_fd;
/* fd is negative or greater than the maximum allowable number */
if (BUILTIN_EXPECT((fd >= NR_OPEN) || (fd < 0), 0))
return -EBADF;
/* fd is not an active, valid file descriptor. */
if (curr_task->fildes_table[fd] == NULL)
return -EBADF;
/* Get a free file descriptor */
new_fd = get_fildes();
/* validate the file descriptor */
if (BUILTIN_EXPECT((new_fd >= NR_OPEN) || (fd < 0), 0))
return new_fd; /* in this case fd = errno */
curr_task->fildes_table[new_fd] = curr_task->fildes_table[fd];
curr_task->fildes_table[fd]->count++;
@ -233,18 +353,26 @@ static int sys_dup2(int fd, int fd2)
{
task_t* curr_task = per_core(current_task);
/* fd and fd2 is negative or greater than the maximum allowable number */
if (BUILTIN_EXPECT((fd >= NR_OPEN) || (fd < 0), 0))
return -EBADF;
if (BUILTIN_EXPECT((fd2 >= NR_OPEN) || (fd2 < 0), 0))
return -EBADF;
/* fd is not an active, valid file descriptor. */
if (curr_task->fildes_table[fd] == NULL)
return -EBADF;
if (fd == fd2)
/* If fd and fd2 are equal, then dup2() just returns fd2 */
if (fd == fd2)
return fd2;
/*
* if descriptor fd2 is already in use, it is first deallocated
* as if a close(2) call had been done first
*/
if (curr_task->fildes_table[fd2] != NULL)
sys_close(fd2);
curr_task->fildes_table[fd2] = curr_task->fildes_table[fd];
curr_task->fildes_table[fd]->count++;
@ -296,9 +424,7 @@ int syscall_handler(uint32_t sys_nr, ...)
int fd = va_arg(vl, int);
const char* buf = va_arg(vl, const char*);
size_t len = va_arg(vl, size_t);
if (fd >= 0)
ret = write_fs(per_core(current_task)->fildes_table[fd],
(uint8_t*)buf, len);
ret = sys_write(fd, buf, len);
break;
}
case __NR_open: {
@ -310,8 +436,7 @@ int syscall_handler(uint32_t sys_nr, ...)
}
case __NR_close: {
int fd = va_arg(vl, int);
if (fd >= 0)
ret = sys_close(fd);
ret = sys_close(fd);
break;
}
case __NR_dup: {
@ -328,7 +453,6 @@ int syscall_handler(uint32_t sys_nr, ...)
case __NR_stat: {
const char* name = va_arg(vl, const char*);
struct stat* st = va_arg(vl, struct stat*);
ret = sys_stat(name, st);
break;
}
@ -336,17 +460,14 @@ int syscall_handler(uint32_t sys_nr, ...)
int fd = va_arg(vl, int);
const char* buf = va_arg(vl, const char*);
size_t len = va_arg(vl, size_t);
if (fd >= 0)
ret = read_fs(per_core(current_task)->fildes_table[fd],
(uint8_t*)buf, len);
ret = sys_read(fd, buf, len);
break;
}
case __NR_lseek: {
int fd = va_arg(vl, int);
off_t pos = va_arg(vl, off_t);
int origin = va_arg(vl, int);
if (fd >= 0)
ret = sys_lseek(fd, pos, origin);
ret = sys_lseek(fd, pos, origin);
break;
}
case __NR_sbrk: {