rllib  1
Public Member Functions | Public Attributes | Private Attributes | List of all members
rlSpawn Class Reference

#include <rlspawn.h>

Public Member Functions

 rlSpawn ()
 
virtual ~rlSpawn ()
 
int spawn (const char *command)
 
const char * readLine ()
 
int getchar ()
 
int select (int timeout=50)
 
int writeString (const char *buf)
 
int write (const char *buf, int len)
 
int printf (const char *format,...)
 
void printAll ()
 
FILE * getFilepointer ()
 
int sigkill ()
 
int readJpegBuffer (unsigned char *buffer, int maxbuffer)
 

Public Attributes

int pid
 

Private Attributes

HANDLE toChildRD
 
HANDLE toChildWR
 
HANDLE fromChildRD
 
HANDLE fromChildWR
 
HANDLE hThread
 
HANDLE hProcess
 
char line [4096]
 

Detailed Description

Spawn an external program.
Redirect <stdin> <stdout> <stderr> of external program to this class
Now you can communicate with this external program over a pipe.
Attention: This class is only available on unix like systems.

Definition at line 40 of file rlspawn.h.

Constructor & Destructor Documentation

◆ rlSpawn()

rlSpawn::rlSpawn ( )

Definition at line 137 of file rlspawn.cpp.

138 {
139 #ifdef RLWIN32
140  fromChildRD = NULL;
141  fromChildRD = NULL;
142  toChildRD = NULL;
143  toChildWR = NULL;
144  hThread = NULL;
145  hProcess = NULL;
146  pid = 0;
147 #else
148  toChild = fromChild = NULL;
149  pid = 0;
150 #endif
151 }
HANDLE fromChildRD
Definition: rlspawn.h:159
HANDLE hProcess
Definition: rlspawn.h:162
HANDLE hThread
Definition: rlspawn.h:161
int pid
Definition: rlspawn.h:153
HANDLE toChildWR
Definition: rlspawn.h:158
HANDLE toChildRD
Definition: rlspawn.h:157

◆ ~rlSpawn()

rlSpawn::~rlSpawn ( )
virtual

Definition at line 153 of file rlspawn.cpp.

154 {
155 #ifdef RLWIN32
156  if(fromChildRD != NULL) CloseHandle(fromChildRD);
157  if(fromChildWR != NULL) CloseHandle(fromChildWR);
158  if(toChildRD != NULL) CloseHandle(toChildRD);
159  if(toChildWR != NULL) CloseHandle(toChildWR);
160  if(hThread != NULL) CloseHandle(hThread);
161  if(hProcess != NULL) CloseHandle(hProcess);
162 #else
163  if(toChild != NULL) ::fclose((FILE*) toChild);
164  if(fromChild != NULL) ::fclose((FILE*) fromChild);
165 #endif
166 }
HANDLE fromChildRD
Definition: rlspawn.h:159
HANDLE hProcess
Definition: rlspawn.h:162
HANDLE hThread
Definition: rlspawn.h:161
HANDLE fromChildWR
Definition: rlspawn.h:160
HANDLE toChildWR
Definition: rlspawn.h:158
HANDLE toChildRD
Definition: rlspawn.h:157

Member Function Documentation

◆ getchar()

int rlSpawn::getchar ( )
Read a char from the spawned command.
When the command terminates EOF is returned.

Definition at line 355 of file rlspawn.cpp.

356 {
357 #ifdef RLWIN32
358  if(fromChildRD == NULL) return EOF;
359  DWORD readed = 0;
360  unsigned char buf[4];
361  int ret = (int) ReadFile(fromChildRD, buf, 1, &readed, NULL);
362  if(ret)
363  { // success
364  if(readed == 1) return buf[0];
365  }
366  if(fromChildRD != NULL) CloseHandle(fromChildRD);
367  if(fromChildWR != NULL) CloseHandle(fromChildWR);
368  if(toChildRD != NULL) CloseHandle(toChildRD);
369  if(toChildWR != NULL) CloseHandle(toChildWR);
370  if(hThread != NULL) CloseHandle(hThread);
371  if(hProcess != NULL) CloseHandle(hProcess);
372  fromChildRD = NULL;
373  fromChildWR = NULL;
374  toChildRD = NULL;
375  toChildWR = NULL;
376  hThread = NULL;
377  hProcess = NULL;
378  return EOF;
379 #else
380  if(fromChild == NULL) return EOF;
381  return ::fgetc((FILE*) fromChild);
382 #endif
383 }
HANDLE fromChildRD
Definition: rlspawn.h:159
HANDLE hProcess
Definition: rlspawn.h:162
HANDLE hThread
Definition: rlspawn.h:161
HANDLE fromChildWR
Definition: rlspawn.h:160
HANDLE toChildWR
Definition: rlspawn.h:158
HANDLE toChildRD
Definition: rlspawn.h:157

