return feof(call_sock) || errno==ECONNRESET;
}
-// Does protocol exchange. Returns 0 if OK, error msg if peer was garbage.
-static const char *protocol_exchange(FILE *call_sock) {
- char ack;
- size_t sr = fread(&ack, sizeof(ack), 1, call_sock);
+// Returns -1 on EOF
+static int protocol_read_maybe(FILE *call_sock, void *data, size_t sz) {
+ size_t sr = fread(data, sz, 1, call_sock);
if (sr != 1) {
- if (was_eof(call_sock)) return "initial monitor process quit";
- diee("read() ack byte");
+ if (was_eof(call_sock)) return -1;
+ diee("read() on monitor call socket");
}
- if (ack != '\n') die("got ack byte 0x%02x, not '\n'", ack);
+ return 0;
+}
+
+static void protocol_read(FILE *call_sock, void *data, size_t sz) {
+ if (protocol_read_maybe(call_sock, data, sz) < 0)
+ die("monitor process quit unexpectedly");
+}
+
+// Does protocol exchange. Returns 0 if OK, error msg if peer was garbage.
+static const char *protocol_exchange(FILE *call_sock) {
+ char magic[sizeof(header_magic)];
+
+ if (protocol_read_maybe(&magic, sizeof(magic)) < 0)
+ return "initial monitor process quit";
+
+ if (memcmp(header, header_magic, sizeof(header_magic)))
+ die("got unexpected protocol magic 0x%04lx",
+ header[0], header[1], header[2], header[3]);
+
+ uint32_t xdata_len;
+ protocol_read(&xdata_len, sizeof(xdata_len));
+ void *xdata = xmalloc(xdata_len);
+ protocol_read(xdata, xdata_len);
// We're committed now, send the request (or bail out)
send_request(call_sock);
if (dup2(null_0, 0)) diee("dup2 /dev/null onto stdin");
if (dup2(2, 1) != 1) die("dup2 stderr onto stdout");
+ // Extension could work like this:
+ //
+ // We advertise a new protocol (perhaps one which is nearly entirely
+ // different after the connect) by putting a name for it comma-separated
+ // next to "v1". Simple extension can be done by having the script
+ // side say something about it in the ack xdata, which we currently ignore.
putenv(m_asprintf("PREFORK_INTERP=v1 %d,%d %s",
sfd, call_fd, socket_path));
FILE *call_sock = connect_or_spawn();
uint32_t status;
- ssize_t sr = fread(&status, sizeof(status), 1, call_sock);
- if (sr != 1) {
- if (was_eof(call_sock)) die("per-call server monitor process quit");
- diee("read status from call socket");
- }
+ protocol_read(&status, sizeof(status);
status = ntohl(status);
if (status > INT_MAX) die("status 0x%lx does not fit in an int",