Hi,
ich habe den Code jetzt umgeschrieben...
#include <sys/wait.h>
#define PIPE_READ_END(x) x[0]
#define PIPE_WRITE_END(x) x[1]
typedef enum{
acc_read = 0,
acc_write = 1
} pipe_access_type;
#define MAX_PIPE_FD 2
#define MAX_BUFFER 257
typedef enum{
exited,
killed,
stopped,
continued,
undefined
} process_status_type;
typedef struct
{
int pipe_fd[ MAX_PIPE_FD ];
int fnctl_flags [ MAX_PIPE_FD ];
pipe_access_type pipe_access;
}
pipe_stdin_type,
pipe_stdout_type,
pipe_stderr_type;
typedef struct{
pipe_stderr_type pipe_stderr;
pipe_stdin_type pipe_stdin;
pipe_stdout_type pipe_stdout;
} pipe_type;
int run_executable( pipe_type &child_pipe,
const char* progname,
int &child_pid );
int read_pipebuffer( char* buff, int &no_bytes, int pipe_fd );
int monitor_child( const int &cpid, process_status_type &status);
int child_response(const char* response, pipe_type const &App_Pipe, int const &App_pid );
und ...
...
int App1_pid = 0;
int App2_pid = 0;
int App3_pid = 0;
const char* App1path = "/home/frank/workspace/App1/App1";
const char* App2path = "/home/frank/workspace/App2/App2";
const char* App3path = "/home/frank/workspace/App3/App3";
const char* App1_response = "******Ready App1";
const char* App2_response = "******Ready App2";
const char* App3_response = "******Ready App3";
pipe_type App1_Pipe;
pipe_type App2_Pipe;
pipe_type App3_Pipe;
int child_response(const char* response,
pipe_type const &App_Pipe,
int const &App_pid ){
char buff[ MAX_BUFFER ];
int no_bytes = 0;
bzero( buff, sizeof( buff ) );
if( App_pid > 0 ){
read_pipebuffer( buff,
no_bytes,
PIPE_READ_END(App_Pipe.pipe_stdout.pipe_fd) );
}
if( no_bytes > 0 ){
printf("%s\n", buff);
char *pWord = NULL;
pWord = strstr( buff, response);
if(pWord){
return 1;
}
}
return 0;
}
int monitor_child( const int &cpid, process_status_type &proc_status){
pid_t w;
int status;
do {
w = waitpid(cpid, &status, WUNTRACED | WCONTINUED);
if (w == -1) {
perror("waitpid");
return -1;
}
if (WIFEXITED(status)){
proc_status == exited;
//printf("exited, status=%d\n", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
proc_status == killed;
//printf("killed by signal %d\n", WTERMSIG(status));
} else if (WIFSTOPPED(status)) {
proc_status = stopped;
//printf("stopped by signal %d\n", WSTOPSIG(status));
break;
} else if (WIFCONTINUED(status)) {
proc_status = continued;
//printf("continued\n");
break;
}
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
return 0;
}
int run_executable( pipe_type &child_pipe,
const char* progname,
int &child_pid )
{
if( pipe( child_pipe.pipe_stdin.pipe_fd ) == -1) {
perror( "pipe" );
}
//init stdin stream
PIPE_READ_END( child_pipe.pipe_stdin.fnctl_flags ) =
fcntl( PIPE_READ_END( child_pipe.pipe_stdin.pipe_fd ),
F_GETFL );
fcntl( PIPE_READ_END( child_pipe.pipe_stdin.fnctl_flags ),
F_SETFL,
PIPE_READ_END( child_pipe.pipe_stdin.fnctl_flags ) | O_NONBLOCK );
if( pipe( child_pipe.pipe_stdout.pipe_fd ) == -1) {
perror( "pipe" );
}
//init stdout stream
PIPE_READ_END( child_pipe.pipe_stdout.fnctl_flags ) =
fcntl( PIPE_READ_END( child_pipe.pipe_stdout.pipe_fd ),
F_GETFL );
fcntl( PIPE_READ_END( child_pipe.pipe_stdout.fnctl_flags ),
F_SETFL,
PIPE_READ_END( child_pipe.pipe_stdout.fnctl_flags ) | O_NONBLOCK );
if( pipe( child_pipe.pipe_stderr.pipe_fd ) == -1) {
perror( "pipe" );
}
//init stderr stream
PIPE_READ_END( child_pipe.pipe_stderr.fnctl_flags ) =
fcntl( PIPE_READ_END( child_pipe.pipe_stderr.pipe_fd ),
F_GETFL );
fcntl( PIPE_READ_END( child_pipe.pipe_stderr.fnctl_flags ),
F_SETFL,
PIPE_READ_END( child_pipe.pipe_stderr.fnctl_flags ) | O_NONBLOCK );
int pid = vfork();
if( pid == -1 ) {
perror("fork");
exit( EXIT_FAILURE );
}
else if(pid == 0){
child_pid = getpid();
close( PIPE_WRITE_END( child_pipe.pipe_stdin.pipe_fd ) );
close( PIPE_READ_END( child_pipe.pipe_stdout.pipe_fd ) );
close( PIPE_READ_END( child_pipe.pipe_stderr.pipe_fd ) );
dup2( PIPE_READ_END( child_pipe.pipe_stdin.pipe_fd ), STDIN_FILENO );
dup2( PIPE_WRITE_END( child_pipe.pipe_stdout.pipe_fd ), STDOUT_FILENO );
dup2( PIPE_WRITE_END( child_pipe.pipe_stderr.pipe_fd ), STDERR_FILENO );
execl( progname, progname, (char*) 0 );
_exit(1);
}
else if( pid > 0 ){
close( PIPE_READ_END( child_pipe.pipe_stdin.pipe_fd ) );
close( PIPE_WRITE_END( child_pipe.pipe_stdout.pipe_fd ) );
close( PIPE_WRITE_END( child_pipe.pipe_stderr.pipe_fd ) );
}
return 0;
}
int read_pipebuffer( char* buff, int &no_bytes, int pipe_fd )
{
char tmpBuff[ MAX_BUFFER ] = {0};
int i;
size_t bytesread = 0;
fd_set fds;
struct timeval tv;
tv.tv_sec = tv.tv_usec = 1;
FD_ZERO( &fds );
FD_SET( pipe_fd, &fds);
int rv = select( pipe_fd + 1, &fds, NULL, NULL, &tv );
if( rv == -1 )
perror("select");
else if ( rv > 0 ){
if( FD_ISSET( pipe_fd, &fds ) )
{
bytesread = read( pipe_fd,
tmpBuff,
sizeof( tmpBuff ) );
no_bytes = bytesread;
if( bytesread == 0 )
{
return -1;
}
}
}
if(bytesread > 0 ){
if( strlen( tmpBuff ) > 0 ){
sprintf( buff, "%s", tmpBuff );
tmpBuff[ MAX_BUFFER ] = 0;
}
}
FD_CLR( pipe_fd, &fds );
return 0;
}
int main()
{
char buff[ MAX_BUFFER ], buff2[ MAX_BUFFER ], buff3[ MAX_BUFFER ];
int status;
cout << "Ok, jetzt gehts los." << endl;
process_status_type proc_status;
int App1_stopped = 1,
App2_stopped = 1,
App3_stopped = 1,
App4_stopped = 1;
while (1)
{
//run App1 while App2 & App3 stopped
if( App1_pid == 0 && App1_stopped && App2_stopped && App3_stopped )
{
run_executable( App1_Pipe, App1path, App1_pid );
App1_stopped = 0;
}
else if( App1_pid > 0 && ( App1_stopped && App2_stopped && App3_stopped ) ){
kill( App1_pid, SIGCONT );
App1_stopped = 0;
}
if ( child_response( App1_response, App1_Pipe, App1_pid ) ){
kill( App1_pid, SIGSTOP );
proc_status = undefined;
monitor_child( App1_pid, proc_status );
if( proc_status == stopped ) {App1_stopped = 1;}
}
//run App2 while App1 & App3 stopped...
if( App2_pid == 0 && ( App1_stopped && App2_stopped && App3_stopped ) )
{
run_executable( App2_Pipe, App2path, App2_pid );
App2_stopped = 0;
}
else if( App2_pid > 0 && App1_stopped && App2_stopped && App3_stopped ){
kill( App2_pid, SIGCONT );
App2_stopped = 0;
}
if ( child_response( App2_response, App2_Pipe, App2_pid ) ){
kill( App2_pid, SIGSTOP );
proc_status = undefined;
monitor_child( App2_pid, proc_status );
if( proc_status == stopped ) App2_stopped = 1;
}
//run App3 while App2 & App1 stopped...
if( App3_pid == 0 && (App1_stopped && App2_stopped && App3_stopped ) )
{
run_executable( App3_Pipe, App3path, App3_pid );
App3_stopped = 0;
}
else if( App3_pid > 0 && ( App3_stopped && App2_stopped && App1_stopped ) ){
kill( App3_pid, SIGCONT );
App3_stopped = 0;
}
if ( child_response( App3_response, App3_Pipe, App3_pid ) ){
kill( App3_pid, SIGSTOP );
proc_status = undefined;
monitor_child( App3_pid, proc_status );
if( proc_status == stopped ) App3_stopped = 1;
}
}
return 0;
}
bin ich jetzt näher an meiner Reihenfolge dran?
Gruß