ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtd.C
Revision: 1.9
Committed: Fri Feb 13 13:28:17 2004 UTC (20 years, 3 months ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_1_0, rel-2_4, rel-2_2, rel-2_3, rel-2_0, rel-1_9
Changes since 1.8: +12 -9 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.9 #include "../config.h"
2     #include "rxvt.h"
3 pcg 1.1 #include "rxvtdaemon.h"
4     #include "iom.h"
5    
6     #include <cstdio>
7     #include <cstdlib>
8 pcg 1.3 #include <cstdarg>
9     #include <cstring>
10 pcg 1.1
11     #include <unistd.h>
12 pcg 1.5 #include <sys/types.h>
13     #include <sys/stat.h>
14 pcg 1.1 #include <sys/socket.h>
15     #include <sys/un.h>
16    
17 pcg 1.3 #include <cerrno>
18    
19     extern char **environ;
20    
21 pcg 1.1 struct server : rxvt_connection {
22     void read_cb (io_watcher &w, short revents); io_watcher read_ev;
23    
24     server (int fd)
25     : read_ev (this, &server::read_cb)
26     {
27     this->fd = fd;
28     read_ev.start (fd, EVENT_READ);
29     }
30    
31 pcg 1.3 void err (const char *format = 0, ...);
32 pcg 1.1 };
33    
34 pcg 1.5 struct unix_listener {
35 pcg 1.1 int fd;
36    
37     void accept_cb (io_watcher &w, short revents); io_watcher accept_ev;
38    
39 pcg 1.5 unix_listener (const char *sockname);
40 pcg 1.1 };
41    
42 pcg 1.5 unix_listener::unix_listener (const char *sockname)
43     : accept_ev (this, &unix_listener::accept_cb)
44 pcg 1.1 {
45     if ((fd = socket (PF_LOCAL, SOCK_STREAM, 0)) < 0)
46     {
47     perror ("unable to create listening socket");
48     exit (EXIT_FAILURE);
49     }
50    
51     sockaddr_un sa;
52    
53     sa.sun_family = AF_UNIX;
54 pcg 1.5 strcpy (sa.sun_path, sockname);
55 pcg 1.1
56     unlink (rxvt_connection::unix_sockname ());
57    
58 pcg 1.5 mode_t omask = umask (0077);
59    
60 pcg 1.1 if (bind (fd, (sockaddr *)&sa, sizeof (sa)))
61     {
62     perror ("unable to bind listening socket");
63     exit (EXIT_FAILURE);
64     }
65    
66 pcg 1.5 umask (omask);
67    
68 pcg 1.1 if (listen (fd, 5))
69     {
70     perror ("unable to listen on socket");
71     exit (EXIT_FAILURE);
72     }
73    
74     accept_ev.start (fd, EVENT_READ);
75     }
76    
77 pcg 1.5 void unix_listener::accept_cb (io_watcher &w, short revents)
78 pcg 1.1 {
79     int fd2 = accept (fd, 0, 0);
80    
81     if (fd2 >= 0)
82     new server (fd2);
83     }
84    
85 pcg 1.3 void server::err (const char *format, ...)
86 pcg 1.1 {
87 pcg 1.3 if (format)
88     {
89     char err[1024];
90    
91     va_list ap;
92     va_start (ap, format);
93     vsnprintf (err, 1024, format, ap);
94     va_end (ap);
95    
96     send ("ERR"), send (err);
97     }
98    
99 pcg 1.1 close (fd);
100     delete this;
101     }
102    
103     void server::read_cb (io_watcher &w, short revents)
104     {
105 pcg 1.2 auto_str tok;
106 pcg 1.1
107 pcg 1.2 if (recv (tok))
108 pcg 1.1 {
109 pcg 1.2 if (!strcmp (tok, "NEW"))
110 pcg 1.1 {
111 pcg 1.9 stringvec *argv = new stringvec;
112     stringvec *envv = new stringvec;
113 pcg 1.2
114     for (;;)
115     {
116     if (!recv (tok))
117     return err ();
118    
119     if (!strcmp (tok, "END"))
120     break;
121 pcg 1.3 else if (!strcmp (tok, "ENV") && recv (tok))
122 pcg 1.9 envv->push_back (tok.get ());
123 pcg 1.3 else if (!strcmp (tok, "CWD") && recv (tok))
124     {
125     if (chdir (tok))
126     err ("unable to change to working directory to '%s': %s",
127     (char *)tok, strerror (errno));
128     }
129 pcg 1.2 else if (!strcmp (tok, "ARG") && recv (tok))
130 pcg 1.9 argv->push_back (tok.get ());
131 pcg 1.2 else
132 pcg 1.3 return err ("protocol error: unexpected NEW token");
133 pcg 1.2 }
134    
135 pcg 1.9 envv->push_back (0);
136 pcg 1.3
137     {
138     char **old_environ = environ;
139 pcg 1.9 environ = envv->begin ();
140 pcg 1.3
141 pcg 1.9 rxvt_term *term = rxvt_init (argv->size (), argv->begin ());
142    
143     term->argv = argv;
144     term->envv = envv;
145 pcg 1.2
146 pcg 1.3 environ = old_environ;
147     }
148 pcg 1.1 }
149     else
150 pcg 1.3 return err ("protocol error: request '%s' unsupported.", (char *)tok);
151 pcg 1.1 }
152     else
153 pcg 1.2 return err ();
154 pcg 1.1 }
155    
156     int
157 pcg 1.8 main (int argc, const char *const *argv)
158 pcg 1.1 {
159 pcg 1.5 rxvt_init_signals ();
160    
161     char *sockname = rxvt_connection::unix_sockname ();
162     unix_listener l (sockname);
163     printf ("rxvtd listening on %s.\n", sockname);
164     free (sockname);
165    
166 pcg 1.1 iom.loop ();
167    
168     #if 0
169 pcg 1.8 if (rxvt_init (argc, argv) == NULL)
170 pcg 1.1 return EXIT_FAILURE;
171    
172     dR;
173 pcg 1.8 rxvt_main_loop (aR); /* main processing loop */
174 pcg 1.1 #endif
175     return EXIT_SUCCESS;
176     }
177 pcg 1.7