AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
sys_proc.c
Go to the documentation of this file.
1
7
8#include "syscalls.h"
9
16long sys_exit(int code)
17{
18 syscall_log(LOG_DEBUG, "exit(code=%d)\n", code);
19
20 struct proc *owner = curproc;
21
22 owner->exit = PROC_EXIT(code, 0); /* exited normally, not by a signal */
23
24 proc_kill(owner);
25 arch_sleep();
26
27 /* not reached: the process is gone, this thread with it */
28 for (;;);
29 return 0;
30}
31
42long sys_execve(const char *path, char * const argp[], char * const envp[])
43{
44 syscall_log(LOG_DEBUG, "execve(path=%p, argp=%p, envp=%p)\n", path, argp, envp);
45
46 char *fn;
47 int err = upath_get(path, &fn);
48
49 if (err) {
50 return err;
51 }
52
53 if (!*fn) {
54 kfree(fn);
55 return -ENOENT;
56 }
57
58 err = proc_execve(curthread, fn, argp, envp);
59
60 kfree(fn);
61
62 if (err)
63 return err;
64
65 /* start the new program, from its entry point: no return from here */
67 return 0;
68}
69
76long sys_fork(void)
77{
78 syscall_log(LOG_DEBUG, "fork()\n");
79
80 struct proc *fork = NULL;
81 int err = proc_fork(curthread, &fork);
82
83 if (err) {
84 return err;
85 }
86
87 /* the child runs from fork()'s return, where it gets 0
88 * (proc_fork()) */
89 struct thread *thread = (struct thread *) fork->threads.head->value;
91
92 return fork->pid;
93}
94
100long sys_getpid(void)
101{
102 syscall_log(LOG_DEBUG, "getpid()\n");
103 return curproc->pid;
104}
105
115{
116 syscall_log(LOG_DEBUG, "sbrk(incr=0x%x)\n", incr);
117
118 uintptr_t heap_start = curproc->heap_start;
119 uintptr_t heap = curproc->heap;
120
121 /* the heap may grow up to the next mapped region (or the stack) */
122 uintptr_t heap_limit = USER_STACK_BASE;
123 struct qnode *next = curproc->heap_vm->qnode->next;
124
125 if (next)
126 heap_limit = ((struct vm_entry *) next->value)->base;
127
128 if ((incr < 0 && (uintptr_t) -incr > heap - heap_start) ||
129 (incr > 0 && (heap_limit < heap || (uintptr_t) incr > heap_limit - heap))) {
130 /* the C library passes the result through and only treats
131 * (void *) -1 as a failure, so return that instead of -ENOMEM */
132 return (uintptr_t) -1;
133 }
134
135 curproc->heap = heap + incr;
136 curproc->heap_vm->size = PAGE_ROUND(heap + incr - heap_start);
137
138 return heap;
139}
140
148long sys_times(struct aquila_tms *buf)
149{
150 syscall_log(LOG_DEBUG, "times(buf=%p)\n", buf);
151
152 const uint64_t tick = 1000000000ULL / AQUILA_CLK_TCK; /* ns */
153
154 struct aquila_tms tms = {
155 .tms_utime = curproc->utime / tick,
156 .tms_stime = curproc->stime / tick,
157 .tms_cutime = curproc->cutime / tick,
158 .tms_cstime = curproc->cstime / tick,
159 };
160
161 if (copyout(buf, &tms, sizeof(tms))) {
162 return -EFAULT;
163 }
164
165 /* the real time elapsed since boot */
166 return (uint32_t) (arch_rtime_ns() / tick);
167}
168
181long sys_waitpid(int pid, int *stat_loc, int options)
182{
183 syscall_log(LOG_DEBUG, "waitpid(pid=%d, stat_loc=%p, options=0x%x)\n", pid, stat_loc, options);
184
185 /* pid > 0: that child
186 * pid == -1: any child
187 * pid == 0: any child in the caller's process group
188 * pid < -1: any child in the process group -pid */
189 pid_t pgid = pid == 0 ? curproc->pgrp->pgid : -pid;
190
191 for (;;) {
192 int found = 0;
193
194 queue_for (node, procs) {
195 struct proc *proc = node->value;
196 int status, event = 0;
197
198 if (proc->parent != curproc)
199 continue;
200
201 if (pid > 0 ? proc->pid != pid : pid != -1 && proc->pgrp->pgid != pgid)
202 continue;
203
204 found = 1;
205
206 if (proc->zombie) {
207 status = proc->exit;
208 } else if ((options & WUNTRACED) && (proc->wait_event & WAIT_STOPPED)) {
209 event = WAIT_STOPPED;
210 status = (proc->stopped << 8) | 0x7f;
211 } else if ((options & WCONTINUED) && (proc->wait_event & WAIT_CONTINUED)) {
212 event = WAIT_CONTINUED;
213 status = 0xffff;
214 } else {
215 continue;
216 }
217
218 /* if the status can't be written out, nothing is consumed: a
219 * zombie, or a stop or continue event, stays to be waited for
220 * again */
221 if (stat_loc && copyout(stat_loc, &status, sizeof(status))) {
222 return -EFAULT;
223 }
224
225 proc->wait_event &= ~event;
226
227 pid_t child = proc->pid;
228
229 if (proc->zombie)
231
232 return child;
233 }
234
235 if (!found) {
236 return -ECHILD;
237 }
238
239 if (options & WNOHANG) {
240 return 0;
241 }
242
243 if (waitq_sleep(&curproc->wait_queue)) {
244 return -ERESTARTSYS;
245 }
246 }
247}
248
249/* the host name: set by sethostname(), shown by uname() */
250static char nodename[sizeof(((struct utsname *) 0)->nodename)] = UTSNAME_NODENAME;
251
259long sys_uname(struct utsname *name)
260{
261 syscall_log(LOG_DEBUG, "uname(name=%p)\n", name);
262
263 struct utsname u;
264 memset(&u, 0, sizeof(u));
265
266 strcpy(u.sysname, UTSNAME_SYSNAME);
267 strcpy(u.nodename, nodename);
268 strcpy(u.release, UTSNAME_RELEASE);
269 /* the compiler's version string may be long */
270 size_t n = MIN(sizeof(u.version) - 1, (size_t) strlen(UTSNAME_VERSION));
271 memcpy(u.version, UTSNAME_VERSION, n);
272 strcpy(u.machine, UTSNAME_MACHINE);
273
274 return copyout(name, &u, sizeof(u));
275}
276
286long sys_thread_create(struct aquila_thread_args *__uthread)
287{
288 struct aquila_thread_args a;
289
290 if (copyin(&a, __uthread, sizeof(a))) {
291 return -EFAULT;
292 }
293
294 syscall_log(LOG_DEBUG,
295 "thread_create(stack=%p, entry=%p, uentry=%p, arg=%p, attr=%p)\n",
296 a.stack, a.entry, a.uentry, a.arg, a.attr);
297
298 uintptr_t stack = a.stack;
299
300 /* the kernel pushes the initial frame (3 words) on the user stack */
301 if (stack < 3 * sizeof(uintptr_t) ||
302 uaccess_check((void *) (stack - 3 * sizeof(uintptr_t)), 3 * sizeof(uintptr_t))) {
303 return -EFAULT;
304 }
305
306 int err = 0;
307 struct thread *thread = NULL;
308
309 if ((err = thread_create(curthread, stack, a.entry, a.uentry, a.arg, a.attr, &thread))) {
310 return err;
311 }
312
314 return thread->tid;
315}
316
325long sys_thread_exit(void *value_ptr)
326{
327 syscall_log(LOG_DEBUG, "thread_exit(value_ptr=%p)\n", value_ptr);
328
329 curthread->exit_value = value_ptr;
330 struct proc *owner = curproc;
331
332 /* the last live thread ending ends the process */
333 int alive = 0;
334 queue_for (node, &owner->threads) {
335 struct thread *thread = node->value;
336 if (thread != curthread && thread->state != ZOMBIE)
337 ++alive;
338 }
339
340 if (!alive)
341 sys_exit(0);
342
343 /* wake up the threads waiting to join one */
345
346 /* The thread stays on its process's list as a zombie, freed by
347 * thread_join() or when the process ends. Its kernel stack, which this
348 * runs on, is freed from the idle stack by arch_cur_thread_kill(). */
349 curthread->state = ZOMBIE;
351
352 /* not reached: the thread is gone */
353 for (;;);
354 return 0;
355}
356
367long sys_thread_join(int tid, void **value_ptr)
368{
369 syscall_log(LOG_DEBUG, "thread_join(tid=%d, value_ptr=%p)\n", tid, value_ptr);
370
371 struct proc *owner = curproc;
372 struct thread *thread = NULL;
373
374 queue_for (node, &owner->threads) {
375 struct thread *_thread = node->value;
376 if (_thread->tid == tid)
377 thread = _thread;
378 }
379
380 /* no such thread, or it was joined already */
381 if (!thread) {
382 return -ESRCH;
383 }
384
385 /* a thread joining itself would wait forever */
386 if (thread == curthread) {
387 return -EDEADLK;
388 }
389
390 while (thread->state != ZOMBIE) {
391 if (waitq_sleep(&curproc->thread_join)) {
392 return -ERESTARTSYS;
393 }
394 }
395
396 if (value_ptr && copyout(value_ptr, &thread->exit_value, sizeof(void *))) {
397 return -EFAULT;
398 }
399
400 /* free what is left of it: thread_exit() freed the rest, and its CPU
401 * is done with it, since it let go of the kernel lock */
402 int joined = thread->tid;
403 queue_remove(&owner->threads, thread);
404 kfree(thread);
405
406 return joined;
407}
408
418long sys_setpgid(pid_t pid, pid_t pgid)
419{
420 syscall_log(LOG_DEBUG, "setpgid(pid=%d, pgid=%d)\n", pid, pgid);
421
422 if (pgid < 0) {
423 return -EINVAL;
424 }
425
426 /* only the caller or one of its children */
427 struct proc *proc = pid ? proc_pid_find(pid) : curproc;
428
429 if (!proc || (proc != curproc && proc->parent != curproc)) {
430 return -ESRCH;
431 }
432
433 struct session *session = proc->pgrp->session;
434
435 /* a session leader can't change its group, nor can a process outside
436 * the caller's session */
437 if (session != curproc->pgrp->session || session->leader == proc) {
438 return -EPERM;
439 }
440
441 return proc_setpgid(proc, pgid ? pgid : proc->pid);
442}
443
452{
453 syscall_log(LOG_DEBUG, "setuid(uid=%d)\n", uid);
454
455 if (curproc->uid != 0 && uid != curproc->uid) {
456 return -EPERM;
457 }
458
459 curproc->uid = uid;
460 return 0;
461}
462
471{
472 syscall_log(LOG_DEBUG, "setgid(gid=%d)\n", gid);
473
474 if (curproc->uid != 0 && gid != curproc->gid) {
475 return -EPERM;
476 }
477
478 curproc->gid = gid;
479 return 0;
480}
481
487long sys_getuid(void)
488{
489 syscall_log(LOG_DEBUG, "getuid()\n");
490 return curproc->uid;
491}
492
498long sys_getgid(void)
499{
500 syscall_log(LOG_DEBUG, "getgid()\n");
501 return curproc->gid;
502}
503
514long sys_mmap(struct aquila_mmap_args *uargs, void **ret)
515{
516 struct aquila_mmap_args _args, *args = &_args;
517 void *none = NULL;
518
519 /* the address is written out at the end: check first that it can be */
520 if (copyin(args, uargs, sizeof(*args)) || copyout(ret, &none, sizeof(none))) {
521 return -EFAULT;
522 }
523
524 syscall_log(LOG_DEBUG, "mmap(addr=%p, len=%d, prot=%x, flags=%x, fildes=%d, off=%d, ret=%p)\n",
525 args->addr, args->len, args->prot, args->flags, args->fildes, args->off, ret);
526
527 int err = 0;
528 int anon = args->flags & MAP_ANONYMOUS;
529
530 /* anonymous memory is the process's own (fork() copies it), so it
531 * can't be shared */
532 if (anon && (args->flags & MAP_SHARED)) {
533 return -EINVAL;
534 }
535
536 struct file *file = anon ? NULL : fd_file(args->fildes);
537
538 if (!anon && !file) { /* the descriptor isn't open */
539 return -EBADF;
540 }
541
542 if (file && (file->flags & FILE_SOCKET)) {
543 return -ENODEV;
544 }
545
546 if (!args->len) {
547 return -EINVAL;
548 }
549
550 /* a fixed mapping must start on a page, and lie entirely in user
551 * space */
552 if ((args->flags & MAP_FIXED) && (((uintptr_t) args->addr & PAGE_MASK) ||
553 uaccess_check(args->addr, args->len))) {
554 return -EINVAL;
555 }
556
557 /* the mapping */
558 struct vm_entry *vm_entry;
560
561 if (vm_entry == NULL) {
562 err = -ENOMEM;
563 goto error;
564 }
565
566 vm_entry->base = (uintptr_t) args->addr;
567 vm_entry->size = PAGE_ROUND(args->len);
568 vm_entry->flags = args->prot & PROT_READ ? VM_UR : 0;
569 vm_entry->flags |= args->prot & PROT_WRITE ? VM_UW : 0;
570 vm_entry->flags |= args->prot & PROT_EXEC ? VM_UX : 0;
571 vm_entry->flags |= args->flags & MAP_SHARED ? VM_SHARED : 0;
572 vm_entry->off = anon ? 0 : args->off;
573
574 /* without an object, pages are zero-filled when first touched */
575 vm_entry->vm_object = anon ? NULL : vm_object_vnode(file->vnode);
576
577 if (!anon && !vm_entry->vm_object) {
578 err = -ENOMEM;
579 goto error;
580 }
581
582 if (vm_entry->vm_object)
584
585 if (!(args->flags & MAP_FIXED))
586 vm_entry->base = 0; /* vm_space_insert() chooses the address */
587
588 struct vm_space *vm_space = &curproc->vm_space;
589 if ((err = vm_space_insert(vm_space, vm_entry)))
590 goto error;
591
592 if (!anon && !(args->flags & MAP_PRIVATE) && (err = vfs_map(vm_space, vm_entry)))
593 goto error;
594
595 void *addr = (void *) vm_entry->base;
596 err = copyout(ret, &addr, sizeof(addr));
597
598 return err;
599
600error:
601 if (vm_entry) {
602 if (vm_entry->qnode)
603 queue_node_remove(&curproc->vm_space.vm_entries, vm_entry->qnode);
604
605 if (vm_entry->vm_object)
607
609 }
610
611 return err;
612}
613
622long sys_munmap(void *addr, size_t len)
623{
624 syscall_log(LOG_DEBUG, "munmap(addr=%p, len=%d)\n", addr, len);
625
626 struct vm_space *vm_space = &curproc->vm_space;
627
628 if (!len) {
629 return -EINVAL;
630 }
631
632 queue_for (node, &vm_space->vm_entries) {
633 struct vm_entry *vm_entry = node->value;
634
635 /* the heap and the stack are the kernel's to manage (sbrk() and
636 * exec) */
637 if (vm_entry == curproc->heap_vm || vm_entry == curproc->stack_vm)
638 continue;
639
640 if (vm_entry->base == (uintptr_t) addr && vm_entry->size == PAGE_ROUND(len)) {
641 queue_node_remove(&vm_space->vm_entries, vm_entry->qnode);
645 return 0;
646 }
647 }
648
649 /* no such mapping */
650 return -EINVAL;
651}
652
659long sys_sysconf(int name)
660{
661 syscall_log(LOG_DEBUG, "sysconf(name=%d)\n", name);
662 return -ENOSYS;
663}
664
670long sys_getppid(void)
671{
672 syscall_log(LOG_DEBUG, "getppid()\n");
673
674 /* orphans are init's; init and the kernel's process have no parent */
675 return curproc->parent ? curproc->parent->pid : 0;
676}
677
683long sys_getpgrp(void)
684{
685 syscall_log(LOG_DEBUG, "getpgrp()\n");
686 return curproc->pgrp->pgid;
687}
688
698long sys_getrandom(void *buf, size_t len, unsigned flags __unused)
699{
700 if (uaccess_check(buf, len)) {
701 return -EFAULT;
702 }
703
704 /* a piece at a time, through a buffer on the stack */
705 uint8_t kbuf[256];
706 size_t done = 0;
707
708 while (done < len) {
709 size_t n = MIN(len - done, sizeof(kbuf));
710 random_get(kbuf, n);
711
712 if (copyout((char *) buf + done, kbuf, n))
713 break;
714
715 done += n;
716 }
717
718 memset(kbuf, 0, sizeof(kbuf));
719 return done || !len ? (ssize_t) done : -EFAULT;
720}
721
728{
729 return curthread->tid;
730}
731
740long sys_reboot(unsigned cmd)
741{
742 syscall_log(LOG_DEBUG, "reboot(cmd=0x%x)\n", cmd);
743
744 if (curproc->uid) {
745 return -EPERM;
746 }
747
748 return kernel_reboot(cmd);
749}
750
758long sys_setsid(void)
759{
760 syscall_log(LOG_DEBUG, "setsid()\n");
761
762 struct proc *proc = curproc;
763 struct pgroup *pgrp = proc->pgrp;
764 struct qnode *pgrp_node = proc->pgrp_node;
765
766 /* a group leader can't leave its group: the group would be in two
767 * sessions */
768 if (pgrp->pgid == proc->pid) {
769 return -EPERM;
770 }
771
772 int ret = session_new(proc);
773
774 if (ret) {
775 proc->pgrp = pgrp;
776 proc->pgrp_node = pgrp_node;
777 return ret;
778 }
779
780 queue_node_remove(pgrp->procs, pgrp_node);
781 pgrp_release(pgrp);
782 return proc->pid;
783}
784
793long sys_sethostname(const char *name, size_t len)
794{
795 syscall_log(LOG_DEBUG, "sethostname(name=%p, len=%d)\n", name, len);
796
797 if (curproc->uid != 0) {
798 return -EPERM;
799 }
800
801 if (len >= sizeof(nodename)) {
802 return -EINVAL;
803 }
804
805 char name_in[sizeof(nodename)];
806
807 if (copyin(name_in, name, len)) {
808 return -EFAULT;
809 }
810
811 memcpy(nodename, name_in, len);
812 nodename[len] = '\0';
813 return 0;
814}
#define UTSNAME_MACHINE
Definition config.h:9
#define USER_STACK_BASE
Definition arch.h:61
#define PAGE_MASK
Definition system.h:8
void arch_sleep(void)
Puts the current thread to sleep.
Definition sched.c:101
void arch_cur_thread_kill(void)
Ends the current thread.
Definition sched.c:87
struct vm_object * vm_object_vnode(struct vnode *vnode)
Gets a vnode's vm object, making it the first time.
Definition vm_object.c:31
#define UTSNAME_VERSION
Definition config.h:41
#define UTSNAME_SYSNAME
Definition config.h:37
#define UTSNAME_RELEASE
Definition config.h:38
#define UTSNAME_NODENAME
Definition config.h:39
#define MIN(a, b)
Definition system.h:11
#define PAGE_ROUND(ptr)
Definition mm.h:10
void kfree(void *)
Frees an object that kmalloc() gave.
Definition kvmem.c:146
void * memset(void *dst, int c, size_t n)
Sets n bytes to c.
Definition libc.c:23
void * memcpy(void *dst, const void *src, size_t n)
Copies n bytes; dst and src must not overlap.
Definition libc.c:11
#define LOG_DEBUG
Definition printk.h:19
int proc_reap(struct proc *proc)
Frees a zombie, once its parent waited for it (or doesn't wait for its children).
Definition proc.c:484
int proc_fork(struct thread *thread, struct proc **ref)
Makes a child process, a copy of the process of thread.
Definition fork.c:81
int proc_execve(struct thread *thread, const char *fn, char *const argv[], char *const env[])
Runs another program in a thread's process, for execve().
Definition execve.c:358
#define PROC_EXIT(info, code)
Definition proc.h:207
struct proc * proc_pid_find(pid_t pid)
Finds a process by its ID.
Definition proc.c:179
int session_new(struct proc *proc)
Makes a new session, with a new process group, both led by a process and with its ID,...
Definition proc.c:596
int proc_setpgid(struct proc *proc, pid_t pgid)
Moves a process into a process group of its session, as setpgid() does.
Definition proc.c:667
struct queue * procs
Definition proc.c:37
void proc_kill(struct proc *proc)
Ends a process: its threads end, its descriptors are closed, its memory is freed, its children go to ...
Definition proc.c:375
void pgrp_release(struct pgroup *pgrp)
Frees a process group if no process is left in it, and its session if that was the session's last gro...
Definition proc.c:742
#define queue_for(n, q)
Definition queue.h:37
void random_get(void *_buf, size_t len)
Fills a buffer with random bytes.
Definition random.c:93
int kernel_reboot(unsigned cmd)
Carries out a reboot() command.
Definition reboot.c:29
#define curproc
Definition sched.h:13
#define curthread
Definition sched.h:12
void sched_thread_ready(struct thread *thread)
Puts a thread at the end of the ready list, to run in its turn.
Definition sched.c:298
void sched_thread_spawn(struct thread *thread)
Starts running a thread for the first time.
Definition sched.c:361
#define WAIT_STOPPED
Definition signal.h:67
#define WAIT_CONTINUED
Definition signal.h:68
#define ERESTARTSYS
Definition signal.h:81
#define FILE_SOCKET
Definition socket.h:70
#define NULL
Definition stddef.h:27
__SIZE_TYPE__ uintptr_t
Definition stddef.h:12
unsigned int uint32_t
Definition stddef.h:22
__PTRDIFF_TYPE__ ptrdiff_t
Definition stddef.h:10
unsigned char uint8_t
Definition stddef.h:20
unsigned long long int uint64_t
Definition stddef.h:23
An open file (POSIX's "open file description", fs/file.c).
Definition vfs.h:157
int flags
Definition vfs.h:164
A process group: the processes of a job.
Definition proc.h:56
struct queue * procs
its processes
Definition proc.h:67
struct session * session
its session
Definition proc.h:61
pid_t pgid
the group's ID
Definition proc.h:58
A process.
Definition proc.h:75
pid_t pid
the process's ID
Definition proc.h:77
struct proc * parent
its parent
Definition proc.h:90
struct qnode * pgrp_node
Definition proc.h:81
struct waitq thread_join
threads waiting in thread_join() sleep here
Definition proc.h:143
int exit
its exit status (PROC_EXIT())
Definition proc.h:160
int stopped
the signal that stopped it, or 0; and what waitpid() has to report (WAIT_*)
Definition proc.h:100
struct queue threads
its threads
Definition proc.h:136
struct pgroup * pgrp
its process group, and its node on the group's list
Definition proc.h:80
int wait_event
Definition proc.h:101
int zombie
proc_kill() is done with it, so it can be reaped (that isn't as soon as it stops running: closing its...
Definition proc.h:167
A queue's node, holding one entry.
Definition queue.h:19
void * value
Definition queue.h:20
struct qnode * next
Definition queue.h:22
struct qnode * head
Definition queue.h:31
A session: its process groups, and its controlling terminal.
Definition proc.h:26
struct proc * leader
its leader, the process that made it
Definition proc.h:34
A thread.
Definition thread.h:23
state_t state
its state
Definition thread.h:28
tid_t tid
the thread's ID, in its process
Definition thread.h:25
uintptr_t stack
its user stack
Definition thread.h:39
struct proc * owner
its process
Definition thread.h:31
void * exit_value
what the thread exited with (thread_exit()), for thread_join()
Definition thread.h:58
A mapping (map entry): a range of an address space, its permissions, and where its pages come from.
Definition vm.h:66
uint32_t flags
its permissions and flags (VM_*)
Definition vm.h:78
size_t off
where the mapping starts in its object
Definition vm.h:87
vaddr_t base
where the mapping starts in its address space
Definition vm.h:72
struct vm_object * vm_object
its object: what its other pages come from (a file)
Definition vm.h:84
struct qnode * qnode
its node in its address space's list of mappings
Definition vm.h:90
size_t size
its size
Definition vm.h:75
An address space: its mappings, and its page tables.
Definition vm.h:25
struct queue vm_entries
its mappings (map entries), in address order
Definition vm.h:30
struct file * fd_file(int fd)
Finds the open file that a descriptor of the current process refers to, and holds it until the system...
Definition syscall.c:22
int upath_get(const char *upath, char **path)
Copies a path from user memory into a new kernel buffer.
Definition syscall.c:46
long sys_setuid(uid_t uid)
Implements setuid(): sets the process's user ID.
Definition sys_proc.c:451
long sys_uname(struct utsname *name)
Implements uname(): the system's name, release, version and machine, and the host name.
Definition sys_proc.c:259
long sys_thread_self(void)
Returns the calling thread's ID, for pthread_self().
Definition sys_proc.c:727
long sys_setgid(gid_t gid)
Implements setgid(): sets the process's group ID.
Definition sys_proc.c:470
long sys_getgid(void)
Implements getgid().
Definition sys_proc.c:498
long sys_getpid(void)
Implements getpid().
Definition sys_proc.c:100
long sys_setpgid(pid_t pid, pid_t pgid)
Implements setpgid(): moves a process (the caller or one of its children) into a process group of its...
Definition sys_proc.c:418
long sys_getpgrp(void)
Implements getpgrp().
Definition sys_proc.c:683
long sys_sethostname(const char *name, size_t len)
Implements sethostname().
Definition sys_proc.c:793
long sys_thread_exit(void *value_ptr)
Ends the calling thread (for pthread_exit()).
Definition sys_proc.c:325
static char nodename[sizeof(((struct utsname *) 0) ->nodename)]
Definition sys_proc.c:250
long sys_getrandom(void *buf, size_t len, unsigned flags)
Implements getrandom() (and the C library's getentropy()): fills a buffer with random bytes.
Definition sys_proc.c:698
long sys_fork(void)
Implements fork(): makes a child process, a copy of the caller.
Definition sys_proc.c:76
long sys_setsid(void)
Implements setsid(): makes the calling process the leader of a new session and process group.
Definition sys_proc.c:758
long sys_munmap(void *addr, size_t len)
Implements munmap(): removes a mapping.
Definition sys_proc.c:622
long sys_mmap(struct aquila_mmap_args *uargs, void **ret)
Implements mmap(): maps anonymous memory or a file into the calling process.
Definition sys_proc.c:514
long sys_sbrk(ptrdiff_t incr)
Implements sbrk(): grows or shrinks the heap.
Definition sys_proc.c:114
long sys_times(struct aquila_tms *buf)
Implements times(): the CPU times of the process and of its children that it waited for,...
Definition sys_proc.c:148
long sys_thread_create(struct aquila_thread_args *__uthread)
Makes a new thread in the calling process (for pthread_create()), and makes it ready to run.
Definition sys_proc.c:286
long sys_getppid(void)
Implements getppid().
Definition sys_proc.c:670
long sys_waitpid(int pid, int *stat_loc, int options)
Implements waitpid(): waits for a child to end (or stop, or continue, if asked), and reaps it if it e...
Definition sys_proc.c:181
long sys_reboot(unsigned cmd)
Implements reboot(): restarts, halts or powers off the machine, or sets what Ctrl+Alt+Del does.
Definition sys_proc.c:740
long sys_getuid(void)
Implements getuid().
Definition sys_proc.c:487
long sys_thread_join(int tid, void **value_ptr)
Waits for a thread of the calling process to end, and frees it (for pthread_join()).
Definition sys_proc.c:367
long sys_execve(const char *path, char *const argp[], char *const envp[])
Implements execve(): runs another program in the calling process.
Definition sys_proc.c:42
long sys_sysconf(int name)
Implements sysconf(): not supported; the C library answers it.
Definition sys_proc.c:659
long sys_exit(int code)
Implements _exit(): ends the calling process.
Definition sys_proc.c:16
static void options(const struct tcp_hdr *th, size_t hlen, struct seg *s)
Reads a segment's options; the only one used is the MSS.
Definition tcp_input.c:36
int thread_create(struct thread *thread, uintptr_t stack, uintptr_t entry, uintptr_t uentry, uintptr_t arg, uintptr_t attr, struct thread **new_thread)
Makes a new thread in the process of an existing one, for pthread_create().
Definition thread.c:86
@ ZOMBIE
Definition thread.h:19
uint64_t arch_rtime_ns(void)
Reads the monotonic clock, which starts at boot.
Definition timer.c:56
static void(*) tick(void)
Definition timer.c:17
int pid_t
Definition types.h:8
long int ssize_t
Definition types.h:12
uint32_t gid_t
Definition types.h:21
uint32_t uid_t
Definition types.h:20
static int uaccess_check(const void *ptr, size_t len)
Checks that [ptr, ptr + len) is in user space.
Definition uaccess.h:27
void vm_unmap_full(struct vm_space *vm_space, struct vm_entry *vm_entry)
Unmaps every page of a map entry's range.
Definition vmm.c:42
int vm_space_insert(struct vm_space *vm_space, struct vm_entry *vm_entry)
Adds a map entry to an address space, in address order.
Definition vm_space.c:27
#define VM_UR
user read
Definition vm.h:41
void vm_object_decref(struct vm_object *vm_object)
Drops a reference to a vm object: one mapping of it less.
Definition vm_object.c:38
#define VM_SHARED
shared: a fork doesn't copy it
Definition vm.h:46
void vm_entry_destroy(struct vm_entry *vm_entry)
Releases what a map entry holds: its references to its anon and its object.
Definition vm_entry.c:32
struct vm_entry * vm_entry_new(void)
Makes a new, empty map entry.
Definition vm_entry.c:18
#define VM_UX
user execute
Definition vm.h:43
void vm_object_incref(struct vm_object *vm_object)
Adds a reference to a vm object: one more mapping of it.
Definition vm_object.c:25
#define VM_UW
user write
Definition vm.h:42
int vfs_map(struct vm_space *vm_space, struct vm_entry *vm_entry)
Maps a file into an address space, for mmap(): a device's own mapping, or the filesystem's.
Definition vops.c:205
void waitq_wakeup(struct waitq *waitq)
Wakes up every thread sleeping on a wait queue, and every thread polling it.
Definition waitq.c:178
int waitq_sleep(struct waitq *waitq)
Puts the current thread to sleep on a wait queue until it is woken up.
Definition waitq.c:50