libposix: (almost working) waitpid
This commit is contained in:
parent
be7c067507
commit
cf974abe0e
|
@ -167,3 +167,10 @@ extern int libposix_translate_exit_status(PosixExitStatusTranslator translator);
|
||||||
typedef int (*PosixSignalTrampoline)(int signal);
|
typedef int (*PosixSignalTrampoline)(int signal);
|
||||||
|
|
||||||
extern int libposix_set_signal_trampoline(PosixSignalTrampoline trampoline);
|
extern int libposix_set_signal_trampoline(PosixSignalTrampoline trampoline);
|
||||||
|
|
||||||
|
/* Define of WCONTINUED, WNOHANG and WUNTRACED bit flags.
|
||||||
|
*
|
||||||
|
* Note that WCONTINUED and WUNTRACED are not yet supported by libposix
|
||||||
|
* and thus defining them cause an error.
|
||||||
|
*/
|
||||||
|
int libposix_set_wait_options(int wcontinued, int wnohang, int wuntraced);
|
||||||
|
|
|
@ -40,7 +40,6 @@ libposix_init(int argc, char *argv[], PosixInit init)
|
||||||
int status;
|
int status;
|
||||||
int error_codes[ERRNO_LAST-ERRNO_FIRST];
|
int error_codes[ERRNO_LAST-ERRNO_FIRST];
|
||||||
|
|
||||||
|
|
||||||
assert(__initialized == 0);
|
assert(__initialized == 0);
|
||||||
|
|
||||||
/* initialize PosixErrors map */
|
/* initialize PosixErrors map */
|
||||||
|
|
|
@ -15,6 +15,14 @@
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with Jehanne. If not, see <http://www.gnu.org/licenses/>.
|
* along with Jehanne. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
typedef struct WaitList WaitList;
|
||||||
|
struct WaitList
|
||||||
|
{
|
||||||
|
int pid;
|
||||||
|
int status;
|
||||||
|
WaitList *next;
|
||||||
|
};
|
||||||
|
|
||||||
extern void __libposix_files_check_conf(void);
|
extern void __libposix_files_check_conf(void);
|
||||||
extern void __libposix_errors_check_conf(void);
|
extern void __libposix_errors_check_conf(void);
|
||||||
extern void __libposix_processes_check_conf(void);
|
extern void __libposix_processes_check_conf(void);
|
||||||
|
|
|
@ -22,17 +22,10 @@
|
||||||
|
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
|
||||||
typedef struct WaitList WaitList;
|
|
||||||
struct WaitList
|
|
||||||
{
|
|
||||||
int pid;
|
|
||||||
int status;
|
|
||||||
WaitList *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
WaitList **__libposix_wait_list;
|
WaitList **__libposix_wait_list;
|
||||||
static PosixSignalTrampoline __libposix_signal_trampoline;
|
static PosixSignalTrampoline __libposix_signal_trampoline;
|
||||||
static PosixExitStatusTranslator __libposix_exit_status_translator;
|
static PosixExitStatusTranslator __libposix_exit_status_translator;
|
||||||
|
static int __libposix_wnohang;
|
||||||
|
|
||||||
#define __POSIX_SIGNAL_PREFIX_LEN (sizeof(__POSIX_SIGNAL_PREFIX)-1)
|
#define __POSIX_SIGNAL_PREFIX_LEN (sizeof(__POSIX_SIGNAL_PREFIX)-1)
|
||||||
|
|
||||||
|
@ -40,7 +33,7 @@ void
|
||||||
POSIX_exit(int code)
|
POSIX_exit(int code)
|
||||||
{
|
{
|
||||||
char buf[64], *s;
|
char buf[64], *s;
|
||||||
WaitList *wl, c;
|
WaitList *wl, *c;
|
||||||
|
|
||||||
/* free the wait list as the memory is shared */
|
/* free the wait list as the memory is shared */
|
||||||
wl = *__libposix_wait_list;
|
wl = *__libposix_wait_list;
|
||||||
|
@ -52,7 +45,7 @@ POSIX_exit(int code)
|
||||||
wl = c->next;
|
wl = c->next;
|
||||||
free(c);
|
free(c);
|
||||||
}
|
}
|
||||||
while (wl != nil)
|
while (wl != nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(__libposix_exit_status_translator != nil
|
if(__libposix_exit_status_translator != nil
|
||||||
|
@ -105,7 +98,8 @@ POSIX_wait(int *errnop, int *status)
|
||||||
l = *__libposix_wait_list;
|
l = *__libposix_wait_list;
|
||||||
if(l != nil){
|
if(l != nil){
|
||||||
*__libposix_wait_list = l->next;
|
*__libposix_wait_list = l->next;
|
||||||
*status = l->status;
|
if(status != nil)
|
||||||
|
*status = l->status;
|
||||||
pid = l->pid;
|
pid = l->pid;
|
||||||
free(l);
|
free(l);
|
||||||
return pid;
|
return pid;
|
||||||
|
@ -128,27 +122,63 @@ POSIX_wait(int *errnop, int *status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(status != nil)
|
if(status != nil)
|
||||||
*status = ret;
|
*status = ret << 8;
|
||||||
free(w);
|
free(w);
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
POSIX_waitpid(int *errnop, int pid, int *status, int options)
|
POSIX_waitpid(int *errnop, int reqpid, int *status, int options)
|
||||||
{
|
{
|
||||||
Waitmsg *w;
|
Waitmsg *w;
|
||||||
WaitList *c, **nl;
|
WaitList *c, **nl;
|
||||||
char *s;
|
char *s;
|
||||||
int ret = 0, pid;
|
int ret = 0, nohang = 0, pid;
|
||||||
|
|
||||||
|
|
||||||
|
if(options & __libposix_wnohang){
|
||||||
|
nohang = 1;
|
||||||
|
}
|
||||||
|
// else if(options != 0){
|
||||||
|
// /* WARNING: WCONTINUED and WUNTRACED are not supported */
|
||||||
|
// *errnop = __libposix_get_errno(PosixEINVAL);
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
switch(reqpid){
|
||||||
|
case -1:
|
||||||
|
if(nohang){
|
||||||
|
*errnop = __libposix_get_errno(PosixEINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return POSIX_wait(errnop, status);
|
||||||
|
case 0:
|
||||||
|
/* not yet implemented; requires changes to Waitmsg */
|
||||||
|
*errnop = __libposix_get_errno(PosixEINVAL);
|
||||||
|
return -1;
|
||||||
|
default:
|
||||||
|
if(reqpid < -1){
|
||||||
|
/* not yet implemented; requires changes to Waitmsg */
|
||||||
|
*errnop = __libposix_get_errno(PosixEINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
nl = __libposix_wait_list;
|
nl = __libposix_wait_list;
|
||||||
l = *nl'
|
c = *nl;
|
||||||
while(l != nil){
|
while(c != nil){
|
||||||
}
|
*nl = c->next;
|
||||||
if(l != nil){
|
if(c->pid == reqpid){
|
||||||
|
if(status != nil)
|
||||||
|
*status = c->status;
|
||||||
|
free(c);
|
||||||
|
return reqpid;
|
||||||
|
}
|
||||||
|
c = *nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WaitAgain:
|
||||||
w = wait();
|
w = wait();
|
||||||
if(w == nil){
|
if(w == nil){
|
||||||
*errnop = __libposix_get_errno(PosixECHILD);
|
*errnop = __libposix_get_errno(PosixECHILD);
|
||||||
|
@ -165,11 +195,20 @@ POSIX_waitpid(int *errnop, int pid, int *status, int options)
|
||||||
ret = 127;
|
ret = 127;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(status != nil)
|
if(pid == reqpid){
|
||||||
*status = ret;
|
if(status != nil)
|
||||||
free(w);
|
*status = ret << 8;
|
||||||
return pid;
|
return reqpid;
|
||||||
|
}
|
||||||
|
c = malloc(sizeof(WaitList));
|
||||||
|
c->next = nil;
|
||||||
|
c->pid = pid;
|
||||||
|
c->status = ret << 8;
|
||||||
|
*nl = c;
|
||||||
|
if(!nohang)
|
||||||
|
goto WaitAgain;
|
||||||
|
*errnop = __libposix_get_errno(PosixECHILD);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -282,10 +321,23 @@ libposix_set_signal_trampoline(PosixSignalTrampoline trampoline)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
libposix_set_wait_options(int wcontinued, int wnohang, int wuntraced)
|
||||||
|
{
|
||||||
|
if(wcontinued != 0)
|
||||||
|
sysfatal("libposix: unsupported WCONTINUED");
|
||||||
|
if(wuntraced != 0)
|
||||||
|
sysfatal("libposix: unsupported WUNTRACED");
|
||||||
|
__libposix_wnohang = wnohang;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
__libposix_processes_check_conf(void)
|
__libposix_processes_check_conf(void)
|
||||||
{
|
{
|
||||||
if(__libposix_signal_trampoline == nil)
|
if(__libposix_signal_trampoline == nil)
|
||||||
sysfatal("libposix: no signal trampoline");
|
sysfatal("libposix: no signal trampoline");
|
||||||
|
if(__libposix_wnohang == 0)
|
||||||
|
sysfatal("libposix: WNOHANG is undefined");
|
||||||
/* __libposix_exit_status_translator is optional */
|
/* __libposix_exit_status_translator is optional */
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue