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.1 by pcg, Mon Nov 24 17:28:08 2003 UTC vs.
Revision 1.5 by pcg, Thu Nov 27 10:12:10 2003 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines