aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/route/route.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/sbin/route/route.c b/sbin/route/route.c
index a357a4d03851..ee312a4d36cb 100644
--- a/sbin/route/route.c
+++ b/sbin/route/route.c
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
#include <err.h>
#include <errno.h>
#include <paths.h>
+#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@@ -144,6 +145,16 @@ static int fiboptlist_range(const char *, struct fibl_head_t *);
static void usage(const char *) __dead2;
+#define READ_TIMEOUT 10
+static volatile sig_atomic_t stop_read;
+
+static void
+stopit(int sig __unused)
+{
+
+ stop_read = 1;
+}
+
static void
usage(const char *cp)
{
@@ -776,6 +787,7 @@ set_metric(char *value, int key)
static void
newroute(int argc, char **argv)
{
+ struct sigaction sa;
struct hostent *hp;
struct fibl *fl;
char *cmd;
@@ -791,6 +803,12 @@ newroute(int argc, char **argv)
hp = NULL;
TAILQ_INIT(&fibl_head);
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sa.sa_handler = stopit;
+ if (sigaction(SIGALRM, &sa, 0) == -1)
+ warn("sigaction SIGALRM");
+
cmd = argv[0];
if (*cmd != 'g' && *cmd != 's')
shutdown(s, SHUT_RD); /* Don't want to read back our messages */
@@ -1541,9 +1559,17 @@ rtmsg(int cmd, int flags, int fib)
return (-1);
}
if (cmd == RTM_GET) {
+ stop_read = 0;
+ alarm(READ_TIMEOUT);
do {
l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
- } while (l > 0 && (rtm.rtm_seq != rtm_seq || rtm.rtm_pid != pid));
+ } while (l > 0 && stop_read == 0 &&
+ (rtm.rtm_seq != rtm_seq || rtm.rtm_pid != pid));
+ if (stop_read != 0) {
+ warnx("read from routing socket timed out");
+ return (-1);
+ } else
+ alarm(0);
if (l < 0)
warn("read from routing socket");
else