ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtd.C
Revision: 1.10
Committed: Wed Mar 17 05:15:02 2004 UTC (20 years, 3 months ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_5
Changes since 1.9: +31 -4 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 pcg 1.10 log_callback log_cb;
23    
24 pcg 1.1 void read_cb (io_watcher &w, short revents); io_watcher read_ev;
25 pcg 1.10 void log_msg (const char *msg);
26 pcg 1.1
27     server (int fd)
28 pcg 1.10 : read_ev (this, &server::read_cb),
29     log_cb (this, &server::log_msg)
30 pcg 1.1 {
31     this->fd = fd;
32     read_ev.start (fd, EVENT_READ);
33     }
34    
35 pcg 1.3 void err (const char *format = 0, ...);
36 pcg 1.1 };
37    
38 pcg 1.5 struct unix_listener {
39 pcg 1.1 int fd;
40    
41     void accept_cb (io_watcher &w, short revents); io_watcher accept_ev;
42    
43 pcg 1.5 unix_listener (const char *sockname);
44 pcg 1.1 };
45    
46 pcg 1.5 unix_listener::unix_listener (const char *sockname)
47     : accept_ev (this, &unix_listener::accept_cb)
48 pcg 1.1 {
49     if ((fd = socket (PF_LOCAL, SOCK_STREAM, 0)) < 0)
50     {
51     perror ("unable to create listening socket");
52     exit (EXIT_FAILURE);
53     }
54    
55     sockaddr_un sa;
56    
57     sa.sun_family = AF_UNIX;
58 pcg 1.5 strcpy (sa.sun_path, sockname);
59 pcg 1.1
60     unlink (rxvt_connection::unix_sockname ());
61    
62 pcg 1.5 mode_t omask = umask (0077);
63    
64 pcg 1.1 if (bind (fd, (sockaddr *)&sa, sizeof (sa)))
65     {
66     perror ("unable to bind listening socket");
67     exit (EXIT_FAILURE);
68     }
69    
70 pcg 1.5 umask (omask);
71    
72 pcg 1.1 if (listen (fd, 5))
73     {
74     perror ("unable to listen on socket");
75     exit (EXIT_FAILURE);
76     }
77    
78     accept_ev.start (fd, EVENT_READ);
79     }
80    
81 pcg 1.5 void unix_listener::accept_cb (io_watcher &w, short revents)
82 pcg 1.1 {
83     int fd2 = accept (fd, 0, 0);
84    
85     if (fd2 >= 0)
86     new server (fd2);
87     }
88    
89 pcg 1.10 void server::log_msg (const char *msg)
90     {
91     send ("MSG"), send (msg);
92     }
93    
94 pcg 1.3 void server::err (const char *format, ...)
95 pcg 1.1 {
96 pcg 1.3 if (format)
97     {
98     char err[1024];
99    
100     va_list ap;
101     va_start (ap, format);
102     vsnprintf (err, 1024, format, ap);
103     va_end (ap);
104    
105 pcg 1.10 send ("MSG"), send (err);
106 pcg 1.3 }
107    
108 pcg 1.10 send ("END", 0);
109 pcg 1.1 close (fd);
110     delete this;
111     }
112    
113     void server::read_cb (io_watcher &w, short revents)
114     {
115 pcg 1.2 auto_str tok;
116 pcg 1.1
117 pcg 1.2 if (recv (tok))
118 pcg 1.1 {
119 pcg 1.2 if (!strcmp (tok, "NEW"))
120 pcg 1.1 {
121 pcg 1.9 stringvec *argv = new stringvec;
122     stringvec *envv = new stringvec;
123 pcg 1.2
124     for (;;)
125     {
126     if (!recv (tok))
127     return err ();
128    
129     if (!strcmp (tok, "END"))
130     break;
131 pcg 1.3 else if (!strcmp (tok, "ENV") && recv (tok))
132 pcg 1.9 envv->push_back (tok.get ());
133 pcg 1.3 else if (!strcmp (tok, "CWD") && recv (tok))
134     {
135     if (chdir (tok))
136     err ("unable to change to working directory to '%s': %s",
137     (char *)tok, strerror (errno));
138     }
139 pcg 1.2 else if (!strcmp (tok, "ARG") && recv (tok))
140 pcg 1.9 argv->push_back (tok.get ());
141 pcg 1.2 else
142 pcg 1.3 return err ("protocol error: unexpected NEW token");
143 pcg 1.2 }
144    
145 pcg 1.9 envv->push_back (0);
146 pcg 1.3
147     {
148     char **old_environ = environ;
149 pcg 1.9 environ = envv->begin ();
150 pcg 1.3
151 pcg 1.10 rxvt_term *term = new rxvt_term;
152    
153     term->log_hook = &log_cb;
154 pcg 1.9 term->argv = argv;
155     term->envv = envv;
156 pcg 1.2
157 pcg 1.10 bool success;
158    
159     try
160     {
161     success = term->init (argv->size (), argv->begin ());
162     }
163     catch (const class rxvt_failure_exception &e)
164     {
165     success = false;
166     }
167    
168 pcg 1.3 environ = old_environ;
169 pcg 1.10
170     if (!success)
171     term->destroy ();
172    
173     send ("END"); send (success ? 1 : 0);
174 pcg 1.3 }
175 pcg 1.1 }
176     else
177 pcg 1.3 return err ("protocol error: request '%s' unsupported.", (char *)tok);
178 pcg 1.1 }
179     else
180 pcg 1.2 return err ();
181 pcg 1.1 }
182    
183     int
184 pcg 1.8 main (int argc, const char *const *argv)
185 pcg 1.1 {
186 pcg 1.5 rxvt_init_signals ();
187    
188     char *sockname = rxvt_connection::unix_sockname ();
189     unix_listener l (sockname);
190     printf ("rxvtd listening on %s.\n", sockname);
191     free (sockname);
192    
193 pcg 1.1 iom.loop ();
194    
195     #if 0
196 pcg 1.8 if (rxvt_init (argc, argv) == NULL)
197 pcg 1.1 return EXIT_FAILURE;
198    
199     dR;
200 pcg 1.8 rxvt_main_loop (aR); /* main processing loop */
201 pcg 1.1 #endif
202     return EXIT_SUCCESS;
203     }
204 pcg 1.7