4 #include <minix/callnr.h>
6 #include <minix/config.h>
7 #include <minix/const.h>
9 #include <minix/endpoint.h>
10 #include <minix/keymap.h>
11 #include <minix/minlib.h>
12 #include <minix/type.h>
13 #include <minix/ipc.h>
14 #include <minix/sysutil.h>
15 #include <minix/syslib.h>
16 #include <minix/debug.h>
17 #include <minix/bitmap.h>
28 #include "sanitycheck.h"
32 /*===========================================================================*
34 *===========================================================================*/
35 int do_fork(message
*msg
)
37 int r
, proc
, childproc
;
38 struct vmproc
*vmp
, *vmc
;
42 SANITYCHECK(SCL_FUNCTIONS
);
44 if(vm_isokendpt(msg
->VMF_ENDPOINT
, &proc
) != OK
) {
45 printf("VM: bogus endpoint VM_FORK %d\n", msg
->VMF_ENDPOINT
);
46 SANITYCHECK(SCL_FUNCTIONS
);
50 childproc
= msg
->VMF_SLOTNO
;
51 if(childproc
< 0 || childproc
>= NR_PROCS
) {
52 printf("VM: bogus slotno VM_FORK %d\n", msg
->VMF_SLOTNO
);
53 SANITYCHECK(SCL_FUNCTIONS
);
57 vmp
= &vmproc
[proc
]; /* parent */
58 vmc
= &vmproc
[childproc
]; /* child */
59 assert(vmc
->vm_slot
== childproc
);
61 /* The child is basically a copy of the parent. */
64 vmc
->vm_slot
= childproc
;
65 region_init(&vmc
->vm_regions_avl
);
66 vmc
->vm_endpoint
= NONE
; /* In case someone tries to use it. */
70 vmc
->vm_bytecopies
= 0;
73 if(pt_new(&vmc
->vm_pt
) != OK
) {
74 printf("VM: fork: pt_new failed\n");
78 SANITYCHECK(SCL_DETAIL
);
80 if(map_proc_copy(vmc
, vmp
) != OK
) {
81 printf("VM: fork: map_proc_copy failed\n");
86 /* Only inherit these flags. */
87 vmc
->vm_flags
&= VMF_INUSE
;
89 /* inherit the priv call bitmaps */
90 memcpy(&vmc
->vm_call_mask
, &vmp
->vm_call_mask
, sizeof(vmc
->vm_call_mask
));
92 /* Tell kernel about the (now successful) FORK. */
93 if((r
=sys_fork(vmp
->vm_endpoint
, childproc
,
94 &vmc
->vm_endpoint
, PFF_VMINHIBIT
, &msgaddr
)) != OK
) {
95 panic("do_fork can't sys_fork: %d", r
);
98 if((r
=pt_bind(&vmc
->vm_pt
, vmc
)) != OK
)
99 panic("fork can't pt_bind: %d", r
);
103 /* making these messages writable is an optimisation
104 * and its return value needn't be checked.
107 if (handle_memory(vmc
, vir
, sizeof(message
), 1) != OK
)
108 panic("do_fork: handle_memory for child failed\n");
110 if (handle_memory(vmp
, vir
, sizeof(message
), 1) != OK
)
111 panic("do_fork: handle_memory for parent failed\n");
114 /* Inform caller of new child endpoint. */
115 msg
->VMF_CHILD_ENDPOINT
= vmc
->vm_endpoint
;
117 SANITYCHECK(SCL_FUNCTIONS
);