Make output pipe blocking once the input has been opened.
[vsys.git] / vsyssh / vsyssh.c
1 /* gcc -Wall -O2 -g chpid.c -o chpid */
2 #define _XOPEN_SOURCE
3 #define _XOPEN_SOURCE_EXTENDED
4 #define _SVID_SOURCE
5 #define _GNU_SOURCE
6 #include <stdio.h>
7 #include <errno.h>
8 #include <string.h>
9 #include <signal.h>
10 #include <stdlib.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <sys/syscall.h>
14 #include <sys/wait.h>
15 #include <sys/time.h>
16 #include <sys/select.h>
17 #include <sys/resource.h>
18 #include <sys/mount.h>
19 #include <sys/vfs.h>
20 #include <fcntl.h>
21 #include <unistd.h>
22 #include <sched.h>
23 #include <stdarg.h>
24 #include <dirent.h>
25
26 void pipe_handler (int sig) {
27         printf("SIGPIPE");
28 }
29
30 int main(int argc, char **argv, char **envp)
31 {
32         if (argc<2) {
33                 printf("Usage: vsyssh <vsys entry> [cmd]\n");
34                 exit(1);
35         }
36         else {
37                 int vfd0,vfd1;
38                 char *inf,*outf;
39                 struct timeval tv;
40
41                 signal(SIGPIPE,pipe_handler);
42                 inf=(char *)malloc(strlen(argv[1])+3);
43                 outf=(char *)malloc(strlen(argv[1])+4);
44                 strcpy(inf,argv[1]);
45                 strcpy(outf,argv[1]);
46                 strcat(inf,".in");
47                 strcat(outf,".out");
48
49                 vfd0 = open(outf,O_RDONLY|O_NONBLOCK);
50                 vfd1 = open(inf,O_WRONLY);
51
52                 if (vfd0==-1 || vfd1 == -1) {
53                         printf("Error opening vsys entry %s (%s)\n", argv[1],strerror(errno));
54                         exit(1);
55                 }
56
57                 if (fcntl(vfd0, F_SETFL, O_RDONLY) == -1) {
58                         printf("Error making pipe blocking: %m\n");
59                         exit(1);
60                 }
61
62                 if (argc<3) {
63                         fd_set set;
64                         char do_input = 1, do_output = 1;
65
66                         while (1)
67                         {
68                                 int ret;
69                                 printf("vsys>");fflush(stdout);
70                                 FD_ZERO(&set);
71                                 if (do_input)
72                                         FD_SET(0, &set);
73                                 if (do_output)
74                                         FD_SET(vfd0, &set);
75                                 ret = select(vfd0+1, &set, NULL, NULL, NULL);
76                                 if (FD_ISSET(0,&set)) {
77                                         char lineread[2048];
78                                         int ret;
79                                         ret=read(0,lineread,2048);
80                                         if (ret == 0)
81                                                 do_input = 0;
82                                         lineread[ret]='\0';
83                                         printf ("writing %s\n",lineread);
84                                         write(vfd1,lineread,ret);
85                                 }
86                                 if (FD_ISSET(vfd0,&set)) {
87                                         char lineread[2048];
88                                         int ret;
89                                         ret = read(vfd0,lineread,2048);
90                                         if (ret == 0)
91                                                 break;
92                                         write(1,lineread,ret);
93                                 }
94                         }
95
96                 }
97                 else {
98                         close(0);
99                         close(1);
100
101                         dup2(vfd0,0);
102                         dup2(vfd1,1);
103                         execve(argv[2],argv+2,envp);
104                 }
105        }
106
107        return -1;
108
109 }