diff -rdupN postgresql-9.4beta2/INSTALL postgresql-9.4beta2_qnx/INSTALL
--- postgresql-9.4beta2/INSTALL	2014-07-21 15:24:46.000000000 -0400
+++ postgresql-9.4beta2_qnx/INSTALL	2014-07-29 15:40:50.000000000 -0400
@@ -1513,3 +1513,16 @@ make: *** [postgres] Error 1
 
    your DTrace installation is too old to handle probes in static
    functions. You need Solaris 10u4 or newer.
+     __________________________________________________________________
+
+QNX 6.5 and QNX 6.6
+
+   PostgreSQL can be built natively on QNX 6.5 SP1 using gcc.  
+   The executables will also run on QNX 6.6.
+   Changes required for QNX:
+   a. Replace all System V shared memory with POSIX named shared memory (posix_shmem.c).
+   b. port.h now includes a #ifdef __QNX__ section, where macros to retry 
+      interrupeted system calls (e.g., read, write) are defined.  
+	 This is needed because QNX does not support sigaction SA_RESTART.
+
+   ./configure --without-readline --disable-thread-safety
diff -rdupN postgresql-9.4beta2/configure postgresql-9.4beta2_qnx/configure
--- postgresql-9.4beta2/configure	2014-07-21 15:07:50.000000000 -0400
+++ postgresql-9.4beta2_qnx/configure	2014-07-29 16:06:00.000000000 -0400
@@ -2850,7 +2850,7 @@ case $host_os in
 dragonfly*) template=netbsd ;;
  freebsd*) template=freebsd ;;
     hpux*) template=hpux ;;
- linux*|gnu*|k*bsd*-gnu)
+ linux*|gnu*|k*bsd*-gnu|*qnx6*)
            template=linux ;;
    mingw*) template=win32 ;;
   netbsd*) template=netbsd ;;
@@ -13895,16 +13895,21 @@ fi
 
 
 # Select shared-memory implementation type.
-if test "$PORTNAME" != "win32"; then
+if test "$PORTNAME" = "win32"; then
 
-$as_echo "#define USE_SYSV_SHARED_MEMORY 1" >>confdefs.h
+$as_echo "#define USE_WIN32_SHARED_MEMORY 1" >>confdefs.h
 
-  SHMEM_IMPLEMENTATION="src/backend/port/sysv_shmem.c"
+  SHMEM_IMPLEMENTATION="src/backend/port/win32_shmem.c"
+elif test x"$USE_POSIX_SHARED_MEMORY" = x"1" ; then
+
+$as_echo "#define USE_POSIX_SHARED_MEMORY 1" >>confdefs.h
+
+  SHMEM_IMPLEMENTATION="src/backend/port/posix_shmem.c"
 else
 
-$as_echo "#define USE_WIN32_SHARED_MEMORY 1" >>confdefs.h
+$as_echo "#define USE_SYSV_SHARED_MEMORY 1" >>confdefs.h
 
-  SHMEM_IMPLEMENTATION="src/backend/port/win32_shmem.c"
+  SHMEM_IMPLEMENTATION="src/backend/port/sysv_shmem.c"
 fi
 
 # Select latch implementation type.
diff -rdupN postgresql-9.4beta2/configure.in postgresql-9.4beta2_qnx/configure.in
--- postgresql-9.4beta2/configure.in	2014-07-21 15:07:50.000000000 -0400
+++ postgresql-9.4beta2_qnx/configure.in	2014-07-29 16:07:38.000000000 -0400
@@ -64,7 +64,7 @@ case $host_os in
 dragonfly*) template=netbsd ;;
  freebsd*) template=freebsd ;;
     hpux*) template=hpux ;;
- linux*|gnu*|k*bsd*-gnu)
+ linux*|gnu*|k*bsd*-gnu|*qnx6*)
            template=linux ;;
    mingw*) template=win32 ;;
   netbsd*) template=netbsd ;;
@@ -1794,12 +1794,15 @@ fi
 
 
 # Select shared-memory implementation type.
-if test "$PORTNAME" != "win32"; then
-  AC_DEFINE(USE_SYSV_SHARED_MEMORY, 1, [Define to select SysV-style shared memory.])
-  SHMEM_IMPLEMENTATION="src/backend/port/sysv_shmem.c"
-else
+if test "$PORTNAME" = "win32"; then
   AC_DEFINE(USE_WIN32_SHARED_MEMORY, 1, [Define to select Win32-style shared memory.])
   SHMEM_IMPLEMENTATION="src/backend/port/win32_shmem.c"