◆ getFilepointer()

FILE * rlSpawn::getFilepointer ( )
Get FILE pointer fromChild

Definition at line 488 of file rlspawn.cpp.

489 {
490 #ifdef RLWIN32
491  return NULL;
492 #else
493  return (FILE *) fromChild;
494 #endif
495 }

◆ printAll()

void rlSpawn::printAll ( )
Print all outputs from spawned command to <stdout>

Definition at line 450 of file rlspawn.cpp.

451 {
452  const char *cptr;
453  while((cptr=readLine()) != NULL) ::printf("%s",cptr);
454 }
int printf(const char *format,...)
Definition: rlspawn.cpp:402
const char * readLine()
Definition: rlspawn.cpp:307

◆ printf()

int rlSpawn::printf ( const char *  format,
  ... 
)
similar to printf
Return: number of bytes written
        -1 error

Definition at line 402 of file rlspawn.cpp.

403 {
404  int ret;
405  char message[rl_PRINTF_LENGTH]; // should be big enough
406 
407  va_list ap;
408  va_start(ap,format);
409  ret = rlvsnprintf(message, rl_PRINTF_LENGTH - 1, format, ap);
410  va_end(ap);
411  if(ret < 0) return ret;
412  return write(message,strlen(message));
413 }
#define rl_PRINTF_LENGTH
Definition: rldefine.h:71
int write(const char *buf, int len)
Definition: rlspawn.cpp:385
int rlvsnprintf(char *text, int len, const char *format, va_list ap)
Definition: rlcutil.cpp:197

◆ readJpegBuffer()

