Exemplo n.º 1
0
int
waitpid(int pid, int *status, int options)
{
	int noptions, ret;
	int nstatus;

	if ((int)status == -1) {
		errno = EFAULT;
		return (-1);
	}

	/*
	 * BSD's wait* routines only support WNOHANG & WUNTRACED
	 */
	if (options & ~(WNOHANG|WUNTRACED))
		return (EINVAL);
	noptions = (N_WEXITED|N_WTRAPPED);
	if (options & WNOHANG)
		noptions |= N_WNOHANG;
	if (options & WUNTRACED)
		noptions |= N_WUNTRACED;	/* == N_WSTOPPED */
	
	ret = _waitpid(pid, &nstatus, noptions);
	
	if (status)
		mapstatus(status, nstatus);

	return (ret);
}
int
lms_finish_slave(struct pinfo *pinfo, int (*finish)(const struct fds *fds))
{
    int r;

    if (pinfo->child <= 0)
        return 0;

    r = finish(&pinfo->master);
    if (r == 0)
        r = _waitpid(pinfo->child);
    else {
        r = kill(pinfo->child, SIGKILL);
        if (r < 0)
            perror("kill");
        else
            r =_waitpid(pinfo->child);
    }
    pinfo->child = 0;

    return r;
}
Exemplo n.º 3
0
int
grantpt(int fildes) {
    int retval, serrno, status;
    pid_t pid, spid;
    gid_t gid;
    char* slave;
    sigset_t oblock, nblock;
    struct group* grp;
    retval = -1;
    serrno = errno;

    if ((slave = ptsname(fildes)) != NULL) {
        /*
         * Block SIGCHLD.
         */
        (void)sigemptyset(&nblock);
        (void)sigaddset(&nblock, SIGCHLD);
        (void)_sigprocmask(SIG_BLOCK, &nblock, &oblock);

        switch (pid = fork()) {
        case -1:
            break;

        case 0:     /* child */
            /*
             * pt_chown expects the master pseudo TTY to be its
             * standard input.
             */
            (void)_dup2(fildes, STDIN_FILENO);
            (void)_sigprocmask(SIG_SETMASK, &oblock, NULL);
            execl(_PATH_PTCHOWN, _PATH_PTCHOWN, (char*)NULL);
            _exit(EX_UNAVAILABLE);

        /* NOTREACHED */
        default:    /* parent */

            /*
             * Just wait for the process.  Error checking is
             * done below.
             */
            while ((spid = _waitpid(pid, &status, 0)) == -1 &&
                    (errno == EINTR))
                ;

            if (spid != -1 && WIFEXITED(status) &&
                    WEXITSTATUS(status) == EX_OK) {
                retval = 0;
            } else {
                errno = EACCES;
            }

            break;
        }

        /*
         * Restore process's signal mask.
         */
        (void)_sigprocmask(SIG_SETMASK, &oblock, NULL);

        if (retval) {
            /*
             * pt_chown failed.  Try to manually change the
             * permissions for the slave.
             */
            gid = (grp = getgrnam("tty")) ? grp->gr_gid : -1;

            if (chown(slave, getuid(), gid) == -1 ||
                    chmod(slave, S_IRUSR | S_IWUSR | S_IWGRP) == -1) {
                errno = EACCES;
            } else {
                retval = 0;
            }
        }
    }

    if (!retval) {
        errno = serrno;
    }

    return (retval);
}