+elif test x"$USE_POSIX_SHARED_MEMORY" = x"1" ; then
+  AC_DEFINE(USE_POSIX_SHARED_MEMORY, 1, [Define to select POSIX-style shared memory (QNX).])
+  SHMEM_IMPLEMENTATION="src/backend/port/posix_shmem.c"
+else
+  AC_DEFINE(USE_SYSV_SHARED_MEMORY, 1, [Define to select SysV-style shared memory.])
+  SHMEM_IMPLEMENTATION="src/backend/port/sysv_shmem.c"
 fi
 
 # Select latch implementation type.
diff -rdupN postgresql-9.4beta2/src/backend/Makefile postgresql-9.4beta2_qnx/src/backend/Makefile
--- postgresql-9.4beta2/src/backend/Makefile	2014-07-21 15:07:50.000000000 -0400
+++ postgresql-9.4beta2_qnx/src/backend/Makefile	2014-07-29 15:40:51.000000000 -0400
@@ -52,6 +52,7 @@ all: submake-libpgport submake-schemapg 
 ifneq ($(PORTNAME), cygwin)
 ifneq ($(PORTNAME), win32)
 ifneq ($(PORTNAME), aix)
+ifeq (,$(findstring qnx6, $(host_os)))
 
 postgres: $(OBJS)
 	$(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) $(call expand_subsys,$^) $(LIBS) -o $@
@@ -59,6 +60,7 @@ postgres: $(OBJS)
 endif
 endif
 endif
+endif
 
 ifeq ($(PORTNAME), cygwin)
 
@@ -105,6 +107,14 @@ endif
 
 endif # aix
 
+ifneq (,$(findstring qnx6, $(host_os)))
+
+postgres: $(OBJS)
+	$(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) $(call expand_subsys,$^) $(LIBS) -o $@
+	ldrel -S 3M $@
+
+endif # nto-qnx6.5.0
+
 # Update the commonly used headers before building the subdirectories
 $(SUBDIRS:%=%-recursive): $(top_builddir)/src/include/parser/gram.h $(top_builddir)/src/include/catalog/schemapg.h $(top_builddir)/src/include/utils/fmgroids.h $(top_builddir)/src/include/utils/errcodes.h $(top_builddir)/src/include/utils/probes.h
 
diff -rdupN postgresql-9.4beta2/src/backend/commands/dbcommands.c postgresql-9.4beta2_qnx/src/backend/commands/dbcommands.c
--- postgresql-9.4beta2/src/backend/commands/dbcommands.c	2014-07-21 15:07:50.000000000 -0400
+++ postgresql-9.4beta2_qnx/src/backend/commands/dbcommands.c	2014-07-29 15:40:51.000000000 -0400
@@ -348,7 +348,19 @@ createdb(const CreatedbStmt *stmt)
 	 * nor any indexes that depend on collation or ctype, so template0 can be
 	 * used as template for creating a database with any encoding or locale.
 	 */
-	if (strcmp(dbtemplate, "template0") != 0)
+	if ((strcmp(dbtemplate, "template0") != 0)
+#ifdef __QNX__
+	    /* KBAKER: QNX6 port has some problem here.  
+		* Regression test fails when copying template1 to template0 with msg below:
+		*     copying template1 to template0 FATAL:  22023: 
+		*     new LC_CTYPE (C;collate:POSIX;ctype:POSIX) is incompatible with 
+		*     the LC_CTYPE of the template database (POSIX;messages:C)
+		*
+		* For now QNX6 will live with the assumption/restriction that template1 will contain only ASCII
+	     */
+	    && (strcmp(dbtemplate, "template1") != 0) 
+#endif
+		)
 	{
 		if (encoding != src_encoding)
 			ereport(ERROR,
diff -rdupN postgresql-9.4beta2/src/backend/port/posix_shmem.c postgresql-9.4beta2_qnx/src/backend/port/posix_shmem.c
--- postgresql-9.4beta2/src/backend/port/posix_shmem.c	1969-12-31 19:00:00.000000000 -0500
+++ postgresql-9.4beta2_qnx/src/backend/port/posix_shmem.c	2014-07-29 17:27:43.000000000 -0400
@@ -0,0 +1,492 @@
+/*-------------------------------------------------------------------------
+ *
+ * posix_shmem.c
+ *	  Implement shared memory using POSIX (non-SysV) facilities
+ *
+ * These routines represent a fairly thin layer on top of POSIX (non-SysV) shared
+ * memory functionality. Originally created for QNX6 port.
+ *
+ * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ *	  src/backend/port/posix_shmem.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include <signal.h>
+#include <unistd.h>
+#include <sys/file.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#ifdef HAVE_SYS_IPC_H
+#include <sys/ipc.h>
+#endif
+#ifdef HAVE_SYS_SHM_H
+#include <sys/shm.h>
+#endif
+
+#include "postgres.h"
+#include "miscadmin.h"
+#include "storage/ipc.h"
+#include "storage/pg_shmem.h"
+
+
+typedef key_t IpcMemoryKey;		/* shared memory key passed to shmget(2) */
+typedef int IpcMemoryId;		/* shared memory ID returned by shmget(2) */
+
+#define IPCProtection	(0600)	/* access/modify by user only */
+
+#ifdef SHM_SHARE_MMU			/* use intimate shared memory on Solaris */
+#define PG_SHMAT_FLAGS			SHM_SHARE_MMU
+#else
+#define PG_SHMAT_FLAGS			0
+#endif
+
+/* Linux prefers MAP_ANONYMOUS, but the flag is called MAP_ANON on other systems. */
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS			MAP_ANON
+#endif
+
+/* BSD-derived systems have MAP_HASSEMAPHORE, but it's not present (or needed) on Linux. */
+#ifndef MAP_HASSEMAPHORE
+#define MAP_HASSEMAPHORE		0
+#endif
+
+#define PG_MMAP_FLAGS			(MAP_SHARED|MAP_ANONYMOUS|MAP_HASSEMAPHORE)
+
+/* Some really old systems don't define MAP_FAILED. */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *) -1)
+#endif
+
+
+/* Variables to remember details for the USED named shared memory segment (small) */
+#define USED_SHMEM_SEG_NAME_MAX 100
+static char   UsedShmemSegName[USED_SHMEM_SEG_NAME_MAX];
+static Size   UsedShmemSegSize= 0;
+unsigned long UsedShmemSegID = 0;
+void         *UsedShmemSegAddr = NULL;
+
+/* Variables to remember details for the MAIN anonymous shared memory segment (large) */
+static Size AnonymousShmemSize;
+static void *AnonymousShmem;
+
+static void *InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size);
+static void IpcMemoryDetach(int status, Datum shmaddr);
+static void IpcMemoryDelete(int status, Datum shmId);
+static PGShmemHeader *PGSharedMemoryAttach(IpcMemoryKey key,
+					 IpcMemoryId *shmid);
+
+
+static char *
+keytoname(key_t key, char *name)
+{
+	/* POSIX shared memory segment names which start with "/" are system-wide (across processes) */
+     sprintf(name, "/PgShmHdr%x", key);
+	     return name;
+}
+
+/*
+ *	InternalIpcMemoryCreate(memKey, size)
+ *
+ * Attempt to create a new shared memory segment with the specified key.
+ * Will fail (return NULL) if such a segment already exists.  If successful,
+ * attach the segment to the current process and return its attached address.
+ * On success, callbacks are registered with on_shmem_exit to detach and
+ * delete the segment when on_shmem_exit is called.
+ *
+ * If we fail with a failure code other than collision-with-existing-segment,
+ * print out an error and abort.  Other types of errors are not recoverable.
+ */
+static void *
+InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
+{
+	IpcMemoryId shmid;
+	void	   *memAddress;
+
+	keytoname(memKey, UsedShmemSegName);
+
+	shmid = shm_open(UsedShmemSegName, (O_CREAT | O_EXCL | O_RDWR),  0);
+
+	if (shmid < 0)
+	{
+		int			shmopen_errno = errno;
+
+		/*
+		 * Fail quietly if error indicates a collision with existing segment.
+		 * One would expect EEXIST, given that we said IPC_EXCL, but perhaps
+		 * we could get a permission violation instead?  Also, EIDRM might
+		 * occur if an old seg is slated for destruction but not gone yet.
+		 */
+		if (shmopen_errno == EEXIST || shmopen_errno == EACCES
+#ifdef EIDRM
+			|| shmopen_errno == EIDRM
+#endif
+			)
+			return NULL;
+
+
+		/*
+		 * Else complain and abort.
+		 */
+		errno = shmopen_errno;
+
+			ereport(FATAL,
+					(errmsg("could not map used shared memory (%s): %m", UsedShmemSegName),
+					 (shmopen_errno == ENOMEM) ?
+				errhint("This error usually means that PostgreSQL's request "
+					 "for a shared memory segment exceeded available memory "
+					  "or swap space. To reduce the request size (currently "
+					  "%lu bytes), reduce PostgreSQL's shared memory usage, "
+						"perhaps by reducing shared_buffers or "
+						"max_connections.",
+						(unsigned long) size) : 0));
+
+			return NULL;
+	}
+
+	/* we need to set the size of the shared memory segment after creation */
+	if (ftruncate(shmid, size) < 0)
+		elog(FATAL, "ftruncate(shmid=%d, size=%lu) failed: %m", shmid, (unsigned long) size);
+
+	/* Register on-exit routine to delete the new segment */
+	on_shmem_exit(IpcMemoryDelete, Int32GetDatum(shmid));
+
+	/* OK, should be able to attach to the segment */
+	memAddress = mmap(NULL, size, (PROT_READ|PROT_WRITE), MAP_SHARED, shmid, 0);
+
+	/* remember the USED shared memory info so we can unmap and unlink (delete) it upon exit */
+	UsedShmemSegID = shmid;
+	UsedShmemSegAddr = memAddress;
+	UsedShmemSegSize = size;
+
+	if (memAddress == (void *) -1)
+		//TODO: fix elog
+		elog(FATAL, "mmap(id=%d, name=%s, size=%lu) failed: %m", shmid, UsedShmemSegName, (unsigned long)UsedShmemSegSize);
+
+	/* Register on-exit routine to detach new segment before deleting */
+	on_shmem_exit(IpcMemoryDetach, PointerGetDatum(memAddress));
+
+	/*
+	 * Store shmem key and ID in data directory lockfile.  Format to try to
+	 * keep it the same length always (trailing junk in the lockfile won't
+	 * hurt, but might confuse humans).
+	 */
+	{
+		char		line[64];
+
+		sprintf(line, "%9lu %9lu",
+				(unsigned long) memKey, (unsigned long) shmid);
+		AddToDataDirLockFile(LOCK_FILE_LINE_SHMEM_KEY, line);
+	}
+
+	return memAddress;
+}
+
+/*										from process' address spaceq		*/
+/*	(called as an on_shmem_exit callback, hence funny argument list)		*/
+/****************************************************************************/
+static void
+IpcMemoryDetach(int status, Datum shmaddr)
+{
+	/* Release USED shared memory block, if any. */
+	if (UsedShmemSegAddr != NULL
+		&& munmap(UsedShmemSegAddr, UsedShmemSegSize) < 0)
+		elog(LOG, "munmap(%p) failed: %m", UsedShmemSegAddr);
+	/* Release anonymous shared memory block, if any. */
+	if (AnonymousShmem != NULL
+		&& munmap(AnonymousShmem, AnonymousShmemSize) < 0)
+		elog(LOG, "munmap(%p) failed: %m", AnonymousShmem);
+}
+
+/****************************************************************************/
+/*	IpcMemoryDelete(status, shmId)		deletes a shared memory segment		*/
+/*	(called as an on_shmem_exit callback, hence funny argument list)		*/
+/****************************************************************************/
+static void
+IpcMemoryDelete(int status, Datum shmId)
+{
+	
+	if (shm_unlink(UsedShmemSegName) < 0)
+		elog(LOG, "shm_unlink(%s) failed: %m",
+			 UsedShmemSegName);
+}
+
+/*
+ * PGSharedMemoryIsInUse
+ *
+ * Is a previously-existing shmem segment still existing and in use?
+ *
+ * The point of this exercise is to detect the case where a prior postmaster
+ * crashed, but it left child backends that are still running.	Therefore
+ * we only care about shmem segments that are associated with the intended
+ * DataDir.  This is an important consideration since accidental matches of
+ * shmem segment IDs are reasonably common.
+ */
+bool
+PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2)
+{
+    /* TODO: Enhance for QNX? */
+	return false;
+}
+
+
+/*
+ * PGSharedMemoryCreate
+ *
+ * Create a shared memory segment of the given size and initialize its
+ * standard header.  Also, register an on_shmem_exit callback to release
+ * the storage.
+ *
+ * Dead Postgres segments are recycled if found, but we do not fail upon
+ * collision with non-Postgres shmem segments.	The idea here is to detect and
+ * re-use keys that may have been assigned by a crashed postmaster or backend.
+ *
+ * makePrivate means to always create a new segment, rather than attach to
+ * or recycle any existing segment.
+ *
+ * The port number is passed for possible use as a key (for SysV, we use
+ * it to generate the starting shmem key).	In a standalone backend,
+ * zero will be passed.
+ */
+PGShmemHeader *
+PGSharedMemoryCreate(Size size, bool makePrivate, int port,
+/* KBAKER: added for 9.4beta */ PGShmemHeader **shim
+)
+{
+	IpcMemoryKey NextShmemSegID;
+	void	   *memAddress;
+	PGShmemHeader *hdr;
+	struct stat statbuf;
+	Size		sysvsize = size;
+
+	/* Room for a header? */
+	Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
+
+	/*
+	 * As of PostgreSQL 9.3, we normally allocate only a very small amount of
+	 * System V shared memory, and only for the purposes of providing an
+	 * interlock to protect the data directory.  The real shared memory block
+	 * is allocated using mmap().  This works around the problem that many
+	 * systems have very low limits on the amount of System V shared memory
+	 * that can be allocated.  Even a limit of a few megabytes will be enough
+	 * to run many copies of PostgreSQL without needing to adjust system
+	 * settings.
+	 *
+	 * However, we disable this logic in the EXEC_BACKEND case, and fall back
+	 * to the old method of allocating the entire segment using System V
+	 * shared memory, because there's no way to attach an mmap'd segment to a
+	 * process after exec().  Since EXEC_BACKEND is intended only for
+	 * developer use, this shouldn't be a big problem.
+	 */
+#ifndef EXEC_BACKEND
+	{
+		long		pagesize = sysconf(_SC_PAGE_SIZE);
+
+		/*
+		 * Ensure request size is a multiple of pagesize.
+		 *
+		 * pagesize will, for practical purposes, always be a power of two.
+		 * But just in case it isn't, we do it this way instead of using
+		 * TYPEALIGN().
+		 */
+		if (pagesize > 0 && size % pagesize != 0)
+			size += pagesize - (size % pagesize);
+
+		/*
+		 * We assume that no one will attempt to run PostgreSQL 9.3 or later
+		 * on systems that are ancient enough that anonymous shared memory is
+		 * not supported, such as pre-2.4 versions of Linux.  If that turns
+		 * out to be false, we might need to add a run-time test here and do
+		 * this only if the running kernel supports it.
+		 */
+		AnonymousShmem = mmap(NULL, size, PROT_READ | PROT_WRITE, PG_MMAP_FLAGS,
+							  -1, 0);
+		if (AnonymousShmem == MAP_FAILED)
+		{
+			int		saved_errno = errno;
+
+			ereport(FATAL,
+					(errmsg("could not map anonymous shared memory: %m"),
+					 (saved_errno == ENOMEM) ?
+				errhint("This error usually means that PostgreSQL's request "
+					 "for a shared memory segment exceeded available memory "
+					  "or swap space. To reduce the request size (currently "
+					  "%lu bytes), reduce PostgreSQL's shared memory usage, "
+						"perhaps by reducing shared_buffers or "
+						"max_connections.",
+						(unsigned long) size) : 0));
+		}
+		AnonymousShmemSize = size;
+
+		/* Now we need only allocate a minimal-sized SysV shmem block. */
+		sysvsize = sizeof(PGShmemHeader);
+
+
+	}
+#endif
+
+	/* Make sure PGSharedMemoryAttach doesn't fail without need */
+	UsedShmemSegAddr = NULL;
+
+	/* Loop till we find a free IPC key */
+	NextShmemSegID = port * 1000;
+
+	for (NextShmemSegID++;; NextShmemSegID++)
+	{
+		/* Try to create new segment */
+		memAddress = InternalIpcMemoryCreate(NextShmemSegID, sysvsize);
+		if (memAddress)
+			break;				/* successful create and attach */
+
+		/*
+		 * Can only get here if some other process managed to create the same
+		 * shmem key before we did.  Let him have that one, loop around to try
+		 * next key.
+		 */
+	}
+
+	/*
+	 * 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;
+	hdr->dsm_control = 0; /* KBAKER: Added for 9.4beta */
+
+	/* Fill in the data directory ID info, too */
+	if (stat(DataDir, &statbuf) < 0)
+		ereport(FATAL,
+				(errcode_for_file_access(),
+				 errmsg("could not stat data directory \"%s\": %m",
+						DataDir)));
+	hdr->device = statbuf.st_dev;
+	hdr->inode = statbuf.st_ino;
+
+	/*
+	 * Initialize space allocation status for segment.
+	 */
+	hdr->totalsize = size;
+	hdr->freeoffset = MAXALIGN(sizeof(PGShmemHeader));
+	*shim = hdr; /* KBAKER: Added for 9.4beta */
+
+	/* Save info for possible future use */
+	UsedShmemSegAddr = memAddress;
+	UsedShmemSegID = (unsigned long) NextShmemSegID;
+
+	/*
+	 * If AnonymousShmem is NULL here, then we're not using anonymous shared
+	 * memory, and should return a pointer to the System V shared memory
+	 * block. Otherwise, the System V shared memory block is only a shim, and
+	 * we must return a pointer to the real block.
+	 */
+	if (AnonymousShmem == NULL)
+		return hdr;
+	memcpy(AnonymousShmem, hdr, sizeof(PGShmemHeader));
+	return (PGShmemHeader *) AnonymousShmem;
+}
+
+#ifdef EXEC_BACKEND
+
+/*
+ * PGSharedMemoryReAttach
+ *
+ * Re-attach to an already existing shared memory segment.	In the non
+ * EXEC_BACKEND case this is not used, because postmaster children inherit
+ * the shared memory segment attachment via fork().
+ *
+ * UsedShmemSegID and UsedShmemSegAddr are implicit parameters to this
+ * routine.  The caller must have already restored them to the postmaster's
+ * values.
+ */
+void
+PGSharedMemoryReAttach(void)
+{
+	IpcMemoryId shmid;
+	void	   *hdr;
+	void	   *origUsedShmemSegAddr = UsedShmemSegAddr;
+
+	Assert(UsedShmemSegAddr != NULL);
+	Assert(IsUnderPostmaster);
+
+#ifdef __CYGWIN__
+	/* cygipc (currently) appears to not detach on exec. */
+	PGSharedMemoryDetach();
+	UsedShmemSegAddr = origUsedShmemSegAddr;
+#endif
+
+	elog(DEBUG3, "attaching to %p", UsedShmemSegAddr);
+	hdr = (void *) PGSharedMemoryAttach((IpcMemoryKey) UsedShmemSegID, &shmid);
+	if (hdr == NULL)
+		elog(FATAL, "could not reattach to shared memory (key=%d, addr=%p): %m",
+			 (int) UsedShmemSegID, UsedShmemSegAddr);
+	if (hdr != origUsedShmemSegAddr)
+		elog(FATAL, "reattaching to shared memory returned unexpected address (got %p, expected %p)",
+			 hdr, origUsedShmemSegAddr);
+
+	UsedShmemSegAddr = hdr;		/* probably redundant */
+}
+#endif   /* EXEC_BACKEND */
+
+/*
+ * PGSharedMemoryDetach
+ *
+ * Detach from the shared memory segment, if still attached.  This is not
+ * intended for use by the process that originally created the segment
+ * (it will have an on_shmem_exit callback registered to do that).	Rather,
+ * this is for subprocesses that have inherited an attachment and want to
+ * get rid of it.
+ */
+void
+PGSharedMemoryDetach(void)
+{
+	if (UsedShmemSegAddr != NULL
+		&& munmap(UsedShmemSegAddr, UsedShmemSegSize) < 0)
+	{
+		elog(LOG, "used munmap(%p) failed: %m", UsedShmemSegAddr);
+	}
+	else
+	{
+		UsedShmemSegAddr = NULL;
+	}
+
+	/* Release anonymous shared memory block, if any. */
+	if (AnonymousShmem != NULL
+		&& munmap(AnonymousShmem, AnonymousShmemSize) < 0)
+		elog(LOG, "anonymous munmap(%p) failed: %m", AnonymousShmem);
+}
+
+
+/*
+ * Attach to shared memory and make sure it has a Postgres header
+ *
+ * Returns attach address if OK, else NULL
+ */
+static PGShmemHeader *
+PGSharedMemoryAttach(IpcMemoryKey key, IpcMemoryId *shmid)
+{
+	PGShmemHeader *hdr;
+
+	keytoname(key, UsedShmemSegName);
+
+	*shmid = shm_open(UsedShmemSegName, (O_RDWR),  IPCProtection);
+	if (*shmid == -1)
+		return NULL;
+
+	hdr = mmap(UsedShmemSegAddr, UsedShmemSegSize, (PROT_READ|PROT_WRITE), MAP_SHARED, *shmid, 0);
+
+	if (hdr == (PGShmemHeader *) -1)
+		return NULL;			/* failed: must be some other app's */
+
+	if (hdr->magic != PGShmemMagic)
+	{
+		munmap(UsedShmemSegName, UsedShmemSegSize);
+		return NULL;			/* segment belongs to a non-Postgres app */
+	}
+
+	return hdr;
+}
diff -rdupN postgresql-9.4beta2/src/backend/replication/logical/logical.c postgresql-9.4beta2_qnx/src/backend/replication/logical/logical.c
--- postgresql-9.4beta2/src/backend/replication/logical/logical.c	2014-07-21 15:07:50.000000000 -0400
+++ postgresql-9.4beta2_qnx/src/backend/replication/logical/logical.c	2014-07-29 16:16:04.000000000 -0400
@@ -168,7 +168,7 @@ StartupDecodingContext(List *output_plug
 
 	ctx->out = makeStringInfo();
 	ctx->prepare_write = prepare_write;
-	ctx->write = do_write;
+	ctx->do_write = do_write;
 
 	ctx->output_plugin_options = output_plugin_options;
 
@@ -510,7 +510,7 @@ OutputPluginWrite(struct LogicalDecoding
 	if (!ctx->prepared_write)
 		elog(ERROR, "OutputPluginPrepareWrite needs to be called before OutputPluginWrite");
 
-	ctx->write(ctx, ctx->write_location, ctx->write_xid, last_write);
+	ctx->do_write(ctx, ctx->write_location, ctx->write_xid, last_write);
 	ctx->prepared_write = false;
 }
 
diff -rdupN postgresql-9.4beta2/src/backend/utils/error/elog.c postgresql-9.4beta2_qnx/src/backend/utils/error/elog.c
--- postgresql-9.4beta2/src/backend/utils/error/elog.c	2014-07-21 15:07:50.000000000 -0400
+++ postgresql-9.4beta2_qnx/src/backend/utils/error/elog.c	2014-07-29 15:40:51.000000000 -0400
@@ -3326,8 +3326,10 @@ get_errno_symbol(int errnum)
 			return "EAGAIN";
 #endif
 #ifdef EALREADY
+#if !defined(__QNX__)
 		case EALREADY:
 			return "EALREADY";
+#endif /* !defined(__QNX__) */
 #endif
 		case EBADF:
 			return "EBADF";
diff -rdupN postgresql-9.4beta2/src/backend/utils/misc/postgresql.conf.sample postgresql-9.4beta2_qnx/src/backend/utils/misc/postgresql.conf.sample
--- postgresql-9.4beta2/src/backend/utils/misc/postgresql.conf.sample	2014-07-21 15:07:50.000000000 -0400
+++ postgresql-9.4beta2_qnx/src/backend/utils/misc/postgresql.conf.sample	2014-07-29 16:56:42.000000000 -0400
@@ -408,6 +408,7 @@
 #log_disconnections = off
 #log_duration = off
 #log_error_verbosity = default		# terse, default, or verbose messages
+#log_error_verbosity = verbose		# terse, default, or verbose messages
 #log_hostname = off
 #log_line_prefix = ''			# special values:
 					#   %a = application name
diff -rdupN postgresql-9.4beta2/src/include/port.h postgresql-9.4beta2_qnx/src/include/port.h
--- postgresql-9.4beta2/src/include/port.h	2014-07-21 15:07:50.000000000 -0400
+++ postgresql-9.4beta2_qnx/src/include/port.h	2014-07-29 16:35:33.000000000 -0400
@@ -479,4 +479,97 @@ extern char *escape_single_quotes_ascii(
 /* port/wait_error.c */
 extern char *wait_result_to_str(int exit_status);
 
+
+#if defined(__QNX__)
+
+#include <sys/mman.h>
+#include <sys/select.h>
+#include <fcntl.h>
+
+/* QNX does not support sigaction SA_RESTART. We must retry interrupted calls (EINTR) */
+
+/* Helper macros, used to build our retry macros */
+#define PG_RETRY_EINTR3(exp,val,type) ({ type _tmp_rc; do _tmp_rc = (exp); while (_tmp_rc == (val) && errno == EINTR); _tmp_rc; })
+#define PG_RETRY_EINTR(exp) PG_RETRY_EINTR3(exp,-1L,long int)
+#define PG_RETRY_EINTR_FILE(exp) PG_RETRY_EINTR3(exp,NULL,FILE *)
+
+/* override calls known to return EINTR when interrupted */
+#define close(a) PG_RETRY_EINTR(close(a))
+#define fclose(a) PG_RETRY_EINTR(fclose(a))
+#define fdopen(a,b) PG_RETRY_EINTR_FILE(fdopen(a,b))
+#define fopen(a,b) PG_RETRY_EINTR_FILE(fopen(a,b))
+#define freopen(a,b,c) PG_RETRY_EINTR_FILE(freopen(a,b,c))
+#define fseek(a,b,c) PG_RETRY_EINTR(fseek(a,b,c))
+#define fseeko(a,b,c) PG_RETRY_EINTR(fseeko(a,b,c))
+#define ftruncate(a,b) PG_RETRY_EINTR(ftruncate(a,b))
+#define lseek(a,b,c) PG_RETRY_EINTR(lseek(a,b,c))
+#define open(a,b,...) ({ int _tmp_rc; do _tmp_rc = open(a,b,##__VA_ARGS__); while (_tmp_rc == (-1) && errno == EINTR); _tmp_rc; })
+#define shm_open(a,b,c) PG_RETRY_EINTR(shm_open(a,b,c))
+#define stat(a,b) PG_RETRY_EINTR(stat(a,b))
+#define unlink(a) PG_RETRY_EINTR(unlink(a))
+
+/* reads and writes can be partial, and not always return -1 on failure. retry these partials. */
+#define read(fildes,buf,nbytes) ({ \
+      ssize_t _tmp_bytes_completed = 0; \
+      while (_tmp_bytes_completed < (nbytes)) { \
+          ssize_t _tmp_rc = read(fildes, (char *)(buf) + _tmp_bytes_completed, (nbytes) - _tmp_bytes_completed); \
+          if (_tmp_rc <= 0) { \
+              if (errno == EINTR) continue; \
+		    if (_tmp_bytes_completed == 0) _tmp_bytes_completed = _tmp_rc; \
+              break; \
+          } \
+		else { \
+              _tmp_bytes_completed += _tmp_rc; \
+          } \
+      } \
+      _tmp_bytes_completed; \
+    })
+#define fread(buf,size,num,fp) ({ \
+      size_t _tmp_elements_completed = 0; \
+      while (_tmp_elements_completed < (num)) { \
+          size_t _tmp_rc = fread((char *)(buf) + (_tmp_elements_completed * (size)), size, (num) - _tmp_elements_completed, fp); \
+          if (_tmp_rc <= 0) { \
+              if (errno == EINTR) continue; \
+		    if (_tmp_elements_completed == 0) _tmp_elements_completed = _tmp_rc; \
+              break; \
+          } \
+		else { \
+              _tmp_elements_completed += _tmp_rc; \
+          } \
+      } \
+      _tmp_elements_completed; \
+    })
+#define write(fildes,buf,nbytes) ({ \
+      ssize_t _tmp_bytes_completed = 0; \
+      while (_tmp_bytes_completed < (nbytes)) { \
+          ssize_t _tmp_rc = write(fildes, (char *)(buf) + _tmp_bytes_completed, (nbytes) - _tmp_bytes_completed); \
+          if (_tmp_rc <= 0) { \
+              if (errno == EINTR) continue; \
+		    if (_tmp_bytes_completed == 0) _tmp_bytes_completed = _tmp_rc; \
+              break; \
+          } \
+		else { \
+              _tmp_bytes_completed += _tmp_rc; \
+          } \
+      } \
+      _tmp_bytes_completed; \
+    })
+#define fwrite(buf,size,num,fp) ({ \
+      size_t _tmp_elements_completed = 0; \
+      while (_tmp_elements_completed < (num)) { \
+          size_t _tmp_rc = fwrite((char *)(buf) + (_tmp_elements_completed * (size)), size, (num) - _tmp_elements_completed, fp); \
+          if (_tmp_rc <= 0) { \
+              if (errno == EINTR) continue; \
+		    if (_tmp_elements_completed == 0) _tmp_elements_completed = _tmp_rc; \
+              break; \
+          } \
+		else { \
+              _tmp_elements_completed += _tmp_rc; \
+          } \
+      } \
+      _tmp_elements_completed; \
+    })
+
+#endif	/* __QNX__ */
+
 #endif   /* PG_PORT_H */
