[PATCH] alarm: use common implementation calling setitimer()

Enrico Scholz <[email protected]> Sun, 20 Feb 2011 16:16:44 +0100
Newsgroups gmane.linux.lib.dietlibc
Message-ID <1298215004-28546-8-git-send-email-enrico.scholz@informatik.tu-chemnitz.de>
Instead of providing yet another arm/__alarm.c file for ARM-EABI, this
patch merges existing alarm(2) implementations into one global source
file.  Build of it depends on the existence of the __NR_alarm symbol.

Patch adds a test for alarm(2) functionality.

Signed-off-by: Enrico Scholz <[email protected]>
---
 alpha/__alarm.c  |   13 -----------
 ia64/__alarm.c   |    1 -
 lib/__alarm.c    |   16 +++++++++++++
 test/Makefile    |    2 +-
 test/alarm.c     |   64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 test/runtests.sh |    2 +-
 6 files changed, 82 insertions(+), 16 deletions(-)
 delete mode 100644 alpha/__alarm.c
 delete mode 100644 ia64/__alarm.c
 create mode 100644 lib/__alarm.c
 create mode 100644 test/alarm.c

diff --git a/alpha/__alarm.c b/alpha/__alarm.c
deleted file mode 100644
index 7ca35cb..0000000
--- a/alpha/__alarm.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <unistd.h>
-#include <sys/time.h>
-
-unsigned int alarm(unsigned int seconds) {
-  struct itimerval old, new;
-  unsigned int ret;
-  new.it_interval.tv_usec=0;
-  new.it_interval.tv_sec=0;
-  new.it_value.tv_usec	=0;
-  new.it_value.tv_sec	=(long)seconds;
-  if (setitimer(ITIMER_REAL,&new,&old)==-1) return 0;
-  return old.it_value.tv_sec+(old.it_value.tv_usec?1:0);
-}
diff --git a/ia64/__alarm.c b/ia64/__alarm.c
deleted file mode 100644
index e2c499f..0000000
--- a/ia64/__alarm.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "alpha/__alarm.c"
diff --git a/lib/__alarm.c b/lib/__alarm.c
new file mode 100644
index 0000000..9b4bc30
--- /dev/null
+++ b/lib/__alarm.c
@@ -0,0 +1,16 @@
+#include <unistd.h>
+#include <sys/time.h>
+#include <syscalls.h>
+
+#ifndef __NR_alarm
+unsigned int alarm(unsigned int seconds) {
+  struct itimerval old, new;
+  unsigned int ret;
+  new.it_interval.tv_usec=0;
+  new.it_interval.tv_sec=0;
+  new.it_value.tv_usec	=0;
+  new.it_value.tv_sec	=(long)seconds;
+  if (setitimer(ITIMER_REAL,&new,&old)==-1) return 0;
+  return old.it_value.tv_sec+(old.it_value.tv_usec?1:0);
+}
+#endif
diff --git a/test/Makefile b/test/Makefile
index d86bb8d..c6f4b29 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -7,7 +7,7 @@ CFLAGS=-nostdinc -Wall
 
 LCOMPAT=-lcompat
 
-TESTPROGRAMS=adjtime argv asprintf atexit bsearch byteswap calloc confstr cycles empty fadvise flush fnmatch \
+TESTPROGRAMS=adjtime alarm argv asprintf atexit bsearch byteswap calloc confstr cycles empty fadvise flush fnmatch \
 fputc ftw fwrite getaddrinfo getenv getgrnam gethostbyaddr gethostbyname \
 gethostbyname_r getmntent getopt getpass getpwnam getservbyname getservbyport getusershell \
 glob grent hasmntopt hello iconv if_nameindex ltostr malloc-debugger md5_testharness \
diff --git a/test/alarm.c b/test/alarm.c
new file mode 100644
index 0000000..d1e13ce
--- /dev/null
+++ b/test/alarm.c
@@ -0,0 +1,64 @@
+#include <stdlib.h>
+#include <assert.h>
+
+#include <time.h>
+#include <unistd.h>
+#include <signal.h>
+
+static volatile int	alrm_triggered;
+
+static void sig_alrm(int s)
+{
+	alrm_triggered = 1;
+}
+
+int main()
+{
+	int		rc;
+	time_t		end;
+	sighandler_t	old_sig;
+
+	alarm(50);
+
+	old_sig = signal(SIGALRM, &sig_alrm);
+	assert(old_sig != SIG_ERR);
+
+	/* check whether alarm() returns correct number of remaining
+	 * seconds */
+	rc = alarm(2);
+	assert(rc > 40 && rc <= 50);
+
+	/* check whether SIGALRM is triggered within the set time */
+	end = time(NULL) + 5;
+	while (!alrm_triggered && time(NULL) < end) {
+		/* noop */
+	}
+	assert(alrm_triggered);
+
+	/* there should be no pending alarm */
+	rc = alarm(0);
+	assert(rc == 0);
+
+	alrm_triggered = 0;
+
+	/* test whether alarm can be canceled */
+	rc = alarm(2);
+	assert(rc == 0);
+
+	rc = alarm(0);
+	assert(rc > 0 && rc < 4);
+	assert(!alrm_triggered);
+
+	/* there should not happen an alarm */
+	end = time(NULL) + 5;
+	while (!alrm_triggered && time(NULL) < end) {
+		/* noop */
+	}
+	assert(!alrm_triggered);
+
+	/* there should be no pending alarm */
+	rc = alarm(0);
+	assert(rc == 0);
+
+	return EXIT_SUCCESS;
+}
diff --git a/test/runtests.sh b/test/runtests.sh
index f74ee0c..6bb3c46 100644
--- a/test/runtests.sh
+++ b/test/runtests.sh
@@ -1,6 +1,6 @@
 SUBDIRS="dirent inet stdio string stdlib time"
 
-TESTPROGRAMS="adjtime argv atexit bsearch byteswap calloc confstr empty fadvise flush fputc ffs fnmatch ftw fwrite getaddrinfo getenv getdelim getgrnam gethostbyaddr gethostbyname gethostbyname_r getmntent getopt getpwnam getservbyname getservbyport getusershell glob grent hasmntopt hello iconv if_nameindex ltostr malloc-debugger md5_testharness memccpy memchr memcmp memrchr memusage mktime mmap_test pipe printf printftest protoent prototypes putenv pwent rand48 readdir regex select sendfile servent siglist speed spent sprintf sscanf stdarg strcasecmp strcmp strncat strncpy strptime strrchr strstr strtol sysenter ungetc waitpid"
+TESTPROGRAMS="adjtime alarm argv atexit bsearch byteswap calloc confstr empty fadvise flush fputc ffs fnmatch ftw fwrite getaddrinfo getenv getdelim getgrnam gethostbyaddr gethostbyname gethostbyname_r getmntent getopt getpwnam getservbyname getservbyport getusershell glob grent hasmntopt hello iconv if_nameindex ltostr malloc-debugger md5_testharness memccpy memchr memcmp memrchr memusage mktime mmap_test pipe printf printftest protoent prototypes putenv pwent rand48 readdir regex select sendfile servent siglist speed spent sprintf sscanf stdarg strcasecmp strcmp strncat strncpy strptime strrchr strstr strtol sysenter ungetc waitpid"
 
 STDIN="read1"
 PASS="getpass" 
-- 
1.7.4