wait.c

来自「这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易」· C语言 代码 · 共 151 行

C
151
字号
#include "lib.h"#include <stdlib.h>#include <sys/wait.h>#include <sys/time.h>#include <sys/resource.h>#include <sys/stat.h>#include <unistd.h>#include <string.h>#include <errno.h>#include <stdio.h>#include "sys9.h"#include "dir.h"/* * status not yet collected for processes that have exited */typedef struct Waited Waited;struct Waited {	Waitmsg*	msg;	Waited*	next;};static Waited *wd;static Waitmsg *lookpid(int pid){	Waited **wl, *w;	Waitmsg *msg;	for(wl = &wd; (w = *wl) != nil; wl = &w->next)		if(pid <= 0 || w->msg->pid == pid){			msg = w->msg;			*wl = w->next;			free(w);			return msg;		}	return 0;}static voidaddpid(Waitmsg *msg){	Waited *w;	w = malloc(sizeof(*w));	if(w == nil){		/* lost it; what can we do? */		free(msg);		return;	}	w->msg = msg;	w->next = wd;	wd = w;}static intwaitstatus(Waitmsg *w){	int r, t;	char *bp, *ep;	r = 0;	t = 0;	if(w->msg[0]){		/* message is 'prog pid:string' */		bp = w->msg;		while(*bp){			if(*bp++ == ':')				break;		}		if(*bp == 0)			bp = w->msg;		r = strtol(bp, &ep, 10);		if(*ep == 0){			if(r < 0 || r >= 256)				r = 1;		}else{			t = _stringsig(bp);			if(t == 0)				r = 1;		}	}	return (r<<8) | t;}static voidwaitresource(struct rusage *ru, Waitmsg *w){	memset(ru, 0, sizeof(*ru));	ru->ru_utime.tv_sec = w->time[0]/1000;	ru->ru_utime.tv_usec = (w->time[0]%1000)*1000;	ru->ru_stime.tv_sec = w->time[1]/1000;	ru->ru_stime.tv_usec = (w->time[1]%1000)*1000;}pid_twait(int *status){	return wait4(-1, status, 0, nil);}pid_twaitpid(pid_t wpid, int *status, int options){	return wait4(wpid, status, options, nil);}pid_twait3(int *status, int options, struct rusage *res){	return wait4(-1, status, options, res);}pid_twait4(pid_t wpid, int *status, int options, struct rusage *res){	char pname[50];	Dir *d;	Waitmsg *w;	w = lookpid(wpid);	if(w == nil){		if(options & WNOHANG){			snprintf(pname, sizeof(pname), "/proc/%d/wait", getpid());			d = _dirstat(pname);			if(d != nil && d->length == 0){				free(d);				return 0;			}			free(d);		}		for(;;){			w = _WAIT();			if(w == nil){				_syserrno();				return -1;			}			if(wpid <= 0 || w->pid == wpid)				break;			addpid(w);		}	}	if(res != nil)		waitresource(res, w);	if(status != nil)		*status = waitstatus(w);	wpid = w->pid;	free(w);	return wpid;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?