ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtd.C
(Generate patch)

Comparing rxvt-unicode/src/rxvtd.C (file contents):
Revision 1.2 by pcg, Mon Nov 24 19:52:16 2003 UTC vs.
Revision 1.10 by pcg, Wed Mar 17 05:15:02 2004 UTC

1#include "../config.h"
1#include "rxvtlib.h" 2#include "rxvt.h"
2#include "rxvtdaemon.h" 3#include "rxvtdaemon.h"
3#include "iom.h" 4#include "iom.h"
4 5
5#include <cstdio> 6#include <cstdio>
6#include <cstdlib> 7#include <cstdlib>
8#include <cstdarg>
9#include <cstring>
7 10
8#include <unistd.h> 11#include <unistd.h>
12#include <sys/types.h>
13#include <sys/stat.h>
9#include <sys/socket.h> 14#include <sys/socket.h>
10#include <sys/un.h> 15#include <sys/un.h>
11 16
17#include <cerrno>
18
19extern char **environ;
20
12struct server : rxvt_connection { 21struct server : rxvt_connection {
22 log_callback log_cb;
23
13 void read_cb (io_watcher &w, short revents); io_watcher read_ev; 24 void read_cb (io_watcher &w, short revents); io_watcher read_ev;
25 void log_msg (const char *msg);
14 26
15 server (int fd) 27 server (int fd)
16 : read_ev (this, &server::read_cb) 28 : read_ev (this, &server::read_cb),
29 log_cb (this, &server::log_msg)
17 { 30 {
18 this->fd = fd; 31 this->fd = fd;
19 read_ev.start (fd, EVENT_READ); 32 read_ev.start (fd, EVENT_READ);
20 } 33 }
21 34
22 void err (); 35 void err (const char *format = 0, ...);
23}; 36};
24 37
25struct listener { 38struct unix_listener {
26 int fd; 39 int fd;
27 40
28 void accept_cb (io_watcher &w, short revents); io_watcher accept_ev; 41 void accept_cb (io_watcher &w, short revents); io_watcher accept_ev;
29 42
30 listener (); 43 unix_listener (const char *sockname);
31}; 44};
32 45
33listener::listener () 46unix_listener::unix_listener (const char *sockname)
34: accept_ev (this, &listener::accept_cb) 47: accept_ev (this, &unix_listener::accept_cb)
35{ 48{
36 if ((fd = socket (PF_LOCAL, SOCK_STREAM, 0)) < 0) 49 if ((fd = socket (PF_LOCAL, SOCK_STREAM, 0)) < 0)
37 { 50 {
38 perror ("unable to create listening socket"); 51 perror ("unable to create listening socket");
39 exit (EXIT_FAILURE); 52 exit (EXIT_FAILURE);
40 } 53 }
41 54
42 sockaddr_un sa; 55 sockaddr_un sa;
43 56
44 sa.sun_family = AF_UNIX; 57 sa.sun_family = AF_UNIX;
45 strcpy (sa.sun_path, rxvt_connection::unix_sockname ()); 58 strcpy (sa.sun_path, sockname);
46 59
47 unlink (rxvt_connection::unix_sockname ()); 60 unlink (rxvt_connection::unix_sockname ());
61
62 mode_t omask = umask (0077);
48 63
49 if (bind (fd, (sockaddr *)&sa, sizeof (sa))) 64 if (bind (fd, (sockaddr *)&sa, sizeof (sa)))
50 { 65 {
51 perror ("unable to bind listening socket"); 66 perror ("unable to bind listening socket");
52 exit (EXIT_FAILURE); 67 exit (EXIT_FAILURE);
53 } 68 }
54 69
70 umask (omask);
71
55 if (listen (fd, 5)) 72 if (listen (fd, 5))
56 { 73 {
57 perror ("unable to listen on socket"); 74 perror ("unable to listen on socket");
58 exit (EXIT_FAILURE); 75 exit (EXIT_FAILURE);
59 } 76 }
60 77
61 accept_ev.start (fd, EVENT_READ); 78 accept_ev.start (fd, EVENT_READ);
62} 79}
63 80
64void listener::accept_cb (io_watcher &w, short revents) 81void unix_listener::accept_cb (io_watcher &w, short revents)
65{ 82{
66 int fd2 = accept (fd, 0, 0); 83 int fd2 = accept (fd, 0, 0);
67 84
68 if (fd2 >= 0) 85 if (fd2 >= 0)
69 new server (fd2); 86 new server (fd2);
70} 87}
71 88
72void server::err () 89void server::log_msg (const char *msg)
73{ 90{
91 send ("MSG"), send (msg);
92}
93
94void server::err (const char *format, ...)
95{
96 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 send ("MSG"), send (err);
106 }
107
108 send ("END", 0);
74 close (fd); 109 close (fd);
75 delete this; 110 delete this;
76} 111}
77 112
78void server::read_cb (io_watcher &w, short revents) 113void server::read_cb (io_watcher &w, short revents)
81 116
82 if (recv (tok)) 117 if (recv (tok))
83 { 118 {
84 if (!strcmp (tok, "NEW")) 119 if (!strcmp (tok, "NEW"))
85 { 120 {
86 auto_str display, cwd; 121 stringvec *argv = new stringvec;
87 simplevec<auto_str> argv; 122 stringvec *envv = new stringvec;
88 123
89 for (;;) 124 for (;;)
90 { 125 {
91 if (!recv (tok)) 126 if (!recv (tok))
92 return err (); 127 return err ();
93 128
94 if (!strcmp (tok, "END")) 129 if (!strcmp (tok, "END"))
95 break; 130 break;
96 else if (!strcmp (tok, "DISPLAY") && recv (display)) 131 else if (!strcmp (tok, "ENV") && recv (tok))
97 ; 132 envv->push_back (tok.get ());
98 else if (!strcmp (tok, "CWD") && recv (cwd)) 133 else if (!strcmp (tok, "CWD") && recv (tok))
99 ; 134 {
135 if (chdir (tok))
136 err ("unable to change to working directory to '%s': %s",
137 (char *)tok, strerror (errno));
138 }
100 else if (!strcmp (tok, "ARG") && recv (tok)) 139 else if (!strcmp (tok, "ARG") && recv (tok))
101 argv.push_back (tok); 140 argv->push_back (tok.get ());
102 else 141 else
103 return err (); 142 return err ("protocol error: unexpected NEW token");
104 } 143 }
105 144
106 // TODO: no setenv, please 145 envv->push_back (0);
107 setenv ("DISPLAY", display.get (), 1);
108 146
109 rxvt_init (argv.size (), reinterpret_cast<char **>(argv.begin ()));
110 dR; 147 {
111 rxvt_main_loop (aR); 148 char **old_environ = environ;
149 environ = envv->begin ();
150
151 rxvt_term *term = new rxvt_term;
152
153 term->log_hook = &log_cb;
154 term->argv = argv;
155 term->envv = envv;
156
157 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 environ = old_environ;
169
170 if (!success)
171 term->destroy ();
172
173 send ("END"); send (success ? 1 : 0);
174 }
112 } 175 }
113 else 176 else
114 return err (); 177 return err ("protocol error: request '%s' unsupported.", (char *)tok);
115 } 178 }
116 else 179 else
117 return err (); 180 return err ();
118} 181}
119 182
120int 183int
121main(int argc, const char *const *argv) 184main (int argc, const char *const *argv)
122{ 185{
123 listener l; 186 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
124 iom.loop (); 193 iom.loop ();
125 194
126#if 0 195#if 0
127 if (rxvt_init(argc, argv) == NULL) 196 if (rxvt_init (argc, argv) == NULL)
128 return EXIT_FAILURE; 197 return EXIT_FAILURE;
129 198
130 dR; 199 dR;
131 rxvt_main_loop(aR); /* main processing loop */ 200 rxvt_main_loop (aR); /* main processing loop */
132#endif 201#endif
133 return EXIT_SUCCESS; 202 return EXIT_SUCCESS;
134} 203}
204

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines