Index: trunk/src/emx/include/InnoTekLIBC/backend.h
===================================================================
--- trunk/src/emx/include/InnoTekLIBC/backend.h	(revision 1986)
+++ trunk/src/emx/include/InnoTekLIBC/backend.h	(revision 1987)
@@ -35,4 +35,5 @@
 #include <sys/wait.h>
 #include <sys/sem.h>
+#include <sys/shm.h>
 #include <signal.h>
 #include <emx/io.h>
Index: trunk/src/emx/include/sys/sem.h
===================================================================
--- trunk/src/emx/include/sys/sem.h	(revision 1986)
+++ trunk/src/emx/include/sys/sem.h	(revision 1987)
@@ -11,4 +11,5 @@
  * FreeBSD 5.3
  * @changed     bird: no padding in semid_ds. seminfo and semexit are static in our 'kernel'.
+ * @changed     bird: added time_t, size_t and pid_t as per POSIX.
  */
 
@@ -17,4 +18,25 @@
 
 #include <sys/ipc.h>
+#include <sys/_types.h>
+
+#if !defined(_TIME_T_DECLARED) && !defined(_TIME_T) /* bird: EMX */
+typedef	__time_t	time_t;
+#define	_TIME_T_DECLARED
+#define _TIME_T                         /* bird: EMX */
+#endif
+
+#include <sys/_types.h>
+#if !defined(_SIZE_T_DECLARED) && !defined(_SIZE_T) /* bird: emx */
+typedef	__size_t	size_t;
+#define	_SIZE_T_DECLARED
+#define _SIZE_T                         /* bird: emx */
+#endif
+
+#if !defined(_PID_T_DECLARED) && !defined(_PID_T) /* bird:emx */
+typedef	__pid_t		pid_t;		/* process id */
+#define	_PID_T_DECLARED
+#define _PID_T                          /* bird: emx */
+#endif
+
 
 struct sem;
Index: trunk/src/emx/include/sys/shm.h
===================================================================
--- trunk/src/emx/include/sys/shm.h	(revision 1986)
+++ trunk/src/emx/include/sys/shm.h	(revision 1987)
@@ -39,5 +39,6 @@
 /** @file
  * FreeBSD 5.3
- * @changed the SHMLBA to 64KB.
+ * @changed     bird: the SHMLBA to 64KB.
+ * @changed     bird: added pid_t, time_t and size_t (POSIX).
  */
 
@@ -46,4 +47,25 @@
 
 #include <sys/ipc.h>
+
+#include <sys/_types.h>
+
+#if !defined(_TIME_T_DECLARED) && !defined(_TIME_T)
+typedef	__time_t	time_t;
+#define	_TIME_T_DECLARED
+#define _TIME_T
+#endif
+
+#include <sys/_types.h>
+#if !defined(_SIZE_T_DECLARED) && !defined(_SIZE_T)
+typedef	__size_t	size_t;
+#define	_SIZE_T_DECLARED
+#define _SIZE_T
+#endif
+
+#if !defined(_PID_T_DECLARED) && !defined(_PID_T)
+typedef	__pid_t		pid_t;		
+#define	_PID_T_DECLARED
+#define _PID_T
+#endif
 
 #define SHM_RDONLY  010000  /* Attach read-only (else read-write) */
Index: trunk/src/emx/src/lib/sys/sysv_sem.c
===================================================================
--- trunk/src/emx/src/lib/sys/sysv_sem.c	(revision 1986)
+++ trunk/src/emx/src/lib/sys/sysv_sem.c	(revision 1987)
@@ -562,5 +562,5 @@
         uid_t uid;
         uintptr_t hmtx;
