diff -crP postgresql-7.2b2/configure postgresql-7.2b2.patched/configure
*** postgresql-7.2b2/configure	Tue Nov  6 14:12:07 2001
--- postgresql-7.2b2.patched/configure	Thu Nov 15 01:30:09 2001
***************
*** 686,691 ****
--- 686,693 ----
    
    # --with-template not given
  
+ echo $host_os
+ 
  case $host_os in
       aix*) template=aix ;;
      beos*) template=beos ;;
***************
*** 702,707 ****
--- 704,710 ----
   openbsd*) template=openbsd ;;
       osf*) template=osf ;;
       qnx*) template=qnx4 ;;
+      nto*) template=qnx6 ;;
       sco*) template=sco ;;
   solaris*) template=solaris ;;
     sunos*) template=sunos4 ;;
diff -crP postgresql-7.2b2/configure.in postgresql-7.2b2.patched/configure.in
*** postgresql-7.2b2/configure.in	Tue Nov  6 14:12:07 2001
--- postgresql-7.2b2.patched/configure.in	Thu Nov  8 14:00:33 2001
***************
*** 72,77 ****
--- 72,78 ----
   openbsd*) template=openbsd ;;
       osf*) template=osf ;;
       qnx*) template=qnx4 ;;
+      nto*) template=qnx6 ;;
       sco*) template=sco ;;
   solaris*) template=solaris ;;
     sunos*) template=sunos4 ;;
diff -crP postgresql-7.2b2/src/Makefile.shlib postgresql-7.2b2.patched/src/Makefile.shlib
*** postgresql-7.2b2/src/Makefile.shlib	Fri Oct  5 16:15:38 2001
--- postgresql-7.2b2.patched/src/Makefile.shlib	Thu Nov  8 18:49:24 2001
***************
*** 263,268 ****
--- 263,274 ----
    SHLIB_LINK		+= -ltermcap -lstdc++.r4 -lbind -lsocket -L/boot/develop/lib/x86
  endif
  
+ ifeq ($(PORTNAME), qnx6)
+   shlib			:= lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION).$(SO_MINOR_VERSION)
+   LINK.shared		= $(COMPILER) -shared -Wl,-soname,$(soname)
+   SHLIB_LINK		+= -lm -lsocket -lc
+ endif
+ 
  SHLIB_LINK := $(filter -L%, $(LDFLAGS)) $(SHLIB_LINK)
  ifeq ($(enable_rpath), yes)
  SHLIB_LINK += $(rpath)
diff -crP postgresql-7.2b2/src/backend/port/Makefile.in postgresql-7.2b2.patched/src/backend/port/Makefile.in
*** postgresql-7.2b2/src/backend/port/Makefile.in	Tue May  8 14:38:57 2001
--- postgresql-7.2b2.patched/src/backend/port/Makefile.in	Mon Nov 19 21:30:10 2001
***************
*** 30,35 ****
--- 30,42 ----
  ifeq ($(PORTNAME), qnx4)
  OBJS += getrusage.o qnx4/SUBSYS.o
  endif
+ #
+ # Uncomment below lines if you want to use SysV emulation on QNX6
+ # But you don't want it probably.
+ #
+ #ifeq ($(PORTNAME), qnx6)
+ #OBJS += qnx6/SUBSYS.o
+ #endif
  ifeq ($(PORTNAME), beos)
  OBJS += beos/SUBSYS.o
  endif
***************
*** 46,51 ****
--- 53,67 ----
  
  qnx4.dir:
  	$(MAKE) -C qnx4 all
+ 
+ #
+ # Uncomment below lines if you want to use SysV emulation on QNX6
+ # See README in qnx6 directory
+ #
+ #qnx6/SUBSYS.o: qnx6.dir
+ 
+ #qnx6.dir:
+ #	$(MAKE) -C qnx6 all
  
  beos/SUBSYS.o: beos.dir
  
diff -crP postgresql-7.2b2/src/backend/port/dynloader/qnx6.c postgresql-7.2b2.patched/src/backend/port/dynloader/qnx6.c
*** postgresql-7.2b2/src/backend/port/dynloader/qnx6.c	Wed Dec 31 18:00:00 1969
--- postgresql-7.2b2.patched/src/backend/port/dynloader/qnx6.c	Sun Nov  4 06:54:05 2001
***************
*** 0 ****
--- 1,4 ----
+ /* Dummy file used for nothing at this point
+  *
+  * see qnx6.h
+  */
diff -crP postgresql-7.2b2/src/backend/port/dynloader/qnx6.h postgresql-7.2b2.patched/src/backend/port/dynloader/qnx6.h
*** postgresql-7.2b2/src/backend/port/dynloader/qnx6.h	Wed Dec 31 18:00:00 1969
--- postgresql-7.2b2.patched/src/backend/port/dynloader/qnx6.h	Sun Nov  4 06:54:41 2001
***************
*** 0 ****
--- 1,14 ----
+ /* $Header: /home/projects/pgsql/cvsroot/pgsql/src/backend/port/dynloader/solaris.h,v 1.3 2001/03/22 03:59:43 momjian Exp $ */
+ 
+ #ifndef DYNLOADER_NEUTRINO_H
+ #define DYNLOADER_NEUTRINO_H
+ 
+ #include <dlfcn.h>
+ #include "utils/dynamic_loader.h"
+ 
+ #define pg_dlopen(f)	dlopen(f,RTLD_NOW)
+ #define pg_dlsym		dlsym
+ #define pg_dlclose		dlclose
+ #define pg_dlerror		dlerror
+ 
+ #endif	 /* DYNLOADER_NEUTRINO_H */
diff -crP postgresql-7.2b2/src/backend/port/qnx6/Makefile postgresql-7.2b2.patched/src/backend/port/qnx6/Makefile
*** postgresql-7.2b2/src/backend/port/qnx6/Makefile	Wed Dec 31 18:00:00 1969
--- postgresql-7.2b2.patched/src/backend/port/qnx6/Makefile	Thu Nov  8 16:47:53 2001
***************
*** 0 ****
--- 1,38 ----
+ #-------------------------------------------------------------------------
+ #
+ # Makefile--
+ #    Makefile for port/sparc
+ #
+ # IDENTIFICATION
+ #    $Header: /home/projects/pgsql/cvsroot/pgsql/src/backend/port/qnx4/Makefile,v 1.3 2000/08/31 16:10:19 petere Exp $
+ #
+ #-------------------------------------------------------------------------
+ 
+ subdir = src/backend/port/qnx6
+ top_builddir = ../../../..
+ include $(top_builddir)/src/Makefile.global
+ 
+ CC = gcc -g
+ OBJS = sem.o shm.o
+ 
+ all: SUBSYS.o tstsem tstshm
+ #all: SUBSYS.o 
+ 
+ SUBSYS.o: $(OBJS)
+ 	$(LD) $(LDREL) $(LDOUT) SUBSYS.o $(OBJS)
+ 
+ tstsem: tstsem.o sem.o
+ 	$(CC) -o tstsem sem.o tstsem.o
+ 
+ tstshm: tstshm.o shm.o
+ 	$(CC) -o tstshm shm.o tstshm.o
+ 
+ depend dep:
+ 	$(CC) -MM $(CFLAGS) *.c >depend
+ 
+ clean: 
+ 	rm -f SUBSYS.o $(OBJS) tstrint tstsem tstsem.o tstshm tstshm.o
+ 
+ ifeq (depend,$(wildcard depend))
+ include depend
+ endif
diff -crP postgresql-7.2b2/src/backend/port/qnx6/README postgresql-7.2b2.patched/src/backend/port/qnx6/README
*** postgresql-7.2b2/src/backend/port/qnx6/README	Wed Dec 31 18:00:00 1969
--- postgresql-7.2b2.patched/src/backend/port/qnx6/README	Mon Nov 19 21:14:42 2001
***************
*** 0 ****
--- 1,13 ----
+ This is SysV IPC emulation (shared memory & semaphores)
+ for QNX6. It was inherited from QNX4 directory, but modified
+ to use anomymous shared memory.
+ 
+ QNX6 in fact should use HAVE_POSIX_IPC code, so this is only
+ left here for historical/reference purposes. If for some
+ reason you want to use this code, uncomment lines containing
+ 'qnx6' in ../Makefile (and ../Makefile.in, if you want to re-run
+ configure). Otherwise this code is compiled, but not linked
+ with Postgres.
+ 
+ - Igor Kovalenko
+ 11/19/2001
diff -crP postgresql-7.2b2/src/backend/port/qnx6/ipc.h postgresql-7.2b2.patched/src/backend/port/qnx6/ipc.h
*** postgresql-7.2b2/src/backend/port/qnx6/ipc.h	Wed Dec 31 18:00:00 1969
--- postgresql-7.2b2.patched/src/backend/port/qnx6/ipc.h	Mon Nov  5 11:46:27 2001
***************
*** 0 ****
--- 1,31 ----
+ /*-------------------------------------------------------------------------
+  *
+  * ipc.h
+  *	  System V IPC Emulation
+  *
+  * Copyright (c) 1999, repas AEG Automation GmbH
+  *
+  *
+  * IDENTIFICATION
+  *	  $Header: /cvsroot/pgsql/src/backend/port/qnx4/ipc.h,v 1.6 2001/11/05 17:46:27 momjian Exp $
+  *
+  *-------------------------------------------------------------------------
+  */
+ 
+ #ifndef _SYS_IPC_H
+ #define _SYS_IPC_H
+ 
+ /* Common IPC definitions. */
+ /* Mode bits. */
+ #define IPC_CREAT	0001000		/* create entry if key doesn't exist */
+ #define IPC_EXCL	0002000		/* fail if key exists */
+ #define IPC_NOWAIT	0004000		/* error if request must wait */
+ 
+ /* Keys. */
+ #define IPC_PRIVATE (key_t)0	/* private key */
+ 
+ /* Control Commands. */
+ #define IPC_RMID	0			/* remove identifier */
+ #define IPC_STAT	1			/* get shm status */
+ 
+ #endif   /* _SYS_IPC_H */
diff -crP postgresql-7.2b2/src/backend/port/qnx6/sem.c postgresql-7.2b2.patched/src/backend/port/qnx6/sem.c
*** postgresql-7.2b2/src/backend/port/qnx6/sem.c	Wed Dec 31 18:00:00 1969
--- postgresql-7.2b2.patched/src/backend/port/qnx6/sem.c	Mon Nov 19 19:15:22 2001
***************
*** 0 ****
--- 1,348 ----
+ /*-------------------------------------------------------------------------
+  *
+  * sem.c
+  *	  System V Semaphore Emulation
+  *
+  * Copyright (c) 1999, repas AEG Automation GmbH
+  * Copyright (c) 2001, Igor Kovalenko ikovalenko@sourceforge.net
+  *
+  * - Original code was changed to use anonymous shared memory
+  *
+  * IDENTIFICATION
+  *	  $Header: /cvsroot/pgsql/src/backend/port/qnx4/sem.c,v 1.9 2001/10/28 06:25:47 momjian Exp $
+  *
+  *-------------------------------------------------------------------------
+  */
+ 
+ #include "postgres.h"
+ 
+ #include <errno.h>
+ #include <semaphore.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/sem.h>
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+ 
+ #include "miscadmin.h"
+ #include "storage/ipc.h"
+ #include "storage/proc.h"
+ 
+ 
+ #define SEMMAX	(PROC_NSEMS_PER_SET+1)
+ #define OPMAX	8
+ 
+ struct pending_ops
+ {
+ 	int			op[OPMAX];		/* array of pending operations */
+ 	int			idx;			/* index of first free array member */
+ };
+ 
+ struct sem_set_info
+ {
+ 	key_t		key;
+ 	int			nsems;
+ 	sem_t		sem[SEMMAX];	/* array of POSIX semaphores */
+ 	struct sem	semV[SEMMAX];	/* array of System V semaphore structures */
+ 	struct pending_ops pendingOps[SEMMAX];		/* array of pending
+ 												 * operations */
+ };
+ 
+ struct sem_info
+ {
+ 	sem_t		sem;
+ 	int			nsets;
+ 	/* there are actually nsets of these: */
+ 	struct sem_set_info set[1]; /* VARIABLE LENGTH ARRAY */
+ };
+ 
+ static struct sem_info *SemInfo = (struct sem_info *) - 1;
+ 
+ int
+ semctl(int semid, int semnum, int cmd, ... )
+ {
+ 	int			r = 0;
+ 	va_list		arg_list;
+ 	union semun	arg;
+ 	
+ 	va_start(arg_list, cmd);
+ 	arg = va_arg(arg_list, union semun);
+ 	va_end(arg_list);
+ 
+ 	sem_wait(&SemInfo->sem);
+ 
+ 	if (semid < 0 || semid >= SemInfo->nsets ||
+ 		semnum < 0 || semnum >= SemInfo->set[semid].nsems)
+ 	{
+ 		sem_post(&SemInfo->sem);
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+ 
+ 	switch (cmd)
+ 	{
+ 		case GETNCNT:
+ 			r = SemInfo->set[semid].semV[semnum].semncnt;
+ 			break;
+ 
+ 		case GETPID:
+ 			r = SemInfo->set[semid].semV[semnum].sempid;
+ 			break;
+ 
+ 		case GETVAL:
+ 			r = SemInfo->set[semid].semV[semnum].semval;
+ 			break;
+ 
+ 		case GETALL:
+ 			for (semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++)
+ 				arg.array[semnum] = SemInfo->set[semid].semV[semnum].semval;
+ 			break;
+ 
+ 		case SETVAL:
+ 			SemInfo->set[semid].semV[semnum].semval = arg.val;
+ 			break;
+ 
+ 		case SETALL:
+ 			for (semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++)
+ 				SemInfo->set[semid].semV[semnum].semval = arg.array[semnum];
+ 			break;
+ 
+ 		case GETZCNT:
+ 			r = SemInfo->set[semid].semV[semnum].semzcnt;
+ 			break;
+ 
+ 		case IPC_RMID:
+ 			for (semnum = 0; semnum < SemInfo->set[semid].nsems; semnum++)
+ 			{
+ 				if (sem_destroy(&SemInfo->set[semid].sem[semnum]) == -1)
+ 					r = -1;
+ 			}
+ 			SemInfo->set[semid].key = -1;
+ 			SemInfo->set[semid].nsems = 0;
+ 			break;
+ 
+ 		default:
+ 			sem_post(&SemInfo->sem);
+ 			errno = EINVAL;
+ 			return -1;
+ 	}
+ 
+ 	sem_post(&SemInfo->sem);
+ 
+ 	return r;
+ }
+ 
+ int
+ semget(key_t key, int nsems, int semflg)
+ {
+ 	int			semid,
+ 				semnum,
+ 				nsets;
+ 	Size		sem_info_size;
+ 	struct stat statbuf;
+ 
+ 	if (nsems < 0 || nsems > SEMMAX)
+ 	{
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+ 
+ 	/* open and map shared memory */
+ 	if (SemInfo == (struct sem_info *) - 1)
+ 	{
+ 		SemInfo = mmap(NULL, sem_info_size,
+ 					   PROT_READ | PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
+ 		if (SemInfo == MAP_FAILED)
+ 			return -1;
+ 		/* initialize shared memory */
+ 		memset(SemInfo, 0, sem_info_size);
+ 		SemInfo->nsets = nsets;
+ 		for (semid = 0; semid < nsets; semid++)
+ 			SemInfo->set[semid].key = -1;
+ 		/* create semaphore for locking */
+ 		sem_init(&SemInfo->sem, 1, 1);
+ 	}
+ 
+ 	sem_wait(&SemInfo->sem);
+ 	nsets = SemInfo->nsets;
+ 
+ 	if (key != IPC_PRIVATE)
+ 	{
+ 		/* search existing element */
+ 		semid = 0;
+ 		while (semid < nsets && SemInfo->set[semid].key != key)
+ 			semid++;
+ 		if (!(semflg & IPC_CREAT) && semid >= nsets)
+ 		{
+ 			sem_post(&SemInfo->sem);
+ 			errno = ENOENT;
+ 			return -1;
+ 		}
+ 		else if (semid < nsets)
+ 		{
+ 			if (semflg & IPC_CREAT && semflg & IPC_EXCL)
+ 			{
+ 				sem_post(&SemInfo->sem);
+ 				errno = EEXIST;
+ 				return -1;
+ 			}
+ 			else
+ 			{
+ 				if (nsems != 0 && SemInfo->set[semid].nsems < nsems)
+ 				{
+ 					sem_post(&SemInfo->sem);
+ 					errno = EINVAL;
+ 					return -1;
+ 				}
+ 				sem_post(&SemInfo->sem);
+ 				return semid;
+ 			}
+ 		}
+ 	}
+ 
+ 	/* search first free element */
+ 	semid = 0;
+ 	while (semid < nsets && SemInfo->set[semid].key != -1)
+ 		semid++;
+ 	if (semid >= nsets)
+ 	{
+ 		sem_post(&SemInfo->sem);
+ 		errno = ENOSPC;
+ 		return -1;
+ 	}
+ 
+ 	for (semnum = 0; semnum < nsems; semnum++)
+ 	{
+ 		sem_init(&SemInfo->set[semid].sem[semnum], 1, 0);
+ /* Currently sem_init always returns -1. */
+ #ifdef NOT_USED
+ 		if (sem_init(&SemInfo->set[semid].sem[semnum], 1, 0) == -1)
+ 		{
+ 			int			semnum1;
+ 
+ 			for (semnum1 = 0; semnum1 < semnum; semnum1++)
+ 				sem_destroy(&SemInfo->set[semid].sem[semnum1]);
+ 			sem_post(&SemInfo->sem);
+ 			return -1;
+ 		}
+ #endif
+ 	}
+ 
+ 	SemInfo->set[semid].key = key;
+ 	SemInfo->set[semid].nsems = nsems;
+ 
+ 	sem_post(&SemInfo->sem);
+ 
+ 	return semid;
+ }
+ 
+ int
+ semop(int semid, struct sembuf * sops, size_t nsops)
+ {
+ 	int			i,
+ 				r = 0,
+ 				r1,
+ 				errno1 = 0,
+ 				op;
+ 
+ 	sem_wait(&SemInfo->sem);
+ 
+ 	if (semid < 0 || semid >= SemInfo->nsets)
+ 	{
+ 		sem_post(&SemInfo->sem);
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+ 	for (i = 0; i < nsops; i++)
+ 	{
+ 		if ( /* sops[i].sem_num < 0 || */ sops[i].sem_num >= SemInfo->set[semid].nsems)
+ 		{
+ 			sem_post(&SemInfo->sem);
+ 			errno = EFBIG;
+ 			return -1;
+ 		}
+ 	}
+ 
+ 	for (i = 0; i < nsops; i++)
+ 	{
+ 		if (sops[i].sem_op < 0)
+ 		{
+ 			if (SemInfo->set[semid].semV[sops[i].sem_num].semval < -sops[i].sem_op)
+ 			{
+ 				if (sops[i].sem_flg & IPC_NOWAIT)
+ 				{
+ 					sem_post(&SemInfo->sem);
+ 					errno = EAGAIN;
+ 					return -1;
+ 				}
+ 				SemInfo->set[semid].semV[sops[i].sem_num].semncnt++;
+ 				if (SemInfo->set[semid].pendingOps[sops[i].sem_num].idx >= OPMAX)
+ 				{
+ 					/* pending operations array overflow */
+ 					sem_post(&SemInfo->sem);
+ 					errno = ERANGE;
+ 					return -1;
+ 				}
+ 				SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx++] = sops[i].sem_op;
+ 				/* suspend */
+ 				sem_post(&SemInfo->sem);		/* avoid deadlock */
+ 				r1 = sem_wait(&SemInfo->set[semid].sem[sops[i].sem_num]);
+ 				sem_wait(&SemInfo->sem);
+ 				if (r1)
+ 				{
+ 					errno1 = errno;
+ 					r = r1;
+ 					/* remove pending operation */
+ 					SemInfo->set[semid].pendingOps[sops[i].sem_num].op[--SemInfo->set[semid].pendingOps[sops[i].sem_num].idx] = 0;
+ 				}
+ 				else
+ 					SemInfo->set[semid].semV[sops[i].sem_num].semval -= -sops[i].sem_op;
+ 				SemInfo->set[semid].semV[sops[i].sem_num].semncnt--;
+ 			}
+ 			else
+ 				SemInfo->set[semid].semV[sops[i].sem_num].semval -= -sops[i].sem_op;
+ 		}
+ 		else if (sops[i].sem_op > 0)
+ 		{
+ 			SemInfo->set[semid].semV[sops[i].sem_num].semval += sops[i].sem_op;
+ 			op = sops[i].sem_op;
+ 			while (op > 0 && SemInfo->set[semid].pendingOps[sops[i].sem_num].idx > 0)
+ 			{					/* operations pending */
+ 				if (SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx - 1] + op >= 0)
+ 				{
+ 					/* unsuspend processes */
+ 					if (sem_post(&SemInfo->set[semid].sem[sops[i].sem_num]))
+ 					{
+ 						errno1 = errno;
+ 						r = -1;
+ 					}
+ 					/* adjust pending operations */
+ 					op += SemInfo->set[semid].pendingOps[sops[i].sem_num].op[--SemInfo->set[semid].pendingOps[sops[i].sem_num].idx];
+ 					SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx] = 0;
+ 				}
+ 				else
+ 				{
+ 					/* adjust pending operations */
+ 					SemInfo->set[semid].pendingOps[sops[i].sem_num].op[SemInfo->set[semid].pendingOps[sops[i].sem_num].idx - 1] += op;
+ 					op = 0;
+ 				}
+ 			}
+ 		}
+ 		else
+ 			/* sops[i].sem_op == 0 */
+ 		{
+ 			/* not supported */
+ 			sem_post(&SemInfo->sem);
+ 			errno = ENOSYS;
+ 			return -1;
+ 		}
+ 		SemInfo->set[semid].semV[sops[i].sem_num].sempid = getpid();
+ 	}
+ 
+ 	sem_post(&SemInfo->sem);
+ 
+ 	errno = errno1;
+ 	return r;
+ }
diff -crP postgresql-7.2b2/src/backend/port/qnx6/sem.h postgresql-7.2b2.patched/src/backend/port/qnx6/sem.h
*** postgresql-7.2b2/src/backend/port/qnx6/sem.h	Wed Dec 31 18:00:00 1969
--- postgresql-7.2b2.patched/src/backend/port/qnx6/sem.h	Thu Nov  8 14:18:32 2001
***************
*** 0 ****
--- 1,68 ----
+ /*-------------------------------------------------------------------------
+  *
+  * sem.h
+  *	  System V Semaphore Emulation
+  *
+  * Copyright (c) 1999, repas AEG Automation GmbH
+  *
+  *
+  * IDENTIFICATION
+  *	  $Header: /cvsroot/pgsql/src/backend/port/qnx4/sem.h,v 1.6 2001/11/05 17:46:27 momjian Exp $
+  *
+  *-------------------------------------------------------------------------
+  */
+ 
+ #ifndef _SYS_SEM_H
+ #define _SYS_SEM_H
+ 
+ #include "ipc.h"
+ 
+ #ifdef __cplusplus
+ extern		"C"
+ {
+ #endif
+ 
+ /*
+  *	Semctl Command Definitions.
+  */
+ 
+ #define GETNCNT 3				/* get semncnt */
+ #define GETPID	4				/* get sempid */
+ #define GETVAL	5				/* get semval */
+ #define GETALL	6				/* get all semval's */
+ #define GETZCNT 7				/* get semzcnt */
+ #define SETVAL	8				/* set semval */
+ #define SETALL	9				/* set all semval's */
+ 
+ /*
+  *	There is one semaphore structure for each semaphore in the system.
+  */
+ 
+ 	struct sem
+ 	{
+ 		ushort_t	semval;		/* semaphore text map address	*/
+ 		pid_t		sempid;		/* pid of last operation	*/
+ 		ushort_t	semncnt;	/* # awaiting semval > cval */
+ 		ushort_t	semzcnt;	/* # awaiting semval = 0	*/
+ 	};
+ 
+ /*
+  * User semaphore template for semop system calls.
+  */
+ 
+ 	struct sembuf
+ 	{
+ 		ushort_t	sem_num;	/* semaphore #			*/
+ 		short		sem_op;		/* semaphore operation		*/
+ 		short		sem_flg;	/* operation flags		*/
+ 	};
+ 
+ 	extern int	semctl(int semid, int semnum, int cmd, /* ... */ union semun arg);
+ 	extern int	semget(key_t key, int nsems, int semflg);
+ 	extern int	semop(int semid, struct sembuf * sops, size_t nsops);
+ 
+ #ifdef __cplusplus
+ }
+ #endif
+ 
+ #endif   /* _SYS_SEM_H */
diff -crP postgresql-7.2b2/src/backend/port/qnx6/shm.c postgresql-7.2b2.patched/src/backend/port/qnx6/shm.c
*** postgresql-7.2b2/src/backend/port/qnx6/shm.c	Wed Dec 31 18:00:00 1969
--- postgresql-7.2b2.patched/src/backend/port/qnx6/shm.c	Thu Nov  8 14:42:31 2001
***************
*** 0 ****
--- 1,276 ----
+ /*-------------------------------------------------------------------------
+  *
+  * shm.c
+  *	  System V Shared Memory Emulation
+  *
+  * Copyright (c) 1999, repas AEG Automation GmbH
+  *
+  *
+  * IDENTIFICATION
+  *	  $Header: /cvsroot/pgsql/src/backend/port/qnx4/shm.c,v 1.7 2001/10/25 05:49:40 momjian Exp $
+  *
+  *-------------------------------------------------------------------------
+  */
+ 
+ #include "postgres.h"
+ 
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
+ #include <sys/mman.h>
+ #include "shm.h"
+ #include <sys/stat.h>
+ 
+ 
+ #define MODE	0777
+ 
+ #define SHMMAX	1024
+ 
+ 
+ struct shm_info
+ {
+ 	int			shmid;
+ 	key_t		key;
+ 	size_t		size;
+ 	void	   *addr;
+ };
+ 
+ static struct shm_info *ShmInfo;
+ 
+ 
+ static int	shm_putinfo(struct shm_info * info);
+ static int	shm_updinfo(int i, struct shm_info * info);
+ static int	shm_getinfo(int shmid, struct shm_info * info);
+ static int	shm_getinfobyaddr(const void *addr, struct shm_info * info);
+ 
+ static char *
+ keytoname(key_t key, char *name)
+ {
+ 	sprintf(name, "PgShm%x", key);
+ 	return name;
+ }
+ 
+ static int
+ shm_putinfo(struct shm_info * info)
+ {
+ 	int			i;
+ 
+ 	if (ShmInfo == NULL)
+ 	{
+ 		ShmInfo = calloc(SHMMAX, sizeof(struct shm_info));
+ 		if (ShmInfo == NULL)
+ 			return -1;
+ 		/* initialize ShmInfo */
+ 		for (i = 0; i < SHMMAX; i++)
+ 			ShmInfo[i].shmid = -1;
+ 	}
+ 
+ 	/* search first free element */
+ 	i = 0;
+ 	while (i < SHMMAX && ShmInfo[i].shmid != -1)
+ 		i++;
+ 	if (i >= SHMMAX)
+ 	{
+ 		errno = ENOSPC;
+ 		return -1;
+ 	}
+ 
+ 	memcpy(&ShmInfo[i], info, sizeof(struct shm_info));
+ 
+ 	return i;
+ }
+ 
+ static int
+ shm_updinfo(int i, struct shm_info * info)
+ {
+ 	if (i >= SHMMAX)
+ 		return -1;
+ 	if (ShmInfo == NULL)
+ 		return -1;
+ 
+ 	memcpy(&ShmInfo[i], info, sizeof(struct shm_info));
+ 
+ 	return i;
+ }
+ 
+ static int
+ shm_getinfo(int shmid, struct shm_info * info)
+ {
+ 	int			i;
+ 
+ 	if (ShmInfo == NULL)
+ 		return -1;
+ 
+ 	/* search element */
+ 	i = 0;
+ 	while (i < SHMMAX && ShmInfo[i].shmid != shmid)
+ 		i++;
+ 	if (i >= SHMMAX)
+ 		return -1;
+ 
+ 	memcpy(info, &ShmInfo[i], sizeof(struct shm_info));
+ 
+ 	return i;
+ }
+ 
+ static int
+ shm_getinfobyaddr(const void *addr, struct shm_info * info)
+ {
+ 	int			i;
+ 
+ 	if (ShmInfo == (struct shm_info *) - 1)
+ 		return -1;
+ 
+ 	/* search element */
+ 	i = 0;
+ 	while (i < SHMMAX && ShmInfo[i].addr != addr)
+ 		i++;
+ 	if (i >= SHMMAX)
+ 		return -1;
+ 
+ 	memcpy(info, &ShmInfo[i], sizeof(struct shm_info));
+ 
+ 	return i;
+ }
+ 
+ 
+ void *
+ shmat(int shmid, const void *shmaddr, int shmflg)
+ {
+ 	struct shm_info info;
+ 	int			i;
+ 
+ 	i = shm_getinfo(shmid, &info);
+ 	if (i == -1)
+ 	{
+ 		errno = EACCES;
+ 		return (void *) -1;
+ 	}
+ 
+ 	info.addr = mmap((void *) shmaddr, info.size,
+ 					 PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
+ 	if (info.addr == MAP_FAILED)
+ 		return info.addr;
+ 
+ 	if (shm_updinfo(i, &info) == -1)
+ 	{
+ 		errno = EACCES;
+ 		return (void *) -1;
+ 	}
+ 
+ 	return info.addr;
+ }
+ 
+ int
+ shmdt(const void *addr)
+ {
+ 	struct shm_info info;
+ 
+ 	if (shm_getinfobyaddr(addr, &info) == -1)
+ 	{
+ 		errno = EACCES;
+ 		return -1;
+ 	}
+ 
+ 	return munmap((void *) addr, info.size);
+ }
+ 
+ int
+ shmctl(int shmid, int cmd, struct shmid_ds * buf)
+ {
+ 	struct shm_info info;
+ 	char		name[NAME_MAX + 1];
+ 	int			result;
+ 	int			fd;
+ 	struct stat statbuf;
+ 
+ 
+ 	switch (cmd)
+ 	{
+ 		case IPC_RMID:
+ 			if (shm_getinfo(shmid, &info) == -1)
+ 			{
+ 				errno = EACCES;
+ 				return -1;
+ 			}
+ 			close(info.shmid);
+ 			keytoname(info.key, name);
+ 			return shm_unlink(name);
+ 
+ 		case IPC_STAT:
+ 
+ 			/*
+ 			 * we have to open it first. stat() does no prefix tracking ->
+ 			 * the call would go to fsys instead of proc
+ 			 */
+ 			keytoname(shmid, name);
+ 			fd = shm_open(name, 0, MODE);
+ 			if (fd >= 0)
+ 			{
+ 				result = fstat(fd, &statbuf);
+ 
+ 				/*
+ 				 * if the file exists, subtract 2 from linkcount : one for
+ 				 * our own open and one for the dir entry
+ 				 */
+ 				if (!result)
+ 					buf->shm_nattch = statbuf.st_nlink - 2;
+ 				close(fd);
+ 				return result;
+ 			}
+ 			else
+ 			{
+ 				/*
+ 				 * if there's no entry for this key it doesn't matter the
+ 				 * next shmget() would get a different shm anyway
+ 				 */
+ 				buf->shm_nattch = 0;
+ 				return 0;
+ 			}
+ 	}
+ 	errno = EINVAL;
+ 	return -1;
+ }
+ 
+ int
+ shmget(key_t key, size_t size, int flags)
+ {
+ 	char		name[NAME_MAX + 1];
+ 	int			oflag = 0;
+ 	struct shm_info info;
+ 
+ 	if (flags & IPC_CREAT)
+ 		oflag |= O_CREAT;
+ 	if (flags & IPC_EXCL)
+ 		oflag |= O_EXCL;
+ 	if (flags & SHM_R)
+ 	{
+ 		if (flags & SHM_W)
+ 			oflag |= O_RDWR;
+ 		else
+ 			oflag |= O_RDONLY;
+ 	}
+ 	info.shmid = shm_open(keytoname(key, name), oflag, MODE);
+ 
+ 	/* store shared memory information */
+ 	if (info.shmid != -1)
+ 	{
+ 		info.key = key;
+ 		info.size = size;
+ 		info.addr = NULL;
+ 		if (shm_putinfo(&info) == -1)
+ 		{
+ 			close(info.shmid);
+ 			if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+ 				shm_unlink(name);
+ 			return -1;
+ 		}
+ 	}
+ 
+ 	/* The size may only be set once. Ignore errors. */
+ 	ftruncate(info.shmid, size);
+ 
+ 	return info.shmid;
+ }
diff -crP postgresql-7.2b2/src/backend/port/qnx6/shm.h postgresql-7.2b2.patched/src/backend/port/qnx6/shm.h
*** postgresql-7.2b2/src/backend/port/qnx6/shm.h	Wed Dec 31 18:00:00 1969
--- postgresql-7.2b2.patched/src/backend/port/qnx6/shm.h	Mon Nov  5 11:46:27 2001
***************
*** 0 ****
--- 1,43 ----
+ /*-------------------------------------------------------------------------
+  *
+  * shm.h
+  *	  System V Shared Memory Emulation
+  *
+  * Copyright (c) 1999, repas AEG Automation GmbH
+  *
+  *
+  * IDENTIFICATION
+  *	  $Header: /cvsroot/pgsql/src/backend/port/qnx4/shm.h,v 1.6 2001/11/05 17:46:27 momjian Exp $
+  *
+  *-------------------------------------------------------------------------
+  */
+ 
+ #ifndef _SYS_SHM_H
+ #define _SYS_SHM_H
+ 
+ #include <sys/ipc.h>
+ 
+ #ifdef	__cplusplus
+ extern		"C"
+ {
+ #endif
+ 
+ #define SHM_R	0400			/* read permission */
+ #define SHM_W	0200			/* write permission */
+ 
+ 	struct shmid_ds
+ 	{
+ 		int			dummy;
+ 		int			shm_nattch;
+ 	};
+ 
+ 	extern void *shmat(int shmid, const void *shmaddr, int shmflg);
+ 	extern int	shmdt(const void *addr);
+ 	extern int	shmctl(int shmid, int cmd, struct shmid_ds * buf);
+ 	extern int	shmget(key_t key, size_t size, int flags);
+ 
+ #ifdef	__cplusplus
+ }
+ #endif
+ 
+ #endif   /* _SYS_SHM_H */
diff -crP postgresql-7.2b2/src/backend/port/qnx6/tstsem.c postgresql-7.2b2.patched/src/backend/port/qnx6/tstsem.c
*** postgresql-7.2b2/src/backend/port/qnx6/tstsem.c	Wed Dec 31 18:00:00 1969
--- postgresql-7.2b2.patched/src/backend/port/qnx6/tstsem.c	Thu Nov  8 16:15:01 2001
***************
*** 0 ****
--- 1,208 ----
+ /*-------------------------------------------------------------------------
+  *
+  * tstsem.c
+  *	  Test of System V Semaphore Emulation
+  *
+  * Copyright (c) 1999, repas AEG Automation GmbH
+  *
+  *
+  * IDENTIFICATION
+  *	  $Header: /cvsroot/pgsql/src/backend/port/qnx4/tstsem.c,v 1.6 2001/10/25 05:49:40 momjian Exp $
+  *
+  *-------------------------------------------------------------------------
+  */
+ 
+ #include "postgres.h"
+ 
+ #include <signal.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include "storage/ipc.h"
+ #include <sys/mman.h>
+ #include <sys/sem.h>
+ 
+ 
+ #define SEMMAX	16
+ #define OPSMAX	1
+ 
+ static int	semid;
+ 
+ int	MaxBackends = 32;
+ 
+ static void
+ sig_handler(int sig_no)
+ {
+ 	union semun arg;
+ 	int			i = semctl(semid, 0, GETNCNT, arg);
+ 
+ 	if (i == -1)
+ 		perror("semctl");
+ 	else
+ 		printf("semval = %d\n", i);
+ }
+ 
+ void		on_proc_exit(void (*function) (), Datum arg)
+ {
+ 	atexit(function);
+ }
+ int
+ main(int argc, char **argv)
+ {
+ 	int			c,
+ 				errflg = 0;
+ 	char		s[80];
+ 	key_t		key = IPC_PRIVATE;
+ 	int			nsems = SEMMAX;
+ 	int			semflg = 0;
+ 	int			unlink = 0;
+ 	int			i;
+ 	struct sembuf sops[OPSMAX];
+ 	u_short		array[SEMMAX];
+ 	union semun arg;
+ 
+ 	optarg = NULL;
+ 	while (!errflg && (c = getopt(argc, argv, "k:n:cxu")) != -1)
+ 	{
+ 		switch (c)
+ 		{
+ 			case 'k':
+ 				key = atoi(optarg);
+ 				break;
+ 			case 'n':
+ 				nsems = atoi(optarg);
+ 				break;
+ 			case 'c':
+ 				semflg |= IPC_CREAT;
+ 				break;
+ 			case 'x':
+ 				semflg |= IPC_EXCL;
+ 				break;
+ 			case 'u':
+ 				unlink = 1;
+ 				break;
+ 			default:
+ 				errflg++;
+ 		}
+ 	}
+ 	if (errflg)
+ 	{
+ 		printf("usage: tstsem [-k key] [-n nsems] [-cxu]\n");
+ 		exit(1);
+ 	}
+ 
+ 	if (unlink)
+ 	{
+ 		i = shm_unlink("SysV_Sem_Info");
+ 		if (i == -1)
+ 			perror("shm_unlink");
+ 		exit(i);
+ 	}
+ 
+ 	semid = semget(key, nsems, semflg);
+ 	if (semid == -1)
+ 	{
+ 		perror("semget");
+ 		exit(semid);
+ 	}
+ 
+ 	/* test signal interrupts */
+ 	signal(SIGTERM, sig_handler);
+ 
+ 	do
+ 	{
+ 		printf("(-)sem_op, (+)sem_op, (G)ETVAL, (S)ETVAL, GET(P)ID, GET(A)LL, SETA(L)L, GET(N)CNT, GET(Z)CNT, e(x)it: ");
+ 		scanf("%s", s);
+ 		switch (s[0])
+ 		{
+ 			case '-':
+ 			case '+':
+ 				sops[0].sem_num = 0;
+ 				sops[0].sem_op = atoi(s);
+ 				if (sops[0].sem_op == 0)
+ 					sops[0].sem_op = s[0] == '+' ? +1 : -1;
+ 				sops[0].sem_flg = 0;
+ 				if (semop(semid, sops, 1) == -1)
+ 					perror("semop");
+ 				break;
+ 
+ 			case 'G':
+ 			case 'g':
+ 				i = semctl(semid, 0, GETVAL, arg);
+ 				if (i == -1)
+ 					perror("semctl");
+ 				else
+ 					printf("semval = %d\n", i);
+ 				break;
+ 
+ 			case 'S':
+ 			case 's':
+ 				printf("semval = ");
+ 				scanf("%d", &arg.val);
+ 				if (semctl(semid, 0, SETVAL, arg) == -1)
+ 					perror("semctl");
+ 				break;
+ 
+ 			case 'P':
+ 			case 'p':
+ 				i = semctl(semid, 0, GETPID, arg);
+ 				if (i == -1)
+ 					perror("semctl");
+ 				else
+ 					printf("PID = %d\n", i);
+ 				break;
+ 
+ 			case 'A':
+ 			case 'a':
+ 				arg.array = array;
+ 				i = semctl(semid, 0, GETALL, arg);
+ 				if (i == -1)
+ 					perror("semctl");
+ 				else
+ 				{
+ 					for (i = 0; i < nsems; i++)
+ 						printf("semval[%d] = %hu\n", i, arg.array[i]);
+ 				}
+ 				break;
+ 
+ 			case 'L':
+ 			case 'l':
+ 				arg.array = array;
+ 				for (i = 0; i < nsems; i++)
+ 				{
+ 					printf("semval[%d] = ", i);
+ 					scanf("%hu", &arg.array[i]);
+ 				}
+ 				if (semctl(semid, 0, SETALL, arg) == -1)
+ 					perror("semctl");
+ 				break;
+ 
+ 			case 'N':
+ 			case 'n':
+ 				i = semctl(semid, 0, GETNCNT, arg);
+ 				if (i == -1)
+ 					perror("semctl");
+ 				else
+ 					printf("semval = %d\n", i);
+ 				break;
+ 
+ 			case 'Z':
+ 			case 'z':
+ 				i = semctl(semid, 0, GETZCNT, arg);
+ 				if (i == -1)
+ 					perror("semctl");
+ 				else
+ 					printf("semval = %d\n", i);
+ 				break;
+ 		}
+ 	}
+ 	while (s[0] != 'x');
+ 
+ 	if (semctl(semid, 0, IPC_RMID, arg) == -1)
+ 	{
+ 		perror("semctl");
+ 		exit(-1);
+ 	}
+ 
+ 	exit(0);
+ }
diff -crP postgresql-7.2b2/src/backend/port/qnx6/tstshm.c postgresql-7.2b2.patched/src/backend/port/qnx6/tstshm.c
*** postgresql-7.2b2/src/backend/port/qnx6/tstshm.c	Wed Dec 31 18:00:00 1969
--- postgresql-7.2b2.patched/src/backend/port/qnx6/tstshm.c	Thu Nov  8 16:19:43 2001
***************
*** 0 ****
--- 1,100 ----
+ /*-------------------------------------------------------------------------
+  *
+  * tstshm.c
+  *	  Test of System V Shared Memory Emulation
+  *
+  * Copyright (c) 1999, repas AEG Automation GmbH
+  *
+  *
+  * IDENTIFICATION
+  *	  $Header: /cvsroot/pgsql/src/backend/port/qnx4/tstshm.c,v 1.3 2001/08/24 14:07:49 petere Exp $
+  *
+  *-------------------------------------------------------------------------
+  */
+ 
+ #include "postgres.h"
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include "shm.h"
+ 
+ 
+ int
+ main(int argc, char **argv)
+ {
+ 	int			c,
+ 				errflg = 0;
+ 	char		s[80];
+ 	key_t		key = 0x1000;
+ 	size_t		size = 256;
+ 	int			shmid = -1;
+ 	caddr_t		addr = NULL;
+ 
+ 	optarg = NULL;
+ 	while (!errflg && (c = getopt(argc, argv, "k:s:")) != -1)
+ 	{
+ 		switch (c)
+ 		{
+ 			case 'k':
+ 				key = atoi(optarg);
+ 				break;
+ 			case 's':
+ 				size = atoi(optarg);
+ 				break;
+ 			default:
+ 				errflg++;
+ 		}
+ 	}
+ 	if (errflg)
+ 	{
+ 		printf("usage: tstshm [-k key] [-s size]\n");
+ 		exit(1);
+ 	}
+ 
+ 	do
+ 	{
+ 		printf("shm(g)et, shm(a)t, shm(d)t, shm(c)tl, (w)rite, (r)ead, e(x)it: ");
+ 		scanf("%s", s);
+ 		switch (s[0])
+ 		{
+ 			case 'g':
+ 				shmid = shmget(key, size, IPC_CREAT | SHM_R | SHM_W);
+ 				if (shmid == -1)
+ 					perror("shmget");
+ 				break;
+ 
+ 			case 'a':
+ 				addr = shmat(shmid, NULL, 0);
+ 				if (addr == (void *) -1)
+ 					perror("shmat");
+ 				break;
+ 
+ 			case 'd':
+ 				if (shmdt(addr) == -1)
+ 					perror("shmdt");
+ 				else
+ 					addr = NULL;
+ 				break;
+ 
+ 			case 'c':
+ 				if (shmctl(shmid, IPC_RMID, NULL) == -1)
+ 					perror("shmctl");
+ 				else
+ 					shmid = -1;
+ 				break;
+ 
+ 			case 'w':
+ 				printf("String to write: ");
+ 				scanf("%s", addr);
+ 				break;
+ 
+ 			case 'r':
+ 				puts(addr);
+ 				break;
+ 		}
+ 	}
+ 	while (s[0] != 'x');
+ 
+ 	return 0;
+ }
diff -crP postgresql-7.2b2/src/backend/storage/ipc/ipc.c postgresql-7.2b2.patched/src/backend/storage/ipc/ipc.c
*** postgresql-7.2b2/src/backend/storage/ipc/ipc.c	Mon Nov  5 11:46:28 2001
--- postgresql-7.2b2.patched/src/backend/storage/ipc/ipc.c	Sat Nov 17 23:32:28 2001
***************
*** 33,38 ****
--- 33,41 ----
  #include <sys/file.h>
  
  #include "storage/ipc.h"
+ 
+ #ifndef HAVE_POSIX_IPC
+ 
  /* In Ultrix, sem.h and shm.h must be included AFTER ipc.h */
  #ifdef HAVE_SYS_SEM_H
  #include <sys/sem.h>
***************
*** 40,58 ****
  #ifdef HAVE_SYS_SHM_H
  #include <sys/shm.h>
  #endif
! #ifdef HAVE_KERNEL_OS_H
! #include <kernel/OS.h>
  #endif
  
  #if defined(__darwin__)
  #include "port/darwin/sem.h"
  #endif
  
  #include "miscadmin.h"
  #include "utils/memutils.h"
  #include "libpq/libpq.h"
  
- 
  /*
   * This flag is set during proc_exit() to change elog()'s behavior,
   * so that an elog() from an on_proc_exit routine cannot get us out
--- 43,67 ----
  #ifdef HAVE_SYS_SHM_H
  #include <sys/shm.h>
  #endif
! 
! #if defined(__QNXNTO__)
! #include "../backend/port/qnx6/shm.h"
  #endif
  
  #if defined(__darwin__)
  #include "port/darwin/sem.h"
  #endif
  
+ #endif /* HAVE_POSIX_IPC */
+ 
+ #ifdef HAVE_KERNEL_OS_H
+ #include <kernel/OS.h>
+ #endif
+ 
  #include "miscadmin.h"
  #include "utils/memutils.h"
  #include "libpq/libpq.h"
  
  /*
   * This flag is set during proc_exit() to change elog()'s behavior,
   * so that an elog() from an on_proc_exit routine cannot get us out
***************
*** 60,65 ****
--- 69,75 ----
   */
  bool		proc_exit_inprogress = false;
  
+ #ifndef HAVE_POSIX_IPC
  static IpcSemaphoreId InternalIpcSemaphoreCreate(IpcSemaphoreKey semKey,
  						   int numSems, int permission,
  						   int semStartValue, bool removeOnExit);
***************
*** 70,75 ****
--- 80,86 ----
  static void IpcMemoryDelete(int status, Datum shmId);
  static void *PrivateMemoryCreate(uint32 size);
  static void PrivateMemoryDelete(int status, Datum memaddr);
+ #endif /* HAVE_POSIX_IPC */
  
  
  /* ----------------------------------------------------------------
***************
*** 86,91 ****
--- 97,105 ----
   *
   * XXX these functions probably ought to live in some other module.
   * ----------------------------------------------------------------
+  *
+  * XXX it is unclear to me whether or not all this mess is required 
+  * with POSIX IPC. So far I assume it is  - i.k.
   */
  
  #define MAX_ON_EXITS 20
***************
*** 234,239 ****
--- 248,488 ----
  	on_proc_exit_index = 0;
  }
  
+ #ifdef HAVE_POSIX_IPC
+ 
+ /* 
+ 	Use POSIX semaphores and anonymous shared memory via mmap().
+ 	That means we don't need to worry about crap like finding keys, 
+ 	detecting and removing leftovers, registering cleanup handlers
+ 	and whatever else SysV IPC requires one to do.
+ 	
+ 	We just ask system to allocate anunymous semaphores and put
+ 	them into anonymous shared segment. That all is cleaned up by
+ 	OS when process terminates for whatever reason. Easy, clean
+ 	and fast.
+ 	
+ 	OTOH, since POSIX semaphores are in process space, and are not
+ 	scalar objects, they need to be explicitly placed into shared 
+ 	segment. Just returning 'id' to store in shared memory does not 
+ 	work. So our 'create' routine expects caller to provide storage
+ 	and make arrangements about sharing it.
+ 	
+ 	That means we need little hacks in proc.c & spin.c as well.
+ 	Basically, storage for POSIX semaphores will be allocated within
+ 	global shared segment, along with SemId. It then becomes really
+ 	redundant to even have SemId there, but that way we can keep
+ 	semaphore API changes between SysV & POSIX to minimum. 
+ */
+ void IpcInitKeyAssignment(int port)
+ {
+ 	port = port;
+ }
+ 
+ static void
+ CallbackSemaphoreKill(int status, Datum semId)
+ {
+ 	IpcSemaphoreKill((IpcSemaphoreId)DatumGetPointer(semId));
+ }
+ 
+ IpcSemaphoreId IpcSemaphoreCreate(void *storage, bool shared,
+ 				   int semStartValue,
+ 				   bool removeOnExit)
+ {
+ 	IpcSemaphoreId	semp = (IpcSemaphoreId)storage;
+ 
+ 	if (!semp)
+ 	{
+ 		if (shared)
+ 		{
+ 			fprintf(stderr, "IpcSemaphoreCreate(shared): No storage\n");
+ 			proc_exit(255);
+ 		}
+ 		if ((semp = malloc(sizeof(sem_t))) < 0)
+ 		{
+ 			fprintf(stderr, "IpcSemaphoreCreate(): malloc(%d) failed: %s\n",
+ 				sizeof(sem_t), strerror(errno));
+ 			proc_exit(255);
+ 		}
+ 	}
+ 
+ 	if (sem_init(semp, shared, semStartValue) < 0)
+ 	{
+ 		fprintf(stderr, "IpcSemaphoreCreate: sem_init(%d) failed: %s\n",
+ 				semStartValue, strerror(errno));
+ 		if (errno == ENOSPC)
+ 			fprintf(stderr,
+ 					"\nThis error does *not* mean that you have run out of disk space.\n"
+ 					"\n"
+ 					"It occurs when either the system limit for the maximum number of\n"
+ 					"POSIX semaphores would be exceeded.  You need to raise the\n"
+ 					"respective kernel parameter.  Alternatively, reduce PostgreSQL's\n"
+ 					"consumption of semaphores by reducing its max_connections parameter\n"
+ 					"(currently %d).\n"
+ 					"\n"
+ 					"The PostgreSQL Administrator's Guide contains more information about\n"
+ 					"configuring your system for PostgreSQL.\n\n",
+ 					MaxBackends);
+ 		proc_exit(255);
+ 	}
+ 
+ 	if (removeOnExit)
+ 		on_shmem_exit(CallbackSemaphoreKill, PointerGetDatum(semp));
+ 
+ 	return semp;
+ }
+ 
+ void IpcSemaphoreKill(IpcSemaphoreId semId)
+ {
+ 	if (sem_destroy(semId) < 0)
+ 			fprintf(stderr, "IpcSemaphoreKill: sem_destroy(%p) failed: %s\n",
+ 				semId, strerror(errno));
+ 	/* 
+ 		We don't free memory allocated for private semaphores here,
+ 		because we don't know if we should. It will be responsibility of
+ 		caller.
+ 	*/
+ }
+ 
+ void IpcSemaphoreLock(IpcSemaphoreId semId, int sem, bool interruptOK)
+ {
+ 	int			errStatus;
+ 
+ 	do
+ 	{
+ 		ImmediateInterruptOK = interruptOK;
+ 		CHECK_FOR_INTERRUPTS();
+ 		errStatus = sem_wait(semId);
+ 		ImmediateInterruptOK = false;
+ 	} while (errStatus == -1 && errno == EINTR);
+ 
+ 	if (errStatus == -1)
+ 	{
+ 		fprintf(stderr, "IpcSemaphoreLock: sem_wait(id=%d) failed: %s\n",
+ 				sem, strerror(errno));
+ 		proc_exit(255);
+ 	}
+ }
+ 
+ void IpcSemaphoreUnlock(IpcSemaphoreId semId, int sem)
+ {
+ 	int			errStatus;
+ 
+ 	do
+ 	{
+ 		errStatus = sem_post(semId);
+ 	} while (errStatus == -1 && errno == EINTR);
+ 
+ 	if (errStatus == -1)
+ 	{
+ 		fprintf(stderr, "IpcSemaphoreUnlock: sem_post(id=%d) failed: %s\n",
+ 				sem, strerror(errno));
+ 		proc_exit(255);
+ 	}
+ }
+ 
+ bool IpcSemaphoreTryLock(IpcSemaphoreId semId, int sem)
+ {
+ 	int			errStatus;
+ 
+ 	/*
+ 	 * Note: if errStatus is -1 and errno == EINTR then it means we
+ 	 * returned from the operation prematurely because we were sent a
+ 	 * signal.	So we try and lock the semaphore again.
+ 	 */
+ 	do
+ 	{
+ 		errStatus = sem_trywait(semId);
+ 	} while (errStatus == -1 && errno == EINTR);
+ 
+ 	if (errStatus == -1)
+ 	{
+ 		/* Expect EAGAIN or EWOULDBLOCK (platform-dependent) */
+ #ifdef EAGAIN
+ 		if (errno == EAGAIN)
+ 			return false;		/* failed to lock it */
+ #endif
+ #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
+ 		if (errno == EWOULDBLOCK)
+ 			return false;		/* failed to lock it */
+ #endif
+ 		/* Otherwise we got trouble */
+ 		fprintf(stderr, "IpcSemaphoreTryLock: sem_trywait(id=%d) failed: %s\n",
+ 				sem, strerror(errno));
+ 		proc_exit(255);
+ 	}
+ 
+ 	return true;
+ }
+ 
+ int	IpcSemaphoreGetValue(IpcSemaphoreId semId, int sem)
+ {
+ 	int	value = -1;
+ 
+ 	if (sem_getvalue(semId, &value) < 0)
+ 		fprintf(stderr, "IpcSemaphoreGetValue: sem_getvalue(id=%d) failed: %s\n",
+ 				sem, strerror(errno));
+ 	return value;
+ }
+ 
+ static void
+ IpcMemoryDetach(int status, Datum shmaddr)
+ {
+ 	void *p = DatumGetPointer(shmaddr);
+ 	
+ 	if (munmap(p, ((PGShmemHeader *)p)->totalsize) < 0)
+ 		fprintf(stderr, "IpcMemoryDetach: munmap(%p) failed: %s\n",
+ 				DatumGetPointer(shmaddr), strerror(errno));
+ }
+ 
+ PGShmemHeader *
+ IpcMemoryCreate(uint32 size, bool makePrivate, int permission)
+ {
+ 	void	   *memAddress;
+ 	PGShmemHeader *hdr;
+ 
+ 	/* Room for a header? */
+ 	Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
+ 
+ 	memAddress = mmap(0, size, PROT_READ|PROT_WRITE, 
+ 					MAP_ANON|(makePrivate ? MAP_PRIVATE : MAP_SHARED), -1, 0);
+ 	if (memAddress == (void *) -1)
+ 	{
+ 		fprintf(stderr, "IpcMemoryCreate(size=%d): mmap() failed: %s\n",
+ 			size, strerror(errno));
+ 		proc_exit(255);
+ 	}
+ 	hdr = (PGShmemHeader *) memAddress;
+ 
+ 	/*
+ 	 * OK, we created a new segment.  Mark it as created by this process.
+ 	 * The order of assignments here is critical so that another Postgres
+ 	 * process can't see the header as valid but belonging to an invalid
+ 	 * PID!
+ 	 */
+ 	hdr = (PGShmemHeader *) memAddress;
+ /*
+ 	hdr->creatorPID = getpid();
+ 	hdr->magic = PGShmemMagic;
+ */
+ 	/*
+ 	 * Initialize space allocation status for segment.
+ 	 */
+ 	hdr->totalsize = size;
+ 	hdr->freeoffset = MAXALIGN(sizeof(PGShmemHeader));
+ 
+ 	/* Register on-exit routine to delete the new segment */
+ 	on_shmem_exit(IpcMemoryDetach, PointerGetDatum(hdr));
+ 
+ 	return hdr;
+ }
+ 
+ bool
+ SharedMemoryIsInUse(IpcMemoryKey shmKey, IpcMemoryId shmId)
+ {
+ 	return false;
+ }
+ 
+ #else /* no POSIX IPC */
  
  /* ----------------------------------------------------------------
   *						Semaphore support
***************
*** 530,536 ****
  	return semctl(semId, sem, GETPID, dummy);
  }
  
- 
  /* ----------------------------------------------------------------
   *						Shared memory support
   *
--- 779,784 ----
***************
*** 980,982 ****
--- 1228,1231 ----
  
  	return semId;
  }
+ #endif /* HAVE_POSIX_IPC */
diff -crP postgresql-7.2b2/src/backend/storage/lmgr/proc.c postgresql-7.2b2.patched/src/backend/storage/lmgr/proc.c
*** postgresql-7.2b2/src/backend/storage/lmgr/proc.c	Mon Nov  5 18:38:26 2001
--- postgresql-7.2b2.patched/src/backend/storage/lmgr/proc.c	Sat Nov 17 22:16:22 2001
***************
*** 52,57 ****
--- 52,60 ----
  #include <sys/time.h>
  
  #include "storage/ipc.h"
+ 
+ #ifndef HAVE_POSIX_IPC
+ 
  /* In Ultrix, sem.h and shm.h must be included AFTER ipc.h */
  #ifdef HAVE_SYS_SEM_H
  #include <sys/sem.h>
***************
*** 61,66 ****
--- 64,71 ----
  #include "port/darwin/sem.h"
  #endif
  
+ #endif /* HAVE_POSIX_IPC */
+ 
  #include "miscadmin.h"
  #include "access/xact.h"
  #include "storage/proc.h"
***************
*** 152,158 ****
  
  		for (i = 0; i < semMapEntries; i++)
  		{
! 			ProcGlobal->procSemMap[i].procSemId = -1;
  			ProcGlobal->procSemMap[i].freeSemMap = 0;
  		}
  
--- 157,163 ----
  
  		for (i = 0; i < semMapEntries; i++)
  		{
! 			ProcGlobal->procSemMap[i].procSemId = (IpcSemaphoreId)-1;
  			ProcGlobal->procSemMap[i].freeSemMap = 0;
  		}
  
***************
*** 170,175 ****
--- 175,184 ----
  		 */
  		for (i = 0; i < semMapEntries; i++)
  		{
+ #ifdef HAVE_POSIX_IPC
+ 			ProcGlobal->procSemMap[i].procSemId = 
+ 				IpcSemaphoreCreate(&ProcGlobal->procSemMap[i].procSemMem, true, 1, false);
+ #else
  			IpcSemaphoreId semId;
  
  			semId = IpcSemaphoreCreate(PROC_NSEMS_PER_SET,
***************
*** 177,182 ****
--- 186,192 ----
  									   1,
  									   false);
  			ProcGlobal->procSemMap[i].procSemId = semId;
+ #endif
  		}
  
  		/*
***************
*** 242,248 ****
  	 * Initialize all fields of MyProc.
  	 */
  	SHMQueueElemInit(&(MyProc->links));
! 	MyProc->sem.semId = -1;		/* no wait-semaphore acquired yet */
  	MyProc->sem.semNum = -1;
  	MyProc->errType = STATUS_OK;
  	MyProc->xid = InvalidTransactionId;
--- 252,258 ----
  	 * Initialize all fields of MyProc.
  	 */
  	SHMQueueElemInit(&(MyProc->links));
! 	MyProc->sem.semId = (IpcSemaphoreId)-1;		/* no wait-semaphore acquired yet */
  	MyProc->sem.semNum = -1;
  	MyProc->errType = STATUS_OK;
  	MyProc->xid = InvalidTransactionId;
***************
*** 348,353 ****
--- 358,390 ----
  static void
  ZeroProcSemaphore(PROC *proc)
  {
+ #ifdef HAVE_POSIX_IPC
+ 	int errval;
+ 
+ 	if (proc->sem.semId == (IpcSemaphoreId)-1)
+ 		return;	
+ 	/* 
+ 		there's no way to 'reset' value of POSIX semaphore after sem_init().
+ 		So just roll it down to 0 using sem_trywait(). Hopefully, nobody
+ 		rolls it up at the same time... but either way we don't return until
+ 		it has reached 0, it might just take little longer ...
+ 	*/
+ 	while(1) 
+ 	{ 
+ 		errval = sem_trywait(proc->sem.semId); 
+ 		if (errval == -1 && errno != EINTR)	break;
+ 	} 
+ #ifdef EAGAIN
+ 	if (errno != EAGAIN)
+ #elif defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
+ 	if (errno != EWOULDBLOCK)
+ #endif
+ 	{
+ 		fprintf(stderr, "ZeroProcSemaphore: sem_trywait(id=%p) failed: %s\n",
+ 				proc->sem.semId, strerror(errno));
+ 		proc_exit(255);
+ 	}
+ #else
  	union semun semun;
  
  	semun.val = 0;
***************
*** 357,362 ****
--- 394,400 ----
  				proc->sem.semId, strerror(errno));
  		proc_exit(255);
  	}
