[master] 56a571a Handle input from stdin properly in varnishadm
Tollef Fog Heen
tfheen at varnish-cache.org
Wed Jun 12 13:15:35 CEST 2013
commit 56a571a70f9e00545b5d5f08437fc65425c1a573
Author: Tollef Fog Heen <tfheen at varnish-software.com>
Date: Wed Jun 12 13:07:36 2013 +0200
Handle input from stdin properly in varnishadm
readline doesn't really handle when input comes from a file or pipe,
so only use readline if stdin is a tty.
Thanks to johnnyrun for a patch which was used for inspiration here.
Fixes #1314
diff --git a/bin/varnishadm/varnishadm.c b/bin/varnishadm/varnishadm.c
index 4029178..0e5706b 100644
--- a/bin/varnishadm/varnishadm.c
+++ b/bin/varnishadm/varnishadm.c
@@ -227,7 +227,7 @@ varnishadm_completion (const char *text, int start, int end)
* Send a "banner" to varnish, to provoke a welcome message.
*/
static void
-pass(int sock)
+interactive(int sock)
{
struct pollfd fds[2];
char buf[1024];
@@ -236,11 +236,7 @@ pass(int sock)
unsigned u, status;
_line_sock = sock;
rl_already_prompted = 1;
- if (isatty(0)) {
- rl_callback_handler_install("varnish> ", send_line);
- } else {
- rl_callback_handler_install("", send_line);
- }
+ rl_callback_handler_install("varnish> ", send_line);
rl_attempted_completion_function = varnishadm_completion;
fds[0].fd = sock;
@@ -311,6 +307,65 @@ pass(int sock)
}
}
+/*
+ * No arguments given, simply pass bytes on stdin/stdout and CLI socket
+ */
+static void
+pass(int sock)
+{
+ struct pollfd fds[2];
+ char buf[1024];
+ int i;
+ char *answer = NULL;
+ unsigned u, status;
+ ssize_t n;
+
+ fds[0].fd = sock;
+ fds[0].events = POLLIN;
+ fds[1].fd = 0;
+ fds[1].events = POLLIN;
+ while (1) {
+ i = poll(fds, 2, -1);
+ if (i == -1 && errno == EINTR) {
+ continue;
+ }
+ assert(i > 0);
+ if (fds[0].revents & POLLIN) {
+ u = VCLI_ReadResult(fds[0].fd, &status, &answer,
+ timeout);
+ if (u) {
+ if (status == CLIS_COMMS)
+ RL_EXIT(0);
+ if (answer)
+ fprintf(stderr, "%s\n", answer);
+ RL_EXIT(1);
+ }
+
+ sprintf(buf, "%u\n", status);
+ u = write(1, buf, strlen(buf));
+ if (answer) {
+ u = write(1, answer, strlen(answer));
+ u = write(1, "\n", 1);
+ free(answer);
+ answer = NULL;
+ }
+ }
+ if (fds[1].revents & POLLIN || fds[1].revents & POLLHUP) {
+ n = read(fds[1].fd, buf, sizeof buf);
+ if (n == 0) {
+ AZ(shutdown(sock, SHUT_WR));
+ fds[1].fd = -1;
+ } else if (n < 0) {
+ RL_EXIT(0);
+ } else {
+ buf[n] = '\0';
+ cli_write(sock, buf);
+ }
+ }
+ }
+}
+
+
static void
usage(void)
{
@@ -414,8 +469,12 @@ main(int argc, char * const *argv)
if (argc > 0)
do_args(sock, argc, argv);
- else
- pass(sock);
-
+ else {
+ if (isatty(0)) {
+ interactive(sock);
+ } else {
+ pass(sock);
+ }
+ }
exit(0);
}
More information about the varnish-commit
mailing list