diff -rdupN postgresql-9.4beta2/src/include/replication/logical.h postgresql-9.4beta2_qnx/src/include/replication/logical.h
--- postgresql-9.4beta2/src/include/replication/logical.h	2014-07-21 15:07:50.000000000 -0400
+++ postgresql-9.4beta2_qnx/src/include/replication/logical.h	2014-07-29 16:15:08.000000000 -0400
@@ -49,7 +49,7 @@ typedef struct LogicalDecodingContext
 	 * User-Provided callback for writing/streaming out data.
 	 */
 	LogicalOutputPluginWriterPrepareWrite prepare_write;
-	LogicalOutputPluginWriterWrite write;
+	LogicalOutputPluginWriterWrite do_write;
 
 	/*
 	 * Output buffer.
diff -rdupN postgresql-9.4beta2/src/include/storage/dsm_impl.h postgresql-9.4beta2_qnx/src/include/storage/dsm_impl.h
--- postgresql-9.4beta2/src/include/storage/dsm_impl.h	2014-07-21 15:07:50.000000000 -0400
+++ postgresql-9.4beta2_qnx/src/include/storage/dsm_impl.h	2014-07-29 16:27:14.000000000 -0400
@@ -32,10 +32,14 @@
 #define USE_DSM_POSIX
 #define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE		DSM_IMPL_POSIX
 #endif
+
+#if !defined(__QNX__)
 #define USE_DSM_SYSV
 #ifndef DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE
 #define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE		DSM_IMPL_SYSV
 #endif
+#endif /* !defined(__QNX__) */
+
 #define USE_DSM_MMAP
 #endif
 
