|
@@ -583,76 +583,6 @@ char *qemu_get_pid_name(pid_t pid)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-pid_t qemu_fork(Error **errp)
|
|
|
|
-{
|
|
|
|
- sigset_t oldmask, newmask;
|
|
|
|
- struct sigaction sig_action;
|
|
|
|
- int saved_errno;
|
|
|
|
- pid_t pid;
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * Need to block signals now, so that child process can safely
|
|
|
|
- * kill off caller's signal handlers without a race.
|
|
|
|
- */
|
|
|
|
- sigfillset(&newmask);
|
|
|
|
- if (pthread_sigmask(SIG_SETMASK, &newmask, &oldmask) != 0) {
|
|
|
|
- error_setg_errno(errp, errno,
|
|
|
|
- "cannot block signals");
|
|
|
|
- return -1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- pid = fork();
|
|
|
|
- saved_errno = errno;
|
|
|
|
-
|
|
|
|
- if (pid < 0) {
|
|
|
|
- /* attempt to restore signal mask, but ignore failure, to
|
|
|
|
- * avoid obscuring the fork failure */
|
|
|
|
- (void)pthread_sigmask(SIG_SETMASK, &oldmask, NULL);
|
|
|
|
- error_setg_errno(errp, saved_errno,
|
|
|
|
- "cannot fork child process");
|
|
|
|
- errno = saved_errno;
|
|
|
|
- return -1;
|
|
|
|
- } else if (pid) {
|
|
|
|
- /* parent process */
|
|
|
|
-
|
|
|
|
- /* Restore our original signal mask now that the child is
|
|
|
|
- * safely running. Only documented failures are EFAULT (not
|
|
|
|
- * possible, since we are using just-grabbed mask) or EINVAL
|
|
|
|
- * (not possible, since we are using correct arguments). */
|
|
|
|
- (void)pthread_sigmask(SIG_SETMASK, &oldmask, NULL);
|
|
|
|
- } else {
|
|
|
|
- /* child process */
|
|
|
|
- size_t i;
|
|
|
|
-
|
|
|
|
- /* Clear out all signal handlers from parent so nothing
|
|
|
|
- * unexpected can happen in our child once we unblock
|
|
|
|
- * signals */
|
|
|
|
- sig_action.sa_handler = SIG_DFL;
|
|
|
|
- sig_action.sa_flags = 0;
|
|
|
|
- sigemptyset(&sig_action.sa_mask);
|
|
|
|
-
|
|
|
|
- for (i = 1; i < NSIG; i++) {
|
|
|
|
- /* Only possible errors are EFAULT or EINVAL The former
|
|
|
|
- * won't happen, the latter we expect, so no need to check
|
|
|
|
- * return value */
|
|
|
|
- (void)sigaction(i, &sig_action, NULL);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Unmask all signals in child, since we've no idea what the
|
|
|
|
- * caller's done with their signal mask and don't want to
|
|
|
|
- * propagate that to children */
|
|
|
|
- sigemptyset(&newmask);
|
|
|
|
- if (pthread_sigmask(SIG_SETMASK, &newmask, NULL) != 0) {
|
|
|
|
- Error *local_err = NULL;
|
|
|
|
- error_setg_errno(&local_err, errno,
|
|
|
|
- "cannot unblock signals");
|
|
|
|
- error_report_err(local_err);
|
|
|
|
- _exit(1);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return pid;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
void *qemu_alloc_stack(size_t *sz)
|
|
void *qemu_alloc_stack(size_t *sz)
|
|
{
|
|
{
|
|
void *ptr, *guardpage;
|
|
void *ptr, *guardpage;
|