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.7 by pcg, Fri Jan 16 22:11:09 2004 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)
81 105
82 if (recv (tok)) 106 if (recv (tok))
83 { 107 {
84 if (!strcmp (tok, "NEW")) 108 if (!strcmp (tok, "NEW"))
85 { 109 {
86 auto_str display, cwd; 110 stringvec argv;
87 simplevec<auto_str> argv; 111 stringvec envv;
88 112
89 for (;;) 113 for (;;)
90 { 114 {
91 if (!recv (tok)) 115 if (!recv (tok))
92 return err (); 116 return err ();
93 117
94 if (!strcmp (tok, "END")) 118 if (!strcmp (tok, "END"))
95 break; 119 break;
96 else if (!strcmp (tok, "DISPLAY") && recv (display)) 120 else if (!strcmp (tok, "ENV") && recv (tok))
97 ; 121 envv.push_back (tok.get ());
98 else if (!strcmp (tok, "CWD") && recv (cwd)) 122 else if (!strcmp (tok, "CWD") && recv (tok))
99 ; 123 {
124 if (chdir (tok))
125 err ("unable to change to working directory to '%s': %s",
126 (char *)tok, strerror (errno));
127 }
100 else if (!strcmp (tok, "ARG") && recv (tok)) 128 else if (!strcmp (tok, "ARG") && recv (tok))
101 argv.push_back (tok); 129 argv.push_back (tok.get ());
102 else 130 else
103 return err (); 131 return err ("protocol error: unexpected NEW token");
104 } 132 }
105 133
106 // TODO: no setenv, please 134 envv.push_back (0);
107 setenv ("DISPLAY", display.get (), 1);
108 135
109 rxvt_init (argv.size (), reinterpret_cast<char **>(argv.begin ()));
110 dR; 136 {
111 rxvt_main_loop (aR); 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 }
112 } 145 }
113 else 146 else
114 return err (); 147 return err ("protocol error: request '%s' unsupported.", (char *)tok);
115 } 148 }
116 else 149 else
117 return err (); 150 return err ();
118} 151}
119 152
120int 153int
121main(int argc, const char *const *argv) 154main(int argc, const char *const *argv)
122{ 155{
123 listener l; 156 rxvt_init_signals ();
157
158 char *sockname = rxvt_connection::unix_sockname ();
159 unix_listener l (sockname);
160 printf ("rxvtd listening on %s.\n", sockname);
161 free (sockname);
162
124 iom.loop (); 163 iom.loop ();
125 164
126#if 0 165#if 0
127 if (rxvt_init(argc, argv) == NULL) 166 if (rxvt_init(argc, argv) == NULL)
128 return EXIT_FAILURE; 167 return EXIT_FAILURE;
130 dR; 169 dR;
131 rxvt_main_loop(aR); /* main processing loop */ 170 rxvt_main_loop(aR); /* main processing loop */
132#endif 171#endif
133 return EXIT_SUCCESS; 172 return EXIT_SUCCESS;
134} 173}
174

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines