libposix: (almost working) waitpid

This commit is contained in:
Giacomo Tesio 2017-05-02 00:57:18 +02:00
parent be7c067507
commit cf974abe0e
4 changed files with 94 additions and 28 deletions

View File

@ -167,3 +167,10 @@ extern int libposix_translate_exit_status(PosixExitStatusTranslator translator);
typedef int (*PosixSignalTrampoline)(int signal);
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);

View File

@ -39,14 +39,13 @@ libposix_init(int argc, char *argv[], PosixInit init)
WaitList *wait_list;
int status;
int error_codes[ERRNO_LAST-ERRNO_FIRST];
assert(__initialized == 0);
/* initialize PosixErrors map */
memset(error_codes, 0, sizeof(error_codes));
__libposix_errors_codes=error_codes;
/* initialize wait_list; see also POSIX_fork and POSIX_exit */
wait_list = nil;
__libposix_wait_list = &wait_list;

View File

@ -15,6 +15,14 @@
* You should have received a copy of the GNU Affero General Public License
* 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_errors_check_conf(void);
extern void __libposix_processes_check_conf(void);

View File

@ -22,17 +22,10 @@
extern char **environ;
typedef struct WaitList WaitList;
struct WaitList
{
int pid;
int status;
WaitList *next;
};
WaitList **__libposix_wait_list;
static PosixSignalTrampoline __libposix_signal_trampoline;
static PosixExitStatusTranslator __libposix_exit_status_translator;
static int __libposix_wnohang;
#define __POSIX_SIGNAL_PREFIX_LEN (sizeof(__POSIX_SIGNAL_PREFIX)-1)
@ -40,7 +33,7 @@ void
POSIX_exit(int code)
{
char buf[64], *s;
WaitList *wl, c;
WaitList *wl, *c;
/* free the wait list as the memory is shared */
wl = *__libposix_wait_list;
@ -52,7 +45,7 @@ POSIX_exit(int code)
wl = c->next;
free(c);
}
while (wl != nil)
while (wl != nil);
}
if(__libposix_exit_status_translator != nil
@ -102,15 +95,16 @@ POSIX_wait(int *errnop, int *status)
char *s;
int ret = 0, pid;
l = *__libposix_wait_list;
l = *__libposix_wait_list;
if(l != nil){
*__libposix_wait_list = l->next;
*status = l->status;
if(status != nil)
*status = l->status;
pid = l->pid;
free(l);
return pid;
}
w = wait();
if(w == nil){
*errnop = __libposix_get_errno(PosixECHILD);
@ -128,27 +122,63 @@ POSIX_wait(int *errnop, int *status)
}
}
if(status != nil)
*status = ret;
*status = ret << 8;
free(w);
return pid;
}
int
POSIX_waitpid(int *errnop, int pid, int *status, int options)
POSIX_waitpid(int *errnop, int reqpid, int *status, int options)
{
Waitmsg *w;
WaitList *c, **nl;
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;
l = *nl'
while(l != nil){
}
if(l != nil){
c = *nl;
while(c != nil){
*nl = c->next;
if(c->pid == reqpid){
if(status != nil)
*status = c->status;
free(c);
return reqpid;
}
c = *nl;
}
WaitAgain:
w = wait();
if(w == nil){
*errnop = __libposix_get_errno(PosixECHILD);
@ -165,11 +195,20 @@ POSIX_waitpid(int *errnop, int pid, int *status, int options)
ret = 127;
}
}
if(status != nil)
*status = ret;
free(w);
return pid;
if(pid == reqpid){
if(status != nil)
*status = ret << 8;
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
@ -282,10 +321,23 @@ libposix_set_signal_trampoline(PosixSignalTrampoline trampoline)
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
__libposix_processes_check_conf(void)
{
if(__libposix_signal_trampoline == nil)
sysfatal("libposix: no signal trampoline");
if(__libposix_wnohang == 0)
sysfatal("libposix: WNOHANG is undefined");
/* __libposix_exit_status_translator is optional */
}