1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define _GNU_SOURCE
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <config.h>
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <errno.h>
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h>
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h>
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <sys/ipc.h>
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <sys/sem.h>
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <time.h>
10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <unistd.h>
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main(int argc, char **argv)
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   int semid;
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct sembuf sop;
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef HAVE_SEMTIMEDOP
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct timespec ts;
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if ((semid = semget(IPC_PRIVATE, 1, 0600)) < 0)
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   {
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      perror("semget");
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      exit(1);
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sop.sem_num = 0;
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sop.sem_op = 1;
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sop.sem_flg = 0;
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (semop(semid, &sop, 1) < 0)
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   {
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      perror("semop");
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      semctl(semid, 0, IPC_RMID);
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      exit(1);
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
36436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (semctl(semid, 0, GETVAL) != 1)
37436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   {
38436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      perror("semctl GETVAL");
39436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      semctl(semid, 0, IPC_RMID);
40436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      exit(1);
41436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
42436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
43436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (semctl(semid, 0, GETPID) != getpid())
44436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   {
45436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      perror("semctl GETPID");
46436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      semctl(semid, 0, IPC_RMID);
47436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      exit(1);
48436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
49436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* The next call to semtimedop causes the program to hang on
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ppc32-linux (Yellow Dog 4.0).  I don't know why.  Hence the
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      extended ifdef. */
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(HAVE_SEMTIMEDOP) && !defined(__powerpc__)
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sop.sem_num = 0;
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sop.sem_op = 0;
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sop.sem_flg = 0;
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ts.tv_sec = 0;
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ts.tv_nsec = 1000000;
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (semtimedop(semid, &sop, 1, &ts) < 0 && errno != EAGAIN)
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   {
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      perror("semtimedop");
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      semctl(semid, 0, IPC_RMID);
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      exit(1);
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sop.sem_num = 0;
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sop.sem_op = -1;
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sop.sem_flg = 0;
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (semop(semid, &sop, 1) < 0)
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   {
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      perror("semop");
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      semctl(semid, 0, IPC_RMID);
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      exit(1);
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef HAVE_SEMTIMEDOP
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sop.sem_num = 0;
82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sop.sem_op = 0;
83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sop.sem_flg = 0;
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ts.tv_sec = 0;
86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ts.tv_nsec = 1000;
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (semtimedop(semid, &sop, 1, &ts) < 0)
89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   {
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      perror("semtimedop");
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      semctl(semid, 0, IPC_RMID);
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      exit(1);
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (semctl(semid, 0, IPC_RMID) < 0)
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   {
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      perror("semctl(IPC_RMID)");
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      exit(1);
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   exit(0);
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
104