+ #endif
  }
  
  /*
***************
*** 1115,1121 ****
  		}
  	}
  	/* can't elog here!!! */
! 	fprintf(stderr, "ProcFreeSem: no ProcGlobal entry for semId %d\n", semId);
  }
  
  /*
--- 1153,1159 ----
  		}
  	}
  	/* can't elog here!!! */
! 	fprintf(stderr, "ProcFreeSem: no ProcGlobal entry for semId %d\n", (int)semId);
  }
  
  /*
diff -crP postgresql-7.2b2/src/backend/storage/lmgr/spin.c postgresql-7.2b2.patched/src/backend/storage/lmgr/spin.c
*** postgresql-7.2b2/src/backend/storage/lmgr/spin.c	Mon Nov  5 11:46:28 2001
--- postgresql-7.2b2.patched/src/backend/storage/lmgr/spin.c	Mon Nov 19 21:21:17 2001
***************
*** 24,29 ****
--- 24,32 ----
  #include <errno.h>
  
  #include "storage/ipc.h"
+ 
+ #ifndef HAVE_POSIX_IPC
+ 
  /* In Ultrix, sem.h and shm.h must be included AFTER ipc.h */
  #ifdef HAVE_SYS_SEM_H
  #include <sys/sem.h>
***************
*** 33,44 ****
  #include "port/darwin/sem.h"
  #endif
  
  #include "storage/lwlock.h"
  #include "storage/proc.h"
  #include "storage/spin.h"
  
  
