146#define WITHEXTERNALCHANNEL 1
148#define FORM_INLINE __inline
150#define FORM_INLINE inline
156typedef unsigned char UBYTE;
159extern int (*writeBufToExtChannel)(
char *buffer,
size_t n);
160extern int (*getcFromExtChannel)();
161extern int (*setTerminatorForExternalChannel)(
char *buffer);
162extern int (*setKillModeForExternalChannel)(
int signum,
int sentToWholeGroup);
174#ifdef WITHEXTERNALCHANNEL
180#include <sys/types.h>
194int writeBufToExtChannelFailure(
char *buf,
size_t count)
196 DUMMYUSE(buf); DUMMYUSE(count);
200int setTerminatorForExternalChannelFailure(
char *newTerminator)
202 DUMMYUSE(newTerminator);
206int setKillModeForExternalChannelFailure(
int signum,
int sentToWholeGroup)
208 DUMMYUSE(signum); DUMMYUSE(sentToWholeGroup);
212int getcFromExtChannelFailure(
void)
217int (*writeBufToExtChannel)(
char *buffer,
size_t n) = &writeBufToExtChannelFailure;
218int (*setTerminatorForExternalChannel)(
char *buffer) =
219 &setTerminatorForExternalChannelFailure;
220int (*setKillModeForExternalChannel)(
int signum,
int sentToWholeGroup) =
221 &setKillModeForExternalChannelFailure;
222int (*getcFromExtChannel)(void) = &getcFromExtChannelFailure;
228#ifndef WITHEXTERNALCHANNEL
230int openExternalChannel(UBYTE *cmd,
int daemonize, UBYTE *shellname, UBYTE *stderrname)
231{ DUMMYUSE(cmd); DUMMYUSE(daemonize); DUMMYUSE(shellname); DUMMYUSE(stderrname);
return(-1); };
232int initPresetExternalChannels(UBYTE *theline,
int thetimeout) { DUMMYUSE(theline); DUMMYUSE(thetimeout);
return(-1); };
233int closeExternalChannel(
int n) { DUMMYUSE(n);
return(-1); };
234int selectExternalChannel(
int n) { DUMMYUSE(n);
return(-1); };
235int getCurrentExternalChannel(
void) {
return(0); };
236void closeAllExternalChannels(
void) {};
244typedef void (*mysighandler_t)(int);
252#define DELTA_EXT_BUF 128
256#define DELTA_EXT_LIST 8
260#define MAX_FAILS_IO 2
263typedef struct ExternalChannel {
286static EXTHANDLE *externalChannelsList=0;
288static int externalChannelsListStop=0;
289static int externalChannelsListFill=0;
292static EXTHANDLE *externalChannelsListTop=0;
303int StrLen(
char *pattern)
305register char *p=(
char*)pattern;
307 return((
int) ((p-(
char*)pattern)) );
309void *Malloc1(
int l,
char *c)
313void M_free(
void *p,
char *c)
318char *strDup1(UBYTE *instring,
char *ifwrong)
320 UBYTE *s = instring, *to;
322 to = s = (UBYTE *)Malloc1((s-instring)+1,ifwrong);
323 while ( *instring ) *to++ = *instring++;
329int PutPreVar(UBYTE *a,UBYTE *b,UBYTE *c,
int i)
341static FORM_INLINE
void extHandlerInit(EXTHANDLE *h)
346 h->killSignal=SIGKILL;
349 h->INbuf=h->IBfill=h->IBfull=h->IBstop=
350 h->terminator=h->cmd=h->shellname=h->stderrname=NULL;
354static FORM_INLINE
void extHandlerSwallowCopy(EXTHANDLE *to, EXTHANDLE *from)
358 to->fsend=from->fsend;
359 to->killSignal=from->killSignal;
360 to->daemonize=from->daemonize;
362 to->INbuf=from->INbuf;
363 to->IBfill=from->IBfill;
364 to->IBfull=from->IBfull;
365 to->IBstop=from->IBstop;
366 to->terminator=from->terminator;
368 to->shellname=from->shellname;
369 to->stderrname=from->stderrname;
374static FORM_INLINE
void
375extHandlerAlloc(EXTHANDLE *h,
char *cmd,
char *shellname,
char *stderrname)
377 h->IBfill=h->IBfull=h->INbuf=
378 Malloc1(DELTA_EXT_BUF,
"External channel buffer");
379 h->IBstop=h->INbuf+DELTA_EXT_BUF;
381 *(h->terminator=Malloc1(DELTA_EXT_BUF,
"External channel terminator"))=
'\n';
382 (h->terminator)[1]=
'\0';
385 h->cmd=(
char *)strDup1((UBYTE *)cmd,
"External channel command");
387 h->cmd=(
char *)strDup1((UBYTE *)
"/",
"External channel command");
390 (
char *)strDup1((UBYTE *)shellname,
"External channel shell name");
393 (
char *)strDup1((UBYTE *)stderrname,
"External channel stderr name");
397static FORM_INLINE
void extHandlerFree(EXTHANDLE *h)
399 if(h->stderrname) M_free(h->stderrname,
"External channel stderr name");
400 if(h->shellname) M_free(h->shellname,
"External channel shell name");
401 if(h->cmd) M_free(h->cmd,
"External channel command");
402 if(h->terminator)M_free(h->terminator,
"External channel terminator");
403 if(h->INbuf)M_free(h->INbuf,
"External channel buffer");
408static void destroyExternalChannel(EXTHANDLE *h)
413 if( (h->pid > 0) && (h->killSignal > 0) ){
416 chstatus=kill(-h->gpid,h->killSignal);
418 chstatus=kill(h->pid,h->killSignal);
421 waitpid(h->pid, &chstatus, 0);
425 if(h->frec) fclose(h->frec);
426 if( h->fsend > 0) close(h->fsend);
433static FORM_INLINE ssize_t read2b(
int fd,
char *buf,
size_t count)
437 if( (res=read(fd,buf,count)) <1 )
438 while( (errno == EINTR)&&(res <1) )
440 res=read(fd,buf,count);
445static FORM_INLINE ssize_t writeFromb(
int fd,
char *buf,
size_t count)
448 if( (res=write(fd,buf,count)) <1 )
449 while( (errno == EINTR)&&(res <1) )
451 res=write(fd,buf,count);
456static FORM_INLINE pid_t readpid(
int fd)
459 if(read2b(fd,(
char*)&tmp,
sizeof(pid_t))!=
sizeof(pid_t))
465static FORM_INLINE pid_t writepid(
int fd, pid_t thepid)
467 if(writeFromb(fd,(
char*)&thepid,
sizeof(pid_t))!=
sizeof(pid_t))
475static FORM_INLINE
int writexactly(
int fd,
char *buf,
size_t count)
481 if( (i=writeFromb(fd, buf+j, count-j)) < 0 )
return(-1);
483 if ( ((
size_t)j) == count )
break;
486 if(n>MAX_FAILS_IO)
return (-1);
494static int set_cloexec_flag(
int desc,
int value)
496int oldflags = fcntl (desc, F_GETFD, 0);
502 oldflags |= FD_CLOEXEC;
504 oldflags &= ~FD_CLOEXEC;
506 return (fcntl(desc, F_SETFD, oldflags));
512static void pushDescriptor(
int *fifo,
int top,
int fd)
522 while( (ins>=0)&&(fifo[ins]>fd) )ins--;
524 for(ins++;top>ins; top--)
525 fifo[top]=fifo[top-1];
534static FORM_INLINE
void closeAllDescriptors(
int startFrom,
int *usedFd,
int top)
539 for(;startFrom<maxfd;startFrom++)
544 maxfd=sysconf(_SC_OPEN_MAX);
545 for(;startFrom<maxfd;startFrom++)
549typedef int L_APIPE[2];
551static void closepipe(L_APIPE *thepipe)
553 if( (*thepipe)[0] != -1) close ((*thepipe)[0]);
554 if( (*thepipe)[1] != -1) close ((*thepipe)[1]);
560static FORM_INLINE
int parseline(
char **argv,
char *cmd)
564 for(; (*cmd <=
' ') && (*cmd !=
'\0') ;cmd++);
581static LONG str2i(
char *str,
char **b, LONG maxnum)
585 while(*str<=
' ')
if(*str++ ==
'\0')
return(-1);
587 while (*str>=
'0'&&*str<=
'9')
588 if( (n=10*n + *str++ -
'0')>maxnum )
599static char *l2s(LONG x,
char *to)
604 do { *s++ = (x % 10)+
'0'; i++; }
while ( ( x /= 10 ) != 0 );
608 i = to[j]; to[j] = s[-j]; s[-j] = (char)i; j--;
615static FORM_INLINE
char *addStr(
char *to,
char *from)
617 while( (*to++ = *from++)!=
'\0' );
624static FORM_INLINE ssize_t writeSome(
int fd,
char *buf,
size_t count,
int timeout)
630 int flags = fcntl(fd, F_GETFL,0);
633 fcntl(fd,F_SETFL, flags | O_NONBLOCK);
641 tv.tv_sec =timeout /1000;
642 tv.tv_usec = (timeout % 1000)*1000;
645 switch(select(fd+1, NULL, &wfds, NULL, &tv)){
647 if((nrep == 0)||( errno != EINTR) ){
658 if( (res=write(fd,buf,count)) <0 )
659 while( (errno == EINTR)&&(res <0) )
660 res=write(fd,buf,count);
666 fcntl(fd,F_SETFL, flags);
673static FORM_INLINE ssize_t readSome(
int fd,
char *buf,
size_t count,
int timeout)
685 tv.tv_sec = timeout/1000;
686 tv.tv_usec = (timeout % 1000)*1000;
689 switch(select(fd+1, &rfds, NULL, NULL, &tv)){
691 if((nrep == 0)||( errno != EINTR) ){
702 if( (res=read(fd,buf,count)) <0 )
703 while( (errno == EINTR)&&(res <0) )
704 res=read(fd,buf,count);
719int setTerminatorForExternalChannelOk(
char *newTerminator)
728char *t=externalChannelsListTop->terminator;
731 if( (*t++ = *newTerminator++)==
'\0' )
734 if( (i == DELTA_EXT_BUF)
742int setKillModeForExternalChannelOk(
int signum,
int sentToWholeGroup)
752 externalChannelsListTop->killSignal=signum;
753 if(sentToWholeGroup){
754 if(externalChannelsListTop->gpid <= 0)
755 externalChannelsListTop->gpid=-externalChannelsListTop->gpid;
757 if(externalChannelsListTop->gpid>0)
758 externalChannelsListTop->gpid=-externalChannelsListTop->gpid;
770int getcFromExtChannelOk(
void)
772mysighandler_t oldPIPE = 0;
776 if (externalChannelsListTop->IBfill < externalChannelsListTop->IBfull)
778 return( *(externalChannelsListTop->IBfill++) );
781 h= externalChannelsListTop;
783 if ( PF.me == MASTER ){
789 oldPIPE=signal(SIGPIPE,SIG_IGN);
791 if( fgets(h->INbuf,h->IBstop - h->INbuf, h->frec) == 0 )
794 if( (fgets(h->INbuf,h->IBstop - h->INbuf, h->frec) == 0)
795 ||( *(h->INbuf) ==
'\0')
797 closeExternalChannel(externalChannelsListTop-externalChannelsList+1);
799 goto getcFromExtChannelReady;
808 MesPrint(
"Fail broadcasting external channel results");
812 if( *(h->INbuf) ==
'\0'){
813 closeExternalChannel(externalChannelsListTop-externalChannelsList+1);
814 goto getcFromExtChannelReady;
819 char *t=h->terminator;
823 for(h->IBfull=h->INbuf; *(h->IBfull)!=
'\0'; (h->IBfull)++)
824 if( *t== *(h->IBfull) )
829 while(*(h->IBfull)!=
'\0')(h->IBfull)++;
831 if( (t-h->terminator) == (h->IBfull-h->INbuf) ){
834 h->IBfull=h->IBfill=h->INbuf;
835 externalChannelsListTop=0;
836 writeBufToExtChannel=&writeBufToExtChannelFailure;
837 getcFromExtChannel=&getcFromExtChannelFailure;
838 setTerminatorForExternalChannel=&setTerminatorForExternalChannelFailure;
839 setKillModeForExternalChannel=&setKillModeForExternalChannelFailure;
840 goto getcFromExtChannelReady;
844 while( *(h->IBfull - 1) !=
'\n' ){
846 int l= (h->IBstop - h->INbuf)+DELTA_EXT_BUF;
847 char *newbuf=Malloc1(l,
"External channel buffer");
850 char *n=newbuf,*o=h->INbuf;
851 while( (*n++ = *o++)!=
'\0' );
853 h->IBfull= newbuf+(h->IBfull-h->INbuf);
854 M_free(h->INbuf,
"External channel buffer");
856 h->IBstop = h->INbuf+l;
858 if ( PF.me == MASTER ){
860 if( fgets(h->IBfull,h->IBstop - h->IBfull, h->frec) == 0 ){
872 MesPrint(
"Fail broadcasting external channel results");
878 ( (h->IBfull)[0]==
'\0' )
879 &&( (h->IBfull)[1]==
'!' )
880 &&( (h->IBfull)[2]==
'\0' )
884 if( fgets(h->IBfull,h->IBstop - h->IBfull, h->frec) == 0 )
888 while( *(h->IBfull)!=
'\0' )(h->IBfull)++;
891 ret=*(h->IBfill=h->INbuf);
894 getcFromExtChannelReady:
896 if ( PF.me == MASTER ){
898 signal(SIGPIPE,oldPIPE);
910int writeBufToExtChannelOk(
char *buf,
size_t count)
914mysighandler_t oldPIPE;
917 if ( PF.me == MASTER ){
923 oldPIPE=signal(SIGPIPE,SIG_IGN);
924 ret=writexactly( externalChannelsListTop->fsend, buf, count);
925 signal(SIGPIPE,oldPIPE);
939static FORM_INLINE pid_t do_run_cmd(
952int fdin[2]={-1,-1}, fdout[2]={-1,-1}, fdsig[2]={-1,-1};
955pid_t childpid,fatherchildpid = (pid_t)0;
956mysighandler_t oldPIPE=NULL;
962 )
goto fail_do_run_cmd;
964 if((childpid = fork()) == -1){
966 goto fail_do_run_cmd;
980 pushDescriptor(fifo,top++,fdsig[1]);
981 pushDescriptor(fifo,top++,fdin[0]);
982 pushDescriptor(fifo,top++,fdout[1]);
984 closeAllDescriptors(3,fifo, top);
990 (dup(fdin[0]) == -1 )||
992 (dup(fdout[1]) == -1 )
996 writepid(fdsig[1],(pid_t)-2);
1000 if(stderrname != NULL){
1003 (open(stderrname,O_WRONLY)<0)
1006 writepid(fdsig[1],(pid_t)-2);
1015 if(set_cloexec_flag (fdsig[1], 1)!=0){
1017 writepid(fdsig[1],(pid_t)-2);
1025 (set_cloexec_flag (fdsig2[1], 1)!=0)
1029 writepid(fdsig[1],(pid_t)-2);
1032 set_cloexec_flag (fdsig2[0], 1);
1033 switch(childpid=fork()){
1038 writepid(fdsig2[1],(pid_t)-2);
1043 writepid(fdsig[1],(pid_t)-2);
1048 signal(SIGPIPE,SIG_IGN);
1058 if( readpid(fdsig2[0]) != (pid_t)-1 )
1059 writepid(fdsig[1],(pid_t)-1);
1061 writepid(fdsig[1],childpid);
1068 writepid(fdsig[1],(pid_t)-2);
1078 *fdreceive = fdout[0];
1096 oldPIPE=signal(SIGPIPE,SIG_IGN);
1100 fatherchildpid=childpid;
1101 if( (childpid=readpid(fdsig[0]))<0 ){
1103 childpid=fatherchildpid;
1104 goto fail_do_run_cmd;
1109 if( readpid(fdsig[0])!= (pid_t)-1 )
1110 goto fail_do_run_cmd;
1122 waitpid(fatherchildpid,&i,0);
1126 signal(SIGPIPE,oldPIPE);
1145static FORM_INLINE pid_t run_cmd(
char *cmd,
1156 cmd=(
char*)strDup1((UBYTE*)cmd,
"run_cmd: cmd");
1160 if(shellpath != NULL){
1163 argv=Malloc1(StrLen((UBYTE*)shellpath)*
sizeof(
char*)+2,
"run_cmd:argv");
1164 shellpath=(
char*)strDup1((UBYTE*)shellpath,
"run_cmd: shellpath");
1166 nopt=parseline(argv, shellpath);
1172 argv=Malloc1(StrLen((UBYTE*)cmd)*
sizeof(
char*)+1,
"run_cmd:argv");
1173 parseline(argv, cmd);
1180 (daemonize)?(8|16):0,
1186 M_free(argv,
"run_cmd:argv");
1188 M_free(shellpath,
"run_cmd:argv");
1189 M_free(cmd,
"run_cmd: cmd");
1208static FORM_INLINE
void *createExternalChannel(
1219 ECINFOSTRUCT *psetInfo;
1221 char statusbuf[2]={
'\0',
'\0'};
1228 psetInfo=(ECINFOSTRUCT *)shellname;
1236 if ( PF.me == MASTER ){
1239 h->pid=run_cmd (cmd, &(h->fsend),
1240 &fdreceive,&gpid,daemonize,shellname,stderrname);
1242 gpid=-psetInfo->theppid;
1243 h->pid=psetInfo->theppid;
1244 h->fsend=psetInfo->fdout;
1245 fdreceive=psetInfo->fdin;
1256 }
else if( statusbuf[0]==
'!')
1260 if(h->pid<0)
goto createExternalChannelFails;
1262 if ( PF.me == MASTER ){
1266 if( (h->frec=fdopen(fdreceive,
"r")) == 0 )
goto createExternalChannelFails;
1272 extHandlerAlloc(h,cmd,shellname,stderrname);
1275 createExternalChannelFails:
1277 destroyExternalChannel(h);
1285int openExternalChannel(UBYTE *cmd,
int daemonize, UBYTE *shellname, UBYTE *stderrname)
1287EXTHANDLE *h=externalChannelsListTop;
1290 for(externalChannelsListTop=0;i<externalChannelsListFill;i++)
1291 if(externalChannelsList[i].cmd==0){
1292 externalChannelsListTop=externalChannelsList+i;
1296 if(externalChannelsListTop==0){
1298 if(externalChannelsListFill == externalChannelsListStop){
1300 EXTHANDLE *newbuf=Malloc1(
1301 (externalChannelsListStop+=DELTA_EXT_LIST)*
sizeof(EXTHANDLE),
1302 "External channel list");
1303 for(i=0;i<externalChannelsListFill;i++)
1304 extHandlerSwallowCopy(newbuf+i,externalChannelsList+i);
1305 if(externalChannelsList!=0)
1306 M_free(externalChannelsList,
"External channel list");
1307 for(;i<externalChannelsListStop;i++)
1308 extHandlerInit(newbuf+i);
1309 externalChannelsList=newbuf;
1311 externalChannelsListTop=externalChannelsList+externalChannelsListFill;
1312 externalChannelsListFill++;
1315 if(createExternalChannel(
1316 externalChannelsListTop,
1320 (
char*)stderrname )!=NULL){
1321 writeBufToExtChannel=&writeBufToExtChannelOk;
1322 getcFromExtChannel=&getcFromExtChannelOk;
1323 setTerminatorForExternalChannel=&setTerminatorForExternalChannelOk;
1324 setKillModeForExternalChannel=&setKillModeForExternalChannelOk;
1325 return(externalChannelsListTop-externalChannelsList+1);
1328 externalChannelsListTop=h;
1337static FORM_INLINE
int openPresetExternalChannel(
int fdin,
int fdout, pid_t theppid)
1340 inf.fdin=fdin; inf.fdout=fdout;inf.theppid=theppid;
1341 return( openExternalChannel(NULL,0,(UBYTE *)&inf,NULL) );
1344#define PIDTXTSIZE 23
1345#define BOTHPIDSIZE 45
1348#define LONG_MAX 0x7FFFFFFFL
1367int initPresetExternalChannels(UBYTE *theline,
int thetimeout)
1369 int i, nchannels = 0;
1371 char pidtxt[PIDTXTSIZE],
1372 chdescriptor[PIDTXTSIZE],
1373 bothpidtxt[BOTHPIDSIZE],
1377 if ( theline == NULL )
return(-1);
1379 c = l2s((LONG)getpid(),pidtxt);
1385 pip[0] = (int)str2i((
char*)theline,&c,0xFFFF);
1386 if( ( pip[0] < 0 ) || ( *c !=
',' ) )
goto presetFails;
1388 theline = (UBYTE*)c + 1;
1389 pip[1] = (int)str2i((
char*)theline,&c,0xFFFF);
1390 if ( (pip[1] < 0 ) || ( ( *c !=
',' ) && ( *c !=
'\0' ) ) )
goto presetFails;
1391 theline = (UBYTE *)c + 1;
1398 if ( writeSome(pip[1],pidtxt,pidln,thetimeout) != pidln )
goto presetFails;
1399 i = readSome(pip[0],bothpidtxt,BOTHPIDSIZE,thetimeout);
1401 || ( i == BOTHPIDSIZE )
1404 ppid = (pid_t)str2i(bothpidtxt,&b,getpid());
1405 if( ( *b !=
',' ) || ( ppid != getpid() ) )
goto presetFails;
1411 ppid = (pid_t)str2i(b+1,&b,LONG_MAX);
1412 if ( (*b !=
'\n') || (ppid<2) )
goto presetFails;
1413 i = openPresetExternalChannel(pip[0],pip[1],ppid);
1414 if ( i < 0 )
goto presetFails;
1418 b = l2s(nchannels,addStr(bothpidtxt,
"PIPE"));
1421 *l2s(i,chdescriptor) =
'\0';
1422 PutPreVar((UBYTE*)bothpidtxt,(UBYTE*)chdescriptor,0,0);
1423 }
while ( *c !=
'\0' );
1425 *l2s(nchannels,chdescriptor)=
'\0';
1426 PutPreVar((UBYTE*)
"PIPES_",(UBYTE*)chdescriptor,0,0);
1433 for(i=0; i<nchannels; i++)
1434 destroyExternalChannel(externalChannelsList+i);
1448int selectExternalChannel(
int n)
1451 if(externalChannelsListTop!=0)
1452 ret=externalChannelsListTop-externalChannelsList+1;
1457 externalChannelsListTop=0;
1458 writeBufToExtChannel=&writeBufToExtChannelFailure;
1459 getcFromExtChannel=&getcFromExtChannelFailure;
1460 setTerminatorForExternalChannel=&setTerminatorForExternalChannelFailure;
1461 setKillModeForExternalChannel=&setKillModeForExternalChannelFailure;
1465 (n>=externalChannelsListFill)||
1466 (externalChannelsList[n].cmd==0)
1470 externalChannelsListTop=externalChannelsList+n;
1471 writeBufToExtChannel=&writeBufToExtChannelOk;
1472 getcFromExtChannel=&getcFromExtChannelOk;
1473 setTerminatorForExternalChannel=&setTerminatorForExternalChannelOk;
1474 setKillModeForExternalChannel=&setKillModeForExternalChannelOk;
1488int closeExternalChannel(
int n)
1491 n=externalChannelsListTop-externalChannelsList;
1497 (n>=externalChannelsListFill)||
1498 (externalChannelsList[n].cmd==0)
1502 destroyExternalChannel(externalChannelsList+n);
1504 if(externalChannelsListTop==externalChannelsList+n){
1505 externalChannelsListTop=NULL;
1506 writeBufToExtChannel=&writeBufToExtChannelFailure;
1507 getcFromExtChannel=&getcFromExtChannelFailure;
1508 setTerminatorForExternalChannel=&setTerminatorForExternalChannelFailure;
1509 setKillModeForExternalChannel=&setKillModeForExternalChannelFailure;
1517void closeAllExternalChannels(
void)
1520 for(i=0; i<externalChannelsListFill; i++)
1521 destroyExternalChannel(externalChannelsList+i);
1522 externalChannelsListFill=externalChannelsListStop=0;
1523 externalChannelsListTop=NULL;
1525 writeBufToExtChannel=&writeBufToExtChannelFailure;
1526 getcFromExtChannel=&getcFromExtChannelFailure;
1527 setTerminatorForExternalChannel=&setTerminatorForExternalChannelFailure;
1528 setKillModeForExternalChannel=&setKillModeForExternalChannelFailure;
1530 if(externalChannelsList!=NULL){
1531 M_free(externalChannelsList,
"External channel list");
1532 externalChannelsList=NULL;
1540pid_t getExternalChannelPid(
void)
1542 if(externalChannelsListTop!=0)
1543 return(externalChannelsListTop ->pid);
1552int getCurrentExternalChannel(
void)
1555 if ( externalChannelsListTop != 0 )
1556 return(externalChannelsListTop-externalChannelsList+1);
1575 printf(
"String started with a special letter is a command\n");
1576 printf(
"Known commands are:\n");
1577 printf(
"H or ? -- this help\n");
1578 printf(
"Nn<command> -- start a new command\n");
1579 printf(
"S<command> -- start a new command in a subshell,daemon,stderr>/dev/null\n");
1580 printf(
"C# -- destroy channel #\n");
1581 printf(
"R# -- set a new cahhel(number#) as a current one\n");
1582 printf(
"K#1 #2 -- set signal for kill and kill mode (0 or !=0)\n");
1583 printf(
" ^d to quit\n");
1595 printf(
"Initial channel:%d\n",last=openExternalChannel((UBYTE*)
"cat",0,NULL,NULL));
1597 if( ( i = setTerminatorForExternalChannel(
"qu") ) != 0 )
return 1;
1598 printf(
"Terminator is 'qu'\n");
1600 while ( fgets(buf, 1024, stdin) != NULL ) {
1601 if ( *buf ==
'N' ) {
1602 printf(
"New channel:%d\n",j=openExternalChannel((UBYTE*)buf+1,0,NULL,NULL));
1605 else if ( *buf ==
'C' ) {
1607 sscanf(buf+1,
"%d",&n);
1608 printf(
"Destroy last channel:%d\n",closeExternalChannel(n));
1611 else if ( *buf ==
'R' ) {
1613 sscanf(buf+1,
"%d",&n);
1614 printf(
"Reopen channel %d:%d\n",n,selectExternalChannel(n));
1616 }
else if( *buf ==
'K' ) {
1618 sscanf(buf+1,
"%d %d",&n,&g);
1619 printf(
"setKillMode %d\n",setKillModeForExternalChannel(n,g));
1621 }
else if( *buf ==
'S' ) {
1622 printf(
"New channel with sh&d&stderr:%d\n",
1623 j=openExternalChannel((UBYTE*)buf+1,1,(UBYTE*)
"/bin/sh -c",(UBYTE*)
"/dev/null"));
1626 else if( ( *buf ==
'H' )|| ( *buf ==
'?' ) ){
1631 writeBufToExtChannel(buf,k=StrLen(buf));
1633 for ( j = 0; ( i = getcFromExtChannel() ) !=
'\n'; j++) {
1641 printf(
"I got:'%s'; pid=%d\n",buf2,getExternalChannelPid());
1643 printf(
"Total:%lld bytes\n",sum);
1644 closeAllExternalChannels();
int PutPreVar(UBYTE *, UBYTE *, UBYTE *, int)
int PF_BroadcastString(UBYTE *str)