diff -rdupN postgresql-9.4beta2/src/template/linux postgresql-9.4beta2_qnx/src/template/linux
--- postgresql-9.4beta2/src/template/linux	2014-07-21 15:07:50.000000000 -0400
+++ postgresql-9.4beta2_qnx/src/template/linux	2014-07-29 15:40:51.000000000 -0400
@@ -28,3 +28,10 @@ if test "$SUN_STUDIO_CC" = "yes" ; then
     ;;
   esac
 fi
+
+case $host_os in
+  *qnx6*)
+    USE_UNNAMED_POSIX_SEMAPHORES=1
+    USE_POSIX_SHARED_MEMORY=1
+    ;;
+esac
diff -rdupN postgresql-9.4beta2/src/timezone/private.h postgresql-9.4beta2_qnx/src/timezone/private.h
--- postgresql-9.4beta2/src/timezone/private.h	2014-07-21 15:07:50.000000000 -0400
+++ postgresql-9.4beta2_qnx/src/timezone/private.h	2014-07-29 15:40:52.000000000 -0400
@@ -40,7 +40,10 @@
  */
 
 #ifndef remove
+
+#ifndef __QNX__
 extern int	unlink(const char *filename);
+#endif
 
 #define remove	unlink
 #endif   /* !defined remove */
