FreeBSD/usr.sbin/pmcstudy/pmcstudy.c
/*
 * The following two varients on popen and pclose with
 * the cavet that they get you the PID so that you
 * can supply it to pclose so it can send a SIGTERM 
 *  to the process.
 */
The following two varients on popen and pclose with
the cavet that they get you the PID so that you
can supply it to pclose so it can send a SIGTERM
to the process.
The following two varients on popen and pclose with the cavet that they get you the PID so that you can supply it to pclose so it can send a SIGTERM to the process .
static FILE *
my_popen(const char *command, const char *dir, pid_t *p_pid)
{
	FILE *io_out, *io_in;
	int pdesin[2], pdesout[2];
	char *argv[4];
	pid_t pid;
	char cmd[4];
	char cmd2[1024];
	char arg1[4];
	if ((strcmp(dir, "r") != 0) &&
	    (strcmp(dir, "w") != 0)) {
		errno = EINVAL;
		return(NULL);
	}
	if (pipe(pdesin) < 0)
		return (NULL);
	if (pipe(pdesout) < 0) {
		(void)close(pdesin[0]);
		(void)close(pdesin[1]);
		return (NULL);
	}
	strcpy(cmd, "sh");
	strcpy(arg1, "-c");
	strcpy(cmd2, command);
	argv[0] = cmd;
	argv[1] = arg1;
	argv[2] = cmd2;
	argv[3] = NULL;
	switch (pid = fork()) {
	case -1:			
		(void)close(pdesin[0]);
		(void)close(pdesin[1]);
		(void)close(pdesout[0]);
		(void)close(pdesout[1]);
		return (NULL);
	case 0:				
		(void)close(pdesin[1]);
		(void)close(pdesout[0]);
		close(0);
		(void)dup(pdesin[0]);
		(void)close(pdesin[0]);
		close(1);
		(void)dup(pdesout[1]);
		close(2);
		(void)dup(pdesout[1]);
		(void)close(pdesout[1]);
		execve("/bin/sh", argv, environ);
		exit(127);
	}
	*p_pid = pid;
	if (strcmp(dir, "r") != 0) {
		io_out = fdopen(pdesin[1], "w");
		(void)close(pdesin[0]);
		(void)close(pdesout[0]);
		(void)close(pdesout[1]);
		return(io_out);
 	} else {
		io_in = fdopen(pdesout[0], "r");
		(void)close(pdesout[1]);
		(void)close(pdesin[0]);
		(void)close(pdesin[1]);
		return (io_in);
	}
}
static FILE * my_popen ( const char * command , const char * dir , pid_t * p_pid ) { FILE * io_out , * io_in ; int pdesin [ 2 ] , pdesout [ 2 ] ; char * argv [ 4 ] ; pid_t pid ; char cmd [ 4 ] ; char cmd2 [ 1024 ] ; char arg1 [ 4 ] ; if ( ( strcmp ( dir , " " ) != 0 ) && ( strcmp ( dir , " " ) != 0 ) ) { errno = EINVAL ; return ( NULL ) ; } if ( pipe ( pdesin ) < 0 ) return ( NULL ) ; if ( pipe ( pdesout ) < 0 ) { ( void ) close ( pdesin [ 0 ] ) ; ( void ) close ( pdesin [ 1 ] ) ; return ( NULL ) ; } strcpy ( cmd , " " ) ; strcpy ( arg1 , " " ) ; strcpy ( cmd2 , command ) ; argv [ 0 ] = cmd ; argv [ 1 ] = arg1 ; argv [ 2 ] = cmd2 ; argv [ 3 ] = NULL ; switch ( pid = fork ( ) ) { case -1 : ( void ) close ( pdesin [ 0 ] ) ; ( void ) close ( pdesin [ 1 ] ) ; ( void ) close ( pdesout [ 0 ] ) ; ( void ) close ( pdesout [ 1 ] ) ; return ( NULL ) ; case 0 : ( void ) close ( pdesin [ 1 ] ) ; ( void ) close ( pdesout [ 0 ] ) ; close ( 0 ) ; ( void ) dup ( pdesin [ 0 ] ) ; ( void ) close ( pdesin [ 0 ] ) ; close ( 1 ) ; ( void ) dup ( pdesout [ 1 ] ) ; close ( 2 ) ; ( void ) dup ( pdesout [ 1 ] ) ; ( void ) close ( pdesout [ 1 ] ) ; execve ( " " , argv , environ ) ; exit ( 127 ) ; } * p_pid = pid ; if ( strcmp ( dir , " " ) != 0 ) { io_out = fdopen ( pdesin [ 1 ] , " " ) ; ( void ) close ( pdesin [ 0 ] ) ; ( void ) close ( pdesout [ 0 ] ) ; ( void ) close ( pdesout [ 1 ] ) ; return ( io_out ) ; } else { io_in = fdopen ( pdesout [ 0 ] , " " ) ; ( void ) close ( pdesout [ 1 ] ) ; ( void ) close ( pdesin [ 0 ] ) ; ( void ) close ( pdesin [ 1 ] ) ; return ( io_in ) ; } }
The following two varients on popen and pclose with
 the cavet that they get you the PID so that you
 can supply it to pclose so it can send a SIGTERM
  to the process.
The following two varients on popen and pclose with the cavet that they get you the PID so that you can supply it to pclose so it can send a SIGTERM to the process .
/* Error. */ /* NOTREACHED */ /* Child. */ /* Close out un-used sides */ /* Now prepare the stdin of the process */ /* Now prepare the stdout of the process */ /* And lets do stderr just in case */ /* Now run it */ /* NOTREACHED */ /* Parent; assume fdopen can't fail. */ /* Store the pid */ /* Prepare the input stream */