11 static const unsigned int StringSize = 4096;
15 static void my_close(int fd);
16 static void my_dup2(int old_fd, int new_fd) ;
22 void pipex_open(pipex_t *pipex,
24 const char *working_dir,
26 char string[StringSize];
30 int from_child[2], to_child[2];
36 pipex->io->in_fd = STDIN_FILENO;
37 pipex->io->out_fd = STDOUT_FILENO;
39 // attach standard error to standard output
41 my_dup2(STDOUT_FILENO,STDERR_FILENO);
45 // parse the command line and create the argument list
47 if (strlen(command) >= StringSize) my_fatal("pipex_open(): buffer overflow\n");
48 strcpy(string,command);
51 for (ptr = strtok(string," "); ptr != NULL; ptr = strtok(NULL," ")) {
59 if (pipe(from_child) == -1) {
60 my_fatal("pipex_open(): pipe(): %s\n",strerror(errno));
63 if (pipe(to_child) == -1) {
64 my_fatal("pipex_open(): pipe(): %s\n",strerror(errno));
67 // create the child process
71 if (pipex->pid == -1) {
73 my_fatal("pipex_open(): fork(): %s\n",strerror(errno));
75 } else if (pipex->pid == 0) {
79 // close unused pipe descriptors to avoid deadlocks
81 my_close(from_child[0]);
82 my_close(to_child[1]);
84 // attach the pipe to standard input
86 my_dup2(to_child[0],STDIN_FILENO);
87 my_close(to_child[0]);
89 // attach the pipe to standard output
91 my_dup2(from_child[1],STDOUT_FILENO);
92 my_close(from_child[1]);
94 // attach standard error to standard output
95 // commenting this out gives error messages on the console
97 /* my_dup2(STDOUT_FILENO,STDERR_FILENO); */
99 if(chdir(working_dir)){
100 my_fatal("pipex_open(): cannot change directory: %s\n",
104 // launch the new executable file
106 execvp(argv[0],&argv[0]);
108 // execvp() only returns when an error has occured
110 my_fatal("engine_open(): execvp(): %s\n",strerror(errno));
114 ASSERT(pipex->pid>0);
118 // close unused pipe descriptors to avoid deadlocks
120 my_close(from_child[1]);
121 my_close(to_child[0]);
123 // fill in the pipex struct
125 pipex->io->in_fd = from_child[0];
126 pipex->io->out_fd = to_child[1];
127 pipex->state|=PIPEX_ACTIVE; // can we test if this really TRUE?
134 void pipex_wait_event(pipex_t *pipex[]){
148 while((p=*(q++))!=NULL){
149 ASSERT(p->io->in_fd>=0);
150 FD_SET(p->io->in_fd,set);
151 if (p->io->in_fd > fd_max){
152 fd_max = p->io->in_fd;
156 // wait for something to read (no timeout)
159 val = select(fd_max+1,set,NULL,NULL,NULL);
160 if (val == -1 && errno != EINTR) my_fatal("pipex_wait_event(): select(): %s\n",strerror(errno));
164 while((p=*(q++))!=NULL){
165 if (FD_ISSET(p->io->in_fd,set)) io_get_update(p->io);
172 bool pipex_active(pipex_t *pipex){
173 return (pipex->state&PIPEX_ACTIVE)!=0;
178 bool pipex_eof(pipex_t *pipex){
179 return (pipex->state&PIPEX_EOF)!=0;
183 // pipex_set_priority()
185 void pipex_set_priority(pipex_t *pipex, int value){
187 setpriority(PRIO_PROCESS,pipex->pid,value);
191 // pipex_set_affinity()
193 void pipex_set_affinity(pipex_t *pipex, int value){
194 my_log("POLYGLOT Setting affinity is not yet implemented on posix\n");
199 void pipex_send_eof(pipex_t *pipex){
205 void pipex_exit(pipex_t *pipex){
212 bool pipex_readln(pipex_t *pipex, char *string){
213 while (!io_line_ready(pipex->io)) {
214 io_get_update(pipex->io);
216 if (!io_get_line(pipex->io,string,StringSize)) { // EOF
218 pipex->state|=PIPEX_EOF;
228 bool pipex_readln_nb(pipex_t *pipex, char *string){
229 if(io_line_ready(pipex->io)){
230 return pipex_readln(pipex,string);
239 void pipex_write(pipex_t *pipex, const char *string){
240 io_send_queue(pipex->io,"%s",string);
246 void pipex_writeln(pipex_t *pipex, const char *string){
247 io_send(pipex->io,"%s",string);
252 static void my_close(int fd) {
256 if (close(fd) == -1) my_fatal("my_close(): close(): %s\n",strerror(errno));
261 static void my_dup2(int old_fd, int new_fd) {
266 if (dup2(old_fd,new_fd) == -1) my_fatal("my_dup2(): dup2(): %s\n",strerror(errno));