! #ifdef HAS_TEST_AND_SET
  
  /*
   * CreateSpinlocks --- create and initialize spinlocks during startup
--- 36,49 ----
  #include "port/darwin/sem.h"
  #endif
  
+ #endif /* HAVE_POSIX_IPC */
+ 
  #include "storage/lwlock.h"
  #include "storage/proc.h"
  #include "storage/spin.h"
  
  
! #if defined(HAS_TEST_AND_SET) || defined(USE_PHTREAD_MUTEXES) || defined(USE_PTHREAD_SPINLOCKS)
  
  /*
   * CreateSpinlocks --- create and initialize spinlocks during startup
***************
*** 124,133 ****
--- 129,142 ----
  	/* Create sema sets and set all semas to count 1 */
  	for (i = 0; i < numSpinSets; i++)
  	{
+ #ifdef HAVE_POSIX_IPC
+ 		SpinLockIds[i] = IpcSemaphoreCreate(NULL, false, 1, false);
+ #else
  		SpinLockIds[i] = IpcSemaphoreCreate(SPINLOCKS_PER_SET,
  											IPCProtection,
  											1,
  											false);
+ #endif
  	}
  
  	/* Init counter for allocating dynamic spinlocks */
***************
*** 148,154 ****
--- 157,170 ----
  	for (i = 0; i < numSpinSets; i++)
  	{
  		if (SpinLockIds[i] >= 0)
+ #ifdef HAVE_POSIX_IPC
+ 		{
+ 			IpcSemaphoreKill(SpinLockIds[i]);
+ 			free(SpinLockIds[i]);
+ 		}
+ #else
  			IpcSemaphoreKill(SpinLockIds[i]);
+ #endif
  	}
  	free(SpinLockIds);
  	SpinLockIds = NULL;
