Ticket #2657: draft-shm-001.patch
File draft-shm-001.patch, 19.3 KB (added by , 14 years ago) |
---|
-
new file headers/posix/sys/shm.h
From 6e58174c10ee548fe7e9e67d26e80c63d2590815 Mon Sep 17 00:00:00 2001 From: David Hoeppner <dhoeppne@golem.(none)> Date: Sun, 26 Dec 2010 18:58:43 +0100 Subject: [PATCH] sys/shm.h --- headers/posix/sys/shm.h | 41 ++ headers/private/kernel/posix/xsi_shared_memory.h | 29 ++ headers/private/system/syscalls.h | 7 + src/system/kernel/main.cpp | 2 + src/system/kernel/posix/Jamfile | 1 + src/system/kernel/posix/xsi_shared_memory.cpp | 456 ++++++++++++++++++++++ src/system/kernel/syscalls.cpp | 1 + src/system/libroot/posix/sys/Jamfile | 1 + src/system/libroot/posix/sys/xsi_shm.cpp | 48 +++ src/tests/system/libroot/posix/Jamfile | 1 + src/tests/system/libroot/posix/xsi_shm_test1.cpp | 92 +++++ 11 files changed, 679 insertions(+), 0 deletions(-) create mode 100644 headers/posix/sys/shm.h create mode 100644 headers/private/kernel/posix/xsi_shared_memory.h create mode 100644 src/system/kernel/posix/xsi_shared_memory.cpp create mode 100644 src/system/libroot/posix/sys/xsi_shm.cpp create mode 100644 src/tests/system/libroot/posix/xsi_shm_test1.cpp diff --git a/headers/posix/sys/shm.h b/headers/posix/sys/shm.h new file mode 100644 index 0000000..d51f52f
- + 1 /* 2 * Copyright 2010 Haiku Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef _SYS_SHM_H 6 #define _SYS_SHM_H 7 8 9 #include <sys/ipc.h> 10 #include <sys/types.h> 11 12 #define SHMLBA 1024 13 14 /* Message Flags */ 15 #define SHM_RDONLY 01000 /* attach read-only (else read-write) */ 16 #define SHM_RND 02000 /* rounds attach address to SHMLBA */ 17 18 typedef unsigned long shmatt_t; 19 20 struct shmid_ds { 21 struct ipc_perm shm_perm; 22 size_t shm_segsz; 23 pid_t shm_lpid; 24 pid_t shm_cpid; 25 shmatt_t shm_nattch; 26 time_t shm_atime; 27 time_t shm_dtime; 28 time_t shm_ctime; 29 }; 30 31 32 __BEGIN_DECLS 33 34 void* shmat(int, const void *, int); 35 int shmctl(int, int, struct shmid_ds *); 36 int shmdt(const void *); 37 int shmget(key_t, size_t, int); 38 39 __END_DECLS 40 41 #endif /* _SYS_SHM_H */ -
new file headers/private/kernel/posix/xsi_shared_memory.h
diff --git a/headers/private/kernel/posix/xsi_shared_memory.h b/headers/private/kernel/posix/xsi_shared_memory.h new file mode 100644 index 0000000..f237fce
- + 1 /* 2 * Copyright 2010, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #ifndef KERNEL_XSI_SHARED_MEMORY_H 7 #define KERNEL_XSI_SHARED_MEMORY_H 8 9 #include <sys/shm.h> 10 #include <sys/cdefs.h> 11 12 #include <OS.h> 13 14 #include <kernel.h> 15 16 17 __BEGIN_DECLS 18 19 extern void xsi_shm_init(); 20 21 /* user calls */ 22 status_t _user_xsi_shmat(int, const void*, int, void**); 23 int _user_xsi_shmctl(int, int, struct shmid_ds *); 24 int _user_xsi_shmdt(const void *); 25 int _user_xsi_shmget(key_t key, size_t size, int flags); 26 27 __END_DECLS 28 29 #endif /* KERNEL_XSI_SHARED_MEMORY_H */ -
headers/private/system/syscalls.h
diff --git a/headers/private/system/syscalls.h b/headers/private/system/syscalls.h index 42e6d57..01f2b39 100644
a b struct _sem_t; 35 35 struct sembuf; 36 36 union semun; 37 37 struct sigaction; 38 struct shmid_ds; 38 39 struct stat; 39 40 struct system_profiler_parameters; 40 41 … … extern int _kern_xsi_msgsnd(int messageQueueID, 125 126 const void *messagePointer, size_t messageSize, 126 127 int messageFlags); 127 128 129 /* POSIX XSI shared memory syscalls */ 130 extern status_t _kern_xsi_shmat(int a, const void* memoryPointer, int b, void **addr); 131 extern int _kern_xsi_shmctl(int a, int b, struct shmid_ds *memoryDs); 132 extern int _kern_xsi_shmdt(const void *memoryPointer); 133 extern int _kern_xsi_shmget(key_t key, size_t size, int flags); 134 128 135 /* team & thread syscalls */ 129 136 extern thread_id _kern_load_image(const char* const* flatArgs, 130 137 size_t flatArgsSize, int32 argCount, int32 envCount, -
src/system/kernel/main.cpp
diff --git a/src/system/kernel/main.cpp b/src/system/kernel/main.cpp index eca43c7..649e0a2 100644
a b 42 42 #include <posix/realtime_sem.h> 43 43 #include <posix/xsi_message_queue.h> 44 44 #include <posix/xsi_semaphore.h> 45 #include <posix/xsi_shared_memory.h> 45 46 #include <real_time_clock.h> 46 47 #include <sem.h> 47 48 #include <smp.h> … … _start(kernel_args *bootKernelArgs, int currentCPU) 190 191 realtime_sem_init(); 191 192 xsi_sem_init(); 192 193 xsi_msg_init(); 194 xsi_shm_init(); 193 195 194 196 // Start a thread to finish initializing the rest of the system. Note, 195 197 // it won't be scheduled before calling scheduler_start() (on any CPU). -
src/system/kernel/posix/Jamfile
diff --git a/src/system/kernel/posix/Jamfile b/src/system/kernel/posix/Jamfile index 1eb2f51..ffb2f38 100644
a b KernelMergeObject kernel_posix.o : 6 6 realtime_sem.cpp 7 7 xsi_message_queue.cpp 8 8 xsi_semaphore.cpp 9 xsi_shared_memory.cpp 9 10 10 11 : $(TARGET_KERNEL_PIC_CCFLAGS) 11 12 ; -
new file src/system/kernel/posix/xsi_shared_memory.cpp
diff --git a/src/system/kernel/posix/xsi_shared_memory.cpp b/src/system/kernel/posix/xsi_shared_memory.cpp new file mode 100644 index 0000000..875c9a8
- + 1 /* 2 * Copyright 2011, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * David Höppner <0xffea@gmail.com> 7 */ 8 9 #include <posix/xsi_shared_memory.h> 10 11 #include <stdio.h> 12 13 #include <sys/ipc.h> 14 #include <sys/types.h> 15 16 #include <kernel/lock.h> 17 #include <kernel/debug.h> 18 #include <kernel/team.h> 19 #include <kernel/thread.h> 20 21 #include <vm/vm.h> 22 #include <vm/VMAddressSpace.h> 23 #include <vm/VMArea.h> 24 25 #include <util/AutoLock.h> 26 #include <util/DoublyLinkedList.h> 27 #include <util/OpenHashTable.h> 28 29 30 #define TRACE_XSI_SHM 31 #ifdef TRACE_XSI_SHM 32 # define TRACE(x) dprintf x 33 #else 34 # define TRACE(x) /* nothing */ 35 #endif 36 37 #define MAX_XSI_SHARED_MEMORY_COUNT 64 38 #define MIN_XSI_SHARED_MEMORY_SIZE 1 39 #define MAX_XSI_SHARED_MEMORY_SIZE 256*1024*1024 40 #define MAX_XSI_SHARED_MEMORY_ATTACH 128 41 42 static mutex sXsiSharedMemoryLock = MUTEX_INITIALIZER("Global Shared Memory Lock"); 43 static int sSharedMemoryCount = 0; 44 static int sNextEntryID = 0; 45 46 struct SharedMemoryKey : DoublyLinkedListLinkImpl<SharedMemoryKey> { 47 SharedMemoryKey(key_t key, int id, size_t size) 48 : 49 key(key), 50 id(id), 51 size(size) 52 { 53 } 54 55 key_t key; 56 int id; 57 size_t size; 58 }; 59 60 typedef DoublyLinkedList<SharedMemoryKey> SharedMemoryKeyList; 61 static SharedMemoryKeyList sSharedMemoryKeys; 62 63 64 class SharedMemoryEntry { 65 public: 66 SharedMemoryEntry(key_t key, size_t size, int flags) 67 : 68 fKey(key), 69 fSize(size), 70 fKeyLink(NULL) 71 { 72 fDs.shm_segsz = fSize; 73 74 fDs.shm_cpid = getpid(); 75 fDs.shm_lpid = fDs.shm_nattch = 0; 76 fDs.shm_atime = fDs.shm_dtime = 0; 77 fDs.shm_ctime = real_time_clock(); 78 79 fDs.shm_perm.uid = fDs.shm_perm.cuid = geteuid(); 80 fDs.shm_perm.gid = fDs.shm_perm.cgid = getegid(); 81 fDs.shm_perm.mode = (flags & 0x01ff); 82 } 83 84 status_t Init() 85 { 86 char areaName[B_OS_NAME_LENGTH]; 87 addr_t dummy; 88 89 fId = sNextEntryID; 90 91 snprintf(areaName, B_OS_NAME_LENGTH, "xsi_shared_memory%d", (int) fId); 92 93 virtual_address_restrictions virtualRestrictions = {}; 94 virtualRestrictions.address_specification = B_ANY_KERNEL_ADDRESS; 95 physical_address_restrictions physicalRestrictions = {}; 96 fArea = vm_create_anonymous_area(B_SYSTEM_TEAM, areaName, fSize, B_FULL_LOCK, 97 B_KERNEL_AREA_FLAGS, 0, &virtualRestrictions, &physicalRestrictions, 98 true, (void **) &dummy); 99 100 if (fArea < B_OK) { 101 TRACE(("xsi_shmget: create area failed!\n")); 102 return B_NO_MEMORY; 103 } 104 105 memset((void*)dummy, 0, fSize); 106 107 atomic_add(&sNextEntryID, 1); 108 atomic_add(&sSharedMemoryCount, 1); 109 110 return B_OK; 111 } 112 113 ~SharedMemoryEntry() 114 { 115 status_t status; 116 117 status = vm_delete_area(B_SYSTEM_TEAM, fArea, true); 118 if (status < B_OK) 119 TRACE(("shmctl: failed to delete area %d\n", (int) fArea)); 120 121 atomic_add(&sSharedMemoryCount, -1); 122 } 123 124 void SetKey() 125 { 126 fKey = sNextEntryID; 127 } 128 129 void SetKeyLink(SharedMemoryKey* key) 130 { 131 fKeyLink = key; 132 } 133 134 bool HasPermission() const 135 { 136 137 uid_t uid = geteuid(); 138 if (uid == 0 || 139 uid == fDs.shm_perm.uid || 140 uid == fDs.shm_perm.cuid) 141 return true; 142 143 return false; 144 } 145 146 bool HasReadPermission() const 147 { 148 if (fDs.shm_perm.mode & S_IROTH) 149 return true; 150 151 uid_t uid = geteuid(); 152 if (uid == 0 || (uid == fDs.shm_perm.uid 153 && (fDs.shm_perm.mode & S_IRUSR) != 0)) 154 return true; 155 156 gid_t gid = getegid(); 157 if (uid == 0 || (gid == fDs.shm_perm.gid 158 && (fDs.shm_perm.mode & S_IRGRP) != 0)) 159 return true; 160 161 return false; 162 } 163 164 int Id() const 165 { 166 return fId; 167 } 168 169 key_t Key() const 170 { 171 return fKey; 172 } 173 174 area_id Area() const 175 { 176 return fArea; 177 } 178 179 size_t Size() const 180 { 181 return fSize; 182 } 183 184 SharedMemoryKey* KeyLink() const 185 { 186 return fKeyLink; 187 } 188 189 struct shmid_ds* GetDs() 190 { 191 return &fDs; 192 } 193 194 SharedMemoryEntry*& Link() 195 { 196 return fLink; 197 } 198 199 private: 200 int fId; 201 key_t fKey; 202 area_id fArea; 203 size_t fSize; 204 SharedMemoryKey* fKeyLink; 205 SharedMemoryEntry* fLink; 206 struct shmid_ds fDs; 207 }; 208 209 struct XsiSharedMemoryEntryHashTableDefinition { 210 typedef int KeyType; 211 typedef SharedMemoryEntry ValueType; 212 213 size_t HashKey (const int id) const 214 { 215 return (size_t)(id); 216 } 217 218 size_t Hash(SharedMemoryEntry* variable) const 219 { 220 return (size_t) HashKey(variable->Id()); 221 } 222 223 bool Compare(const int id, SharedMemoryEntry* variable) const 224 { 225 return (int) id == (int) variable->Id(); 226 } 227 228 SharedMemoryEntry*& GetLink(SharedMemoryEntry* variable) const 229 { 230 return variable->Link(); 231 } 232 }; 233 234 static BOpenHashTable<XsiSharedMemoryEntryHashTableDefinition> sSharedMemoryEntryTable; 235 236 237 void 238 xsi_shm_init() 239 { 240 status_t status; 241 242 status = sSharedMemoryEntryTable.Init(); 243 if (status != B_OK) { 244 panic("xsi_shm_init(): Failed to initialize shared memory hash table!\n"); 245 } 246 247 new(&sSharedMemoryKeys) SharedMemoryKeyList; 248 } 249 250 status_t 251 _user_xsi_shmat(int id, const void *addr, int flags, void **raddr) 252 { 253 SharedMemoryEntry* entry; 254 struct shmid_ds* mds; 255 struct area_info info; 256 void* address; 257 uint32 addressSpec = B_ANY_ADDRESS; 258 area_id area; 259 int protection = B_READ_AREA | B_WRITE_AREA; 260 261 TRACE(("shmat: id = %d, addr = %p, flags = %d\n", 262 id, addr, flags)); 263 264 MutexLocker _(sXsiSharedMemoryLock); 265 266 entry = sSharedMemoryEntryTable.Lookup(id); 267 if (entry == NULL) 268 return EINVAL; 269 270 271 mds = entry->GetDs(); 272 if (mds->shm_nattch >= MAX_XSI_SHARED_MEMORY_ATTACH) 273 return EMFILE; 274 275 if (flags & SHM_RDONLY) 276 protection &= ~B_WRITE_AREA; 277 278 if (addr != NULL) { 279 if (flags & SHM_RND) { 280 // TODO address = (void *) (addr - ((uintptr_t) addr % SHMLBA)); 281 return EINVAL; 282 } else { 283 if (!IS_USER_ADDRESS(addr)) 284 return B_BAD_ADDRESS; 285 286 address = (void *) addr; 287 addressSpec = B_EXACT_ADDRESS; 288 } 289 290 if (!IS_USER_ADDRESS(address)) 291 return B_BAD_ADDRESS; 292 } 293 294 get_area_info(entry->Area(), &info); 295 area = vm_clone_area(VMAddressSpace::CurrentID(), info.name, &address, addressSpec, 296 protection, REGION_NO_PRIVATE_MAP, entry->Area(), false); 297 298 if (area < B_OK) 299 return area; 300 301 mds->shm_atime = real_time_clock(); 302 mds->shm_nattch++; 303 304 *raddr = address; 305 306 return B_OK; 307 } 308 309 int 310 _user_xsi_shmctl(int id, int cmd, struct shmid_ds* buffer) 311 { 312 SharedMemoryEntry *entry; 313 struct shmid_ds* mds; 314 status_t status; 315 316 TRACE(("shmctl: id = %d, cmd = %d\n", id, cmd)); 317 318 MutexLocker _(sXsiSharedMemoryLock); 319 320 entry = sSharedMemoryEntryTable.Lookup(id); 321 if (entry == NULL) 322 return EINVAL; 323 324 switch(cmd) { 325 case IPC_STAT: 326 if (!entry->HasReadPermission()) 327 return EACCES; 328 329 if (!IS_USER_ADDRESS(buffer)) 330 return B_BAD_ADDRESS; 331 332 // TODO: EOVERFLOW 333 mds = (struct shmid_ds*)entry->GetDs(); 334 status = user_memcpy(buffer, (const void*) mds, sizeof(struct shmid_ds)); 335 if (status < B_OK) { 336 return B_BAD_ADDRESS; 337 } 338 break; 339 case IPC_SET: 340 if (!entry->HasPermission()) 341 return EPERM; 342 343 if (!IS_USER_ADDRESS(buffer)) 344 return B_BAD_ADDRESS; 345 346 mds = entry->GetDs(); 347 status = user_memcpy(mds, buffer, sizeof(struct shmid_ds)); 348 if (status < B_OK) 349 return B_BAD_ADDRESS; 350 351 break; 352 case IPC_RMID: 353 if (!entry->HasPermission()) 354 return EPERM; 355 356 sSharedMemoryKeys.Remove(entry->KeyLink()); 357 sSharedMemoryEntryTable.Remove(entry); 358 delete entry; 359 360 break; 361 default: 362 return EINVAL; 363 } 364 365 return B_OK; 366 } 367 368 int 369 _user_xsi_shmdt(const void *address) 370 { 371 area_id area; 372 status_t status; 373 374 TRACE(("xsi_shmdt: %p\n", address)); 375 376 area = area_for((void*)address); 377 if (area == B_ERROR) 378 return EINVAL; 379 380 status = vm_delete_area(VMAddressSpace::CurrentID(), area, true); 381 if (status < B_OK) { 382 return EINVAL; 383 } 384 385 MutexLocker _(sXsiSharedMemoryLock); 386 // TODO nattch 387 388 return B_OK; 389 } 390 391 int 392 _user_xsi_shmget(key_t key, size_t size, int flags) 393 { 394 SharedMemoryEntry* entry; 395 SharedMemoryKey* keyEntry = NULL; 396 status_t status; 397 398 TRACE(("shmget: key = %d, size = %d, flags = %d\n", 399 (int) key, (int) size, flags)); 400 401 MutexLocker _(sXsiSharedMemoryLock); 402 403 if (key != IPC_PRIVATE) { 404 SharedMemoryKeyList::Iterator it = sSharedMemoryKeys.GetIterator(); 405 406 while (it.HasNext()) { 407 keyEntry = it.Next(); 408 409 if (keyEntry->key == key) { 410 if ((flags & IPC_CREAT) && (flags & IPC_EXCL)) 411 return EEXIST; 412 413 if (keyEntry->size < size && size != 0) 414 return EINVAL; 415 416 return keyEntry->id; 417 } 418 } 419 420 if (!(flags & IPC_CREAT)) 421 return ENOENT; 422 } 423 424 if (size < MIN_XSI_SHARED_MEMORY_SIZE || 425 size > MAX_XSI_SHARED_MEMORY_SIZE) 426 return EINVAL; 427 428 if (sSharedMemoryCount > MAX_XSI_SHARED_MEMORY_COUNT) 429 return ENOSPC; 430 431 entry = new (std::nothrow) SharedMemoryEntry(key, size, flags); 432 if (entry == NULL) 433 return ENOMEM; 434 435 436 status = entry->Init(); 437 if (status < B_OK) { 438 delete entry; 439 return status; 440 } 441 442 if (key != IPC_PRIVATE) { 443 keyEntry = new(std::nothrow) SharedMemoryKey(key, entry->Id(), size); 444 if (keyEntry == NULL) { 445 delete entry; 446 return ENOMEM; 447 } 448 449 sSharedMemoryKeys.Add(keyEntry); 450 entry->SetKeyLink(keyEntry); 451 } 452 453 sSharedMemoryEntryTable.Insert(entry); 454 455 return entry->Id(); 456 } -
src/system/kernel/syscalls.cpp
diff --git a/src/system/kernel/syscalls.cpp b/src/system/kernel/syscalls.cpp index b8efd95..4c90658 100644
a b 38 38 #include <posix/realtime_sem.h> 39 39 #include <posix/xsi_message_queue.h> 40 40 #include <posix/xsi_semaphore.h> 41 #include <posix/xsi_shared_memory.h> 41 42 #include <real_time_clock.h> 42 43 #include <safemode.h> 43 44 #include <sem.h> -
src/system/libroot/posix/sys/Jamfile
diff --git a/src/system/libroot/posix/sys/Jamfile b/src/system/libroot/posix/sys/Jamfile index 17601c8..40f0d0a 100644
a b MergeObject posix_sys.o : 26 26 wait.c 27 27 xsi_msg_queue.cpp 28 28 xsi_sem.cpp 29 xsi_shm.cpp 29 30 ; -
new file src/system/libroot/posix/sys/xsi_shm.cpp
diff --git a/src/system/libroot/posix/sys/xsi_shm.cpp b/src/system/libroot/posix/sys/xsi_shm.cpp new file mode 100644 index 0000000..8632463
- + 1 /* 2 * Copyright 2010, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * David Höppner <0xffea@gmail.com> 7 */ 8 9 #include <errno.h> 10 11 #include <sys/shm.h> 12 13 #include <syscall_utils.h> 14 #include <syscalls.h> 15 16 17 void * 18 shmat(int key, const void *address, int flags) 19 { 20 status_t status; 21 void *addr; 22 23 status = _kern_xsi_shmat(key, address, flags, &addr); 24 if (status < 0) { 25 errno = status; 26 return (void *) -1; 27 } 28 29 return (void *) addr; 30 } 31 32 int 33 shmctl(int id, int cmd, struct shmid_ds *buffer) 34 { 35 RETURN_AND_SET_ERRNO(_kern_xsi_shmctl(id, cmd, buffer)); 36 } 37 38 int 39 shmdt(const void *address) 40 { 41 RETURN_AND_SET_ERRNO(_kern_xsi_shmdt(address)); 42 } 43 44 int 45 shmget(key_t key, size_t size, int flags) 46 { 47 RETURN_AND_SET_ERRNO(_kern_xsi_shmget(key, size, flags)); 48 } -
src/tests/system/libroot/posix/Jamfile
diff --git a/src/tests/system/libroot/posix/Jamfile b/src/tests/system/libroot/posix/Jamfile index aced757..1a97ba4 100644
a b SimpleTest init_rld_after_fork_test : init_rld_after_fork_test.cpp ; 33 33 # XSI tests 34 34 SimpleTest xsi_msg_queue_test1 : xsi_msg_queue_test1.cpp ; 35 35 SimpleTest xsi_sem_test1 : xsi_sem_test1.cpp ; 36 SimpleTest xsi_shm_test1 : xsi_shm_test1.cpp ; 36 37 37 38 # wide character tests 38 39 SimpleTest mbtest : mbtest.c ; -
new file src/tests/system/libroot/posix/xsi_shm_test1.cpp
diff --git a/src/tests/system/libroot/posix/xsi_shm_test1.cpp b/src/tests/system/libroot/posix/xsi_shm_test1.cpp new file mode 100644 index 0000000..cdbfba6
- + 1 /* 2 * Copyright 2008-2011, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Salvatore Benedetto <salvatore.benedetto@gmail.com> 7 * David Höppner <0xffea@gmail.com> 8 */ 9 10 #include <errno.h> 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <string.h> 14 #include <unistd.h> 15 #include <sys/mman.h> 16 #include <sys/shm.h> 17 #include <sys/time.h> 18 #include <sys/wait.h> 19 #include <time.h> 20 21 #include <OS.h> 22 23 #include "TestUnitUtils.h" 24 25 #define KEY ((key_t)12345) 26 #define SHM_SIZE 16*1024*1024 27 28 static void 29 test_shmget() 30 { 31 TEST_SET("shmget({IPC_PRIVATE, key})"); 32 33 const char* currentTest = NULL; 34 35 // Open private set with IPC_PRIVATE 36 TEST("shmget(IPC_PRIVATE) - private"); 37 int shmID = shmget(IPC_PRIVATE, SHM_SIZE, S_IRUSR | S_IWUSR); 38 assert_posix_bool_success(shmID != -1); 39 40 // Destroy private memory entry 41 TEST("shmctl(IPC_RMID) - private"); 42 status_t status = shmctl(shmID, IPC_RMID, NULL); 43 assert_posix_bool_success(status != -1); 44 45 // Open non-private non-existing set with IPC_CREAT 46 TEST("shmget(KEY, IPC_CREAT) non-existing"); 47 shmID = shmget(KEY, SHM_SIZE, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR 48 | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); 49 assert_posix_bool_success(status != -1); 50 51 // Re-open non-private existing with greater size 52 TEST("shmget(KEY) re-open existing without IPC_CREAT"); 53 int returnID = shmget(KEY, SHM_SIZE+1, 0); 54 assert_posix_bool_success(errno == EINVAL); 55 56 // Re-open non-private existing without IPC_CREAT 57 TEST("shmget(KEY) re-open existing without IPC_CREAT"); 58 returnID = shmget(KEY, SHM_SIZE, 0); 59 assert_equals(shmID, returnID); 60 61 // Re-open non-private existing with IPC_CREAT 62 TEST("shmget(IPC_CREATE) re-open existing with IPC_CREAT"); 63 returnID = shmget(KEY, SHM_SIZE, IPC_CREAT | IPC_EXCL); 64 assert_posix_bool_success(errno == EEXIST); 65 66 // Destroy non-private 67 TEST("shmctl(IPC_RMID)"); 68 status = shmctl(shmID, IPC_RMID, NULL); 69 assert_posix_bool_success(status != -1); 70 71 // Open non-private non-existing without IPC_CREAT 72 TEST("shmget(IPC_CREATE) non-existing without IPC_CREAT"); 73 shmID = shmget(KEY, SHM_SIZE, IPC_EXCL | S_IRUSR | S_IWUSR 74 | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); 75 assert_posix_bool_success(errno == ENOENT); 76 77 // Destroy non-existing 78 TEST("shmctl()"); 79 status = shmctl(shmID, IPC_RMID, NULL); 80 assert_posix_bool_success(errno == EINVAL); 81 82 TEST("done"); 83 } 84 85 86 int 87 main() 88 { 89 test_shmget(); 90 91 printf("\nAll tests OK\n"); 92 }