-
+        int semid_in = semid;
 
         /*
@@ -608,5 +608,5 @@
 	case IPC_RMID:
 		__libc_Back_safesemMtxLock(hmtx = semaptr->hmtx);
-		if ((error = semvalid(semid, semaptr)) != 0)
+		if ((error = semvalid(semid_in, semaptr)) != 0)
 			goto done2;
 		if ((error = -__libc_spmCanIPC(&semaptr->u.sem_perm, IPC_M)))
@@ -634,5 +634,5 @@
 			goto done2;
 		__libc_Back_safesemMtxLock(hmtx = semaptr->hmtx);
-		if ((error = semvalid(semid, semaptr)) != 0)
+		if ((error = semvalid(semid_in, semaptr)) != 0)
 			goto done2;
 		if ((error = -__libc_spmCanIPC(&semaptr->u.sem_perm, IPC_M)))
@@ -647,5 +647,5 @@
 	case IPC_STAT:
 		__libc_Back_safesemMtxLock(hmtx = semaptr->hmtx);
-		if ((error = semvalid(semid, semaptr)) != 0)
+		if ((error = semvalid(semid_in, semaptr)) != 0)
 			goto done2;
 		if ((error = -__libc_spmCanIPC(&semaptr->u.sem_perm, IPC_R)))
@@ -659,5 +659,5 @@
 	case GETNCNT:
 		__libc_Back_safesemMtxLock(hmtx = semaptr->hmtx);
-		if ((error = semvalid(semid, semaptr)) != 0)
+		if ((error = semvalid(semid_in, semaptr)) != 0)
 			goto done2;
 		if ((error = -__libc_spmCanIPC(&semaptr->u.sem_perm, IPC_R)))
@@ -672,5 +672,5 @@
 	case GETPID:
 		__libc_Back_safesemMtxLock(hmtx = semaptr->hmtx);
-		if ((error = semvalid(semid, semaptr)) != 0)
+		if ((error = semvalid(semid_in, semaptr)) != 0)
 			goto done2;
 		if ((error = -__libc_spmCanIPC(&semaptr->u.sem_perm, IPC_R)))
@@ -685,5 +685,5 @@
 	case GETVAL:
 		__libc_Back_safesemMtxLock(hmtx = semaptr->hmtx);
-		if ((error = semvalid(semid, semaptr)) != 0)
+		if ((error = semvalid(semid_in, semaptr)) != 0)
 			goto done2;
 		if ((error = -__libc_spmCanIPC(&semaptr->u.sem_perm, IPC_R)))
@@ -699,5 +699,5 @@
 		array = _hmalloc(sizeof(*array) * semaptr->u.sem_nsems);
 		__libc_Back_safesemMtxLock(hmtx = semaptr->hmtx);
-		if ((error = semvalid(semid, semaptr)) != 0)
+		if ((error = semvalid(semid_in, semaptr)) != 0)
 			goto done2;
 		if ((error = -__libc_spmCanIPC(&semaptr->u.sem_perm, IPC_R)))
@@ -712,5 +712,5 @@
 	case GETZCNT:
 		__libc_Back_safesemMtxLock(hmtx = semaptr->hmtx);
-		if ((error = semvalid(semid, semaptr)) != 0)
+		if ((error = semvalid(semid_in, semaptr)) != 0)
 			goto done2;
 		if ((error = -__libc_spmCanIPC(&semaptr->u.sem_perm, IPC_R)))
@@ -725,5 +725,5 @@
 	case SETVAL:
 		__libc_Back_safesemMtxLock(hmtx = semaptr->hmtx);
-		if ((error = semvalid(semid, semaptr)) != 0)
+		if ((error = semvalid(semid_in, semaptr)) != 0)
 			goto done2;
 		if ((error = -__libc_spmCanIPC(&semaptr->u.sem_perm, IPC_W)))
@@ -747,5 +747,5 @@
 		__libc_Back_safesemMtxLock(hmtx = semaptr->hmtx);
 raced:
-		if ((error = semvalid(semid, semaptr)) != 0)
+		if ((error = semvalid(semid_in, semaptr)) != 0)
 			goto done2;
 		count = semaptr->u.sem_nsems;
@@ -756,5 +756,5 @@
 			break;
 		__libc_Back_safesemMtxLock(hmtx = semaptr->hmtx);
-		if ((error = semvalid(semid, semaptr)) != 0)
+		if ((error = semvalid(semid_in, semaptr)) != 0)
 			goto done2;
 		/* we could have raced? */
@@ -894,5 +894,5 @@
 
 found:
-        errno = -IXSEQ_TO_IPCID(semid, sema[semid].u.sem_perm);
+        error = -IXSEQ_TO_IPCID(semid, sema[semid].u.sem_perm);
 done2:
 	__libc_Back_safesemMtxUnlock(gpGlobals->hmtx);
@@ -948,4 +948,5 @@
 	int error;
 	int do_wakeup, do_undos;
