library/src/filesystem/BP-Filesystem.cc
// executes a file given parms, if retFds is true.. returns a structure
// containing the file descriptors which can be read from or written to
executes a file given parms, if retFds is true.. returns a structure
containing the file descriptors which can be read from or written to
executes a file given parms if retFds is true .. returns a structure containing the file descriptors which can be read from or written to
P_BP_FDSET BP_FExec
(
		char *rootBinPath,
		char **params,
		char **envp,
		BP_BOOL retFds,
		BP_BOOL fork_pty
)
{
	if(!rootBinPath)
		return NULL;
	if(fork_pty && !retFds)
		return NULL;
	P_BP_FDSET fdset = NULL;
	int pid = 0;
	if(retFds)
	{
		fdset = (P_BP_FDSET) bpcalloc(sizeof(BP_FDSET), 1);
	}
	if(retFds && !fork_pty)
	{
		if
		(
			(pipe(fdset->stdin) == 0) && (pipe(fdset->stdout) == 0) && (pipe(fdset->stderr) == 0)
		)
		{}
		else
			return NULL;
	}
	if(!fork_pty)
	{
		pid = fork();
		if(pid == -1)
		{
			if(fdset)
				bpfree(fdset);
			return NULL;
		}
	}
	else
	{
		fdset->forkpty_master = 0;
		pid = forkpty(&fdset->forkpty_master, NULL, NULL, NULL);
		if(pid == -1)
		{
			if(fdset)
			{
				bpfree(fdset);
			}
			return NULL;
		}
		fdset->session_is_forkpty = BP_TRUE;
	}
	if(fdset->session_is_forkpty)
	{
        tcgetattr(STDIN_FILENO, &fdset->oldt);
        fdset->newt = fdset->oldt;
        fdset->newt.c_lflag &= ~(ECHO | ECHONL | ICANON);
        tcsetattr(STDIN_FILENO, TCSAFLUSH, &fdset->newt);
        tcsetattr(STDIN_FILENO, TCSANOW,   &fdset->newt);
	}
	if(!pid)
	{
		if(retFds)
		{
			if(!fdset->session_is_forkpty)
			{
				close(fdset->stdin[1]);
				dup2 (fdset->stdin [0], STDIN_FILENO);
				close(fdset->stdout[0]);
				dup2 (fdset->stdout[1], STDOUT_FILENO);
				close(fdset->stderr[0]);
				dup2 (fdset->stderr[1], STDERR_FILENO);
			}
			else
			{
			}
		}
		execve(rootBinPath, params, envp);
		exit(0);
	}
	if(pid)
	{
		if(retFds == BP_TRUE)
		{
			fdset->pid = pid;
			if(fdset->session_is_forkpty)
			{
			}
		}
	}
	return fdset;
}
P_BP_FDSET BP_FExec ( char * rootBinPath , char * * params , char * * envp , BP_BOOL retFds , BP_BOOL fork_pty ) { if ( ! rootBinPath ) return NULL ; if ( fork_pty && ! retFds ) return NULL ; P_BP_FDSET fdset = NULL ; int pid = 0 ; if ( retFds ) { fdset = ( P_BP_FDSET ) bpcalloc ( sizeof ( BP_FDSET ) , 1 ) ; } if ( retFds && ! fork_pty ) { if ( ( pipe ( fdset -> stdin ) == 0 ) && ( pipe ( fdset -> stdout ) == 0 ) && ( pipe ( fdset -> stderr ) == 0 ) ) { } else return NULL ; } if ( ! fork_pty ) { pid = fork ( ) ; if ( pid == -1 ) { if ( fdset ) bpfree ( fdset ) ; return NULL ; } } else { fdset -> forkpty_master = 0 ; pid = forkpty ( & fdset -> forkpty_master , NULL , NULL , NULL ) ; if ( pid == -1 ) { if ( fdset ) { bpfree ( fdset ) ; } return NULL ; } fdset -> session_is_forkpty = BP_TRUE ; } if ( fdset -> session_is_forkpty ) { tcgetattr ( STDIN_FILENO , & fdset -> oldt ) ; fdset -> newt = fdset -> oldt ; fdset -> newt . c_lflag &= ~ ( ECHO | ECHONL | ICANON ) ; tcsetattr ( STDIN_FILENO , TCSAFLUSH , & fdset -> newt ) ; tcsetattr ( STDIN_FILENO , TCSANOW , & fdset -> newt ) ; } if ( ! pid ) { if ( retFds ) { if ( ! fdset -> session_is_forkpty ) { close ( fdset -> stdin [ 1 ] ) ; dup2 ( fdset -> stdin [ 0 ] , STDIN_FILENO ) ; close ( fdset -> stdout [ 0 ] ) ; dup2 ( fdset -> stdout [ 1 ] , STDOUT_FILENO ) ; close ( fdset -> stderr [ 0 ] ) ; dup2 ( fdset -> stderr [ 1 ] , STDERR_FILENO ) ; } else { } } execve ( rootBinPath , params , envp ) ; exit ( 0 ) ; } if ( pid ) { if ( retFds == BP_TRUE ) { fdset -> pid = pid ; if ( fdset -> session_is_forkpty ) { } } } return fdset ; }
executes a file given parms, if retFds is true.. returns a structure
containing the file descriptors which can be read from or written to
executes a file given parms if retFds is true .. returns a structure containing the file descriptors which can be read from or written to
// ensure we have bin path // if we're forking ptys we must return fds // set of file descriptors stdin/stdout/stderr // declare pid // If we're returning file descriptors, create them now. // allocate space for set // create pipes if we're not forking a pty // create replacement pipes to process // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Fork Application and Handle FDs %%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // run normal fork w/o pty // fork the process (doesn't fork terminal as well) // This is required.  Value cannot be -1 or forkpty fails for some arbitrary reason. // using forkpty allows us to clone our entire terminal // if we got no pid, exit // ensure we have a fdset // destroy the fdset // return null indicating failure // mark session as forkpty // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Preserve Terminal Information If Forkpty %%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // get stdin from current terminal // set terminals // set terminal flags // set attributes (flush/nonblock) // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Handle Child %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // Fork successful, we are in child here // replace pipes/replumb // stdin (STDIN_FILENO) // stdout (STDOUT_FILENO) // stderr (STDERR_FILENO) // !! Actually executes the program here !! // exit the app after execve finishes // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Handle Parent %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // set pid // check if the session comes from forkpty // return the populated fdset