char buf[PATH_MAX];
c.send ("NEW");
- c.send ("DISPLAY"); c.send (getenv ("DISPLAY"));
+ c.send ("DISPLAY"), c.send (getenv ("DISPLAY"));
// instead of getcwd we could opendir(".") and pass the fd for fchdir *g*
- c.send ("CWD"); c.send (getcwd (buf, sizeof (buf)));
+ c.send ("CWD"), c.send (getcwd (buf, sizeof (buf)));
- c.send ("ARGV"); c.send (argc);
for (int i = 0; i < argc; i++)
- c.send (argv[i]);
+ c.send ("ARG"), c.send (argv[i]);
+
c.send ("END");
}
void server::read_cb (io_watcher &w, short revents)
{
- token cmd;
+ auto_str tok;
- if (recv (cmd))
+ if (recv (tok))
{
- if (!strcmp (cmd, "NEW"))
+ if (!strcmp (tok, "NEW"))
{
+ auto_str display, cwd;
+ simplevec<auto_str> argv;
+
+ for (;;)
+ {
+ if (!recv (tok))
+ return err ();
+
+ if (!strcmp (tok, "END"))
+ break;
+ else if (!strcmp (tok, "DISPLAY") && recv (display))
+ ;
+ else if (!strcmp (tok, "CWD") && recv (cwd))
+ ;
+ else if (!strcmp (tok, "ARG") && recv (tok))
+ argv.push_back (tok);
+ else
+ return err ();
+ }
+
+ // TODO: no setenv, please
+ setenv ("DISPLAY", display.get (), 1);
+
+ rxvt_init (argv.size (), reinterpret_cast<char **>(argv.begin ()));
+ dR;
+ rxvt_main_loop (aR);
}
else
- err ();
+ return err ();
}
else
- err ();
+ return err ();
}
int
send (data, strlen (data));
}
-bool rxvt_connection::recv (char *&data, int *len)
+bool rxvt_connection::recv (auto_str &data, int *len)
{
uint8_t s[2];
int l;
return true;
}
-bool rxvt_connection::recv (token &data)
-{
- char *d;
- int l;
-
- if (!recv (d, &l))
- return false;
-
- if (l < sizeof (token) - 1)
- strcpy (data, d);
-
- delete [] d;
-
- return l < sizeof (token) - 1;
-}
-
void rxvt_connection::send (int data)
{
uint8_t s[4];
#ifndef RXVT_DAEMON_H
#define RXVT_DAEMON_H
+#include "rxvtvec.h"
+
struct rxvt_connection {
int fd;
static const char *unix_sockname ();
- typedef char[4] token;
-
void send (const char *data, int len);
void send (const char *data);
void send (int data);
- bool recv (char *&data, int *len = 0);
- bool recv (token &data);
+ bool recv (auto_str &data, int *len = 0);
bool recv (int &data);
};
return first;
}
+template<typename T>
+struct auto_ptr {
+ T *p;
+
+ auto_ptr() : p(0) { }
+ auto_ptr(T *a) : p(a) { }
+
+ template<typename A>
+ auto_ptr(auto_ptr<A> &a)
+ {
+ p = a.p;
+ a.p = 0;
+ }
+
+ // void because it makes sense in our context
+ void operator =(T *a)
+ {
+ delete p;
+ p = a;
+ }
+
+ template<typename A>
+ void operator =(auto_ptr<A> &a)
+ {
+ *this = a.p;
+ a.p = 0;
+ }
+
+ operator T *() const { return p; }
+
+ T *operator ->() const { return p; }
+ T &operator *() const { return *p; }
+
+ T *get ()
+ {
+ T *r = p;
+ p = 0;
+ return r;
+ }
+};
+
+typedef auto_ptr<char> auto_str;
+
#endif