fix disconnect bug in libvncserver
[presencevnc] / libvnc / vncterm / VNCommand.c
1 #ifdef __STRICT_ANSI__
2 #define _BSD_SOURCE
3 #define _POSIX_SOURCE
4 #endif
5 #include "VNConsole.h"
6 #include "vga.h"
7 #ifdef LIBVNCSERVER_HAVE_FCNTL_H
8 #include <fcntl.h>
9 #endif
10 #ifdef LIBVNCSERVER_HAVE_SYS_TIME_H
11 #include <sys/time.h>
12 #endif
13 #ifdef LIBVNCSERVER_HAVE_UNISTD_H
14 #include <unistd.h>
15 #endif
16 #ifdef LIBVNCSERVER_HAVE_SYS_WAIT_H
17 #include <sys/wait.h>
18 #endif
19 #include <errno.h>
20
21
22 int main(int argc, char **argv)
23 {
24   rfbBool interactive=FALSE,sendOnlyWholeLines=TRUE;
25   int serverArgc,programArg0;
26   for(serverArgc=1;serverArgc<argc
27         && argv[serverArgc][0]=='-' && argv[serverArgc][1]!='-';serverArgc++)
28     if(!strcmp(argv[serverArgc],"-interactive")) {
29       interactive=TRUE;
30       sendOnlyWholeLines=FALSE;
31
32       rfbPurgeArguments(&argc,&serverArgc,1,argv);
33     }
34   programArg0=serverArgc;
35   if(programArg0<argc && argv[programArg0][0]=='-' && argv[programArg0][1]=='-')
36     programArg0++;
37   argv[argc]=0;
38
39   if(programArg0<argc) {
40     int in[2],out[2],err[2],pid;
41     if(pipe(in)<0 || pipe(out)<0 || pipe(err)<0) {
42       rfbErr("Couldn't make pipes!");
43       return(1);
44     }
45
46     pid=fork();
47     if(!pid) {
48       dup2(in[0],0);
49       dup2(out[1],1);
50       dup2(err[1],2);
51       /*setbuf(stdin,NULL);*/
52       execvp(argv[programArg0],argv+programArg0);
53     }
54
55     {
56       char buffer[1024];
57       fd_set fs,fs1/*,ifs,ifs1*/;
58       struct timeval tv,tv1;
59       int i,c=1,num_fds,max_fd=out[0],status;
60       FILE *input_pipe;
61       vncConsolePtr console=vcGetConsole(&serverArgc,argv,80,25,&vgaFont,FALSE);
62       if(interactive)
63         console->doEcho = FALSE;
64
65       if(max_fd<err[0])
66         max_fd=err[0];
67       FD_ZERO(&fs);
68       FD_SET(out[0],&fs);
69       FD_SET(err[0],&fs);
70       /*FD_SET(0,&fs);*/
71       tv.tv_sec=0; tv.tv_usec=5000;
72
73       input_pipe=fdopen(in[1],"w");
74       setbuf(input_pipe,NULL);
75       while(c || waitpid(pid,&status,WNOHANG)==0) {
76         /* event loop */
77         vcProcessEvents(console);
78
79         /* get input */
80         if(console->inputCount) {
81           if(sendOnlyWholeLines) {
82             for(i=0;i<console->inputCount;i++)
83               if(console->inputBuffer[i]=='\n') {
84                 i++;
85                 fwrite(console->inputBuffer,i,1,input_pipe);
86                 fflush(input_pipe);
87                 /* fwrite(console->inputBuffer,i,1,stderr); */
88                 if(console->inputCount>i)
89                   memmove(console->inputBuffer,console->inputBuffer+i,console->inputCount-i);
90                 console->inputCount-=i;
91                 i=0;
92               }
93           } else {
94             fwrite(console->inputBuffer,console->inputCount,1,input_pipe);
95             fflush(input_pipe);
96             /* fwrite(console->inputBuffer,console->inputCount,1,stderr); */
97             console->inputCount=0;
98           }
99         }
100         /* process output */
101         fs1=fs; tv1=tv;
102         num_fds=select(max_fd+1,&fs1,NULL,NULL,&tv1);
103         if(num_fds>0) {
104           /*
105           if(FD_ISSET(0,&fs1)) {
106             ch=getchar();
107             fputc(ch,f);
108           }
109           */
110           if(FD_ISSET(out[0],&fs1)) {
111             c=read(out[0],buffer,1024);
112             for(i=0;i<c;i++)
113               vcPutChar(console,buffer[i]);
114           }
115           if(FD_ISSET(err[0],&fs1)) {
116             c=read(err[0],buffer,1024);
117             for(i=0;i<c;i++)
118               vcPutChar(console,buffer[i]);
119           }             
120         } else
121           c=0;
122       }
123     }
124   }
125   rfbLog("exit\n");
126   return(0);
127 }