diff -crP postgresql-7.2b2/src/backend/utils/misc/guc.c postgresql-7.2b2.patched/src/backend/utils/misc/guc.c
*** postgresql-7.2b2/src/backend/utils/misc/guc.c	Mon Oct 29 23:38:56 2001
--- postgresql-7.2b2.patched/src/backend/utils/misc/guc.c	Thu Nov  8 13:52:18 2001
***************
*** 18,23 ****
--- 18,29 ----
  #include <limits.h>
  #include <unistd.h>
  
+ #ifdef __QNXNTO__
+ /* Some bozo has defined DBL_MAX as non-constant */
+ #undef 	DBL_MAX
+ #define DBL_MAX 1.7976931348623157e+308
+ #endif
+ 
  #include "utils/guc.h"
  
  #include "access/xlog.h"
diff -crP postgresql-7.2b2/src/backend/utils/sort/tuplesort.c postgresql-7.2b2.patched/src/backend/utils/sort/tuplesort.c
*** postgresql-7.2b2/src/backend/utils/sort/tuplesort.c	Sun Oct 28 01:25:57 2001
--- postgresql-7.2b2.patched/src/backend/utils/sort/tuplesort.c	Thu Nov 15 02:16:19 2001
***************
*** 1882,1888 ****
  	 * otherwise the sort algorithm wouldn't have checked whether one must
  	 * appear before the other.
  	 */
! 	if (state->enforceUnique && !equal_hasnull)
  		elog(ERROR, "Cannot create unique index. Table contains non-unique values");
  
  	return 0;
--- 1882,1888 ----
  	 * otherwise the sort algorithm wouldn't have checked whether one must
  	 * appear before the other.
  	 */
! 	if (state->enforceUnique && !equal_hasnull && tuple1 != tuple2)
  		elog(ERROR, "Cannot create unique index. Table contains non-unique values");
  
  	return 0;
diff -crP postgresql-7.2b2/src/include/port/qnx6.h postgresql-7.2b2.patched/src/include/port/qnx6.h
*** postgresql-7.2b2/src/include/port/qnx6.h	Wed Dec 31 18:00:00 1969
--- postgresql-7.2b2.patched/src/include/port/qnx6.h	Mon Nov 19 20:51:46 2001
***************
*** 0 ****
--- 1,81 ----
+ #include <sys/types.h>			/* for namser.h */
+ #include <arpa/nameser.h>		/* for BYTE_ORDER */
+ #include <ioctl.h>			/* for unix.h */
+ #include <unix.h>			
+ #include <sys/select.h>			/* for select */
+ #include <ymath.h>			/* for NAN */
+ 
+ /* 
+ 	Define type of locking implementation first.
+ 	USE_PTHREAD_MUTEXES is best on non-SMP
+ 	USE_PTHREAD_SPINLOCK is best on SMP, 
+ 		unless there's assembler code for your platform (x86 & ARM) in which case 
+ 		neither should be defined (HAS_TEST_AND_SET will be used then)
+ */
+ 
+ /* 
+  	1. Figure if we have hardware TAS.
+     	We want to have HAS_TESTAND_SET defined whenever possible to avoid extra tweaking of other files 
+  */
+ #if defined(__i386__) || defined(__arm__)
+ #define HAS_TEST_AND_SET
+ #endif
+ 
+ /*
+ 	2. Now make decision what to use, based on SMP_HARDWARE and HAS_TEST_AND_SET
+ 	Uncomment SMP_HARDWARE line for SMP machines.
+ */
+ /* #define SMP_HARDWARE */
+ #if defined(SMP_HARDWARE)
+ 
+ #ifndef HAS_TEST_AND_SET
+ #define USE_PTHREAD_SPINLOCKS
+ #endif
+ 
+ #else /* non SMP */
+ 
+ #define USE_PTHREAD_MUTEXES
+ 
+ #endif
+ 
+ /*
+ 	3. Finally, include proper header and define lock datatype.
+ */
+ #if defined(USE_PTHREAD_MUTEXES)
+ 
+ #include <pthread.h>
+ typedef pthread_mutex_t slock_t;
+ 
+ #elif defined(USE_PTHREAD_SPINLOCKS)
+ 
+ #include <pthread.h>
+ typedef pthread_spinlock_t slock_t;
+ 
+ #elif defined(HAS_TEST_AND_SET)
+ typedef unsigned char slock_t;
+ 
+ #endif
+ 
+ typedef unsigned short ushort;
+ 
+ /*
+ 	If this is not defined, SysV IPC emulation will be needed.
+ 	I don't think emulation code is much more reliable or better tested. 
+ 	But it certainly is slower and uglier, so this should probably be
+ 	always defined on QNX, unless you see some problem with locking.
+ */
+ #define HAVE_POSIX_IPC
+ 
+ #define HAVE_STRING_H
+ 
+ /* 
+ 	Those are workarounds for bugs in 6.1 (hopefully not needed for 6.1.1) 
+ */
+ #ifndef	NAN
+ #define	NAN	   (*(const double *) &_Nan)
+ #endif	/* NAN */
+ 
+ #if (_NTO_VERSION <= 610)
+ #undef MAXIMUM_ALIGNOF
+ #define MAXIMUM_ALIGNOF	(sizeof(int))
+ #endif
diff -crP postgresql-7.2b2/src/include/storage/ipc.h postgresql-7.2b2.patched/src/include/storage/ipc.h
*** postgresql-7.2b2/src/include/storage/ipc.h	Mon Nov  5 11:46:35 2001
--- postgresql-7.2b2.patched/src/include/storage/ipc.h	Sun Nov 18 00:07:04 2001
***************
*** 19,24 ****
--- 19,33 ----
  #define IPC_H
  
  #include <sys/types.h>
+ 
+ #ifdef HAVE_POSIX_IPC
+ #include <semaphore.h>
+ #include <sys/mman.h>
+ 
+ typedef sem_t * IpcSemaphoreId;
+ 
+ #else /* no POSIX_IPC */
+ 
  #ifdef HAVE_SYS_IPC_H
  #include <sys/ipc.h>
  #endif   /* HAVE_SYS_IPC_H */
***************
*** 30,61 ****
  	struct semid_ds *buf;
  	unsigned short *array;
  };
! #endif
! 
  
  /* generic IPC definitions */
  
! #define IPCProtection	(0600)	/* access/modify by user only */
  
  /* semaphore definitions */
  
- typedef uint32 IpcSemaphoreKey; /* semaphore key passed to semget(2) */
  typedef int IpcSemaphoreId;		/* semaphore ID returned by semget(2) */
  