+        int semid_in = semid;
 
         /*
@@ -996,5 +997,5 @@
 		goto done2;
 	}
-	if (semaptr->u.sem_perm.seq != IPCID_TO_SEQ(semid)) {
+	if (semaptr->u.sem_perm.seq != IPCID_TO_SEQ(semid_in)) {
 		error = EINVAL;
 		goto done2;
@@ -1115,5 +1116,5 @@
 		 */
 		if ((semaptr->u.sem_perm.mode & SEM_ALLOC) == 0 ||
-		    semaptr->u.sem_perm.seq != IPCID_TO_SEQ(semid)) {
+		    semaptr->u.sem_perm.seq != IPCID_TO_SEQ(semid_in)) {
 			error = EIDRM;
 			goto done2;
@@ -1221,4 +1222,5 @@
 {
     	LIBCLOG_ENTER("\n");
+	static volatile int fDone = 0;
 	struct sem_undo *suptr;
 	struct sem_undo **supptr;
@@ -1227,6 +1229,7 @@
          * If no pointer to globals then there is nothing to do (nearly impossible).
          */
-        if (!gpGlobals)
+        if (!gpGlobals || fDone)
 	    LIBCLOG_RETURN_VOID();
+        fDone = 1;
 
 	/*
Index: trunk/src/emx/src/lib/sys/sysv_shm.c
===================================================================
--- trunk/src/emx/src/lib/sys/sysv_shm.c	(revision 1986)
+++ trunk/src/emx/src/lib/sys/sysv_shm.c	(revision 1987)
@@ -122,4 +122,7 @@
 #define	SHMSEG_ALLOCATED	0x0800
 //#define	SHMSEG_WANTED		0x1000 - cannot happen with our locking policy.
+/** Set when the segment is captured by the server.
+ * if cleared it equals the SHMSEG_REMOVED when shm_nattch <= 0. */
+#define	SHMSEG_SERVER           0x1000
 
 static void shm_deallocate_segment(struct shmid_ds *);
@@ -127,5 +130,5 @@
 static struct shmid_ds *shm_find_segment_by_shmid(int);
 static struct shmid_ds *shm_find_segment_by_shmidx(int);
-static int shm_delete_mapping(struct shmmap_state *);
+static int shm_delete_mapping(struct shmmap_state *, int);
 static int shminit(void);
 static void shmexit_myhook(void);
@@ -287,5 +290,5 @@
 
 static int
-shm_delete_mapping(struct shmmap_state *shmmap_s)
+shm_delete_mapping(struct shmmap_state *shmmap_s, int fExitting)
 {
 	struct __libc_SysV_Shm *pGlobals = gpGlobals;
@@ -306,5 +309,6 @@
 	shmseg->shm_dtime = fibGetUnixSeconds();
 	if ((--shmseg->shm_nattch <= 0) &&
-	    (shmseg->shm_perm.mode & SHMSEG_REMOVED)) {
+	    (   (shmseg->shm_perm.mode & SHMSEG_REMOVED)
+             || (fExitting && !(shmseg->shm_perm.mode & SHMSEG_SERVER)))) {
 		shm_deallocate_segment(shmseg);
 		pGlobals->shm_last_free = segnum;
@@ -359,5 +363,5 @@
 		goto done2;
 	}
-	error = shm_delete_mapping(shmmap_s);
+	error = shm_delete_mapping(shmmap_s, 0);
 done2:
 	__libc_Back_safesemMtxUnlock(gpGlobals->hmtx);
@@ -825,20 +829,46 @@
 shmexit_myhook(void)
 {
+	static volatile int fDone = 0;
 	struct __libc_SysV_Shm *pGlobals = gpGlobals;
-	if (pGlobals) {
-		gpGlobals = NULL;
+	if (pGlobals && !fDone) {
+                fDone = 1;
+		__libc_Back_safesemMtxLock(pGlobals->hmtx);
 		struct shmmap_state *shm = g_vm_shm;
 		if (shm) {
     			g_vm_shm = NULL;
-			__libc_Back_safesemMtxLock(pGlobals->hmtx);
 			int c = shminfo.shmseg;
 			while (c-- > 0) {
-				if (shm->shmid != -1)
-					shm_delete_mapping(shm);
+				if (shm->shmid != -1) {
+					shm_delete_mapping(shm, 1);
+                                }
 				shm++;
 			}
-			__libc_Back_safesemMtxUnlock(pGlobals->hmtx);
 		}
+
+                /* Clean out non-referenced objects when the server isn't around for them. */
+                int c = pGlobals->shm_nused;
+                if (c > 0)
+                {
+                    int i = pGlobals->shmalloced;
+                    struct shmid_ds *shmseg = pGlobals->shmsegs;
+                    while (i-- > 0)
+                    {
+                        if (shmseg->shm_perm.mode & SHMSEG_ALLOCATED)
+                        {
+                            if (    shmseg->shm_nattch <= 0
+                                &&  (   !(shmseg->shm_perm.mode & SHMSEG_SERVER)
+                                     ||  (shmseg->shm_perm.mode & SHMSEG_REMOVED)))
+                                shm_deallocate_segment(shmseg);
+                            if (c-- <= 0)
+                                break;
+                        }
+
+                        /* next */
+                        shmseg++;
+                    }
+                }
+		__libc_Back_safesemMtxUnlock(pGlobals->hmtx);
 		__atomic_decrement_u32(&pGlobals->cUsers);
+                gpGlobals = NULL;
 	}
 }
@@ -890,5 +920,5 @@
         if (rc)
             LIBCLOG_RETURN_INT(rc);
-        if (!pSPMHdr->pSysVSem)
+        if (!pSPMHdr->pSysVShm)
         {
             pGlobals = (struct __libc_SysV_Shm *)__libc_spmAllocLocked(cb);
