ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtd.C
Revision: 1.4
Committed: Tue Nov 25 17:34:47 2003 UTC (20 years, 6 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.3: +1 -2 lines
Log Message:
*** empty log message ***

File Contents

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