kernel: ~Stack can grow now (upto 4MB)
[meinos.git] / apps / init / proc.c
blobc9301b483d5b7081df9dc1ee2598a94e154f1971
1 /*
2 meinOS - A unix-like x86 microkernel operating system
3 Copyright (C) 2008 Janosch Gräf <janosch.graef@gmx.net>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <libgen.h>
20 #include <sys/types.h>
21 #include <proc.h>
22 #include <stdlib.h>
23 #include <rpc.h>
24 #include <misc.h>
25 #include <errno.h>
27 #include "init.h"
29 pid_t proc_fork(void *child_entry) {
30 // Create process
31 char *name = getname(rpc_curpid);
32 pid_t pid = proc_create(name,getuidbypid(rpc_curpid),getgidbypid(rpc_curpid),rpc_curpid);
34 if (pid!=-1) {
35 // Copy userspace memory
36 size_t num_pages,i;
37 void **pages = proc_mempagelist(rpc_curpid,&num_pages);
39 if (pages!=NULL) {
40 for (i=0;i<num_pages;i++) {
41 int writable,swappable;
42 void *srcp = proc_memget(rpc_curpid,pages[i],NULL,&writable,&swappable,NULL);
44 if (srcp!=NULL) {
45 // Map parent's page to init
46 void *srcv = proc_memmap(1,NULL,srcp,0,0,0);
48 // Allocate child's page in init's addrspace
49 void *dstv = proc_memmap(1,NULL,NULL,1,0,0);
50 void *dstp = mem_getphysaddr(dstv);
52 // Map child's page to child
53 proc_memmap(pid,pages[i],dstp,writable,swappable,0);
55 // Copy
56 memcpy(dstv,srcv,PAGE_SIZE);
58 proc_memunmap(1,srcv);
59 proc_memunmap(1,dstv);
61 else proc_memmap(pid,pages[i],NULL,writable,swappable,0);
65 // Set stack (we already created one by copying address space)
66 int *stack = proc_getstack(rpc_curpid);
67 proc_setstack(pid,stack);
69 // Set entrypoint of child
70 proc_jump(pid,child_entry);
73 return pid;
76 int proc_exec(const char *file,int var) {
77 // Change process
78 char *_file = strdup(file);
79 proc_setname(rpc_curpid,basename(_file));
80 free(_file);
81 proc_setvar(rpc_curpid,var);
83 // Load executable
84 exe_t *exe = exe_create(file);
85 if (exe!=NULL) {
86 // Remove old addrspace
87 size_t num_pages,i;
88 void **pages = proc_mempagelist(rpc_curpid,&num_pages);
89 if (pages!=NULL) {
90 for (i=0;i<num_pages;i++) proc_memfree(rpc_curpid,pages[i]);
93 void *entrypoint = exe_load(exe,rpc_curpid);
95 if (entrypoint!=NULL) {
96 proc_createstack(rpc_curpid);
97 proc_jump(rpc_curpid,entrypoint);
99 else {
100 dbgmsg("failed loading executable!");
101 dbgmsg("TODO: destroy process\n");
102 while (1);
105 exe_destroy(exe);
106 return 0;
108 else return errno;