1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,132 @@ |
1 |
+/* |
|
2 |
+ * simple test program for libexec |
|
3 |
+ * |
|
4 |
+ * (c) 2024 Dario Rodriguez <antartica@whereismybit.com> |
|
5 |
+ * This file is in the public domain. |
|
6 |
+ */ |
|
7 |
+ |
|
8 |
+#include <stdio.h> |
|
9 |
+#include <stdlib.h> |
|
10 |
+#include <unistd.h> |
|
11 |
+#include <string.h> |
|
12 |
+#include <signal.h> |
|
13 |
+#include <time.h> |
|
14 |
+#include <sys/select.h> |
|
15 |
+#include "libexec.h" |
|
16 |
+ |
|
17 |
+volatile int flag_sigint; |
|
18 |
+volatile int flag_sigchld; |
|
19 |
+void sigchld(int sig); |
|
20 |
+void sigint(int sig); |
|
21 |
+ |
|
22 |
+ |
|
23 |
+int |
|
24 |
+main(int argc, char *argv[], char *envp[]) |
|
25 |
+{ |
|
26 |
+ struct timeval tv; |
|
27 |
+ exec_t *dateexec,*echoexec,*catexec; |
|
28 |
+ exec_t *exec; |
|
29 |
+ fd_set readset,writeset; |
|
30 |
+ flag_sigchld=flag_sigint=0; |
|
31 |
+ int maxfd; |
|
32 |
+ int i; |
|
33 |
+ int queued,nread; |
|
34 |
+ int fd; |
|
35 |
+ char *fdname; |
|
36 |
+ time_t curtimet,lasttimet; |
|
37 |
+ executil_installsignal(SIGINT,sigint); |
|
38 |
+ executil_installsignal(SIGCHLD,sigchld); |
|
39 |
+ dateexec=exec_init("date","/bin/sh -c \"while true ; do sleep 1 ; date ; echo . >&2 ; done\"",envp); |
|
40 |
+ echoexec=exec_init("echo","/bin/echo \"%s\"",envp); |
|
41 |
+ catexec=exec_init("cat","/bin/cat",envp); |
|
42 |
+ exec_open(dateexec,NULL); |
|
43 |
+ exec_open(catexec,NULL); |
|
44 |
+ lasttimet=0; |
|
45 |
+ while(flag_sigint==0) { |
|
46 |
+ int *readfds[]={ |
|
47 |
+ &(dateexec->fdout), |
|
48 |
+ &(dateexec->fderr), |
|
49 |
+ &(echoexec->fdout), |
|
50 |
+ &(echoexec->fderr), |
|
51 |
+ &(catexec->fdout), |
|
52 |
+ &(catexec->fderr), |
|
53 |
+ }; |
|
54 |
+ if(flag_sigchld) { |
|
55 |
+ exec_t *execs[]={dateexec,echoexec,catexec}; |
|
56 |
+ flag_sigchld=0; |
|
57 |
+ exec_reap(dateexec,echoexec,catexec,NULL); |
|
58 |
+ for(i=0;i<(sizeof(execs)/sizeof(execs[0]));i++) { |
|
59 |
+ exec=execs[i]; |
|
60 |
+ if(exec->laststatus!=-1) |
|
61 |
+ fprintf(stderr,"%s: exited with status %i\n",exec->name,exec->laststatus),exec->laststatus=-1; |
|
62 |
+ } |
|
63 |
+ } |
|
64 |
+ tv.tv_sec=1,tv.tv_usec=0; |
|
65 |
+ maxfd=0; |
|
66 |
+ FD_ZERO(&readset); |
|
67 |
+ for(i=0;i<(sizeof(readfds)/sizeof(readfds[0]));i++) { |
|
68 |
+ if(*(readfds[i])==-1) |
|
69 |
+ continue; |
|
70 |
+ FD_SET(*(readfds[i]),&readset); |
|
71 |
+ maxfd=(maxfd<*(readfds[i]))?*(readfds[i]):maxfd; |
|
72 |
+ } |
|
73 |
+ FD_ZERO(&writeset); |
|
74 |
+ curtimet=time(NULL); |
|
75 |
+ if(catexec->fdin!=-1 && curtimet!=lasttimet) { |
|
76 |
+ FD_SET(catexec->fdin,&writeset); |
|
77 |
+ maxfd=(maxfd<catexec->fdin)?catexec->fdin:maxfd; |
|
78 |
+ } |
|
79 |
+ select(maxfd+1,&readset,&writeset,NULL,&tv); |
|
80 |
+#if 1 |
|
81 |
+fprintf(stderr,"ITERATION\n"); |
|
82 |
+#endif |
|
83 |
+ for(i=0;i<(sizeof(readfds)/sizeof(readfds[0]));i++) { |
|
84 |
+ if(*(readfds[i])==-1 || !FD_ISSET(*(readfds[i]),&readset) || (exec=executil_fd2exec(*(readfds[i]),dateexec,echoexec,catexec,NULL))==NULL) |
|
85 |
+ continue; |
|
86 |
+ fd=*(readfds[i]); |
|
87 |
+ fdname=(fd==exec->fdout)?"stdout":"stderr"; |
|
88 |
+ queued=executil_queued(fd); |
|
89 |
+ if(queued<=0) { |
|
90 |
+ /* remote closed connection */ |
|
91 |
+ fprintf(stderr,"%s:%s: remote closed connection (queued:%i)\n",exec->name,fdname,queued); |
|
92 |
+ exec_close(exec); |
|
93 |
+ continue; |
|
94 |
+ } else { |
|
95 |
+ char buf[1024]; |
|
96 |
+ queued=(queued>(sizeof(buf)-1))?(sizeof(buf)-1):queued; |
|
97 |
+ if((nread=read(fd,buf,queued))<queued) { |
|
98 |
+ fprintf(stderr,"%s:%s short read (%i<%i)\n",exec->name,fdname,nread,queued); |
|
99 |
+ exec_close(exec); |
|
100 |
+ } |
|
101 |
+ buf[nread]='\0'; |
|
102 |
+ fprintf(stderr,"%s:%s: read \"",exec->name,fdname); |
|
103 |
+ fwrite(buf,1,nread,stderr); |
|
104 |
+ fprintf(stderr,"\"\n"); |
|
105 |
+ } |
|
106 |
+ } |
|
107 |
+ if(catexec->fdin!=-1 && FD_ISSET(catexec->fdin,&writeset)) { |
|
108 |
+ char msg[32]; |
|
109 |
+ snprintf(msg,sizeof(msg),"%li\n",(long)curtimet); |
|
110 |
+ msg[sizeof(msg)-1]='\0'; |
|
111 |
+ write(catexec->fdin,msg,strlen(msg)); |
|
112 |
+ lasttimet=curtimet; |
|
113 |
+ } |
|
114 |
+ if((time(NULL)%5)==0) { |
|
115 |
+ exec_open(echoexec,"multi 5s"); |
|
116 |
+ } |
|
117 |
+ } |
|
118 |
+ return(0); |
|
119 |
+} |
|
120 |
+ |
|
121 |
+void |
|
122 |
+sigint(int sig) |
|
123 |
+{ |
|
124 |
+ flag_sigint++; |
|
125 |
+} |
|
126 |
+ |
|
127 |
+void |
|
128 |
+sigchld(int sig) |
|
129 |
+{ |
|
130 |
+ flag_sigchld++; |
|
131 |
+} |
|
132 |
+ |