1/* 2 * Copyright (c) 2011, 2013, 2014, ETH Zurich. 3 * All rights reserved. 4 * 5 * This file is distributed under the terms in the attached LICENSE file. 6 * If you do not find this file, copies can be found by writing to: 7 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 8 */ 9 10#include <sys/wait.h> 11#include <assert.h> 12#include <errno.h> 13#include <stdio.h> 14#include <barrelfish/barrelfish.h> 15#include <barrelfish/spawn_client.h> 16#include "posixcompat.h" 17 18#define MAX_CHILDREN 64 19 20static pid_t children[MAX_CHILDREN]; 21 22int _posixcompat_add_child(pid_t pid); 23 24pid_t wait(int *status) 25{ 26 return waitpid(-1, status, 0); 27} 28 29pid_t wait3(int *status, int options, struct rusage *rusage) 30{ 31 // XXX: Won't touch rusage at all 32 return waitpid(-1, status, options); 33} 34 35pid_t waitpid(pid_t pid, int *status, int options) 36{ 37 int i; 38 bool nohang = options & WNOHANG ? true : false; 39 40 if(pid <= 0) { 41 // XXX: We don't have process groups, so all these cases are the same 42 for(i = 0; i < MAX_CHILDREN; i++) { 43 if(children[i] != 0) { 44 break; 45 } 46 } 47 48 if(i == MAX_CHILDREN) { 49 errno = ECHILD; 50 return -1; 51 } 52 } else { 53 for(i = 0; i < MAX_CHILDREN; i++) { 54 if(children[i] == pid) { 55 break; 56 } 57 } 58 59 if(i == MAX_CHILDREN) { 60 errno = ECHILD; 61 return -1; 62 } 63 } 64 65 if(!nohang && pid <= 0) { 66 printf("Warning: waitpid(<= 0, _, _) waits for the first child, " 67 "not all\n"); 68 } 69 70 // We got a child to wait for 71 uint8_t exitcode; 72 errval_t err = spawn_wait_compat(children[i], &exitcode, nohang); 73 if(err_is_fail(err)) { 74 if(err_no(err) == SPAWN_ERR_DOMAIN_RUNNING) { 75 return 0; 76 } else { 77 DEBUG_ERR(err, "spawn_wait"); 78 } 79 return -1; 80 } 81 82 *status = exitcode; 83 pid_t wpid = children[i]; 84 children[i] = 0; 85 86 POSIXCOMPAT_DEBUG("waitpid(%d, %d, %d) = %d\n", 87 pid, *status, options, wpid); 88 89 return wpid; 90} 91 92/** 93 * \brief This is a hack to add a child process, while we don't have fork() or exec(). 94 */ 95int _posixcompat_add_child(pid_t pid) 96{ 97 for(int i = 0; i < MAX_CHILDREN; i++) { 98 if(children[i] == 0) { 99 children[i] = pid; 100 return 0; 101 } 102 } 103 104 return -1; 105} 106