Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
script3r
GitHub Repository: script3r/os161
Path: blob/master/kern/syscall/waitpid.c
2093 views
1
#include <types.h>
2
#include <lib.h>
3
#include <kern/errno.h>
4
#include <kern/wait.h>
5
#include <proc.h>
6
#include <copyinout.h>
7
#include <file.h>
8
#include <filedesc.h>
9
#include <thread.h>
10
#include <current.h>
11
#include <syscall.h>
12
13
int
14
___waitpid( int pid, int *retval, int options ) {
15
struct proc *p = NULL;
16
int err;
17
18
KASSERT( curthread != NULL );
19
KASSERT( curthread->td_proc != NULL );
20
21
//we only support WNOHANG and nothing else.
22
if( options != 0 && options != WNOHANG )
23
return EINVAL;
24
25
//get the process associated with the given pid
26
err = proc_get( pid, &p );
27
if( err )
28
return err;
29
30
//make sure that we are the parent of that process
31
//otherwise we are collecting an the exit code of a process
32
//whose parent might still be interested in.
33
if( p->p_proc != curthread->td_proc ) {
34
PROC_UNLOCK( p );
35
return ECHILD;
36
}
37
38
//if WNOHANG was given, and said process is not yet dead
39
//we immediately, (successfully) return with a value of 0.
40
if( !p->p_is_dead && (options == WNOHANG) ) {
41
PROC_UNLOCK( p );
42
*retval = 0;
43
return 0;
44
}
45
46
//unlock the process, so the child potentially makes progress.
47
//then, consume a signal from the child's semaphore.
48
PROC_UNLOCK( p );
49
P( p->p_sem );
50
PROC_LOCK( p );
51
52
//at this point the child should be certainly dead.
53
KASSERT( p->p_is_dead );
54
55
//copy its exit code to the userland.
56
*retval = _MKWAIT_EXIT(p->p_retval);
57
58
//unlock and destroy.
59
PROC_UNLOCK( p );
60
proc_destroy( p );
61
62
return 0;
63
64
}
65
66
int
67
sys_waitpid( int pid, userptr_t uret, int options, int *retval ) {
68
int kstatus;
69
int err;
70
71
err = ___waitpid( pid, &kstatus, options );
72
if( err )
73
return err;
74
75
//copy its exit code to the userland.
76
err = copyout( &kstatus, uret, sizeof( int ) );
77
78
//if we had an error copying out, we will return
79
//an efault, but we still must destroy the associated
80
//proc since the child is essentially dead.
81
if( err )
82
return err;
83
84
*retval = pid;
85
return 0;
86
}
87
88