fujuntang
2021-08-11 68d23225a38a35f1325eb39fa4ed5a005d5de473
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <time.h>
#include <assert.h>
#include <errno.h>
#include <signal.h>
 
sem_t sem;
 
#define handle_error(msg) \
           do { perror(msg); exit(EXIT_FAILURE); } while (0)
 
static void
handler(int sig)
{
  write(STDOUT_FILENO, "sem_post() from handler\n", 24);
  if (sem_post(&sem) == -1)
  {
    write(STDERR_FILENO, "sem_post() failed\n", 18);
    _exit(EXIT_FAILURE);
  }
}
 
int
main(int argc, char *argv[])
{
  struct sigaction sa;
  struct timespec ts;
  int s;
 
  if (argc != 3)
  {
    fprintf(stderr, "Usage: %s <alarm-secs> <wait-secs>\n",
            argv[0]);
    exit(EXIT_FAILURE);
  }
 
  if (sem_init(&sem, 0, 0) == -1)
    handle_error("sem_init");
 
  /* Establish SIGALRM handler; set alarm timer using argv[1] */
 
  sa.sa_handler = handler;
  sigemptyset(&sa.sa_mask);
  sa.sa_flags = 0;
  if (sigaction(SIGALRM, &sa, NULL) == -1)
    handle_error("sigaction");
 
  alarm(atoi(argv[1]));
 
  /* Calculate relative interval as current time plus
     number of seconds given argv[2] */
 
  if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
    handle_error("clock_gettime");
 
  ts.tv_sec += atoi(argv[2]);
 
  printf("main() about to call sem_timedwait()\n");
  while ((s = sem_timedwait(&sem, &ts)) == -1 && errno == EINTR)
    continue;       /* Restart if interrupted by handler */
 
  /* Check what happened */
 
  if (s == -1)
  {
    if (errno == ETIMEDOUT)
      printf("sem_timedwait() timed out\n");
    else
      perror("sem_timedwait");
  }
  else
    printf("sem_timedwait() succeeded\n");
 
  exit((s == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
}