test-socket-signal: add timer support in client
authorRazvan Deaconescu <razvan.deaconescu@cs.pub.ro>
Tue, 19 Oct 2010 11:13:53 +0000 (14:13 +0300)
committerRazvan Deaconescu <razvan.deaconescu@cs.pub.ro>
Tue, 19 Oct 2010 12:00:25 +0000 (15:00 +0300)
Utils/test-socket-signal/Makefile
Utils/test-socket-signal/client.c

index ca8ac9e..7565f00 100644 (file)
@@ -1,5 +1,6 @@
 CFLAGS = -Wall -g
 CPPFLAGS = -Isock_util
+LDLIBS = -lrt
 
 .PHONY: all clean
 
index 9efc4f2..fb4302a 100644 (file)
@@ -13,6 +13,7 @@
 #include <signal.h>
 
 #include "sock_util.h"
+#include "utils.h"
 
 #define DEFAULT_SERVER_LISTEN_PORT     43210
 #define DEFAULT_SERVER_HOST            "localhost"
 #define DATA_SIZE                      120
 #define PACKET_INDEX_SIZE              8
 
+#define TIMER_FREQUENCY_SECS           1
+#define CLOCKID                                CLOCK_REALTIME
+#define SIG                            SIGRTMIN
+
 static char data[DATA_SIZE+PACKET_INDEX_SIZE];
 
 /* connection socket */
@@ -41,21 +46,62 @@ static void print_buffer(void)
        printf("data: %s\n\n", data);
 }
 
-static int send_buffer(int sockfd)
+static ssize_t send_buffer(int sockfd)
 {
        return send(sockfd, data, DATA_SIZE, 0);
 }
 
 static void timer_handler(int sig, siginfo_t *si, void *uc)
 {
-       if (send_buffer(connectfd) < 0) {
-               perror("send_buffer");
-               exit(EXIT_FAILURE);
-       }
+       ssize_t nbytes;
+
+       nbytes = send_buffer(connectfd);
+       DIE(nbytes < 0, "send_buffer");
+       printf("signal delivered\n");
 }
 
 static void schedule_timer(void)
 {
+       struct sigaction sa;
+       struct sigevent sev;
+       sigset_t mask;
+       timer_t timerid;
+       struct itimerspec its;
+       int rc;
+
+       memset(&sa, 0, sizeof(sa));
+       sa.sa_flags = SA_SIGINFO;
+       sa.sa_sigaction = timer_handler;
+       sigemptyset(&sa.sa_mask);
+       rc = sigaction(SIG, &sa, NULL);
+       DIE(rc < 0, "sigaction");
+
+       /* Block timer signal temporarily */
+       printf("Blocking signal %d\n", SIG);
+       sigemptyset(&mask);
+       sigaddset(&mask, SIG);
+       rc = sigprocmask(SIG_SETMASK, &mask, NULL);
+       DIE(rc < 0, "sigprocmask");
+
+       /* Create the timer */
+       sev.sigev_notify = SIGEV_SIGNAL;
+       sev.sigev_signo = SIG;
+       sev.sigev_value.sival_ptr = &timerid;
+       rc = timer_create(CLOCKID, &sev, &timerid);
+       DIE(rc < 0, "timer_create");
+
+       /* Start the timer */
+       its.it_value.tv_sec = TIMER_FREQUENCY_SECS;
+       its.it_value.tv_nsec = 0;
+       its.it_interval.tv_sec = TIMER_FREQUENCY_SECS;
+       its.it_interval.tv_nsec = 0;
+       rc = timer_settime(timerid, 0, &its, NULL);
+       DIE(rc < 0, "timer_settime");
+
+       /* Unlock the timer signal, so that timer notification
+          can be delivered */
+       rc = sigprocmask(SIG_UNBLOCK, &mask, NULL);
+       DIE(rc < 0, "sigprocmask");
 }
 
 int main(void)
@@ -64,9 +110,7 @@ int main(void)
 
        connectfd = tcp_connect_to_server(DEFAULT_SERVER_HOST,
                        DEFAULT_SERVER_LISTEN_PORT);
-       if (connectfd < 0) {
-               exit(EXIT_FAILURE);
-       }
+       DIE(connectfd < 0, "tcp_connect_to_server");
 
        init_buffer();
        schedule_timer();