Commit e5ff4371 authored by Per Cederqvist's avatar Per Cederqvist
Browse files

(read_stdin): Implement the commands "ping" and "shutdown".

(write_server): Don't return OOP_HALT just because the socket to
	the server is reset, but stop writing in that case.
(main): Allow --write-only without --time-abort.  Retry the final write
	up to 3 times if it fails with EPIPE, ECONNRESET or EINTR.
parent 434feb9c
......@@ -117,11 +117,47 @@ tcp_connect(const char *host,
static void *
read_stdin(oop_source *UNUSED(source),
int UNUSED(fd),
int fd,
oop_event UNUSED(event),
void *UNUSED(user))
{
return OOP_CONTINUE;
static char readbuf[128];
ssize_t rv;
if ((rv = read(fd, readbuf, sizeof(readbuf) - 1)) < 0)
{
if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
fail("read(stdin)");
else
rv = 0;
}
else if (rv == 0)
{
fprintf(stderr, "eof on stdin");
exit(1);
}
readbuf[rv] = '\0';
while (rv > 1
&& (readbuf[rv-1] == '\r'
|| readbuf[rv-1] == '\n'))
{
rv--;
readbuf[rv] = '\0';
}
if (!strcmp(readbuf, "shutdown"))
return OOP_HALT;
if (!strcmp(readbuf, "ping"))
{
puts("pong");
fflush(stdout);
return OOP_CONTINUE;
}
fprintf(stderr, "unknown command on stdin: %s.\n", readbuf);
return OOP_HALT;
}
static const char *
......@@ -268,8 +304,18 @@ read_server(oop_source *UNUSED(source),
return OOP_HALT;
}
static void
stop_writing(oop_source *oop)
{
if (writing_to_server)
{
oop->cancel_fd(oop, server, OOP_WRITE);
writing_to_server = 0;
}
}
static void *
write_server(oop_source *UNUSED(source),
write_server(oop_source *source,
int fd,
oop_event UNUSED(event),
void *UNUSED(user))
......@@ -295,7 +341,10 @@ write_server(oop_source *UNUSED(source),
if (rv < 0)
{
if ((errno == ECONNRESET || errno == EPIPE) && do_write_only)
return OOP_HALT;
{
stop_writing(source);
return OOP_CONTINUE;
}
if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
fail("write(server)");
else
......@@ -389,17 +438,6 @@ end_it(oop_source *UNUSED(source),
return OOP_HALT;
}
static void
stop_writing(oop_source *oop)
{
if (writing_to_server)
{
oop->cancel_fd(oop, server, OOP_WRITE);
writing_to_server = 0;
}
}
static void *
limit_it(oop_source *oop,
struct timeval UNUSED(tv),
......@@ -432,6 +470,8 @@ main(int argc,
struct timeval report_timer;
struct timeval end_timer;
char buf[8192];
int retry;
int again;
/* What should we do? */
int do_limit_time = 0;
......@@ -471,9 +511,6 @@ main(int argc,
}
}
if (do_write_only && !do_abort_time)
fail("usage");
if (optind + 2 != argc)
fail("usage");
......@@ -531,25 +568,38 @@ main(int argc,
if (do_write_only)
{
switch (write(server, "\n", 1))
again = 1;
for (retry = 3; again && retry > 0; retry--)
{
case -1:
/* We expect EPIPE or ECONNRESET. */
if (errno != EPIPE && errno != ECONNRESET)
fail("final write");
break;
again = 0;
switch (write(server, "\n", 1))
{
case -1:
if (retry > 1 && (errno == EAGAIN || errno == EWOULDBLOCK
|| errno == EINTR))
{
again = 1;
sleep(1);
break;
}
case 0:
fprintf(stderr, "final write returned 0\n");
break;
/* We expect EPIPE or ECONNRESET. */
else if (errno != EPIPE && errno != ECONNRESET)
fprintf(stderr, "final write: %s\n", strerror(errno));
break;
case 1:
fprintf(stderr, "ERROR: final write succeeded\n");
break;
case 0:
fprintf(stderr, "final write returned 0\n");
break;
default:
fprintf(stderr, "insane return value from final write\n");
break;
case 1:
fprintf(stderr, "ERROR: final write succeeded\n");
break;
default:
fprintf(stderr, "insane return value from final write\n");
break;
}
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment