2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 2N/A * Use is subject to license terms. 2N/A * pid = vforkx(flags); 2N/A * syscall trap: forksys(2, flags) 2N/A * syscall trap: forksys(2, 0) 2N/A * %edx == 0 in parent process, %edx = 1 in child process. 2N/A * %eax == pid of child in parent, %eax == pid of parent in child. 2N/A * The child gets a zero return value. 2N/A * The parent gets the pid of the child. 2N/A * The child of vfork() will execute in the parent's address space, 2N/A * thereby changing the stack before the parent runs again. 2N/A * Therefore we have to be careful how we return from vfork(). 2N/A * Pity the poor debugger developer who has to deal with this kludge. 2N/A * We block all blockable signals while performing the vfork() system call 2N/A * trap. This enables us to set curthread->ul_vfork safely, so that we 2N/A * don't end up in a signal handler with curthread->ul_vfork set wrong. 2N/A /* reconstruct stack before jumping to __cerror */ 2N/A * To determine if we are (still) a child of vfork(), the child 2N/A * increments curthread->ul_vfork by one and the parent decrements 2N/A * it by one. If the result is zero, then we are not a child of 2N/A * vfork(), else we are. We do this to deal with the case of 2N/A * a vfork() child calling vfork(). 2N/A * Clear the schedctl interface in both parent and child. 2N/A * (The child might have modified the parent.)