Add workaround handling for missing alarm() and pause()

diff --git a/SYSCALLS b/SYSCALLS
index f12bbdf..5439e4a 100644
--- a/SYSCALLS
+++ b/SYSCALLS
@@ -102,9 +102,9 @@
 int rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t)
 int rt_sigsuspend(const sigset_t *, size_t)
 int rt_sigpending(sigset_t *, size_t)
-<!alpha> int pause()
-<!alpha,ia64> unsigned int alarm(unsigned int)
 int rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t)
+int getitimer(int, struct itimerval *);
+int setitimer(int, const struct itimerval *, struct itimerval *);
 
 #
 # Time-related system calls
diff --git a/alarm.c b/alarm.c
new file mode 100644
index 0000000..b4a1ff3
--- /dev/null
+++ b/alarm.c
@@ -0,0 +1,29 @@
+/*
+ * alarm.c
+ */
+
+#include <sys/time.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_alarm
+
+_syscall1(unsigned int,alarm,unsigned int,seconds);
+
+#else
+
+/* Emulate alarm() via setitimer() */
+
+unsigned int alarm(unsigned int seconds)
+{
+  struct itimerval iv;
+
+  iv.it_interval.tv_sec = iv.it_interval.it_usec = 0;
+  iv.it_value.tv_sec = seconds;
+  iv.it_value.tv_usec = 0;
+
+  setitimer(ITIMER_REAL, &iv, &iv);
+
+  return iv.it_value.tv_sec + (iv.it_value.tv_usec ? 1 : 0);
+}
+
+#endif
diff --git a/klibc/Makefile b/klibc/Makefile
index 688ba2d..f05ef1a 100644
--- a/klibc/Makefile
+++ b/klibc/Makefile
@@ -21,7 +21,7 @@
 	  execl.o execle.o execv.o execvpe.o execvp.o execlp.o execlpe.o \
 	  fork.o wait.o wait3.o waitpid.o setpgrp.o \
 	  printf.o vprintf.o fprintf.o vfprintf.o xread.o xwrite.o fputs.o \
-	  sleep.o usleep.o raise.o abort.o assert.o \
+	  sleep.o usleep.o raise.o abort.o assert.o alarm.o pause.o \
 	  signal.o sigaction.o sigpending.o sigprocmask.o sigsuspend.o \
 	  brk.o sbrk.o malloc.o free.o realloc.o calloc.o mmap.o \
 	  memcpy.o memset.o memccpy.o memmem.o strcat.o strchr.o \
diff --git a/klibc/SYSCALLS b/klibc/SYSCALLS
index f12bbdf..5439e4a 100644
--- a/klibc/SYSCALLS
+++ b/klibc/SYSCALLS
@@ -102,9 +102,9 @@
 int rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t)
 int rt_sigsuspend(const sigset_t *, size_t)
 int rt_sigpending(sigset_t *, size_t)
-<!alpha> int pause()
-<!alpha,ia64> unsigned int alarm(unsigned int)
 int rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t)
+int getitimer(int, struct itimerval *);
+int setitimer(int, const struct itimerval *, struct itimerval *);
 
 #
 # Time-related system calls
diff --git a/klibc/alarm.c b/klibc/alarm.c
new file mode 100644
index 0000000..b4a1ff3
--- /dev/null
+++ b/klibc/alarm.c
@@ -0,0 +1,29 @@
+/*
+ * alarm.c
+ */
+
+#include <sys/time.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_alarm
+
+_syscall1(unsigned int,alarm,unsigned int,seconds);
+
+#else
+
+/* Emulate alarm() via setitimer() */
+
+unsigned int alarm(unsigned int seconds)
+{
+  struct itimerval iv;
+
+  iv.it_interval.tv_sec = iv.it_interval.it_usec = 0;
+  iv.it_value.tv_sec = seconds;
+  iv.it_value.tv_usec = 0;
+
+  setitimer(ITIMER_REAL, &iv, &iv);
+
+  return iv.it_value.tv_sec + (iv.it_value.tv_usec ? 1 : 0);
+}
+
+#endif
diff --git a/klibc/pause.c b/klibc/pause.c
new file mode 100644
index 0000000..5748728
--- /dev/null
+++ b/klibc/pause.c
@@ -0,0 +1,21 @@
+/*
+ * pause.c
+ */
+
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_pause
+
+_syscall0(int,pause);
+
+#else
+
+int pause(void)
+{
+  return select(0,NULL,NULL,NULL,NULL);
+}
+
+#endif
diff --git a/pause.c b/pause.c
new file mode 100644
index 0000000..5748728
--- /dev/null
+++ b/pause.c
@@ -0,0 +1,21 @@
+/*
+ * pause.c
+ */
+
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/syscall.h>
+
+#ifdef __NR_pause
+
+_syscall0(int,pause);
+
+#else
+
+int pause(void)
+{
+  return select(0,NULL,NULL,NULL,NULL);
+}
+
+#endif