rllib  1
rlspawn.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                           rlspawn.cpp  -  description
00003                              -------------------
00004     begin                : Tue Jan 02 2001
00005     copyright            : (C) 2001 by Rainer Lehrig
00006     email                : lehrig@t-online.de
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This library is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as        *
00013  *   published by the Free Software Foundation                             *
00014  *                                                                         *
00015  ***************************************************************************/
00016 #include "rldefine.h"
00017 #include <stdio.h>
00018 #include <stdarg.h>
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #ifndef RLWIN32
00022 #include <unistd.h>
00023 #include <sys/time.h>
00024 #include <sys/types.h>
00025 #endif
00026 #include "rlspawn.h"
00027 #include "rlcutil.h"
00028 #ifdef RLUNIX
00029 #include <sys/wait.h>
00030 #include <signal.h>
00031 #endif
00032 
00033 rlSpawn::rlSpawn()
00034 {
00035   toChild = fromChild = NULL;
00036   pid = 0;
00037 }
00038 
00039 rlSpawn::~rlSpawn()
00040 {
00041   if(toChild   != NULL) ::fclose((FILE*) toChild);
00042   if(fromChild != NULL) ::fclose((FILE*) fromChild);
00043 }
00044 
00045 int rlSpawn::spawn(const char *command)
00046 {
00047 #ifdef RLWIN32 
00048   return -1;
00049 #else  
00050   int to_child[2],from_child[2],ret;
00051 
00052   if(toChild   != NULL) ::fclose((FILE*) toChild);
00053   if(fromChild != NULL) ::fclose((FILE*) fromChild);
00054   toChild = fromChild = NULL;
00055 
00056   ret = ::pipe(to_child);
00057   if(ret == -1) return -1;
00058   ret = ::pipe(from_child);
00059   if(ret == -1) return -1;
00060 
00061   if((pid = ::fork()) == 0)
00062   {
00063     if(to_child[0] != 0) // stdin
00064     {
00065       ::dup2(to_child[0],0);
00066       ::close(to_child[0]);
00067     }
00068     if(from_child[1] != 2) // stderr
00069     {
00070       ::dup2(from_child[1] ,2);
00071     }
00072     if(from_child[1] != 1) // stdout
00073     {
00074       ::dup2(from_child[1],1);
00075       ::close(from_child[1]);
00076     }
00077     ::close(to_child[1]);
00078     ::close(from_child[0]);
00079     ::rlexec(command);
00080     ::exit(0);
00081   }
00082 
00083   ::close(to_child[0]);
00084   ::close(from_child[1]);
00085   toChild   = (void*) ::fdopen(to_child[1],"w");
00086   if(toChild == NULL)   {                            return -1; }
00087   fromChild = (void*) ::fdopen(from_child[0],"r");
00088   if(fromChild == NULL) { ::fclose((FILE*) toChild); return -1; }
00089   return pid;
00090 #endif
00091 }
00092 
00093 const char *rlSpawn::readLine()
00094 {
00095   if(fromChild == NULL) return NULL;
00096   if(::fgets(line,sizeof(line)-1,(FILE*) fromChild) == NULL)
00097   {
00098 #ifdef RLUNIX
00099     if(pid != 0)
00100     {
00101       int status;
00102       waitpid(pid, &status, 0);
00103       kill(pid,SIGHUP);
00104     }
00105 #endif
00106     return NULL;
00107   }
00108   return line;
00109 }
00110 
00111 int rlSpawn::getchar()
00112 {
00113   if(fromChild == NULL) return EOF;
00114   return ::fgetc((FILE*) fromChild);
00115 }
00116 
00117 int rlSpawn::write(const char *buf, int len)
00118 {
00119 #ifdef RLWIN32
00120   return -1;
00121 #else  
00122   if(toChild == NULL) return -1;
00123   return ::write(fileno((FILE*)toChild),buf,len);
00124 #endif
00125 }
00126 
00127 int rlSpawn::printf(const char *format, ...)
00128 {
00129   int ret;
00130   char message[rl_PRINTF_LENGTH]; // should be big enough
00131 
00132   va_list ap;
00133   va_start(ap,format);
00134   ret = rlvsnprintf(message, rl_PRINTF_LENGTH - 1, format, ap);
00135   va_end(ap);
00136   if(ret < 0) return ret;
00137   return write(message,strlen(message));
00138 }
00139 
00140 int rlSpawn::writeString(const char *buf)
00141 {
00142   if(toChild == NULL) return -1;
00143   return fprintf((FILE*)toChild,"%s",buf);
00144 }
00145 
00146 void rlSpawn::printAll()
00147 {
00148   const char *cptr;
00149   while((cptr=readLine()) != NULL) ::printf("%s",cptr);
00150 }
00151 
00152 int rlSpawn::select(int timeout)
00153 {
00154 #ifdef RLWIN32
00155   return -1;
00156 #else
00157   struct timeval timout;
00158   fd_set wset,rset,eset;
00159   int    ret,maxfdp1,s;
00160 
00161   if(fromChild == NULL) return -1;
00162   s = fileno((FILE *) fromChild);
00163   /* setup sockets to read */
00164   maxfdp1 = s+1;
00165   FD_ZERO(&rset);
00166   FD_SET (s,&rset);
00167   FD_ZERO(&wset);
00168   FD_ZERO(&eset);
00169   timout.tv_sec  =  timeout / 1000;
00170   timout.tv_usec = (timeout % 1000) * 1000;
00171 
00172   ret = ::select(maxfdp1,&rset,&wset,&eset,&timout);
00173   if(ret == 0) return 0; /* timeout */
00174   return 1;
00175 #endif  
00176 }
00177 
00178 
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines