aboutsummaryrefslogtreecommitdiff
path: root/norns_shell.c
diff options
context:
space:
mode:
Diffstat (limited to 'norns_shell.c')
-rw-r--r--norns_shell.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/norns_shell.c b/norns_shell.c
index 10f10b0..386596e 100644
--- a/norns_shell.c
+++ b/norns_shell.c
@@ -11,6 +11,23 @@
#define MAX_LINE 1024
+#define S(n) (1000000000 * ((long) n))
+#define MS(n) (1000000 * ((long) n))
+
+#define SENTINEL_TIMEOUT (MS(1500))
+#define SENTINEL_DELAY (MS(200))
+
+int timespec_diff_gt(struct timespec *before, struct timespec *after, long ns)
+{
+ /* be careful not to overflow the long... */
+ long ss = ns / S(1) + 1;
+ long ss_diff = after->tv_sec - before->tv_sec;
+ if (ss_diff > ss)
+ return 1;
+ long ns_diff = ss_diff * S(1) + (after->tv_nsec - before->tv_nsec);
+ return ns_diff > ns;
+}
+
int killed = 0;
void handle_signal(int sig_num)
{
@@ -85,8 +102,12 @@ int main (int argc, char **argv)
-- as a sentinel -- repeatedly until we get the corresponding
<ok>.
*/
- /* TODO: time out after three seconds or something. */
int received = 0;
+ struct timespec began = {0};
+ if (clock_gettime(CLOCK_MONOTONIC, &began)) {
+ fprintf(stderr, "Can't use the clock? %m\n");
+ goto error;
+ }
struct timespec sent_sentinel = {0};
/* we'll also wait for one message after EOF... */
@@ -131,16 +152,25 @@ int main (int argc, char **argv)
/* If we can write, see if there's a full line. */
if (poll_s.revents & NN_POLLOUT) {
if (!received) {
- /* only do this five times a second... */
struct timespec now = {0};
if (clock_gettime(CLOCK_MONOTONIC, &now)) {
fprintf(stderr, "Can't use the clock? %m\n");
goto error;
}
- /* first bit syncs with the clock... */
- if ((now.tv_sec - sent_sentinel.tv_sec <= 1)
- && (now.tv_nsec - sent_sentinel.tv_nsec
- <= (1000000000 / 5)))
+ /* if we've been waiting on sentinel response and
+ haven't gotten anything, time out. */
+ if (timespec_diff_gt(&began, &now, SENTINEL_TIMEOUT)) {
+ fprintf(stderr,
+ "# timed out.\n"
+ "# are you sure there's something "
+ "listening at %s?\n",
+ endpoint);
+ goto error;
+ }
+ /* only do this once every SENTINEL_DELAY... */
+ if (!timespec_diff_gt(&sent_sentinel,
+ &now,
+ SENTINEL_DELAY))
break;
memcpy(&sent_sentinel, &now, sizeof(struct timespec));