! #define IPC_NMAXSEM		32		/* maximum number of semaphores per semID */
! 
! #define PGSemaMagic  537		/* must be less than SEMVMX */
  
  /* shared memory definitions */
  
  typedef uint32 IpcMemoryKey;	/* shared memory key passed to shmget(2) */
  typedef int IpcMemoryId;		/* shared memory ID returned by shmget(2) */
  
  typedef struct PGShmemHeader	/* standard header for all Postgres shmem */
  {
  	int32		magic;			/* magic # to identify Postgres segments */
  #define PGShmemMagic  679834892
  	pid_t		creatorPID;		/* PID of creating process */
  	uint32		totalsize;		/* total size of segment */
  	uint32		freeoffset;		/* offset to first free space */
  } PGShmemHeader;
--- 39,73 ----
  	struct semid_ds *buf;
  	unsigned short *array;
  };
! #endif /* HAVE_UNION_SEMUN */
  
  /* generic IPC definitions */
  
! #define PGSemaMagic  	537		/* must be less than SEMVMX */
! #define IPC_NMAXSEM		32		/* maximum number of semaphores per semID */
! 
! typedef uint32 IpcSemaphoreKey; /* semaphore key passed to semget(2) */
  
  /* semaphore definitions */
  
  typedef int IpcSemaphoreId;		/* semaphore ID returned by semget(2) */
  
! #endif	/* POSIX IPC */
  
  /* shared memory definitions */
  
+ #define IPCProtection	(0600)	/* access/modify by user only */
+ 
  typedef uint32 IpcMemoryKey;	/* shared memory key passed to shmget(2) */
  typedef int IpcMemoryId;		/* shared memory ID returned by shmget(2) */
  
  typedef struct PGShmemHeader	/* standard header for all Postgres shmem */
  {
+ #ifndef HAVE_POSIX_IPC
  	int32		magic;			/* magic # to identify Postgres segments */
  #define PGShmemMagic  679834892
  	pid_t		creatorPID;		/* PID of creating process */
+ #endif
  	uint32		totalsize;		/* total size of segment */
  	uint32		freeoffset;		/* offset to first free space */
  } PGShmemHeader;
***************
*** 72,80 ****
--- 84,98 ----
  
  extern void IpcInitKeyAssignment(int port);
  
+ #ifdef HAVE_POSIX_IPC
+ extern IpcSemaphoreId IpcSemaphoreCreate(void *storage, bool shared,
+ 				   int semStartValue,
+ 				   bool removeOnExit);
+ #else
  extern IpcSemaphoreId IpcSemaphoreCreate(int numSems, int permission,
  				   int semStartValue,
  				   bool removeOnExit);
+ #endif
  extern void IpcSemaphoreKill(IpcSemaphoreId semId);
  extern void IpcSemaphoreLock(IpcSemaphoreId semId, int sem, bool interruptOK);
  extern void IpcSemaphoreUnlock(IpcSemaphoreId semId, int sem);
diff -crP postgresql-7.2b2/src/include/storage/proc.h postgresql-7.2b2.patched/src/include/storage/proc.h
*** postgresql-7.2b2/src/include/storage/proc.h	Mon Nov  5 18:38:26 2001
--- postgresql-7.2b2.patched/src/include/storage/proc.h	Sat Nov 17 22:54:01 2001
***************
*** 22,29 ****
  
  typedef struct
  {
! 	IpcSemaphoreId semId;		/* SysV semaphore set ID */
! 	int			semNum;			/* semaphore number within set */
  } SEMA;
  
  /*
--- 22,29 ----
  
  typedef struct
  {
! 	IpcSemaphoreId 	semId;		/* semaphore id */
! 	int				semNum;		/* semaphore number within SysV set */
  } SEMA;
  
  /*
***************
*** 97,111 ****
   * semaphore (see storage/lmgr/proc.c), so the computation may look wrong,
   * but it's right.
   */
  #define  PROC_NSEMS_PER_SET		16
  #define  PROC_SEM_MAP_ENTRIES(maxBackends)	((maxBackends)/PROC_NSEMS_PER_SET+1)
  
  typedef struct
  {
  	/* info about a single set of per-process semaphores */
! 	IpcSemaphoreId procSemId;
! 	int32		freeSemMap;
! 
  	/*
  	 * In freeSemMap, bit i is set if the i'th semaphore of this sema set
  	 * is allocated to a process.  (i counts from 0 at the LSB)
--- 97,117 ----
   * semaphore (see storage/lmgr/proc.c), so the computation may look wrong,
   * but it's right.
   */
+ #ifdef	 HAVE_POSIX_IPC			/* No 'sets' in POSIX */
+ #define  PROC_NSEMS_PER_SET		1
+ #else
  #define  PROC_NSEMS_PER_SET		16
+ #endif
  #define  PROC_SEM_MAP_ENTRIES(maxBackends)	((maxBackends)/PROC_NSEMS_PER_SET+1)
  
  typedef struct
  {
  	/* info about a single set of per-process semaphores */
! 	IpcSemaphoreId 	procSemId;
! 	int32			freeSemMap;
! #ifdef HAVE_POSIX_IPC
! 	sem_t			procSemMem;
! #endif
  	/*
  	 * In freeSemMap, bit i is set if the i'th semaphore of this sema set
  	 * is allocated to a process.  (i counts from 0 at the LSB)
diff -crP postgresql-7.2b2/src/include/storage/s_lock.h postgresql-7.2b2.patched/src/include/storage/s_lock.h
*** postgresql-7.2b2/src/include/storage/s_lock.h	Fri Sep 28 23:02:26 2001
--- postgresql-7.2b2.patched/src/include/storage/s_lock.h	Mon Nov 19 19:49:04 2001
***************
*** 1,3 ****
--- 1,4 ----
+ 
  /*-------------------------------------------------------------------------
   *
   * s_lock.h
***************
*** 67,75 ****
  
  #include "storage/ipc.h"
  
  
! #if defined(HAS_TEST_AND_SET)
  
  
  #if defined(__GNUC__)
  /*************************************************************************
--- 68,119 ----
  
  #include "storage/ipc.h"
  
+ #if defined(USE_PTHREAD_MUTEXES)	
+ /*
+  * Mutexes are better choice when OS has very fast context switches
+  * (i.e., overhead of a system call is negligibly small compared to overhead 
+  * of scheduler) AND we're running on single-CPU system. 
+  * Currently defined on QNX6 but it is portable and might be useful for
+  * other platforms.
+  *
+  * Note that slock_t is assumed to be defined as pthread_mutex_t.
+  *
+  * Implementation of S_LOCK_FREE() is not very efficient, but it is
+  * only used by test program anyway.
+  */
+ #define TAS(lock)		(pthread_mutex_trylock((lock)) != EOK)
+ #define S_LOCK(lock)		pthread_mutex_lock((lock))
+ #define S_UNLOCK(lock)		pthread_mutex_unlock((lock))
+ #define S_INIT_LOCK(lock)	pthread_mutex_init((lock), NULL)
+ #define S_LOCK_FREE(lock)	((pthread_mutex_trylock((lock)) == EOK) ? (pthread_mutex_unlock(lock) == EOK) : 0)
  
! #elif defined(USE_PTHREAD_SPINLOCKS)
! /*
!  * Spinlocks are better choice when we run on SMP system. Performance probably
!  * would be better using hardware TAS, but this should be portable between
!  * OSes and hardware (as per POSIX 1003.1j draft).
!  * If hardware does not support TAS, there's still good chance this will
!  * be more efficient than using SysV semaphores, assuming OS vendor has done
!  * any decent job implementing PTHREADS library.
!  *
!  * It probably does not make sense to use this if hardware supports TAS and
!  * there's assembler implementation for your platform below. It was added
!  * to avoid messing with ugly SysV semaphores when running on non-i386
!  * SMP platforms (PPC could be real possibility). Currently defined on QNX6.
!  *
!  * Note that slock_t is assumed to be defined as pthread_spinlock_t.
!  *
!  * Implementation of S_LOCK_FREE() is not very efficient, but it is
!  * only used by test program anyway.
!  */
! 
! #define TAS(lock)		(pthread_spin_trylock((lock)) != EOK)
! #define S_LOCK(lock)		pthread_spin_lock((lock))
! #define S_UNLOCK(lock)		pthread_spin_unlock((lock))
! #define S_INIT_LOCK(lock)	pthread_spin_init((lock), NULL)
! #define S_LOCK_FREE(lock)	((pthread_spin_trylock((lock)) == EOK) ? (pthread_mutex_unlock(lock) == EOK) : 0)
  
+ #elif defined(HAS_TEST_AND_SET)
  
  #if defined(__GNUC__)
  /*************************************************************************
***************
*** 392,398 ****
  		value [al];
  
  #endif	 /* __QNX__ and __WATCOMC__*/
- 
  
  #if defined(__sgi)
  /*
--- 436,441 ----
diff -crP postgresql-7.2b2/src/makefiles/Makefile.qnx6 postgresql-7.2b2.patched/src/makefiles/Makefile.qnx6
*** postgresql-7.2b2/src/makefiles/Makefile.qnx6	Wed Dec 31 18:00:00 1969
--- postgresql-7.2b2.patched/src/makefiles/Makefile.qnx6	Sat Dec 16 12:14:25 2000
***************
*** 0 ****
--- 1,9 ----
+ AROPT = crs
+ export_dynamic = -export-dynamic
+ rpath = -Wl,-rpath,$(libdir)
+ shlib_symbolic = -Wl,-Bsymbolic
+ DLSUFFIX = .so
+ CFLAGS_SL = -fpic
+ 
+ %.so: %.o
+ 	$(CC) -shared -o $@ $<
diff -crP postgresql-7.2b2/src/template/qnx6 postgresql-7.2b2.patched/src/template/qnx6
*** postgresql-7.2b2/src/template/qnx6	Wed Dec 31 18:00:00 1969
--- postgresql-7.2b2.patched/src/template/qnx6	Tue Nov  6 12:21:28 2001
***************
*** 0 ****
--- 1,2 ----
+ CFLAGS=
+ LIBS=
diff -crP postgresql-7.2b2/src/test/regress/expected/alter_table.out postgresql-7.2b2.patched/src/test/regress/expected/alter_table.out
*** postgresql-7.2b2/src/test/regress/expected/alter_table.out	Sat Nov  3 21:08:11 2001
--- postgresql-7.2b2.patched/src/test/regress/expected/alter_table.out	Sun Nov 18 01:08:29 2001
***************
*** 471,477 ****
  insert into atacc1 (test) values (2);
  -- add a unique constraint (fails)
  alter table atacc1 add constraint atacc_test1 unique (test);
!  NOTICE:  ALTER TABLE / ADD UNIQUE will create implicit index 'atacc_test1' for table 'atacc1'
  ERROR:  Cannot create unique index. Table contains non-unique values
  insert into atacc1 (test) values (3);
  drop table atacc1;
--- 471,477 ----
  insert into atacc1 (test) values (2);
  -- add a unique constraint (fails)
  alter table atacc1 add constraint atacc_test1 unique (test);
! NOTICE:  ALTER TABLE / ADD UNIQUE will create implicit index 'atacc_test1' for table 'atacc1'
  ERROR:  Cannot create unique index. Table contains non-unique values
  insert into atacc1 (test) values (3);
  drop table atacc1;
diff -crP postgresql-7.2b2/src/test/regress/expected/geometry-x86-pc-nto-qnx.out postgresql-7.2b2.patched/src/test/regress/expected/geometry-x86-pc-nto-qnx.out
*** postgresql-7.2b2/src/test/regress/expected/geometry-x86-pc-nto-qnx.out	Wed Dec 31 18:00:00 1969
--- postgresql-7.2b2.patched/src/test/regress/expected/geometry-x86-pc-nto-qnx.out	Sun Nov 18 01:04:25 2001
***************
*** 0 ****
--- 1,532 ----
+ --
+ -- GEOMETRY
+ --
+ --
+ -- Points
+ --
+ SELECT '' AS four, center(f1) AS center
+    FROM BOX_TBL;
+  four | center  
+ ------+---------
+       | (1,1)
+       | (2,2)
+       | (2.5,3)
+       | (3,3)
+ (4 rows)
+ 
+ SELECT '' AS four, (@@ f1) AS center
+    FROM BOX_TBL;
+  four | center  
+ ------+---------
+       | (1,1)
+       | (2,2)
+       | (2.5,3)
+       | (3,3)
+ (4 rows)
+ 
+ SELECT '' AS six, point(f1) AS center
+    FROM CIRCLE_TBL;
+  six |  center   
+ -----+-----------
+      | (0,0)
+      | (1,2)
+      | (1,3)
+      | (1,2)
+      | (100,200)
+      | (100,0)
+ (6 rows)
+ 
+ SELECT '' AS six, (@@ f1) AS center
+    FROM CIRCLE_TBL;
+  six |  center   
+ -----+-----------
+      | (0,0)
+      | (1,2)
+      | (1,3)
+      | (1,2)
+      | (100,200)
+      | (100,0)
+ (6 rows)
+ 
+ SELECT '' AS two, (@@ f1) AS center
+    FROM POLYGON_TBL
+    WHERE (# f1) > 2;
+  two |               center                
+ -----+-------------------------------------
+      | (1.33333333333333,1.33333333333333)
+      | (2.33333333333333,1.33333333333333)
+ (2 rows)
+ 
+ -- "is horizontal" function
+ SELECT '' AS two, p1.f1
+    FROM POINT_TBL p1
+    WHERE ishorizontal(p1.f1, point '(0,0)');
+  two |   f1    
+ -----+---------
+      | (0,0)
+      | (-10,0)
+ (2 rows)
+ 
+ -- "is horizontal" operator
+ SELECT '' AS two, p1.f1
+    FROM POINT_TBL p1
+    WHERE p1.f1 ?- point '(0,0)';
+  two |   f1    
+ -----+---------
+      | (0,0)
+      | (-10,0)
+ (2 rows)
+ 
+ -- "is vertical" function
+ SELECT '' AS one, p1.f1
+    FROM POINT_TBL p1
+    WHERE isvertical(p1.f1, point '(5.1,34.5)');
+  one |     f1     
+ -----+------------
+      | (5.1,34.5)
+ (1 row)
+ 
+ -- "is vertical" operator
+ SELECT '' AS one, p1.f1
+    FROM POINT_TBL p1
+    WHERE p1.f1 ?| point '(5.1,34.5)';
+  one |     f1     
+ -----+------------
+      | (5.1,34.5)
+ (1 row)
+ 
+ --
+ -- Line segments
+ --
+ -- intersection
+ SELECT '' AS count, p.f1, l.s, l.s # p.f1 AS intersection
+    FROM LSEG_TBL l, POINT_TBL p;
+ ERROR:  Unable to identify an operator '#' for types 'lseg' and 'point'
+ 	You will have to retype this query using an explicit cast
+ -- closest point
+ SELECT '' AS thirty, p.f1, l.s, p.f1 ## l.s AS closest
+    FROM LSEG_TBL l, POINT_TBL p;
+  thirty |     f1     |               s               |                closest                
+ --------+------------+-------------------------------+---------------------------------------
+         | (0,0)      | [(1,2),(3,4)]                 | (1,2)
+         | (-10,0)    | [(1,2),(3,4)]                 | (1,2)
+         | (-3,4)     | [(1,2),(3,4)]                 | (1,2)
+         | (5.1,34.5) | [(1,2),(3,4)]                 | (3,4)
+         | (-5,-12)   | [(1,2),(3,4)]                 | (1,2)
+         | (10,10)    | [(1,2),(3,4)]                 | (3,4)
+         | (0,0)      | [(0,0),(6,6)]                 | (-0,0)
+         | (-10,0)    | [(0,0),(6,6)]                 | (0,0)
+         | (-3,4)     | [(0,0),(6,6)]                 | (0.5,0.5)
+         | (5.1,34.5) | [(0,0),(6,6)]                 | (6,6)
+         | (-5,-12)   | [(0,0),(6,6)]                 | (0,0)
+         | (10,10)    | [(0,0),(6,6)]                 | (6,6)
+         | (0,0)      | [(10,-10),(-3,-4)]            | (-2.04878048780488,-4.4390243902439)
+         | (-10,0)    | [(10,-10),(-3,-4)]            | (-3,-4)
+         | (-3,4)     | [(10,-10),(-3,-4)]            | (-3,-4)
+         | (5.1,34.5) | [(10,-10),(-3,-4)]            | (-3,-4)
+         | (-5,-12)   | [(10,-10),(-3,-4)]            | (-1.60487804878049,-4.64390243902439)
+         | (10,10)    | [(10,-10),(-3,-4)]            | (2.39024390243902,-6.48780487804878)
+         | (0,0)      | [(-1000000,200),(300000,-40)] | (0.0028402365895872,15.384614860264)
+         | (-10,0)    | [(-1000000,200),(300000,-40)] | (-9.99715942258202,15.3864610140473)
+         | (-3,4)     | [(-1000000,200),(300000,-40)] | (-2.99789812267519,15.3851688427303)
+         | (5.1,34.5) | [(-1000000,200),(300000,-40)] | (5.09647083221496,15.3836744976925)
+         | (-5,-12)   | [(-1000000,200),(300000,-40)] | (-4.99494420845634,15.3855375281616)
+         | (10,10)    | [(-1000000,200),(300000,-40)] | (10.000993741978,15.3827690473092)
+         | (0,0)      | [(11,22),(33,44)]             | (11,22)
+         | (-10,0)    | [(11,22),(33,44)]             | (11,22)
+         | (-3,4)     | [(11,22),(33,44)]             | (11,22)
+         | (5.1,34.5) | [(11,22),(33,44)]             | (14.3,25.3)
+         | (-5,-12)   | [(11,22),(33,44)]             | (11,22)
+         | (10,10)    | [(11,22),(33,44)]             | (11,22)
+ (30 rows)
+ 
+ --
+ -- Lines
+ --
+ --
+ -- Boxes
+ --
+ SELECT '' as six, box(f1) AS box FROM CIRCLE_TBL;
+  six |                                    box                                     
+ -----+----------------------------------------------------------------------------
+      | (2.12132034355964,2.12132034355964),(-2.12132034355964,-2.12132034355964)
+      | (71.7106781186547,72.7106781186547),(-69.7106781186547,-68.7106781186547)
+      | (4.53553390593274,6.53553390593274),(-2.53553390593274,-0.535533905932737)
+      | (3.12132034355964,4.12132034355964),(-1.12132034355964,-0.121320343559642)
+      | (107.071067811865,207.071067811865),(92.9289321881345,192.928932188135)
+      | (170.710678118655,70.7106781186547),(29.2893218813453,-70.7106781186547)
+ (6 rows)
+ 
+ -- translation
+ SELECT '' AS twentyfour, b.f1 + p.f1 AS translation
+    FROM BOX_TBL b, POINT_TBL p;
+  twentyfour |       translation       
+ ------------+-------------------------
+             | (2,2),(0,0)
+             | (-8,2),(-10,0)
+             | (-1,6),(-3,4)
+             | (7.1,36.5),(5.1,34.5)
+             | (-3,-10),(-5,-12)
+             | (12,12),(10,10)
+             | (3,3),(1,1)
+             | (-7,3),(-9,1)
+             | (0,7),(-2,5)
+             | (8.1,37.5),(6.1,35.5)
+             | (-2,-9),(-4,-11)
+             | (13,13),(11,11)
+             | (2.5,3.5),(2.5,2.5)
+             | (-7.5,3.5),(-7.5,2.5)
+             | (-0.5,7.5),(-0.5,6.5)
+             | (7.6,38),(7.6,37)
+             | (-2.5,-8.5),(-2.5,-9.5)
+             | (12.5,13.5),(12.5,12.5)
+             | (3,3),(3,3)
+             | (-7,3),(-7,3)
+             | (0,7),(0,7)
+             | (8.1,37.5),(8.1,37.5)
+             | (-2,-9),(-2,-9)
+             | (13,13),(13,13)
+ (24 rows)
+ 
+ SELECT '' AS twentyfour, b.f1 - p.f1 AS translation
+    FROM BOX_TBL b, POINT_TBL p;
+  twentyfour |        translation        
+ ------------+---------------------------
+             | (2,2),(0,0)
+             | (12,2),(10,0)
+             | (5,-2),(3,-4)
+             | (-3.1,-32.5),(-5.1,-34.5)
+             | (7,14),(5,12)
+             | (-8,-8),(-10,-10)
+             | (3,3),(1,1)
+             | (13,3),(11,1)
+             | (6,-1),(4,-3)
+             | (-2.1,-31.5),(-4.1,-33.5)
+             | (8,15),(6,13)
+             | (-7,-7),(-9,-9)
+             | (2.5,3.5),(2.5,2.5)
+             | (12.5,3.5),(12.5,2.5)
+             | (5.5,-0.5),(5.5,-1.5)
+             | (-2.6,-31),(-2.6,-32)
+             | (7.5,15.5),(7.5,14.5)
+             | (-7.5,-6.5),(-7.5,-7.5)
+             | (3,3),(3,3)
+             | (13,3),(13,3)
+             | (6,-1),(6,-1)
+             | (-2.1,-31.5),(-2.1,-31.5)
+             | (8,15),(8,15)
+             | (-7,-7),(-7,-7)
+ (24 rows)
+ 
+ -- scaling and rotation
+ SELECT '' AS twentyfour, b.f1 * p.f1 AS rotation
+    FROM BOX_TBL b, POINT_TBL p;
+  twentyfour |          rotation           
+ ------------+-----------------------------
+             | (0,0),(0,0)
+             | (-0,0),(-20,-20)
+             | (-0,2),(-14,0)
+             | (0,79.2),(-58.8,0)
+             | (14,-0),(0,-34)
+             | (0,40),(0,0)
+             | (0,0),(0,0)
+             | (-10,-10),(-30,-30)
+             | (-7,3),(-21,1)
+             | (-29.4,118.8),(-88.2,39.6)
+             | (21,-17),(7,-51)
+             | (0,60),(0,20)
+             | (0,0),(0,0)
+             | (-25,-25),(-25,-35)
+             | (-17.5,2.5),(-21.5,-0.5)
+             | (-73.5,104.1),(-108,99)
+             | (29.5,-42.5),(17.5,-47.5)
+             | (0,60),(-10,50)
+             | (0,0),(0,0)
+             | (-30,-30),(-30,-30)
+             | (-21,3),(-21,3)
+             | (-88.2,118.8),(-88.2,118.8)
+             | (21,-51),(21,-51)
+             | (0,60),(0,60)
+ (24 rows)
+ 
+ SELECT '' AS twenty, b.f1 / p.f1 AS rotation
+    FROM BOX_TBL b, POINT_TBL p
+    WHERE (p.f1 <-> point '(0,0)') >= 1;
+  twenty |                                     rotation                                      
+ --------+-----------------------------------------------------------------------------------
+         | (0,-0),(-0.2,-0.2)
+         | (-0.1,-0.1),(-0.3,-0.3)
+         | (-0.25,-0.25),(-0.25,-0.35)
+         | (-0.3,-0.3),(-0.3,-0.3)
+         | (0.08,-0),(0,-0.56)
+         | (0.12,-0.28),(0.04,-0.84)
+         | (0.26,-0.7),(0.1,-0.82)
+         | (0.12,-0.84),(0.12,-0.84)
+         | (0.0651176557643925,0),(0,-0.0483449262493217)
+         | (0.0976764836465887,-0.0241724631246608),(0.0325588278821962,-0.0725173893739825)
+         | (0.109762715208919,-0.0562379754328844),(0.0813970697054906,-0.0604311578116521)
+         | (0.0976764836465887,-0.0725173893739825),(0.0976764836465887,-0.0725173893739825)
+         | (-0,0.0828402366863905),(-0.201183431952663,0)
+         | (-0.100591715976331,0.124260355029586),(-0.301775147928994,0.0414201183431953)
+         | (-0.251479289940828,0.103550295857988),(-0.322485207100592,0.0739644970414201)
+         | (-0.301775147928994,0.124260355029586),(-0.301775147928994,0.124260355029586)
+         | (0.2,0),(0,0)
+         | (0.3,0),(0.1,0)
+         | (0.3,0.05),(0.25,0)
+         | (0.3,0),(0.3,0)
+ (20 rows)
+ 
+ --
+ -- Paths
+ --
+ SET geqo TO 'off';
+ SELECT '' AS eight, npoints(f1) AS npoints, f1 AS path FROM PATH_TBL;
+  eight | npoints |           path            
+ -------+---------+---------------------------
+        |       2 | [(1,2),(3,4)]
+        |       2 | ((1,2),(3,4))
+        |       4 | [(0,0),(3,0),(4,5),(1,6)]
+        |       2 | ((1,2),(3,4))
+        |       2 | ((1,2),(3,4))
+        |       2 | [(1,2),(3,4)]
+        |       2 | [(11,12),(13,14)]
+        |       2 | ((11,12),(13,14))
+ (8 rows)
+ 
+ SELECT '' AS four, path(f1) FROM POLYGON_TBL;
+  four |        path         
+ ------+---------------------
+       | ((2,0),(2,4),(0,0))
+       | ((3,1),(3,3),(1,0))
+       | ((0,0))
+       | ((0,1),(0,1))
+ (4 rows)
+ 
+ -- translation
+ SELECT '' AS eight, p1.f1 + point '(10,10)' AS dist_add
+    FROM PATH_TBL p1;
+  eight |             dist_add              
+ -------+-----------------------------------
+        | [(11,12),(13,14)]
+        | ((11,12),(13,14))
+        | [(10,10),(13,10),(14,15),(11,16)]
+        | ((11,12),(13,14))
+        | ((11,12),(13,14))
+        | [(11,12),(13,14)]
+        | [(21,22),(23,24)]
+        | ((21,22),(23,24))
+ (8 rows)
+ 
+ -- scaling and rotation
+ SELECT '' AS eight, p1.f1 * point '(2,-1)' AS dist_mul
+    FROM PATH_TBL p1;
+  eight |           dist_mul           
+ -------+------------------------------
+        | [(4,3),(10,5)]
+        | ((4,3),(10,5))
+        | [(0,0),(6,-3),(13,6),(8,11)]
+        | ((4,3),(10,5))
+        | ((4,3),(10,5))
+        | [(4,3),(10,5)]
+        | [(34,13),(40,15)]
+        | ((34,13),(40,15))
+ (8 rows)
+ 
+ RESET geqo;
+ --
+ -- Polygons
+ --
+ -- containment
+ SELECT '' AS twentyfour, p.f1, poly.f1, poly.f1 ~ p.f1 AS contains
+    FROM POLYGON_TBL poly, POINT_TBL p;
+  twentyfour |     f1     |         f1          | contains 
+ ------------+------------+---------------------+----------
+             | (0,0)      | ((2,0),(2,4),(0,0)) | t
+             | (-10,0)    | ((2,0),(2,4),(0,0)) | f
+             | (-3,4)     | ((2,0),(2,4),(0,0)) | f
+             | (5.1,34.5) | ((2,0),(2,4),(0,0)) | f
+             | (-5,-12)   | ((2,0),(2,4),(0,0)) | f
+             | (10,10)    | ((2,0),(2,4),(0,0)) | f
+             | (0,0)      | ((3,1),(3,3),(1,0)) | f
+             | (-10,0)    | ((3,1),(3,3),(1,0)) | f
+             | (-3,4)     | ((3,1),(3,3),(1,0)) | f
+             | (5.1,34.5) | ((3,1),(3,3),(1,0)) | f
+             | (-5,-12)   | ((3,1),(3,3),(1,0)) | f
+             | (10,10)    | ((3,1),(3,3),(1,0)) | f
+             | (0,0)      | ((0,0))             | t
+             | (-10,0)    | ((0,0))             | f
+             | (-3,4)     | ((0,0))             | f
+             | (5.1,34.5) | ((0,0))             | f
+             | (-5,-12)   | ((0,0))             | f
+             | (10,10)    | ((0,0))             | f
+             | (0,0)      | ((0,1),(0,1))       | f
+             | (-10,0)    | ((0,1),(0,1))       | f
+             | (-3,4)     | ((0,1),(0,1))       | f
+             | (5.1,34.5) | ((0,1),(0,1))       | f
+             | (-5,-12)   | ((0,1),(0,1))       | f
+             | (10,10)    | ((0,1),(0,1))       | f
+ (24 rows)
+ 
+ SELECT '' AS twentyfour, p.f1, poly.f1, p.f1 @ poly.f1 AS contained
+    FROM POLYGON_TBL poly, POINT_TBL p;
+  twentyfour |     f1     |         f1          | contained 
+ ------------+------------+---------------------+-----------
+             | (0,0)      | ((2,0),(2,4),(0,0)) | t
+             | (-10,0)    | ((2,0),(2,4),(0,0)) | f
+             | (-3,4)     | ((2,0),(2,4),(0,0)) | f
+             | (5.1,34.5) | ((2,0),(2,4),(0,0)) | f
+             | (-5,-12)   | ((2,0),(2,4),(0,0)) | f
+             | (10,10)    | ((2,0),(2,4),(0,0)) | f
+             | (0,0)      | ((3,1),(3,3),(1,0)) | f
+             | (-10,0)    | ((3,1),(3,3),(1,0)) | f
+             | (-3,4)     | ((3,1),(3,3),(1,0)) | f
+             | (5.1,34.5) | ((3,1),(3,3),(1,0)) | f
+             | (-5,-12)   | ((3,1),(3,3),(1,0)) | f
+             | (10,10)    | ((3,1),(3,3),(1,0)) | f
+             | (0,0)      | ((0,0))             | t
+             | (-10,0)    | ((0,0))             | f
+             | (-3,4)     | ((0,0))             | f
+             | (5.1,34.5) | ((0,0))             | f
+             | (-5,-12)   | ((0,0))             | f
+             | (10,10)    | ((0,0))             | f
+             | (0,0)      | ((0,1),(0,1))       | f
+             | (-10,0)    | ((0,1),(0,1))       | f
+             | (-3,4)     | ((0,1),(0,1))       | f
+             | (5.1,34.5) | ((0,1),(0,1))       | f
+             | (-5,-12)   | ((0,1),(0,1))       | f
+             | (10,10)    | ((0,1),(0,1))       | f
+ (24 rows)
+ 
+ SELECT '' AS four, npoints(f1) AS npoints, f1 AS polygon
+    FROM POLYGON_TBL;
+  four | npoints |       polygon       
+ ------+---------+---------------------
+       |       3 | ((2,0),(2,4),(0,0))
+       |       3 | ((3,1),(3,3),(1,0))
+       |       1 | ((0,0))
+       |       2 | ((0,1),(0,1))
+ (4 rows)
+ 
+ SELECT '' AS four, polygon(f1)
+    FROM BOX_TBL;
+  four |                  polygon                  
+ ------+-------------------------------------------
+       | ((0,0),(0,2),(2,2),(2,0))
+       | ((1,1),(1,3),(3,3),(3,1))
+       | ((2.5,2.5),(2.5,3.5),(2.5,3.5),(2.5,2.5))
+       | ((3,3),(3,3),(3,3),(3,3))
+ (4 rows)
+ 
+ SELECT '' AS four, polygon(f1)
+    FROM PATH_TBL WHERE isclosed(f1);
+  four |      polygon      
+ ------+-------------------
+       | ((1,2),(3,4))
+       | ((1,2),(3,4))
+       | ((1,2),(3,4))
+       | ((11,12),(13,14))
+ (4 rows)
+ 
+ SELECT '' AS four, f1 AS open_path, polygon( pclose(f1)) AS polygon
+    FROM PATH_TBL
+    WHERE isopen(f1);
+  four |         open_path         |          polygon          
+ ------+---------------------------+---------------------------
+       | [(1,2),(3,4)]             | ((1,2),(3,4))
+       | [(0,0),(3,0),(4,5),(1,6)] | ((0,0),(3,0),(4,5),(1,6))
+       | [(1,2),(3,4)]             | ((1,2),(3,4))
+       | [(11,12),(13,14)]         | ((11,12),(13,14))
+ (4 rows)
+ 
+ -- convert circles to polygons using the default number of points
+ SELECT '' AS six, polygon(f1)
+    FROM CIRCLE_TBL;
+  six |                                                                                                                                                                                           polygon                                                                                                                                                                                           
+ -----+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+      | ((-3,0),(-2.59807621135076,1.50000000000442),(-1.49999999999116,2.59807621135842),(1.53102359018026e-11,3),(1.50000000001768,2.59807621134311),(2.59807621136607,1.4999999999779),(3,-3.06204718036052e-11),(2.59807621133545,-1.50000000003094),(1.49999999996464,-2.59807621137373),(-4.59307077054077e-11,-3),(-1.5000000000442,-2.5980762113278),(-2.59807621138139,-1.49999999995138))
+      | ((-99,2),(-85.6025403783588,52.0000000001473),(-48.9999999997054,88.602540378614),(1.00000000051034,102),(51.0000000005893,88.6025403781037),(87.6025403788692,51.9999999992634),(101,1.99999999897932),(87.6025403778485,-48.0000000010313),(50.9999999988214,-84.6025403791243),(0.999999998468976,-98),(-49.0000000014732,-84.6025403775933),(-85.6025403793795,-47.9999999983794))
+      | ((-4,3),(-3.33012701891794,5.50000000000737),(-1.49999999998527,7.3301270189307),(1.00000000002552,8),(3.50000000002946,7.33012701890518),(5.33012701894346,5.49999999996317),(6,2.99999999994897),(5.33012701889242,0.499999999948437),(3.49999999994107,-1.33012701895622),(0.999999999923449,-2),(-1.50000000007366,-1.33012701887967),(-3.33012701896897,0.500000000081028))
+      | ((-2,2),(-1.59807621135076,3.50000000000442),(-0.499999999991161,4.59807621135842),(1.00000000001531,5),(2.50000000001768,4.59807621134311),(3.59807621136607,3.4999999999779),(4,1.99999999996938),(3.59807621133545,0.499999999969062),(2.49999999996464,-0.59807621137373),(0.999999999954069,-1),(-0.500000000044197,-0.598076211327799),(-1.59807621138139,0.500000000048617))
+      | ((90,200),(91.3397459621641,205.000000000015),(95.0000000000295,208.660254037861),(100.000000000051,210),(105.000000000059,208.66025403781),(108.660254037887,204.999999999926),(110,199.999999999898),(108.660254037785,194.999999999897),(104.999999999882,191.339745962088),(99.9999999998469,190),(94.9999999998527,191.339745962241),(91.3397459620621,195.000000000162))
+      | ((0,0),(13.3974596216412,50.0000000001473),(50.0000000002946,86.602540378614),(100.00000000051,100),(150.000000000589,86.6025403781037),(186.602540378869,49.9999999992634),(200,-1.02068239345351e-09),(186.602540377848,-50.0000000010313),(149.999999998821,-86.6025403791243),(99.999999998469,-100),(49.9999999985268,-86.6025403775933),(13.3974596206205,-49.9999999983794))
+ (6 rows)
+ 
+ -- convert the circle to an 8-point polygon
+ SELECT '' AS six, polygon(8, f1)
+    FROM CIRCLE_TBL;
+  six |                                                                                                                  polygon                                                                                                                  
+ -----+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+      | ((-3,0),(-2.12132034355423,2.12132034356506),(1.53102359018026e-11,3),(2.12132034357588,2.1213203435434),(3,-3.06204718036052e-11),(2.12132034353258,-2.12132034358671),(-4.59307077054077e-11,-3),(-2.12132034359753,-2.12132034352175))
+      | ((-99,2),(-69.7106781184743,72.7106781188352),(1.00000000051034,102),(71.7106781191961,72.7106781181135),(101,1.99999999897932),(71.7106781177526,-68.7106781195569),(0.999999998468976,-98),(-69.7106781199178,-68.7106781173917))
+      | ((-4,3),(-2.53553390592372,6.53553390594176),(1.00000000002552,8),(4.5355339059598,6.53553390590567),(6,2.99999999994897),(4.53553390588763,-0.535533905977846),(0.999999999923449,-2),(-2.53553390599589,-0.535533905869586))
+      | ((-2,2),(-1.12132034355423,4.12132034356506),(1.00000000001531,5),(3.12132034357588,4.1213203435434),(4,1.99999999996938),(3.12132034353258,-0.121320343586708),(0.999999999954069,-1),(-1.12132034359753,-0.121320343521752))
+      | ((90,200),(92.9289321881526,207.071067811884),(100.000000000051,210),(107.07106781192,207.071067811811),(110,199.999999999898),(107.071067811775,192.928932188044),(99.9999999998469,190),(92.9289321880082,192.928932188261))
+      | ((0,0),(29.2893218815257,70.7106781188352),(100.00000000051,100),(170.710678119196,70.7106781181135),(200,-1.02068239345351e-09),(170.710678117753,-70.7106781195569),(99.999999998469,-100),(29.2893218800822,-70.7106781173917))
+ (6 rows)
+ 
+ --
+ -- Circles
+ --
+ SELECT '' AS six, circle(f1, 50.0)
+    FROM POINT_TBL;
+  six |     circle      
+ -----+-----------------
+      | <(0,0),50>
+      | <(-10,0),50>
+      | <(-3,4),50>
+      | <(5.1,34.5),50>
+      | <(-5,-12),50>
+      | <(10,10),50>
+ (6 rows)
+ 
+ SELECT '' AS four, circle(f1)
+    FROM BOX_TBL;
+  four |         circle          
+ ------+-------------------------
+       | <(1,1),1.4142135623731>
+       | <(2,2),1.4142135623731>
+       | <(2.5,3),0.5>
+       | <(3,3),0>
+ (4 rows)
+ 
+ SELECT '' AS two, circle(f1)
+    FROM POLYGON_TBL
+    WHERE (# f1) >= 3;
+  two |                         circle                         
+ -----+--------------------------------------------------------
+      | <(1.33333333333333,1.33333333333333),2.04168905063636>
+      | <(2.33333333333333,1.33333333333333),1.47534300379185>
+ (2 rows)
+ 
+ SELECT '' AS twentyfour, c1.f1 AS circle, p1.f1 AS point, (p1.f1 <-> c1.f1) AS distance
+    FROM CIRCLE_TBL c1, POINT_TBL p1
+    WHERE (p1.f1 <-> c1.f1) > 0
+    ORDER BY distance, circle, point using <<;
+  twentyfour |     circle     |   point    |     distance     
+ ------------+----------------+------------+------------------
+             | <(100,0),100>  | (5.1,34.5) | 0.97653192697797
+             | <(1,2),3>      | (-3,4)     | 1.47213595499958
+             | <(0,0),3>      | (-3,4)     |                2
+             | <(100,0),100>  | (-3,4)     | 3.07764064044152
+             | <(100,0),100>  | (-5,-12)   | 5.68348972285122
+             | <(1,3),5>      | (-10,0)    | 6.40175425099138
+             | <(1,3),5>      | (10,10)    | 6.40175425099138
+             | <(0,0),3>      | (-10,0)    |                7
+             | <(1,2),3>      | (-10,0)    | 8.18033988749895
+             | <(1,2),3>      | (10,10)    |  9.0415945787923
+             | <(0,0),3>      | (-5,-12)   |               10
+             | <(100,0),100>  | (-10,0)    |               10
+             | <(0,0),3>      | (10,10)    |  11.142135623731
+             | <(1,3),5>      | (-5,-12)   | 11.1554944214035
+             | <(1,2),3>      | (-5,-12)   | 12.2315462117278
+             | <(1,3),5>      | (5.1,34.5) | 26.7657047773224
+             | <(1,2),3>      | (5.1,34.5) |  29.757594539282
+             | <(0,0),3>      | (5.1,34.5) | 31.8749193547455
+             | <(100,200),10> | (5.1,34.5) | 180.778038568384
+             | <(100,200),10> | (10,10)    | 200.237960416286
+             | <(100,200),10> | (-3,4)     | 211.415898254845
+             | <(100,200),10> | (0,0)      | 213.606797749979
+             | <(100,200),10> | (-10,0)    | 218.254244210267
+             | <(100,200),10> | (-5,-12)   | 226.577682802077
+ (24 rows)
+ 
diff -crP postgresql-7.2b2/src/test/regress/resultmap postgresql-7.2b2.patched/src/test/regress/resultmap
*** postgresql-7.2b2/src/test/regress/resultmap	Sat Aug 25 19:55:15 2001
--- postgresql-7.2b2.patched/src/test/regress/resultmap	Sun Nov 18 02:14:25 2001
***************
*** 3,13 ****
--- 3,17 ----
  abstime/sparc-sun-solaris=abstime-solaris-1947
  abstime/.*-sco=abstime-solaris-1947
  abstime/.*-sysv5=abstime-solaris-1947
+ abstime/.*-nto=abstime-solaris-1947
+ time/.*-nto=time
  float4/.*-qnx=float4-exp-three-digits
+ float4/.*-nto=float4
  float8/.*-freebsd=float8-small-is-zero
  float8/i.86-.*-openbsd=float8-small-is-zero
  float8/i.86-.*-netbsd=float8-small-is-zero
  float8/.*-qnx=float8-exp-three-digits
+ float8/.*-nto=float8
  float8/alpha.*-dec-osf.*:cc=float8-fp-exception
  float8/i.86-pc-cygwin=float8-small-is-zero
  geometry/.*-bsdi=geometry-bsdi-precision
***************
*** 31,36 ****
--- 35,41 ----
  geometry/sparc.*-linux-gnu=geometry-solaris-precision
  geometry/alpha.*-linux-gnu=geometry-solaris-precision
  geometry/.*-beos=geometry-intel-beos
+ geometry/.*-nto=geometry-x86-pc-nto-qnx
  horology/.*-aix4=horology-no-DST-before-1970
  horology/.*-irix6=horology-no-DST-before-1970
  horology/alpha.*-dec-osf=horology-solaris-1947
***************
*** 40,48 ****
--- 45,57 ----
  horology/sparc-sun-solaris=horology-solaris-1947
  horology/.*-sysv5=horology-solaris-1947
  horology/.*-sco=horology-solaris-1947
+ horology/.*-nto=horology-solaris-1947
  int8/.*-qnx=int8-exp-three-digits
+ int8/.*-nto=int8
  tinterval/alpha.*-dec-osf=tinterval-solaris-1947
  tinterval/i.86-pc-solaris=tinterval-solaris-1947
  tinterval/sparc-sun-solaris=tinterval-solaris-1947
  tinterval/.*-sysv5=tinterval-solaris-1947
  tinterval/.*-sco=tinterval-solaris-1947
+ tinterval/.*-nto=tinterval-solaris-1947
+ interval/.*-nto=interval
