From d7d3978337745d458ff053c00d4d2fb238fa608e Mon Sep 17 00:00:00 2001 From: Szabolcs Nagy Date: Sun, 28 Oct 2012 19:20:59 +0100 Subject: [PATCH] general: add sysv ipc shm test, fix ipc_msg and update sem test --- src/general/ipc_msg.c | 2 +- src/general/ipc_shm.c | 117 ++++++++++++++++++++++++++++++++++++++++++ src/general/sem.c | 6 ++- 3 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 src/general/ipc_shm.c diff --git a/src/general/ipc_msg.c b/src/general/ipc_msg.c index 426929d..3b91aeb 100644 --- a/src/general/ipc_msg.c +++ b/src/general/ipc_msg.c @@ -66,7 +66,7 @@ static void snd() if (qid_ds.msg_ctime < t) error("qid_ds.msg_ctime >= t failed: got %ld, want %ld\n", (long)qid_ds.msg_ctime, (long)t); if (qid_ds.msg_qbytes <= 0) - error("qid_ds.msg_qbytes > 0 failed: got %d, want 0\n", qid_ds.msg_ctime, t); + error("qid_ds.msg_qbytes > 0 failed: got %d, want 0\n", qid_ds.msg_qbytes, t); /* test send */ T(msgsnd(qid, &msg, sizeof msg.data, IPC_NOWAIT)); diff --git a/src/general/ipc_shm.c b/src/general/ipc_shm.c new file mode 100644 index 0000000..7d0086b --- /dev/null +++ b/src/general/ipc_shm.c @@ -0,0 +1,117 @@ +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include "test.h" + +static const char path[] = "."; +static const int id = 'x'; + +#define T(f) do{ \ + if ((f)+1 == 0) \ + error("%s failed: %s\n", #f, strerror(errno)); \ +}while(0) + +#define EQ(a,b,fmt) do{ \ + if ((a) != (b)) \ + error("%s == %s failed: " fmt "\n", #a, #b, a, b); \ +}while(0) + +static void set() +{ + time_t t; + key_t k; + int shmid; + struct shmid_ds shmid_ds; + void *p; + + T(t = time(0)); + T(k = ftok(path, id)); + + /* make sure we get a clean shared memory id */ + T(shmid = shmget(k, 100, IPC_CREAT|0666)); + T(shmctl(shmid, IPC_RMID, 0)); + T(shmid = shmget(k, 100, IPC_CREAT|IPC_EXCL|0666)); + + if (test_status) + exit(test_status); + + /* check IPC_EXCL */ + errno = 0; + if (shmget(k, 100, IPC_CREAT|IPC_EXCL|0666) != -1 || errno != EEXIST) + error("shmget(IPC_CREAT|IPC_EXCL) should have failed with EEXIST, got %s\n", strerror(errno)); + + /* check if shmget initilaized the msshmid_ds structure correctly */ + T(shmctl(shmid, IPC_STAT, &shmid_ds)); + EQ(shmid_ds.shm_perm.cuid, geteuid(), "got %d, want %d"); + EQ(shmid_ds.shm_perm.uid, geteuid(), "got %d, want %d"); + EQ(shmid_ds.shm_perm.cgid, getegid(), "got %d, want %d"); + EQ(shmid_ds.shm_perm.gid, getegid(), "got %d, want %d"); + EQ(shmid_ds.shm_perm.mode & 0x1ff, 0666, "got %o, want %o"); + EQ(shmid_ds.shm_segsz, 100, "got %d, want %d"); + EQ(shmid_ds.shm_lpid, 0, "got %d, want %d"); + EQ(shmid_ds.shm_cpid, getpid(), "got %d, want %d"); + EQ((int)shmid_ds.shm_nattch, 0, "got %d, want %d"); + EQ((long)shmid_ds.shm_atime, 0, "got %ld, want %d"); + EQ((long)shmid_ds.shm_dtime, 0, "got %ld, want %d"); + if (shmid_ds.shm_ctime < t) + error("shmid_ds.shm_ctime >= t failed: got %ld, want %ld\n", (long)shmid_ds.shm_ctime, (long)t); + + /* test attach */ + if ((p=shmat(shmid, 0, 0)) == 0) + error("shmat failed: %s\n", strerror(errno)); + T(shmctl(shmid, IPC_STAT, &shmid_ds)); + EQ((int)shmid_ds.shm_nattch, 1, "got %d, want %d"); + EQ(shmid_ds.shm_lpid, getpid(), "got %d, want %d"); + if (shmid_ds.shm_atime < t) + error("shm_atime is %ld want >= %ld\n", (long)shmid_ds.shm_atime, (long)t); + strcpy(p, "test data"); + T(shmdt(p)); +} + +static void get() +{ + key_t k; + int shmid; + void *p; + + T(k = ftok(path, id)); + T(shmid = shmget(k, 0, 0)); + + errno = 0; + if ((p=shmat(shmid, 0, SHM_RDONLY)) == 0) + error("shmat failed: %s\n", strerror(errno)); + + if (strcmp(p, "test data") != 0) + error("reading shared mem failed: got \"%.100s\" want \"test data\"\n", p); + + /* cleanup */ + T(shmdt(p)); + T(shmctl(shmid, IPC_RMID, 0)); +} + +int main(void) +{ + int p; + int status; + + set(); + p = fork(); + if (p == -1) + error("fork failed: %s\n", strerror(errno)); + else if (p == 0) + get(); + else { + T(waitpid(p, &status, 0)); + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) + error("child exit status: %d\n", status); + } + return test_status; +} diff --git a/src/general/sem.c b/src/general/sem.c index 329164a..69ec34e 100644 --- a/src/general/sem.c +++ b/src/general/sem.c @@ -27,7 +27,6 @@ int main(void) "reopening should fail with O_EXCL\n"); TEST(errno == EEXIST, "after reopen failure errno is \"%s\" (%d); want EEXIST (%d)\n", strerror(errno), errno, EEXIST); - errno = 0; TEST(sem_getvalue(sem, &val) == 0, "failed to get sem value\n"); TEST(val == 1, "wrong initial semaphore value: %d\n", val); @@ -35,10 +34,15 @@ int main(void) TEST((sem2=sem_open(buf, 0)) == sem, "could not reopen sem: got %p, want %p\n", sem2, sem); + errno = 0; TEST(sem_wait(sem) == 0, "%s\n", strerror(errno)); TEST(sem_getvalue(sem2, &val) == 0, "%s\n", strerror(errno)); TEST(val == 0, "wrong semaphore value on second handle: %d\n", val); + errno = 0; + TEST(sem_trywait(sem) == -1 && errno == EAGAIN, + "trywait on locked sem: got errno \"%s\" (%d), want EAGAIN (%d)\n", strerror(errno), errno, EAGAIN); + TEST(sem_post(sem) == 0, "%s\n", strerror(errno)); TEST(sem_getvalue(sem2, &val) == 0, "%s\n", strerror(errno)); TEST(val == 1, "wrong semaphore value on second handle: %d\n", val); -- 2.20.1