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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
#define _GNU_SOURCE
#include <config.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <time.h>
#include <unistd.h>
void semctl_test (int trace, const char *fname)
{
key_t key;
int semid;
int nr_of_readers;
int ret;
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
} u;
struct semid_ds ds;
key = ftok (fname, 1);
if (key == -1)
perror ("ftok");
nr_of_readers = 4;
semid = semget (key, 2 * nr_of_readers, IPC_CREAT + 0660);
if (semid == -1) {
perror ("semget");
}
if (trace)
printf("semid %d\n", semid);
u.buf = &ds;
ret = semctl (semid, 0, IPC_STAT, u);
if (ret == -1)
perror("semctl IPC_STAT");
if (trace)
printf("semid %d sem_nsems %d\n", semid, (int) ds.sem_nsems);
{
unsigned short semarray[2 * nr_of_readers];
for (int count = 0; count < nr_of_readers; count++) {
semarray[2 * count] = 0;
semarray[2 * count + 1] = 1000;
}
ret = semctl (semid, 0, SETALL, semarray);
if (ret == -1)
perror ("semctl SETALL");
}
ret = semctl (semid, 0, IPC_RMID);
if (ret == -1)
perror ("semctl IPC_RMID");
}
int main(int argc, char **argv)
{
int semid;
struct sembuf sop;
#ifdef HAVE_SEMTIMEDOP
struct timespec ts;
#endif
if ((semid = semget(IPC_PRIVATE, 1, 0600)) < 0)
{
perror("semget");
exit(1);
}
sop.sem_num = 0;
sop.sem_op = 1;
sop.sem_flg = 0;
if (semop(semid, &sop, 1) < 0)
{
perror("semop");
semctl(semid, 0, IPC_RMID);
exit(1);
}
if (semctl(semid, 0, GETVAL) != 1)
{
perror("semctl GETVAL");
semctl(semid, 0, IPC_RMID);
exit(1);
}
if (semctl(semid, 0, GETPID) != getpid())
{
perror("semctl GETPID");
semctl(semid, 0, IPC_RMID);
exit(1);
}
/* The next call to semtimedop causes the program to hang on
ppc32-linux (Yellow Dog 4.0). I don't know why. Hence the
extended ifdef. */
#if defined(HAVE_SEMTIMEDOP) && !defined(__powerpc__)
sop.sem_num = 0;
sop.sem_op = 0;
sop.sem_flg = 0;
ts.tv_sec = 0;
ts.tv_nsec = 1000000;
if (semtimedop(semid, &sop, 1, &ts) < 0 && errno != EAGAIN)
{
perror("semtimedop");
semctl(semid, 0, IPC_RMID);
exit(1);
}
#endif
sop.sem_num = 0;
sop.sem_op = -1;
sop.sem_flg = 0;
if (semop(semid, &sop, 1) < 0)
{
perror("semop");
semctl(semid, 0, IPC_RMID);
exit(1);
}
#ifdef HAVE_SEMTIMEDOP
sop.sem_num = 0;
sop.sem_op = 0;
sop.sem_flg = 0;
ts.tv_sec = 0;
ts.tv_nsec = 1000;
if (semtimedop(semid, &sop, 1, &ts) < 0)
{
perror("semtimedop");
semctl(semid, 0, IPC_RMID);
exit(1);
}
#endif
if (semctl(semid, 0, IPC_RMID) < 0)
{
perror("semctl(IPC_RMID)");
exit(1);
}
semctl_test(argc > 1, argv[0]);
exit(0);
}
|