void errlogx(int, const char *, ...);
void set_username(void);
void deltmp(void);
+int do_timeout(int, int);
int open_locked(const char *, int, ...);
char *rfc822date(void);
int strprefixcmp(const char *, const char *);
#include <fcntl.h>
#include <netdb.h>
#include <pwd.h>
+#include <setjmp.h>
+#include <signal.h>
#include <stdio.h>
#include <syslog.h>
#include <unistd.h>
}
}
+static sigjmp_buf sigbuf;
+static int sigbuf_valid;
+
+static void
+sigalrm_handler(int signo)
+{
+ (void)signo; /* so that gcc doesn't complain */
+ if (sigbuf_valid)
+ siglongjmp(sigbuf, 1);
+}
+
+int
+do_timeout(int timeout, int dojmp)
+{
+ struct sigaction act;
+ int ret = 0;
+
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+
+ if (timeout) {
+ act.sa_handler = sigalrm_handler;
+ if (sigaction(SIGALRM, &act, NULL) != 0)
+ syslog(LOG_WARNING, "can not set signal handler: %m");
+ if (dojmp) {
+ ret = sigsetjmp(sigbuf, 1);
+ if (ret)
+ goto disable;
+ /* else just programmed */
+ sigbuf_valid = 1;
+ }
+
+ alarm(timeout);
+ } else {
+disable:
+ alarm(0);
+
+ act.sa_handler = SIG_IGN;
+ if (sigaction(SIGALRM, &act, NULL) != 0)
+ syslog(LOG_WARNING, "can not remove signal handler: %m");
+ sigbuf_valid = 0;
+ }
+
+ return (ret);
+}
+
int
open_locked(const char *fname, int flags, ...)
{