Support to multi-threading and pthread interface (POSIX.1-2008) (#23)
[lunaix-os.git] / lunaix-os / kernel / process / process.c
1 #include <klibc/string.h>
2 #include <lunaix/clock.h>
3 #include <lunaix/mm/mmap.h>
4 #include <lunaix/mm/vmm.h>
5 #include <lunaix/mm/region.h>
6 #include <lunaix/mm/valloc.h>
7 #include <lunaix/process.h>
8 #include <lunaix/spike.h>
9 #include <lunaix/status.h>
10 #include <lunaix/syscall.h>
11 #include <lunaix/syslog.h>
12 #include <lunaix/exec.h>
13 #include <lunaix/fs.h>
14
15 #include <sys/abi.h>
16 #include <sys/mm/mm_defs.h>
17
18 LOG_MODULE("PROC")
19
20 __DEFINE_LXSYSCALL(pid_t, getpid)
21 {
22     return __current->pid;
23 }
24
25 __DEFINE_LXSYSCALL(pid_t, getppid)
26 {
27     return __current->parent->pid;
28 }
29
30 __DEFINE_LXSYSCALL(pid_t, getpgid)
31 {
32     return __current->pgid;
33 }
34
35 __DEFINE_LXSYSCALL2(int, setpgid, pid_t, pid, pid_t, pgid)
36 {
37     struct proc_info* proc = pid ? get_process(pid) : __current;
38
39     if (!proc) {
40         syscall_result(EINVAL);
41         return -1;
42     }
43
44     pgid = pgid ? pgid : proc->pid;
45
46     struct proc_info* gruppenfuhrer = get_process(pgid);
47
48     if (!gruppenfuhrer || proc->pgid == gruppenfuhrer->pid) {
49         syscall_result(EINVAL);
50         return -1;
51     }
52
53     llist_delete(&proc->grp_member);
54     llist_append(&gruppenfuhrer->grp_member, &proc->grp_member);
55
56     proc->pgid = pgid;
57     return 0;
58 }
59
60 int
61 spawn_process(struct thread** created, ptr_t entry, bool with_ustack) 
62 {
63     struct proc_info* kproc = alloc_process();
64
65     procvm_init_clean(kproc);
66
67     vmm_mount_pd(VMS_MOUNT_1, vmroot(kproc));
68     
69     struct thread* kthread = create_thread(kproc, VMS_MOUNT_1, with_ustack);
70
71     if (!kthread) {
72         vmm_unmount_pd(VMS_MOUNT_1);
73         delete_process(kproc);
74         return -1;
75     }
76
77     commit_process(kproc);
78     start_thread(kthread, VMS_MOUNT_1, entry);
79
80     vmm_unmount_pd(VMS_MOUNT_1);
81
82     if (created) {
83         *created = kthread;
84     }
85
86     return 0;
87 }
88
89 int
90 spawn_process_usr(struct thread** created, char* path, 
91                     const char** argv, const char** envp)
92 {
93     // FIXME remote injection of user stack not yet implemented
94
95     struct proc_info* proc = alloc_process();
96     
97     assert(!kernel_process(proc));
98
99     procvm_init_clean(proc);
100
101     vmm_mount_pd(VMS_MOUNT_1, vmroot(proc));
102
103     int errno = 0;
104     struct thread* main_thread;
105     if (!(main_thread = create_thread(proc, VMS_MOUNT_1, true))) {
106         errno = ENOMEM;
107         goto fail;
108     }
109
110     struct exec_container container;
111     exec_init_container(&container, main_thread, VMS_MOUNT_1, argv, envp);
112     if ((errno = exec_load_byname(&container, path))) {
113         goto fail;
114     }
115
116     commit_process(proc);
117     start_thread(main_thread, VMS_MOUNT_1, container.exe.entry);
118
119     if (created) {
120         *created = main_thread;
121     }
122
123     vmm_unmount_pd(VMS_MOUNT_1);
124     return 0;
125
126 fail:
127     vmm_unmount_pd(VMS_MOUNT_1);
128     delete_process(proc);
129     return errno;
130 }
131
132
133 ptr_t proc_vmroot() {
134     return __current->mm->vmroot;
135 }