summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/shm.cc
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2004-03-30 15:20:08 +0000
committerCorinna Vinschen <corinna@vinschen.de>2004-03-30 15:20:08 +0000
commit5c7b73ed978ba139423813144e4eecccf016c81a (patch)
treea1138ea59cfdc67fd737da7406aa221b10d72364 /winsup/cygwin/shm.cc
parent66c8e18830451ee6ffc231586c65fbf2c06535b2 (diff)
downloadcygnal-5c7b73ed978ba139423813144e4eecccf016c81a.tar.gz
cygnal-5c7b73ed978ba139423813144e4eecccf016c81a.tar.bz2
cygnal-5c7b73ed978ba139423813144e4eecccf016c81a.zip
* shm.cc (shmat): If shmid is unknown, call a special variation
of shmget to retrieve the shared memory segment from Cygserver instead of failing immediately. * include/cygwin/ipc.h (IPC_KEY_IS_SHMID): New internal flag for shmget when called from shmat.
Diffstat (limited to 'winsup/cygwin/shm.cc')
-rw-r--r--winsup/cygwin/shm.cc23
1 files changed, 20 insertions, 3 deletions
diff --git a/winsup/cygwin/shm.cc b/winsup/cygwin/shm.cc
index 7e4be9ebd..4bae7b2d2 100644
--- a/winsup/cygwin/shm.cc
+++ b/winsup/cygwin/shm.cc
@@ -160,9 +160,26 @@ shmat (int shmid, const void *shmaddr, int shmflg)
}
if (!ssh_entry)
{
- /* Invalid shmid */
- set_errno (EINVAL);
- return (void *) -1;
+ /* The shmid is unknown to this process so far. Try to get it from
+ the server if it exists. Use special internal call to shmget,
+ which interprets the key as a shmid and only returns a valid
+ shmid if one exists. Since shmctl inserts a new entry for this
+ shmid into ssh_list automatically, we just have to go through
+ that list again. If that still fails, well, bad luck. */
+ if (shmid && shmget ((key_t) shmid, 0, IPC_KEY_IS_SHMID) != -1)
+ {
+ SLIST_FOREACH (ssh_entry, &ssh_list, ssh_next)
+ {
+ if (ssh_entry->shmid == shmid)
+ break;
+ }
+ }
+ if (!ssh_entry)
+ {
+ /* Invalid shmid */
+ set_errno (EINVAL);
+ return (void *) -1;
+ }
}
vm_object_t attach_va = NULL;
if (shmaddr)