ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtd.C
Revision: 1.8
Committed: Fri Feb 13 12:16:21 2004 UTC (20 years, 3 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.7: +4 -4 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 pcg 1.5 #include <sys/types.h>
12     #include <sys/stat.h>
13 pcg 1.1 #include <sys/socket.h>
14     #include <sys/un.h>
15    
16 pcg 1.3 #include <cerrno>
17    
18     extern char **environ;
19    
20 pcg 1.1 struct server : rxvt_connection {
21     void read_cb (io_watcher &w, short revents); io_watcher read_ev;
22    
23     server (int fd)
24     : read_ev (this, &server::read_cb)
25     {
26     this->fd = fd;
27     read_ev.start (fd, EVENT_READ);
28     }
29    
30 pcg 1.3 void err (const char *format = 0, ...);
31 pcg 1.1 };
32    
33 pcg 1.5 struct unix_listener {
34 pcg 1.1 int fd;
35    
36     void accept_cb (io_watcher &w, short revents); io_watcher accept_ev;
37    
38 pcg 1.5 unix_listener (const char *sockname);
39 pcg 1.1 };
40    
41 pcg 1.5 unix_listener::unix_listener (const char *sockname)
42     : accept_ev (this, &unix_listener::accept_cb)
43 pcg 1.1 {
44     if ((fd = socket (PF_LOCAL, SOCK_STREAM, 0)) < 0)
45     {
46     perror ("unable to create listening socket");
47     exit (EXIT_FAILURE);
48     }
49    
50     sockaddr_un sa;
51    
52     sa.sun_family = AF_UNIX;
53 pcg 1.5 strcpy (sa.sun_path, sockname);
54 pcg 1.1
55     unlink (rxvt_connection::unix_sockname ());
56    
57 pcg 1.5 mode_t omask = umask (0077);
58    
59 pcg 1.1 if (bind (fd, (sockaddr *)&sa, sizeof (sa)))
60     {
61     perror ("unable to bind listening socket");
62     exit (EXIT_FAILURE);
63     }
64    
65 pcg 1.5 umask (omask);
66    
67 pcg 1.1 if (listen (fd, 5))
68     {
69     perror ("unable to listen on socket");
70     exit (EXIT_FAILURE);
71     }
72    
73     accept_ev.start (fd, EVENT_READ);
74     }
75    
76 pcg 1.5 void unix_listener::accept_cb (io_watcher &w, short revents)
77 pcg 1.1 {
78     int fd2 = accept (fd, 0, 0);
79    
80     if (fd2 >= 0)
81     new server (fd2);
82     }
83    
84 pcg 1.3 void server::err (const char *format, ...)
85 pcg 1.1 {
86 pcg 1.3 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    
98 pcg 1.1 close (fd);
99     delete this;
100     }
101    
102     void server::read_cb (io_watcher &w, short revents)
103     {
104 pcg 1.2 auto_str tok;
105 pcg 1.1
106 pcg 1.2 if (recv (tok))
107 pcg 1.1 {
108 pcg 1.2 if (!strcmp (tok, "NEW"))
109 pcg 1.1 {
110 pcg 1.3 stringvec argv;
111     stringvec envv;
112 pcg 1.2
113     for (;;)
114     {
115     if (!recv (tok))
116     return err ();
117    
118     if (!strcmp (tok, "END"))
119     break;
120 pcg 1.3 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 pcg 1.2 else if (!strcmp (tok, "ARG") && recv (tok))
129 pcg 1.3 argv.push_back (tok.get ());
130 pcg 1.2 else
131 pcg 1.3 return err ("protocol error: unexpected NEW token");
132 pcg 1.2 }
133    
134 pcg 1.3 envv.push_back (0);
135    
136     {
137     char **old_environ = environ;
138     environ = envv.begin ();
139    
140     rxvt_init (argv.size (), argv.begin ());
141 pcg 1.2
142 pcg 1.3 environ = old_environ;
143 pcg 1.8 envv.clear (); // can't yet save the env 'cause rxvt modifies it : (
144 pcg 1.3 }
145 pcg 1.1 }
146     else
147 pcg 1.3 return err ("protocol error: request '%s' unsupported.", (char *)tok);
148 pcg 1.1 }
149     else
150 pcg 1.2 return err ();
151 pcg 1.1 }
152    
153     int
154 pcg 1.8 main (int argc, const char *const *argv)
155 pcg 1.1 {
156 pcg 1.5 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    
163 pcg 1.1 iom.loop ();
164    
165     #if 0
166 pcg 1.8 if (rxvt_init (argc, argv) == NULL)
167 pcg 1.1 return EXIT_FAILURE;
168    
169     dR;
170 pcg 1.8 rxvt_main_loop (aR); /* main processing loop */
171 pcg 1.1 #endif
172     return EXIT_SUCCESS;
173     }
174 pcg 1.7