int rlSpawn::readJpegBuffer ( unsigned char *  buffer,
int  maxbuffer 
)
Read JPEG buffer fromChild
return: length of buffer | -1 as error
Example: A thread continiously reads the mjpeg output of ffmpeg and stores it in jpegBuffer
rlThread mythread;
unsigned char jpegBuffer[256*256*16];
void *myThread(void *arg) // define your thread function
{
  rlSpawn spawn;
  restart:  
  if(arg == NULL) return NULL;
  THREAD_PARAM  *p = (THREAD_PARAM *) arg;
  //myThreadsData *d = (myThreadsData *) p->user;
  spawn.spawn("ffmpeg -f video4linux2 -i /dev/v4l/by-id/usb-046d_0825_A867B3D0-video-index0 -vf \"transpose, hflip" -r 10 -f mjpeg pipe:1");  
  while(p->running)
  {
    int ret = spawn.readJpegBuffer(jpegBuffer,sizeof(jpegBuffer));
    printf("ret=%d\n",ret);
    if(ret < 0) goto restart;
  }
  return arg;
}
Example: The jpegBuffer can now be Send to a Image Widget on the pvbrowser client
extern rlThread mythread;
extern unsigned char jpegBuffer[];
static int slotNullEvent(PARAM *p, DATA *d)
{
  if(p == NULL || d == NULL) return -1;
  pvSendJpegFrame(p,imgWebcam,jpegBuffer);
  return 0;
}
 

Definition at line 526 of file rlspawn.cpp.

527 {
528  int c1, c2;
529 
530  // search for startOfImage ff d8
531  while(1)
532  {
533  if((c1 = getchar()) < 0) return -1;
534  if(c1 == 0x0ff)
535  {
536  if((c2 = getchar()) < 0) return -2;
537  if(c2 == 0x0d8)
538  {
539  break;
540  }
541  }
542  }
543 
544  int ind = 0;
545  buffer[ind++] = (unsigned char) c1;
546  buffer[ind++] = (unsigned char) c2;
547  while(1) // read until endOfImage ff d9
548  {
549  if(ind >= maxbuffer) return -3;
550  if((c1 = getchar()) < 0) return -4;
551  buffer[ind++] = (unsigned char) c1;
552  if(c1 == 0x0ff)
553  {
554  if((c2 = getchar()) < 0) return -5;
555  buffer[ind++] = (unsigned char) c2;
556  if(c2 == 0x0d9)
557  {
558  return ind;;
559  }
560  }
561  }
562 }
int getchar()
Definition: rlspawn.cpp:355

◆ readLine()

const char * rlSpawn::readLine ( )
Read a line from the spawned command.
When the command terminates NULL is returned.

Definition at line 307 of file rlspawn.cpp.

308 {
309 #ifdef RLWIN32
310  char *cptr;
311  if(fromChildRD == NULL) return NULL;
312  int i,c;
313  for(i=0; i < (int) sizeof(line) - 1; i++)
314  {
315  if((c = getchar()) < 0)
316  {
317  if(i==0) return NULL;
318  line[i] = '\0';
319  return line;
320  }
321  line[i] = (char) c;
322  if(c == '\n')
323  {
324  cptr = strchr(line,0x0d);
325  if(cptr != NULL)
326  {
327  cptr[0] = '\n';
328  cptr[1] = '\0';
329  return line;
330  }
331  line[i+1] = '\0';
332  return line;
333  }
334  }
335  line[i] = '\0';
336  return line;
337 #else
338  if(fromChild == NULL) return NULL;
339  if(::fgets(line,sizeof(line)-1,(FILE*) fromChild) == NULL)
340  {
341 #ifdef RLUNIX
342  if(pid != 0)
343  {
344  int status;
345  waitpid(pid, &status, 0);
346  kill(pid,SIGHUP);
347  }
348 #endif
349  return NULL;
350  }
351  return line;
352 #endif
353 }
HANDLE fromChildRD
Definition: rlspawn.h:159
int getchar()
Definition: rlspawn.cpp:355
char line[4096]
Definition: rlspawn.h:166
int pid
Definition: rlspawn.h:153

◆ select()

int rlSpawn::select ( int  timeout = 50)
Wait for characters.
return = 0 // timeout
return = 1 // characters available

Definition at line 456 of file rlspawn.cpp.

457 {
458 #ifdef RLWIN32
459  // windows does not support select on ReadFile
460  // ReadFile will return if there are no more bytes available
461  //if( _kbhit() ) return 1;
462  if(1) return 1;
463  if(timeout > 0) return 0;
464  if(fromChildRD == NULL) return 0;
465  return 0;
466 #else
467  struct timeval timout;
468  fd_set wset,rset,eset;
469  int ret,maxfdp1,s;
470 
471  if(fromChild == NULL) return -1;
472  s = fileno((FILE *) fromChild);
473  /* setup sockets to read */
474  maxfdp1 = s+1;
475  FD_ZERO(&rset);
476  FD_SET (s,&rset);
477  FD_ZERO(&wset);
478  FD_ZERO(&eset);
479  timout.tv_sec = timeout / 1000;
480  timout.tv_usec = (timeout % 1000) * 1000;
481 
482  ret = ::select(maxfdp1,&rset,&wset,&eset,&timout);
483  if(ret == 0) return 0; /* timeout */
484  return 1;
485 #endif
486 }
int select(int timeout=50)
Definition: rlspawn.cpp:456
HANDLE fromChildRD
Definition: rlspawn.h:159

◆ sigkill()

int rlSpawn::sigkill ( )
Kill process on other side of pipe

Definition at line 497 of file rlspawn.cpp.

498 {
499 #ifdef RLUNIX
500  if(pid == -1) return -1;
501  if(pid == 0) return -1;
502  kill(pid,SIGKILL);
503  //printf("kill pid=%ld\n",m_pid);
504 #endif
505 
506 #ifdef __VMS
507  if(pid == -1) return -1;
508  if(pid == 0) return -1;
509  kill(pid,SIGKILL);
510 #endif
511 
512 #ifdef RLWIN32
513  if(hProcess == 0) return -1;
514  TerminateProcess((HANDLE) hProcess, 0);
515  WaitForSingleObject((HANDLE) hProcess, 60000);
516  CloseHandle((HANDLE) hProcess);
517  CloseHandle((HANDLE) hThread);
518  hThread = 0;
519  hProcess = 0;
520 #endif
521 
522  pid = 0;
523  return 0;
524 }
HANDLE hProcess
Definition: rlspawn.h:162
HANDLE hThread
Definition: rlspawn.h:161
int pid
Definition: rlspawn.h:153

◆ spawn()

int rlSpawn::spawn ( const char *  command)
Start an operating system command.
The output from the command can be read with readLine()
You can write to the program with writeString() or write()
Return: 0=success -1=error

Definition at line 168 of file rlspawn.cpp.

169 {
170 #ifdef RLWIN32
171  if(fromChildRD != NULL) CloseHandle(fromChildRD);
172  if(fromChildWR != NULL) CloseHandle(fromChildWR);
173  if(toChildRD != NULL) CloseHandle(toChildRD);
174  if(toChildWR != NULL) CloseHandle(toChildWR);
175  if(hThread != NULL) CloseHandle(hThread);
176  if(hProcess != NULL) CloseHandle(hProcess);
177  fromChildRD = NULL;
178  fromChildWR = NULL;
179  toChildRD = NULL;
180  toChildWR = NULL;
181  hThread = NULL;
182  hProcess = 0;
183 
184  SECURITY_ATTRIBUTES saAttr;
185  saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
186  saAttr.bInheritHandle = TRUE;
187  saAttr.lpSecurityDescriptor = NULL;
188 
189  char cmd[strlen(command)+1];
190  strcpy(cmd,command);
191 
192  if(!CreatePipe(&fromChildRD, &fromChildWR, &saAttr, 0))
193  {
194  printf("CreatePipe() - pipe for child process STDOUT failed\n");
195  return -1;
196  }
197  if(!SetHandleInformation(fromChildRD, HANDLE_FLAG_INHERIT, 0)) // Ensure the read handle to the pipe for STDOUT is not inherited
198  {
199  printf("SetHandleInformation() - pipe STDOUT read handle failed for inheritance\n");
200  CloseHandle(fromChildRD);
201  fromChildRD = NULL;
202  CloseHandle(fromChildWR);
203  fromChildWR = NULL;
204  return -2;
205  }
206  if(!CreatePipe(&toChildRD, &toChildWR, &saAttr, 0))
207  {
208  printf("CreatePipe() - pipe for child process STDIN failed\n");
209  CloseHandle(fromChildRD);
210  fromChildRD = NULL;
211  CloseHandle(fromChildWR);
212  fromChildWR = NULL;
213  return -3;
214  }
215  if(!SetHandleInformation(toChildWR, HANDLE_FLAG_INHERIT, 0)) // Ensure the write handle to the pipe for STDIN is not inherited
216  {
217  printf("SetHandleInformation() - pipe STDIN write handle failed for inheritance\n");
218  CloseHandle(fromChildRD);
219  fromChildRD = NULL;
220  CloseHandle(fromChildWR);
221  fromChildWR = NULL;
222  CloseHandle(toChildRD);
223  toChildRD = NULL;
224  CloseHandle(toChildWR);
225  toChildWR = NULL;
226  return -4;
227  }
228 
229  STARTUPINFO si; // = { sizeof(si)};
230  memset(&si,0,sizeof(si));
231  si.cb = sizeof(si);
232  si.hStdError = fromChildWR;
233  si.hStdOutput = fromChildWR;
234  si.hStdInput = toChildRD;
235  si.dwFlags |= STARTF_USESTDHANDLES;
236 
237  PROCESS_INFORMATION pi;
238  memset(&pi,0,sizeof(pi));
239 
240  DWORD dwCreationFlags = 0;
241 
242  int ret = (int) CreateProcess( NULL, cmd
243  , NULL, NULL
244  , TRUE, dwCreationFlags
245  , NULL, NULL
246  , &si, &pi);
247  if(ret)
248  { // success
249  hProcess = pi.hProcess;
250  hThread = pi.hThread;
251  return 1;
252  }
253  // fail
254  CloseHandle(fromChildRD);
255  fromChildRD = NULL;
256  CloseHandle(fromChildWR);
257  fromChildWR = NULL;
258  CloseHandle(toChildRD);
259  toChildRD = NULL;
260  CloseHandle(toChildWR);
261  toChildWR = NULL;
262  return -1;
263 #else
264  int to_child[2],from_child[2],ret;
265 
266  if(toChild != NULL) ::fclose((FILE*) toChild);
267  if(fromChild != NULL) ::fclose((FILE*) fromChild);
268  toChild = fromChild = NULL;
269 
270  ret = ::pipe(to_child);
271  if(ret == -1) return -1;
272  ret = ::pipe(from_child);
273  if(ret == -1) return -1;
274 
275  if((pid = ::fork()) == 0)
276  {
277  if(to_child[0] != 0) // stdin
278  {
279  ::dup2(to_child[0],0);
280  ::close(to_child[0]);
281  }
282  if(from_child[1] != 2) // stderr
283  {
284  ::dup2(from_child[1] ,2);
285  }
286  if(from_child[1] != 1) // stdout
287  {
288  ::dup2(from_child[1],1);
289  ::close(from_child[1]);
290  }
291  ::close(to_child[1]);
292  ::close(from_child[0]);
293  ::rlexec(command);
294  ::exit(0);
295  }
296 
297  ::close(to_child[0]);
298  ::close(from_child[1]);
299  toChild = (void*) ::fdopen(to_child[1],"w");
300  if(toChild == NULL) { return -1; }
301  fromChild = (void*) ::fdopen(from_child[0],"r");
302  if(fromChild == NULL) { ::fclose((FILE*) toChild); return -1; }
303  return pid;
304 #endif
305 }
HANDLE fromChildRD
Definition: rlspawn.h:159
HANDLE hProcess
Definition: rlspawn.h:162
HANDLE hThread
Definition: rlspawn.h:161
int printf(const char *format,...)
Definition: rlspawn.cpp:402
int rlexec(const char *command)
Definition: rlcutil.cpp:113
int pid
Definition: rlspawn.h:153
HANDLE fromChildWR
Definition: rlspawn.h:160
HANDLE toChildWR
Definition: rlspawn.h:158
HANDLE toChildRD
Definition: rlspawn.h:157

◆ write()

int rlSpawn::write ( const char *  buf,
int  len 
)
Write buf to <stdin> of spawned command
Return: number of bytes written
        -1 error

Definition at line 385 of file rlspawn.cpp.

386 {
387 #ifdef RLWIN32
388  if(toChildWR == NULL) return -1;
389  DWORD written = 0;
390  int ret = (int) WriteFile(toChildWR, buf, len, &written, NULL);
391  if(ret)
392  { // success
393  return written;
394  }
395  return -1;
396 #else
397  if(toChild == NULL) return -1;
398  return ::write(fileno((FILE*)toChild),buf,len);
399 #endif
400 }
HANDLE toChildWR
Definition: rlspawn.h:158

◆ writeString()

int rlSpawn::writeString ( const char *  buf)
Write buf to <stdin> of spawned command
buf must be 0 terminated
Return: number of bytes written
        -1 error

Definition at line 415 of file rlspawn.cpp.

416 {
417  if(buf[0] == EOF && buf[1] == '\0')
418  {
419 #ifdef RLWIN32
420  if(fromChildRD != NULL) CloseHandle(fromChildRD);
421  if(fromChildWR != NULL) CloseHandle(fromChildWR);
422  if(toChildRD != NULL) CloseHandle(toChildRD);
423  if(toChildWR != NULL) CloseHandle(toChildWR);
424  if(hThread != NULL) CloseHandle(hThread);
425  if(hProcess != NULL) CloseHandle(hProcess);
426  fromChildRD = NULL;
427  fromChildWR = NULL;
428  toChildRD = NULL;
429  toChildWR = NULL;
430  hThread = NULL;
431  hProcess = NULL;
432 #else
433  if(toChild != NULL) ::fclose((FILE*) toChild);
434  if(fromChild != NULL) ::fclose((FILE*) fromChild);
435  toChild = NULL;
436  fromChild = NULL;
437 #endif
438  return 0;
439  }
440 #ifdef RLWIN32
441  if(toChildWR == NULL) return -1;
442  int len = strlen(buf);
443  return write(buf,len+1);
444 #else
445  if(toChild == NULL) return -1;
446  return fprintf((FILE*)toChild,"%s",buf);
447 #endif
448 }
HANDLE fromChildRD
Definition: rlspawn.h:159
HANDLE hProcess
Definition: rlspawn.h:162
HANDLE hThread
Definition: rlspawn.h:161
int write(const char *buf, int len)
Definition: rlspawn.cpp:385
HANDLE fromChildWR
Definition: rlspawn.h:160
HANDLE toChildWR
Definition: rlspawn.h:158
HANDLE toChildRD
Definition: rlspawn.h:157

Member Data Documentation

◆ fromChildRD

HANDLE rlSpawn::fromChildRD
private

Definition at line 159 of file rlspawn.h.

◆ fromChildWR

HANDLE rlSpawn::fromChildWR
private

Definition at line 160 of file rlspawn.h.

◆ hProcess

HANDLE rlSpawn::hProcess
private

Definition at line 162 of file rlspawn.h.

◆ hThread

HANDLE rlSpawn::hThread
private

Definition at line 161 of file rlspawn.h.

◆ line

char rlSpawn::line[4096]
private

Definition at line 166 of file rlspawn.h.

◆ pid

int rlSpawn::pid

Definition at line 153 of file rlspawn.h.

◆ toChildRD

HANDLE rlSpawn::toChildRD
private

Definition at line 157 of file rlspawn.h.

◆ toChildWR

HANDLE rlSpawn::toChildWR
private

Definition at line 158 of file rlspawn.h.


The documentation for this class was generated from the following files: