ext2_get_ino_metablock() will allocate blocks
[akaros.git] / kern / src / syscall.c
index ba740ed..97165e7 100644 (file)
@@ -30,7 +30,8 @@
 #include <colored_caches.h>
 #include <hashtable.h>
 #include <arch/bitmask.h>
-#include <kfs.h> // eventually replace this with vfs.h
+#include <vfs.h>
+#include <devfs.h>
 #include <smp.h>
 #include <arsc_server.h>
 
@@ -110,6 +111,7 @@ static int sys_cache_buster(struct proc *p, uint32_t num_writes,
                        upage_alloc(p, &a_page[i],1);
                        page_insert(p->env_pgdir, a_page[i], (void*)INSERT_ADDR + PGSIZE*i,
                                    PTE_USER_RW);
+                       page_decref(a_page[i]);
                }
                spin_unlock(&buster_lock);
        }
@@ -230,6 +232,10 @@ static int sys_proc_create(struct proc *p, char *path, size_t path_l,
        if (load_elf(new_p, program))
                goto late_error;
        kref_put(&program->f_kref);
+       /* Connect to stdin, stdout, stderr (part of proc_create()) */
+       assert(insert_file(&new_p->open_files, dev_stdin,  0) == 0);
+       assert(insert_file(&new_p->open_files, dev_stdout, 0) == 1);
+       assert(insert_file(&new_p->open_files, dev_stderr, 0) == 2);
        __proc_ready(new_p);
        pid = new_p->pid;
        kref_put(&new_p->kref); /* give up the reference created in proc_create() */
@@ -345,8 +351,8 @@ static ssize_t sys_fork(env_t* e)
                                page_decref(pp);
                                return -1;
                        }
-
                        pagecopy(page2kva(pp),ppn2kva(PTE2PPN(*pte)));
+                       page_decref(pp);
                } else {
                        assert(PAGE_PAGED_OUT(*pte));
                        /* TODO: (SWAP) will need to either make a copy or CoW/refcnt the
@@ -386,7 +392,6 @@ static ssize_t sys_fork(env_t* e)
        // when the parent dies, or at least decref it
 
        printd("[PID %d] fork PID %d\n",e->pid,env->pid);
-
        return env->pid;
 }
 
@@ -520,43 +525,8 @@ static ssize_t sys_shared_page_alloc(env_t* p1,
                                      int p1_flags, int p2_flags
                                     )
 {
-       /* When we remove/change this, also get rid of page_insert_in_range() */
-       printk("[kernel] the current shared page alloc is deprecated.\n");
-       //if (!VALID_USER_PERMS(p1_flags)) return -EPERM;
-       //if (!VALID_USER_PERMS(p2_flags)) return -EPERM;
-
-       void * COUNT(1) * COUNT(1) addr = user_mem_assert(p1, _addr, sizeof(void *),
-                                                      PTE_USER_RW);
-       struct proc *p2 = pid2proc(p2_id);
-       if (!p2)
-               return -EBADPROC;
-
-       page_t* page;
-       error_t e = upage_alloc(p1, &page,1);
-       if (e < 0) {
-               kref_put(&p2->kref);
-               return e;
-       }
-
-       void* p2_addr = page_insert_in_range(p2->env_pgdir, page,
-                       (void*SNT)UTEXT, (void*SNT)UTOP, p2_flags);
-       if (p2_addr == NULL) {
-               page_free(page);
-               kref_put(&p2->kref);
-               return -EFAIL;
-       }
-
-       void* p1_addr = page_insert_in_range(p1->env_pgdir, page,
-                       (void*SNT)UTEXT, (void*SNT)UTOP, p1_flags);
-       if(p1_addr == NULL) {
-               page_remove(p2->env_pgdir, p2_addr);
-               page_free(page);
-               kref_put(&p2->kref);
-               return -EFAIL;
-       }
-       *addr = p1_addr;
-       kref_put(&p2->kref);
-       return ESUCCESS;
+       printk("[kernel] shared page alloc is deprecated/unimplemented.\n");
+       return -1;
 }
 
 static int sys_shared_page_free(env_t* p1, void*DANGEROUS addr, pid_t p2)
@@ -835,7 +805,7 @@ static intreg_t sys_open(struct proc *p, const char *path, size_t path_l,
        user_memdup_free(p, t_path);
        if (!file)
                return -1;
-       fd = insert_file(&p->open_files, file); /* stores the ref to file */
+       fd = insert_file(&p->open_files, file, 0);      /* stores the ref to file */
        kref_put(&file->f_kref);
        if (fd < 0) {
                warn("File insertion failed");
@@ -943,13 +913,14 @@ intreg_t sys_fcntl(struct proc *p, int fd, int cmd, int arg)
        }
        switch (cmd) {
                case (F_DUPFD):
-                       printk("[kernel] dup not supported yet\n");
+                       retval = insert_file(&p->open_files, file, arg);
+                       if (retval < 0) {
+                               set_errno(-retval);
+                               retval = -1;
+                       }
                        break;
                case (F_GETFD):
-                       /* GET and SETFD just care about CLOEXEC.  We don't have a separate
-                        * flag variable for the FD (we might need to, technically). */
-                       if (file->f_flags & O_CLOEXEC)
-                               retval = FD_CLOEXEC;
+                       retval = p->open_files.fd[fd].fd_flags;
                        break;
                case (F_SETFD):
                        if (arg == FD_CLOEXEC)
@@ -960,13 +931,14 @@ intreg_t sys_fcntl(struct proc *p, int fd, int cmd, int arg)
                        break;
                case (F_SETFL):
                        /* only allowed to set certain flags. */
-                       arg &= O_APPEND | O_ASYNC | O_DIRECT | O_NOATIME | O_NONBLOCK;
+                       arg &= O_FCNTL_FLAGS;
+                       file->f_flags = (file->f_flags & ~O_FCNTL_FLAGS) | arg;
                        break;
                default:
                        warn("Unsupported fcntl cmd %d\n", cmd);
        }
        kref_put(&file->f_kref);
-       return 0;
+       return retval;
 }
 
 static intreg_t sys_access(struct proc *p, const char *path, size_t path_l,