148#define WITHEXTERNALCHANNEL 1
150#define FORM_INLINE __inline
152#define FORM_INLINE inline
162typedef unsigned char UBYTE;
165extern int (*writeBufToExtChannel)(
char *buffer,
size_t n);
166extern int (*getcFromExtChannel)();
167extern int (*setTerminatorForExternalChannel)(
char *buffer);
168extern int (*setKillModeForExternalChannel)(
int signum,
int sentToWholeGroup);
180#ifdef WITHEXTERNALCHANNEL
186#include <sys/types.h>
200int writeBufToExtChannelFailure(
char *buf,
size_t count)
202 DUMMYUSE(buf); DUMMYUSE(count);
206int setTerminatorForExternalChannelFailure(
char *newTerminator)
208 DUMMYUSE(newTerminator);
212int setKillModeForExternalChannelFailure(
int signum,
int sentToWholeGroup)
214 DUMMYUSE(signum); DUMMYUSE(sentToWholeGroup);
218int getcFromExtChannelFailure()
223int (*writeBufToExtChannel)(
char *buffer,
size_t n) = &writeBufToExtChannelFailure;
224int (*setTerminatorForExternalChannel)(
char *buffer) =
225 &setTerminatorForExternalChannelFailure;
226int (*setKillModeForExternalChannel)(
int signum,
int sentToWholeGroup) =
227 &setKillModeForExternalChannelFailure;
228int (*getcFromExtChannel)() = &getcFromExtChannelFailure;
234#ifndef WITHEXTERNALCHANNEL
236int openExternalChannel(UBYTE *cmd,
int daemonize, UBYTE *shellname, UBYTE *stderrname)
237{ DUMMYUSE(cmd); DUMMYUSE(daemonize); DUMMYUSE(shellname); DUMMYUSE(stderrname);
return(-1); };
238int initPresetExternalChannels(UBYTE *theline,
int thetimeout) { DUMMYUSE(theline); DUMMYUSE(thetimeout);
return(-1); };
239int closeExternalChannel(
int n) { DUMMYUSE(n);
return(-1); };
240int selectExternalChannel(
int n) { DUMMYUSE(n);
return(-1); };
241int getCurrentExternalChannel() {
return(0); };
242void closeAllExternalChannels() {};
250typedef void (*mysighandler_t)(int);
258#define DELTA_EXT_BUF 128
262#define DELTA_EXT_LIST 8
266#define MAX_FAILS_IO 2
269typedef struct ExternalChannel {
293static EXTHANDLE *externalChannelsList=0;
295static int externalChannelsListStop=0;
296static int externalChannelsListFill=0;
299static EXTHANDLE *externalChannelsListTop=0;
310int StrLen(
char *pattern)
312register char *p=(
char*)pattern;
314 return((
int) ((p-(
char*)pattern)) );
316void *Malloc1(
int l,
char *c)
320void M_free(
void *p,
char *c)
325char *strDup1(UBYTE *instring,
char *ifwrong)
327 UBYTE *s = instring, *to;
329 to = s = (UBYTE *)Malloc1((s-instring)+1,ifwrong);
330 while ( *instring ) *to++ = *instring++;
336int PutPreVar(UBYTE *a,UBYTE *b,UBYTE *c,
int i)
348static FORM_INLINE VOID extHandlerInit(EXTHANDLE *h)
353 h->killSignal=SIGKILL;
356 h->INbuf=h->IBfill=h->IBfull=h->IBstop=
357 h->terminator=h->cmd=h->shellname=h->stderrname=NULL;
361static FORM_INLINE VOID extHandlerSwallowCopy(EXTHANDLE *to, EXTHANDLE *from)
365 to->fsend=from->fsend;
366 to->killSignal=from->killSignal;
367 to->daemonize=from->daemonize;
369 to->INbuf=from->INbuf;
370 to->IBfill=from->IBfill;
371 to->IBfull=from->IBfull;
372 to->IBstop=from->IBstop;
373 to->terminator=from->terminator;
375 to->shellname=from->shellname;
376 to->stderrname=from->stderrname;
381static FORM_INLINE VOID
382extHandlerAlloc(EXTHANDLE *h,
char *cmd,
char *shellname,
char *stderrname)
384 h->IBfill=h->IBfull=h->INbuf=
385 Malloc1(DELTA_EXT_BUF,
"External channel buffer");
386 h->IBstop=h->INbuf+DELTA_EXT_BUF;
388 *(h->terminator=Malloc1(DELTA_EXT_BUF,
"External channel terminator"))=
'\n';
389 (h->terminator)[1]=
'\0';
392 h->cmd=(
char *)strDup1((UBYTE *)cmd,
"External channel command");
394 h->cmd=(
char *)strDup1((UBYTE *)
"/",
"External channel command");
397 (
char *)strDup1((UBYTE *)shellname,
"External channel shell name");
400 (
char *)strDup1((UBYTE *)stderrname,
"External channel stderr name");
404static FORM_INLINE VOID extHandlerFree(EXTHANDLE *h)
406 if(h->stderrname) M_free(h->stderrname,
"External channel stderr name");
407 if(h->shellname) M_free(h->shellname,
"External channel shell name");
408 if(h->cmd) M_free(h->cmd,
"External channel command");
409 if(h->terminator)M_free(h->terminator,
"External channel terminator");
410 if(h->INbuf)M_free(h->INbuf,
"External channel buffer");
415static VOID destroyExternalChannel(EXTHANDLE *h)
420 if( (h->pid > 0) && (h->killSignal > 0) ){
423 chstatus=kill(-h->gpid,h->killSignal);
425 chstatus=kill(h->pid,h->killSignal);
428 waitpid(h->pid, &chstatus, 0);
432 if(h->frec) fclose(h->frec);
433 if( h->fsend > 0) close(h->fsend);
440static FORM_INLINE ssize_t read2b(
int fd,
char *buf,
size_t count)
444 if( (res=read(fd,buf,count)) <1 )
445 while( (errno == EINTR)&&(res <1) )
447 res=read(fd,buf,count);
452static FORM_INLINE ssize_t writeFromb(
int fd,
char *buf,
size_t count)
455 if( (res=write(fd,buf,count)) <1 )
456 while( (errno == EINTR)&&(res <1) )
458 res=write(fd,buf,count);
463static FORM_INLINE pid_t readpid(
int fd)
466 if(read2b(fd,(
char*)&tmp,
sizeof(pid_t))!=
sizeof(pid_t))
472static FORM_INLINE pid_t writepid(
int fd, pid_t thepid)
474 if(writeFromb(fd,(
char*)&thepid,
sizeof(pid_t))!=
sizeof(pid_t))
482static FORM_INLINE
int writexactly(
int fd,
char *buf,
size_t count)
488 if( (i=writeFromb(fd, buf+j, count-j)) < 0 )
return(-1);
490 if ( ((
size_t)j) == count )
break;
493 if(n>MAX_FAILS_IO)
return (-1);
501static int set_cloexec_flag(
int desc,
int value)
503int oldflags = fcntl (desc, F_GETFD, 0);
509 oldflags |= FD_CLOEXEC;
511 oldflags &= ~FD_CLOEXEC;
513 return (fcntl(desc, F_SETFD, oldflags));
519static VOID pushDescriptor(
int *fifo,
int top,
int fd)
529 while( (ins>=0)&&(fifo[ins]>fd) )ins--;
531 for(ins++;top>ins; top--)
532 fifo[top]=fifo[top-1];
541static FORM_INLINE VOID closeAllDescriptors(
int startFrom,
int *usedFd,
int top)
546 for(;startFrom<maxfd;startFrom++)
551 maxfd=sysconf(_SC_OPEN_MAX);
552 for(;startFrom<maxfd;startFrom++)
556typedef int L_APIPE[2];
558static VOID closepipe(L_APIPE *thepipe)
560 if( (*thepipe)[0] != -1) close ((*thepipe)[0]);
561 if( (*thepipe)[1] != -1) close ((*thepipe)[1]);
567static FORM_INLINE
int parseline(
char **argv,
char *cmd)
571 for(; (*cmd <=
' ') && (*cmd !=
'\0') ;cmd++);
588static LONG str2i(
char *str,
char **b, LONG maxnum)
592 while(*str<=
' ')
if(*str++ ==
'\0')
return(-1);
594 while (*str>=
'0'&&*str<=
'9')
595 if( (n=10*n + *str++ -
'0')>maxnum )
606static char *l2s(LONG x,
char *to)
611 do { *s++ = (x % 10)+
'0'; i++; }
while ( ( x /= 10 ) != 0 );
615 i = to[j]; to[j] = s[-j]; s[-j] = (char)i; j--;
622static FORM_INLINE
char *addStr(
char *to,
char *from)
624 while( (*to++ = *from++)!=
'\0' );
631static FORM_INLINE ssize_t writeSome(
int fd,
char *buf,
size_t count,
int timeout)
637 int flags = fcntl(fd, F_GETFL,0);
640 fcntl(fd,F_SETFL, flags | O_NONBLOCK);
648 tv.tv_sec =timeout /1000;
649 tv.tv_usec = (timeout % 1000)*1000;
652 switch(select(fd+1, NULL, &wfds, NULL, &tv)){
654 if((nrep == 0)||( errno != EINTR) ){
665 if( (res=write(fd,buf,count)) <0 )
666 while( (errno == EINTR)&&(res <0) )
667 res=write(fd,buf,count);
673 fcntl(fd,F_SETFL, flags);
680static FORM_INLINE ssize_t readSome(
int fd,
char *buf,
size_t count,
int timeout)
692 tv.tv_sec = timeout/1000;
693 tv.tv_usec = (timeout % 1000)*1000;
696 switch(select(fd+1, &rfds, NULL, NULL, &tv)){
698 if((nrep == 0)||( errno != EINTR) ){
709 if( (res=read(fd,buf,count)) <0 )
710 while( (errno == EINTR)&&(res <0) )
711 res=read(fd,buf,count);
726int setTerminatorForExternalChannelOk(
char *newTerminator)
735char *t=externalChannelsListTop->terminator;
738 if( (*t++ = *newTerminator++)==
'\0' )
741 if( (i == DELTA_EXT_BUF)
749int setKillModeForExternalChannelOk(
int signum,
int sentToWholeGroup)
759 externalChannelsListTop->killSignal=signum;
760 if(sentToWholeGroup){
761 if(externalChannelsListTop->gpid <= 0)
762 externalChannelsListTop->gpid=-externalChannelsListTop->gpid;
764 if(externalChannelsListTop->gpid>0)
765 externalChannelsListTop->gpid=-externalChannelsListTop->gpid;
777int getcFromExtChannelOk()
779mysighandler_t oldPIPE = 0;
783 if (externalChannelsListTop->IBfill < externalChannelsListTop->IBfull)
785 return( *(externalChannelsListTop->IBfill++) );
788 h= externalChannelsListTop;
790 if ( PF.me == MASTER ){
796 oldPIPE=signal(SIGPIPE,SIG_IGN);
798 if( fgets(h->INbuf,h->IBstop - h->INbuf, h->frec) == 0 )
801 if( (fgets(h->INbuf,h->IBstop - h->INbuf, h->frec) == 0)
802 ||( *(h->INbuf) ==
'\0')
804 closeExternalChannel(externalChannelsListTop-externalChannelsList+1);
806 goto getcFromExtChannelReady;
815 MesPrint(
"Fail broadcasting external channel results");
819 if( *(h->INbuf) ==
'\0'){
820 closeExternalChannel(externalChannelsListTop-externalChannelsList+1);
821 goto getcFromExtChannelReady;
826 char *t=h->terminator;
830 for(h->IBfull=h->INbuf; *(h->IBfull)!=
'\0'; (h->IBfull)++)
831 if( *t== *(h->IBfull) )
836 while(*(h->IBfull)!=
'\0')(h->IBfull)++;
838 if( (t-h->terminator) == (h->IBfull-h->INbuf) ){
841 h->IBfull=h->IBfill=h->INbuf;
842 externalChannelsListTop=0;
843 writeBufToExtChannel=&writeBufToExtChannelFailure;
844 getcFromExtChannel=&getcFromExtChannelFailure;
845 setTerminatorForExternalChannel=&setTerminatorForExternalChannelFailure;
846 setKillModeForExternalChannel=&setKillModeForExternalChannelFailure;
847 goto getcFromExtChannelReady;
851 while( *(h->IBfull - 1) !=
'\n' ){
853 int l= (h->IBstop - h->INbuf)+DELTA_EXT_BUF;
854 char *newbuf=Malloc1(l,
"External channel buffer");
857 char *n=newbuf,*o=h->INbuf;
858 while( (*n++ = *o++)!=
'\0' );
860 h->IBfull= newbuf+(h->IBfull-h->INbuf);
861 M_free(h->INbuf,
"External channel buffer");
863 h->IBstop = h->INbuf+l;
865 if ( PF.me == MASTER ){
867 if( fgets(h->IBfull,h->IBstop - h->IBfull, h->frec) == 0 ){
879 MesPrint(
"Fail broadcasting external channel results");
885 ( (h->IBfull)[0]==
'\0' )
886 &&( (h->IBfull)[1]==
'!' )
887 &&( (h->IBfull)[2]==
'\0' )
891 if( fgets(h->IBfull,h->IBstop - h->IBfull, h->frec) == 0 )
895 while( *(h->IBfull)!=
'\0' )(h->IBfull)++;
898 ret=*(h->IBfill=h->INbuf);
901 getcFromExtChannelReady:
903 if ( PF.me == MASTER ){
905 signal(SIGPIPE,oldPIPE);
917int writeBufToExtChannelOk(
char *buf,
size_t count)
921mysighandler_t oldPIPE;
924 if ( PF.me == MASTER ){
930 oldPIPE=signal(SIGPIPE,SIG_IGN);
931 ret=writexactly( externalChannelsListTop->fsend, buf, count);
932 signal(SIGPIPE,oldPIPE);
946static FORM_INLINE pid_t do_run_cmd(
959int fdin[2]={-1,-1}, fdout[2]={-1,-1}, fdsig[2]={-1,-1};
962pid_t childpid,fatherchildpid = (pid_t)0;
963mysighandler_t oldPIPE=NULL;
969 )
goto fail_do_run_cmd;
971 if((childpid = fork()) == -1){
973 goto fail_do_run_cmd;
987 pushDescriptor(fifo,top++,fdsig[1]);
988 pushDescriptor(fifo,top++,fdin[0]);
989 pushDescriptor(fifo,top++,fdout[1]);
991 closeAllDescriptors(3,fifo, top);
997 (dup(fdin[0]) == -1 )||
999 (dup(fdout[1]) == -1 )
1003 writepid(fdsig[1],(pid_t)-2);
1007 if(stderrname != NULL){
1010 (open(stderrname,O_WRONLY)<0)
1013 writepid(fdsig[1],(pid_t)-2);
1022 if(set_cloexec_flag (fdsig[1], 1)!=0){
1024 writepid(fdsig[1],(pid_t)-2);
1032 (set_cloexec_flag (fdsig2[1], 1)!=0)
1036 writepid(fdsig[1],(pid_t)-2);
1039 set_cloexec_flag (fdsig2[0], 1);
1040 switch(childpid=fork()){
1045 writepid(fdsig2[1],(pid_t)-2);
1050 writepid(fdsig[1],(pid_t)-2);
1055 signal(SIGPIPE,SIG_IGN);
1065 if( readpid(fdsig2[0]) != (pid_t)-1 )
1066 writepid(fdsig[1],(pid_t)-1);
1068 writepid(fdsig[1],childpid);
1075 writepid(fdsig[1],(pid_t)-2);
1085 *fdreceive = fdout[0];
1103 oldPIPE=signal(SIGPIPE,SIG_IGN);
1107 fatherchildpid=childpid;
1108 if( (childpid=readpid(fdsig[0]))<0 ){
1110 childpid=fatherchildpid;
1111 goto fail_do_run_cmd;
1116 if( readpid(fdsig[0])!= (pid_t)-1 )
1117 goto fail_do_run_cmd;
1129 waitpid(fatherchildpid,&i,0);
1133 signal(SIGPIPE,oldPIPE);
1152static FORM_INLINE pid_t run_cmd(
char *cmd,
1163 cmd=(
char*)strDup1((UBYTE*)cmd,
"run_cmd: cmd");
1167 if(shellpath != NULL){
1170 argv=Malloc1(StrLen((UBYTE*)shellpath)*
sizeof(
char*)+2,
"run_cmd:argv");
1171 shellpath=(
char*)strDup1((UBYTE*)shellpath,
"run_cmd: shellpath");
1173 nopt=parseline(argv, shellpath);
1179 argv=Malloc1(StrLen((UBYTE*)cmd)*
sizeof(
char*)+1,
"run_cmd:argv");
1180 parseline(argv, cmd);
1187 (daemonize)?(8|16):0,
1193 M_free(argv,
"run_cmd:argv");
1195 M_free(shellpath,
"run_cmd:argv");
1196 M_free(cmd,
"run_cmd: cmd");
1215static FORM_INLINE
void *createExternalChannel(
1226 ECINFOSTRUCT *psetInfo;
1228 char statusbuf[2]={
'\0',
'\0'};
1235 psetInfo=(ECINFOSTRUCT *)shellname;
1243 if ( PF.me == MASTER ){
1246 h->pid=run_cmd (cmd, &(h->fsend),
1247 &fdreceive,&gpid,daemonize,shellname,stderrname);
1249 gpid=-psetInfo->theppid;
1250 h->pid=psetInfo->theppid;
1251 h->fsend=psetInfo->fdout;
1252 fdreceive=psetInfo->fdin;
1263 }
else if( statusbuf[0]==
'!')
1267 if(h->pid<0)
goto createExternalChannelFails;
1269 if ( PF.me == MASTER ){
1273 if( (h->frec=fdopen(fdreceive,
"r")) == 0 )
goto createExternalChannelFails;
1279 extHandlerAlloc(h,cmd,shellname,stderrname);
1282 createExternalChannelFails:
1284 destroyExternalChannel(h);
1292int openExternalChannel(UBYTE *cmd,
int daemonize, UBYTE *shellname, UBYTE *stderrname)
1294EXTHANDLE *h=externalChannelsListTop;
1297 for(externalChannelsListTop=0;i<externalChannelsListFill;i++)
1298 if(externalChannelsList[i].cmd==0){
1299 externalChannelsListTop=externalChannelsList+i;
1303 if(externalChannelsListTop==0){
1305 if(externalChannelsListFill == externalChannelsListStop){
1307 EXTHANDLE *newbuf=Malloc1(
1308 (externalChannelsListStop+=DELTA_EXT_LIST)*
sizeof(EXTHANDLE),
1309 "External channel list");
1310 for(i=0;i<externalChannelsListFill;i++)
1311 extHandlerSwallowCopy(newbuf+i,externalChannelsList+i);
1312 if(externalChannelsList!=0)
1313 M_free(externalChannelsList,
"External channel list");
1314 for(;i<externalChannelsListStop;i++)
1315 extHandlerInit(newbuf+i);
1316 externalChannelsList=newbuf;
1318 externalChannelsListTop=externalChannelsList+externalChannelsListFill;
1319 externalChannelsListFill++;
1322 if(createExternalChannel(
1323 externalChannelsListTop,
1327 (
char*)stderrname )!=NULL){
1328 writeBufToExtChannel=&writeBufToExtChannelOk;
1329 getcFromExtChannel=&getcFromExtChannelOk;
1330 setTerminatorForExternalChannel=&setTerminatorForExternalChannelOk;
1331 setKillModeForExternalChannel=&setKillModeForExternalChannelOk;
1332 return(externalChannelsListTop-externalChannelsList+1);
1335 externalChannelsListTop=h;
1344static FORM_INLINE
int openPresetExternalChannel(
int fdin,
int fdout, pid_t theppid)
1347 inf.fdin=fdin; inf.fdout=fdout;inf.theppid=theppid;
1348 return( openExternalChannel(NULL,0,(UBYTE *)&inf,NULL) );
1351#define PIDTXTSIZE 23
1352#define BOTHPIDSIZE 45
1355#define LONG_MAX 0x7FFFFFFFL
1374int initPresetExternalChannels(UBYTE *theline,
int thetimeout)
1376 int i, nchannels = 0;
1378 char pidtxt[PIDTXTSIZE],
1379 chdescriptor[PIDTXTSIZE],
1380 bothpidtxt[BOTHPIDSIZE],
1384 if ( theline == NULL )
return(-1);
1386 c = l2s((LONG)getpid(),pidtxt);
1392 pip[0] = (int)str2i((
char*)theline,&c,0xFFFF);
1393 if( ( pip[0] < 0 ) || ( *c !=
',' ) )
goto presetFails;
1395 theline = (UBYTE*)c + 1;
1396 pip[1] = (int)str2i((
char*)theline,&c,0xFFFF);
1397 if ( (pip[1] < 0 ) || ( ( *c !=
',' ) && ( *c !=
'\0' ) ) )
goto presetFails;
1398 theline = (UBYTE *)c + 1;
1405 if ( writeSome(pip[1],pidtxt,pidln,thetimeout) != pidln )
goto presetFails;
1406 i = readSome(pip[0],bothpidtxt,BOTHPIDSIZE,thetimeout);
1408 || ( i == BOTHPIDSIZE )
1411 ppid = (pid_t)str2i(bothpidtxt,&b,getpid());
1412 if( ( *b !=
',' ) || ( ppid != getpid() ) )
goto presetFails;
1418 ppid = (pid_t)str2i(b+1,&b,LONG_MAX);
1419 if ( (*b !=
'\n') || (ppid<2) )
goto presetFails;
1420 i = openPresetExternalChannel(pip[0],pip[1],ppid);
1421 if ( i < 0 )
goto presetFails;
1425 b = l2s(nchannels,addStr(bothpidtxt,
"PIPE"));
1428 *l2s(i,chdescriptor) =
'\0';
1429 PutPreVar((UBYTE*)bothpidtxt,(UBYTE*)chdescriptor,0,0);
1430 }
while ( *c !=
'\0' );
1432 *l2s(nchannels,chdescriptor)=
'\0';
1433 PutPreVar((UBYTE*)
"PIPES_",(UBYTE*)chdescriptor,0,0);
1440 for(i=0; i<nchannels; i++)
1441 destroyExternalChannel(externalChannelsList+i);
1455int selectExternalChannel(
int n)
1458 if(externalChannelsListTop!=0)
1459 ret=externalChannelsListTop-externalChannelsList+1;
1464 externalChannelsListTop=0;
1465 writeBufToExtChannel=&writeBufToExtChannelFailure;
1466 getcFromExtChannel=&getcFromExtChannelFailure;
1467 setTerminatorForExternalChannel=&setTerminatorForExternalChannelFailure;
1468 setKillModeForExternalChannel=&setKillModeForExternalChannelFailure;
1472 (n>=externalChannelsListFill)||
1473 (externalChannelsList[n].cmd==0)
1477 externalChannelsListTop=externalChannelsList+n;
1478 writeBufToExtChannel=&writeBufToExtChannelOk;
1479 getcFromExtChannel=&getcFromExtChannelOk;
1480 setTerminatorForExternalChannel=&setTerminatorForExternalChannelOk;
1481 setKillModeForExternalChannel=&setKillModeForExternalChannelOk;
1495int closeExternalChannel(
int n)
1498 n=externalChannelsListTop-externalChannelsList;
1504 (n>=externalChannelsListFill)||
1505 (externalChannelsList[n].cmd==0)
1509 destroyExternalChannel(externalChannelsList+n);
1511 if(externalChannelsListTop==externalChannelsList+n){
1512 externalChannelsListTop=NULL;
1513 writeBufToExtChannel=&writeBufToExtChannelFailure;
1514 getcFromExtChannel=&getcFromExtChannelFailure;
1515 setTerminatorForExternalChannel=&setTerminatorForExternalChannelFailure;
1516 setKillModeForExternalChannel=&setKillModeForExternalChannelFailure;
1524void closeAllExternalChannels()
1527 for(i=0; i<externalChannelsListFill; i++)
1528 destroyExternalChannel(externalChannelsList+i);
1529 externalChannelsListFill=externalChannelsListStop=0;
1530 externalChannelsListTop=NULL;
1532 writeBufToExtChannel=&writeBufToExtChannelFailure;
1533 getcFromExtChannel=&getcFromExtChannelFailure;
1534 setTerminatorForExternalChannel=&setTerminatorForExternalChannelFailure;
1535 setKillModeForExternalChannel=&setKillModeForExternalChannelFailure;
1537 if(externalChannelsList!=NULL){
1538 M_free(externalChannelsList,
"External channel list");
1539 externalChannelsList=NULL;
1547pid_t getExternalChannelPid()
1549 if(externalChannelsListTop!=0)
1550 return(externalChannelsListTop ->pid);
1559int getCurrentExternalChannel()
1562 if ( externalChannelsListTop != 0 )
1563 return(externalChannelsListTop-externalChannelsList+1);
1582 printf(
"String started with a special letter is a command\n");
1583 printf(
"Known commands are:\n");
1584 printf(
"H or ? -- this help\n");
1585 printf(
"Nn<command> -- start a new command\n");
1586 printf(
"S<command> -- start a new command in a subshell,daemon,stderr>/dev/null\n");
1587 printf(
"C# -- destroy channel #\n");
1588 printf(
"R# -- set a new cahhel(number#) as a current one\n");
1589 printf(
"K#1 #2 -- set signal for kill and kill mode (0 or !=0)\n");
1590 printf(
" ^d to quit\n");
1602 printf(
"Initial channel:%d\n",last=openExternalChannel((UBYTE*)
"cat",0,NULL,NULL));
1604 if( ( i = setTerminatorForExternalChannel(
"qu") ) != 0 )
return 1;
1605 printf(
"Terminaror is 'qu'\n");
1607 while ( fgets(buf, 1024, stdin) != NULL ) {
1608 if ( *buf ==
'N' ) {
1609 printf(
"New channel:%d\n",j=openExternalChannel((UBYTE*)buf+1,0,NULL,NULL));
1612 else if ( *buf ==
'C' ) {
1614 sscanf(buf+1,
"%d",&n);
1615 printf(
"Destroy last channel:%d\n",closeExternalChannel(n));
1618 else if ( *buf ==
'R' ) {
1620 sscanf(buf+1,
"%d",&n);
1621 printf(
"Reopen channel %d:%d\n",n,selectExternalChannel(n));
1623 }
else if( *buf ==
'K' ) {
1625 sscanf(buf+1,
"%d %d",&n,&g);
1626 printf(
"setKillMode %d\n",setKillModeForExternalChannel(n,g));
1628 }
else if( *buf ==
'S' ) {
1629 printf(
"New channel with sh&d&stderr:%d\n",
1630 j=openExternalChannel((UBYTE*)buf+1,1,(UBYTE*)
"/bin/sh -c",(UBYTE*)
"/dev/null"));
1633 else if( ( *buf ==
'H' )|| ( *buf ==
'?' ) ){
1638 writeBufToExtChannel(buf,k=StrLen(buf));
1640 for ( j = 0; ( i = getcFromExtChannel() ) !=
'\n'; j++) {
1648 printf(
"I got:'%s'; pid=%d\n",buf2,getExternalChannelPid());
1650 printf(
"Total:%lld bytes\n",sum);
1651 closeAllExternalChannels();
int PutPreVar(UBYTE *, UBYTE *, UBYTE *, int)
int PF_BroadcastString(UBYTE *str)