EvolvingObjects
|
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 #ifndef _WINDOWS 00018 00019 #include <cstdlib> 00020 #include <cstring> 00021 #include <stdio.h> 00022 #include <signal.h> 00023 #include <unistd.h> 00024 00025 #include "pipecom.h" 00026 00027 00028 00029 int Check( PCom *com ) 00030 { 00031 if( ! com ) { 00032 fprintf( stderr, "PipeCom: Null pointer.\n" ); 00033 fflush( stderr ); 00034 return 0; 00035 } 00036 if( kill( com->pid, 0 ) != 0 ) { 00037 fprintf( stderr, "PipeCom: process doesn't exists.\n" ); 00038 fflush( stderr ); 00039 return 0; 00040 } 00041 return 1; 00042 } 00043 00044 00045 PCom * PipeComOpen( char *prog ) 00046 { 00047 char *args[2]; 00048 args[0] = prog; 00049 args[1] = NULL; 00050 return PipeComOpenArgv( prog, args ); 00051 } 00052 00053 00054 PCom * PipeComOpenArgv( char *prog, char *argv[] ) 00055 { 00056 int toFils[2]; 00057 int toPere[2]; 00058 int sonPid; 00059 PCom * ret = NULL; 00060 00061 if( pipe( toFils ) < 0 ) { 00062 perror( "PipeComOpen: Creating pipes" ); 00063 return ret; 00064 } 00065 if( pipe( toPere ) < 0 ) { 00066 perror( "PipeComOpen: Creating pipes" ); 00067 return ret; 00068 } 00069 00070 switch( (sonPid = vfork()) ) { 00071 case -1: 00072 perror("PipeComOpen: fork failed" ); 00073 return ret; 00074 break; 00075 00076 case 0: 00077 /* --- Here's the son --- */ 00078 /* --- replace old stdin --- */ 00079 if( dup2( toFils[0], fileno(stdin) ) < 0 ) { 00080 perror( "PipeComOpen(son): could not connect" ); 00081 exit( -1 ); 00082 /* --- AVOIR: kill my father --- */ 00083 } 00084 if( dup2( toPere[1], fileno(stdout) ) < 0 ) { 00085 perror( "PipeComOpen(son): could not connect" ); 00086 exit( -1 ); 00087 } 00088 if( execvp( prog, argv ) < 0 ) { 00089 perror( prog ); 00090 perror( "PipeComOpen: can't exec" ); 00091 exit(1); 00092 } 00093 break; 00094 default: 00095 ret = (PCom *) malloc( sizeof(PCom) ); 00096 if( ! ret ) 00097 return NULL; 00098 00099 ret->fWrit = (FILE *)fdopen( toFils[1], "w" ); 00100 ret->fRead = (FILE *)fdopen( toPere[0], "r" ); 00101 ret->pid = sonPid; 00102 } 00103 return ret; 00104 } 00105 00106 00107 int PipeComSend( PCom *to, const char *line ) 00108 { 00109 int nb = 0; 00110 if( ! Check(to ) ) 00111 return nb; 00112 nb = fprintf( to->fWrit, line, 0 ); 00113 fflush( to->fWrit ); 00114 return nb; 00115 } 00116 00117 00118 int PipeComSendn( PCom *to, const char *data, int n ) 00119 { 00120 int nb = 0; 00121 if( ! Check(to) ) 00122 return nb; 00123 00124 nb = fwrite( data, 1, n, to->fWrit ); 00125 fflush( to->fWrit ); 00126 return nb; 00127 } 00128 00129 00130 int PipeComReceive( PCom *from, char *data, int max ) 00131 { 00132 if( ! Check(from) ) 00133 return 0; 00134 if( ! data ) { 00135 fprintf( stderr, "PipeComReceive: Invalid data pointer\n" ); 00136 fflush( stderr ); 00137 return 0; 00138 } 00139 if( fgets( data, max, from->fRead ) ) 00140 return strlen(data); 00141 return 0; 00142 } 00143 00144 00145 00146 int PipeComClose( PCom *to ) 00147 { 00148 if( ! Check(to) ) 00149 return 0; 00150 fclose( to->fRead ); 00151 fclose( to->fWrit ); 00152 free( to ); 00153 return 1; 00154 } 00155 00156 00157 00158 int PipeComWaitFor( PCom *from, char *what ) 00159 { 00160 char buffer[256]; 00161 do { 00162 if( ! PipeComReceive( from, buffer, 256 ) ) 00163 return 0; 00164 } while( strcmp( buffer, what ) ); 00165 return 1; 00166 } 00167 00168 #endif /*_MSC_VER*/ 00169 00170 00171 // Local Variables: 00172 // coding: iso-8859-1 00173 // c-file-style: "Stroustrup" 00174 // fill-column: 80 00175 // End: