+2004-03-30 Corinna Vinschen <corinna@vinschen.de>
+
+ * 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.
+
2004-03-29 Corinna Vinschen <corinna@vinschen.de>
* fhandler.h (class fhandler_socket): Add has_been_closed member.
/* Mode bits:
*/
+#ifdef _KERNEL
+#define IPC_KEY_IS_SHMID 0x0100 /* Used in shmget when called from shmat. */
+#endif
#define IPC_CREAT 0x0200 /* Create entry if key does not exist. */
#define IPC_EXCL 0x0400 /* Fail if key exists. */
#define IPC_NOWAIT 0x0800 /* Error if request must wait. */
}
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)