diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2004-03-30 15:20:08 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2004-03-30 15:20:08 +0000 |
commit | 5c7b73ed978ba139423813144e4eecccf016c81a (patch) | |
tree | a1138ea59cfdc67fd737da7406aa221b10d72364 /winsup/cygwin/shm.cc | |
parent | 66c8e18830451ee6ffc231586c65fbf2c06535b2 (diff) | |
download | cygnal-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.cc | 23 |
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) |