# pipecom.cpp

    00001 /* ----------------------------------------------------------------------
    00002  * Where........: CMAP - Polytechnique
    00003  * File.........: pipecom.c
    00004  * Author.......: Bertrand Lamy (Equipe genetique)
    00005  * Created......: Mon Mar 13 13:50:11 1995
    00006  * Description..: Communication par pipe bidirectionnel avec un autre process
    00007  * ----------------------------------------------------------------------
    00008  */
    00009
    00010 // MSC equivalent must be written and tested or some #idef instructions added
    00011 // with a clear message at compile time that this is for Unix only ???
    00012
    00013 #ifdef HAVE_CONFIG_H
    00014 #include <config.h>
    00015 #endif
    00016
    00017 #include <cstdlib>
    00018 #include <cstring>
    00019 #include <stdio.h>
    00020 #include <signal.h>
    00021 #include <unistd.h>
    00022
    00023 #include "pipecom.h"
    00024
    00025
    00026
    00027 int Check( PCom *com )
    00028 {
    00029     if( ! com ) {
    00030         fprintf( stderr, "PipeCom: Null pointer.\n" );
    00031         fflush( stderr );
    00032         return 0;
    00033     }
    00034     if( kill( com->pid, 0 ) != 0 ) {
    00035         fprintf( stderr, "PipeCom: process doesn't exists.\n" );
    00036         fflush( stderr );
    00037         return 0;
    00038     }
    00039     return 1;
    00040 }
    00041
    00042
    00043 PCom * PipeComOpen( char *prog )
    00044 {
    00045     char        *args[2];
    00046     args[0] = prog;
    00047     args[1] = NULL;
    00048     return PipeComOpenArgv( prog, args );
    00049 }
    00050
    00051
    00052 PCom * PipeComOpenArgv( char *prog, char *argv[] )
    00053 {
    00054     int         toFils[2];
    00055     int         toPere[2];
    00056     int         sonPid;
    00057     PCom        * ret = NULL;
    00058
    00059     if( pipe( toFils ) < 0 ) {
    00060         perror( "PipeComOpen: Creating pipes" );
    00061         return ret;
    00062     }
    00063     if( pipe( toPere ) < 0 ) {
    00064         perror( "PipeComOpen: Creating pipes" );
    00065         return ret;
    00066     }
    00067
    00068     switch( (sonPid = vfork()) ) {
    00069     case -1:
    00070         perror("PipeComOpen: fork failed" );
    00071         return ret;
    00072         break;
    00073
    00074     case 0:
    00075         /* --- Here's the son --- */
    00076         /* --- replace old stdin --- */
    00077         if( dup2( toFils[0], fileno(stdin) ) < 0 ) {
    00078             perror( "PipeComOpen(son): could not connect" );
    00079             exit( -1 );
    00080             /* --- AVOIR: kill my father --- */
    00081         }
    00082         if( dup2( toPere[1], fileno(stdout) ) < 0 ) {
    00083             perror( "PipeComOpen(son): could not connect" );
    00084             exit( -1 );
    00085         }
    00086         if( execvp( prog, argv ) < 0 ) {
    00087             perror( prog );
    00088             perror( "PipeComOpen: can't exec" );
    00089             exit(1);
    00090         }
    00091         break;
    00092     default:
    00093         ret = (PCom *) malloc( sizeof(PCom) );
    00094         if( ! ret )
    00095             return NULL;
    00096
    00097         ret->fWrit = (FILE *)fdopen( toFils[1], "w" );
    00098         ret->fRead = (FILE *)fdopen( toPere[0], "r" );
    00099         ret->pid = sonPid;
    00100     }
    00101     return ret;
    00102 }
    00103
    00104
    00105 int PipeComSend( PCom *to, const char *line )
    00106 {
    00107     int nb = 0;
    00108     if( ! Check(to ) )
    00109         return nb;
    00110     nb = fprintf( to->fWrit, line );
    00111     fflush( to->fWrit );
    00112     return nb;
    00113 }
    00114
    00115
    00116 int PipeComSendn( PCom *to, const char *data, int n )
    00117 {
    00118     int nb = 0;
    00119     if( ! Check(to) )
    00120         return nb;
    00121
    00122     nb = fwrite( data, 1, n, to->fWrit );
    00123     fflush( to->fWrit );
    00124     return nb;
    00125 }
    00126
    00127
    00128 int PipeComReceive( PCom *from, char *data, int max )
    00129 {
    00130     if( ! Check(from) )
    00131         return 0;
    00132     if( ! data ) {
    00133       fprintf( stderr, "PipeComReceive: Invalid data pointer\n" );
    00134       fflush( stderr );
    00135       return 0;
    00136     }
    00137     if( fgets( data, max, from->fRead ) )
    00138         return strlen(data);
    00139     return 0;
    00140 }
    00141
    00142
    00143
    00144 int PipeComClose( PCom *to )
    00145 {
    00146     if( ! Check(to) )
    00147         return 0;
    00148     fclose( to->fRead );
    00149     fclose( to->fWrit );
    00150     free( to );
    00151     return 1;
    00152 }
    00153
    00154
    00155
    00156 int PipeComWaitFor( PCom *from, char *what )
    00157 {
    00158     char        buffer[256];
    00159     do {
    00160         if( ! PipeComReceive( from, buffer, 256 ) )
    00161             return 0;
    00162     } while( strcmp( buffer, what ) );
    00163     return 1;
    00164 }
    00165
    00166
    00167
    00168 // Local Variables:
    00169 // coding: iso-8859-1
    00170 // c-file-style: "Stroustrup"
    00171 // fill-column: 80
    00172 // End: