Browse code

Initial commit

Dario Rodriguez authored on 02/06/2024 20:53:59
Showing 1 changed files
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
+