Try not to leak PID slots

Set a flag when a child exits, then free the slot when all the fd's
associated with the child have been marked as closed. Presumably this
should prevent the situation where a signal has occurred but there is
pending data on an fd. In this case, the parent would previously discard
the data and free the slot immediately.
This commit is contained in:
Michael Santos
2014-03-12 16:59:21 -04:00
parent 930ed76033
commit dfebfa3c8c
2 changed files with 22 additions and 6 deletions

View File

@@ -53,7 +53,8 @@ static ssize_t alcove_child_stdio(int fdin, pid_t pid, u_int16_t type);
static ssize_t alcove_write(u_int16_t, ETERM *);
static ssize_t alcove_read(int, void *, ssize_t);
static int zero_pid(alcove_child_t *c, void *arg1, void *arg2);
static int exited_pid(alcove_child_t *c, void *arg1, void *arg2);
static int free_pid(alcove_child_t *c, void *arg1, void *arg2);
static int set_pid(alcove_child_t *c, void *arg1, void *arg2);
static int write_to_pid(alcove_child_t *c, void *arg1, void *arg2);
static int read_from_pid(alcove_child_t *c, void *arg1, void *arg2);
@@ -130,13 +131,14 @@ alcove_ctl(alcove_state_t *ap)
case 0:
break;
default:
ap->nchild--;
(void)pid_foreach(ap, pid, NULL, NULL, pid_equal, zero_pid);
(void)pid_foreach(ap, pid, NULL, NULL, pid_equal, exited_pid);
}
child_exited = 0;
}
(void)pid_foreach(ap, 0, ap, NULL, pid_not_equal, free_pid);
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds);
@@ -414,15 +416,28 @@ pid_not_equal(pid_t p1, pid_t p2)
}
static int
zero_pid(alcove_child_t *c, void *arg1, void *arg2)
exited_pid(alcove_child_t *c, void *arg1, void *arg2)
{
(void)close(c->fdin);
c->fdin = -1;
c->pid = 0;
c->exited = 1;
return 0;
}
static int
free_pid(alcove_child_t *c, void *arg1, void *arg2)
{
alcove_state_t *ap = arg1;
if (c->exited && c->fdout == -1 && c->fderr == -1) {
c->pid = 0;
c->exited = 0;
ap->nchild--;
}
return 1;
}
static int
set_pid(alcove_child_t *c, void *arg1, void *arg2)
{

View File

@@ -40,6 +40,7 @@ enum {
typedef struct {
pid_t pid;
int exited;
int fdin;
int fdout;
int fderr;