bugfix: reference to local var was erroneously returned
[vde.git] / vde-2 / src / vdeterm.c
blob5ac37ec61d8b618f5610dc54b728e25c643b5f8b
1 /* Copyright 2005 Renzo Davoli VDE-2
2 * Licensed under the GPLv2
4 * Minimal terminal emulator on a UNIX stream socket
5 */
7 #define _GNU_SOURCE
8 #include <stdio.h>
9 #include <fcntl.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <poll.h>
13 #include <signal.h>
14 #include <errno.h>
15 #include <sys/socket.h>
16 #include <sys/un.h>
17 #include <termios.h>
18 #include <libvdehist.h>
20 char *prompt;
21 static struct termios tiop;
23 static void cleanup(void)
25 fprintf(stderr,"\n");
26 tcsetattr(STDIN_FILENO,TCSAFLUSH,&tiop);
29 static void sig_handler(int sig)
31 cleanup();
32 signal(sig, SIG_DFL);
33 kill(getpid(), sig);
36 static void setsighandlers()
38 /* setting signal handlers.
39 * sets clean termination for SIGHUP, SIGINT and SIGTERM, and simply
40 * ignores all the others signals which could cause termination. */
41 struct { int sig; const char *name; int ignore; } signals[] = {
42 { SIGHUP, "SIGHUP", 0 },
43 { SIGINT, "SIGINT", 0 },
44 { SIGPIPE, "SIGPIPE", 1 },
45 { SIGALRM, "SIGALRM", 1 },
46 { SIGTERM, "SIGTERM", 0 },
47 { SIGUSR1, "SIGUSR1", 1 },
48 { SIGUSR2, "SIGUSR2", 1 },
49 { SIGPROF, "SIGPROF", 1 },
50 { SIGVTALRM, "SIGVTALRM", 1 },
51 #ifdef VDE_LINUX
52 { SIGPOLL, "SIGPOLL", 1 },
53 #ifdef SIGSTKFLT
54 { SIGSTKFLT, "SIGSTKFLT", 1 },
55 #endif
56 { SIGIO, "SIGIO", 1 },
57 { SIGPWR, "SIGPWR", 1 },
58 #ifdef SIGUNUSED
59 { SIGUNUSED, "SIGUNUSED", 1 },
60 #endif
61 #endif
62 #ifdef VDE_DARWIN
63 { SIGXCPU, "SIGXCPU", 1 },
64 { SIGXFSZ, "SIGXFSZ", 1 },
65 #endif
66 { 0, NULL, 0 }
69 int i;
70 for(i = 0; signals[i].sig != 0; i++)
71 if(signal(signals[i].sig,
72 signals[i].ignore ? SIG_IGN : sig_handler) < 0)
73 fprintf(stderr,"Error setting handler for %s: %s\n", signals[i].name,
74 strerror(errno));
77 #define BUFSIZE 1024
78 static char *copy_header_prompt (int vdefd,int termfd,char *sock)
80 char buf[BUFSIZE];
81 int n;
82 char *prompt;
83 while (1) {
84 struct pollfd wfd={vdefd,POLLIN|POLLHUP,0};
85 poll(&wfd,1,-1);
86 while ((n=read(vdefd,buf,BUFSIZE))>0) {
87 if (buf[n-2]=='$' &&
88 buf[n-1]==' ') {
89 n-=2;
90 buf[n]=0;
91 while (n>0 && buf[n] !='\n')
92 n--;
93 write(termfd,buf,n+1);
94 asprintf(&prompt,"%s[%s]: ",buf+n+1,sock);
95 return prompt;
96 } else
97 write(termfd,buf,n);
102 int main(int argc,char *argv[])
104 struct sockaddr_un sun;
105 int fd;
106 int rv;
107 int flags;
108 struct termios newtiop;
109 static struct pollfd pfd[]={
110 {STDIN_FILENO,POLLIN | POLLHUP,0},
111 {STDIN_FILENO,POLLIN | POLLHUP,0}};
112 //static int fileout[]={STDOUT_FILENO,STDOUT_FILENO};
113 struct vdehiststat *vdehst;
114 setsighandlers();
115 atexit(cleanup);
116 sun.sun_family=PF_UNIX;
117 snprintf(sun.sun_path,sizeof(sun.sun_path),"%s",argv[1]);
118 //asprintf(&prompt,"vdterm[%s]: ",argv[1]);
119 if((fd=socket(PF_UNIX,SOCK_STREAM,0))<0) {
120 perror("Socket opening error");
121 exit(-1);
123 if ((rv=connect(fd,(struct sockaddr *)(&sun),sizeof(sun))) < 0) {
124 perror("Socket connecting error");
125 exit(-1);
127 tcgetattr(STDIN_FILENO,&tiop);
128 newtiop=tiop;
129 newtiop.c_cc[VMIN]=1;
130 newtiop.c_cc[VTIME]=0;
131 newtiop.c_lflag &= ~ICANON;
132 newtiop.c_lflag &= ~ECHO;
133 tcsetattr(STDIN_FILENO,TCSAFLUSH,&newtiop);
134 flags = fcntl(fd, F_GETFL);
135 flags |= O_NONBLOCK;
136 fcntl(fd, F_SETFL, flags);
137 pfd[1].fd=fd;
138 prompt=copy_header_prompt(fd,STDOUT_FILENO,argv[1]);
139 vdehst=vdehist_new(STDIN_FILENO,fd);
140 write(STDOUT_FILENO,prompt,strlen(prompt)+1);
141 while(1) {
142 poll(pfd,2,-1);
143 //printf("POLL %d %d\n",pfd[0].revents,pfd[1].revents);
144 if(pfd[0].revents & POLLHUP ||
145 pfd[1].revents & POLLHUP)
146 exit(0);
147 if(pfd[0].revents & POLLIN) {
148 if (vdehist_term_to_mgmt(vdehst) != 0)
149 exit(0);
151 if(pfd[1].revents & POLLIN)
152 vdehist_mgmt_to_term(vdehst);
153 //printf("POLL RETURN!\n");