From 780cb66c8982c84e6f3e58b342b77105ae2912a1 Mon Sep 17 00:00:00 2001
From: Mark Hellegers <mark@firedisk.net>
Date: Tue, 10 Feb 2015 23:37:01 +0100
Subject: [PATCH] Changes to make Postgresql run on Haiku

---
 configure                               |  27 +++++-
 configure.in                            |   8 +-
 src/Makefile.global.in                  |  14 ++++
 src/Makefile.shlib                      |  15 ++++
 src/backend/catalog/dependency.c        |   2 +-
 src/backend/executor/nodeMergeAppend.c  |   2 +-
 src/backend/main/main.c                 |   2 +
 src/backend/port/Makefile               |   3 +
 src/backend/port/dynloader/haiku.c      |   6 ++
 src/backend/port/dynloader/haiku.h      |  33 ++++++++
 src/backend/port/haiku/Makefile         |  14 ++++
 src/backend/port/haiku/shm.c            | 144 ++++++++++++++++++++++++++++++++
 src/backend/tcop/postgres.c             |   2 +-
 src/backend/tsearch/ts_parse.c          |   4 +-
 src/backend/utils/adt/tsquery_cleanup.c |   4 +-
 src/bin/initdb/initdb.c                 |   4 +
 src/bin/pg_basebackup/pg_basebackup.c   |   1 +
 src/bin/pg_ctl/pg_ctl.c                 |   2 +
 src/bin/pg_dump/parallel.c              |   1 +
 src/include/c.h                         |   6 ++
 src/include/pg_config_manual.h          |   2 +-
 src/include/port/haiku.h                |  16 ++++
 src/interfaces/ecpg/pgtypeslib/Makefile |   2 +
 src/makefiles/Makefile.haiku            |   7 ++
 src/template/haiku                      |   0
 25 files changed, 310 insertions(+), 11 deletions(-)
 create mode 100644 src/backend/port/dynloader/haiku.c
 create mode 100644 src/backend/port/dynloader/haiku.h
 create mode 100644 src/backend/port/haiku/Makefile
 create mode 100644 src/backend/port/haiku/shm.c
 create mode 100644 src/include/port/haiku.h
 create mode 100644 src/makefiles/Makefile.haiku
 create mode 100644 src/template/haiku

diff --git a/configure b/configure
index bedd093..fe55a67 100755
--- a/configure
+++ b/configure
@@ -2191,6 +2191,7 @@ case $host_os in
 dragonfly*) template=netbsd ;;
  freebsd*) template=freebsd ;;
     hpux*) template=hpux ;;
+    haiku*) template=haiku ;;
     irix*) template=irix ;;
  linux*|gnu*|k*bsd*-gnu)
            template=linux ;;
@@ -7965,7 +7966,7 @@ return socket ();
   return 0;
 }
 _ACEOF
-for ac_lib in '' socket wsock32; do
+for ac_lib in '' socket wsock32 network; do
   if test -z "$ac_lib"; then
     ac_res="none required"
   else
@@ -28122,6 +28123,9 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <stdio.h>
+#ifdef __HAIKU__
+#include <SupportDefs.h>
+#endif
 
 int
 main ()
@@ -28157,6 +28161,9 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <stdio.h>
+#ifdef __HAIKU__
+#include <SupportDefs.h>
+#endif
 
 int
 main ()
@@ -28226,6 +28233,9 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <stdio.h>
+#ifdef __HAIKU__
+#include <SupportDefs.h>
+#endif
 
 int
 main ()
@@ -28261,6 +28271,9 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <stdio.h>
+#ifdef __HAIKU__
+#include <SupportDefs.h>
+#endif
 
 int
 main ()
@@ -28330,6 +28343,9 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <stdio.h>
+#ifdef __HAIKU__
+#include <SupportDefs.h>
+#endif
 
 int
 main ()
@@ -28365,6 +28381,9 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <stdio.h>
+#ifdef __HAIKU__
+#include <SupportDefs.h>
+#endif
 
 int
 main ()
@@ -28434,6 +28453,9 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <stdio.h>
+#ifdef __HAIKU__
+#include <SupportDefs.h>
+#endif
 
 int
 main ()
@@ -28469,6 +28491,9 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include <stdio.h>
+#ifdef __HAIKU__
+#include <SupportDefs.h>
+#endif
 
 int
 main ()
diff --git a/configure.in b/configure.in
index 04d1092..6bd0ac6 100644
--- a/configure.in
+++ b/configure.in
@@ -60,6 +60,7 @@ case $host_os in
 dragonfly*) template=netbsd ;;
  freebsd*) template=freebsd ;;
     hpux*) template=hpux ;;
+    haiku*) template=haiku ;;
     irix*) template=irix ;;
  linux*|gnu*|k*bsd*-gnu)
            template=linux ;;
@@ -873,7 +874,7 @@ fi
 AC_CHECK_LIB(m, main)
 AC_SEARCH_LIBS(setproctitle, util)
 AC_SEARCH_LIBS(dlopen, dl)
-AC_SEARCH_LIBS(socket, [socket wsock32])
+AC_SEARCH_LIBS(socket, [socket wsock32 network])
 AC_SEARCH_LIBS(shl_load, dld)
 # We only use libld in port/dynloader/aix.c
 case $host_os in
@@ -1732,7 +1733,10 @@ AC_DEFINE_UNQUOTED(MAXIMUM_ALIGNOF, $MAX_ALIGNOF, [Define as the maximum alignme
 # Some platforms predefine the types int8, int16, etc.  Only check
 # a (hopefully) representative subset.
 AC_CHECK_TYPES([int8, uint8, int64, uint64], [], [],
-[#include <stdio.h>])
+[#include <stdio.h>
+#ifdef __HAIKU__
+#include <SupportDefs.h>
+#endif])
 
 # We also check for sig_atomic_t, which *should* be defined per ANSI
 # C, but is missing on some old platforms.
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 8bfb77d..c81ad3e 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -511,6 +511,20 @@ endif
 # Not really standard libc functions, used by the backend.
 TAS         = @TAS@
 
+##########################################################################
+#
+# Packaging on Haiku puts everything in a postgresql directory
+# Force the override into postgresql directory
+
+ifndef PGXS
+ifeq ($(PORTNAME), haiku)
+override datadir := $(datadir)/postgresql
+override sysconfdir := $(sysconfdir)/postgresql
+override pkglibdir := $(pkglibdir)/postgresql
+override pkgincludedir := $(pkgincludedir)/postgresql
+override docdir := $(docdir)/postgresql
+endif
+endif
 
 ##########################################################################
 #
diff --git a/src/Makefile.shlib b/src/Makefile.shlib
index ac09537..f8e5272 100644
--- a/src/Makefile.shlib
+++ b/src/Makefile.shlib
@@ -295,6 +295,12 @@ ifeq ($(PORTNAME), win32)
   haslibarule   = yes
 endif
 
+ifeq ($(PORTNAME), haiku)
+  ifdef SO_MAJOR_VERSION
+    shlib		= lib$(NAME)$(DLSUFFIX)
+  endif
+  LINK.shared = $(CC) -shared
+endif
 
 
 ##
@@ -322,6 +328,7 @@ endif #haslibarule
 
 
 ifeq (,$(filter cygwin win32,$(PORTNAME)))
+ifneq ($(PORTNAME), haiku)
 ifneq ($(PORTNAME), aix)
 
 # Normal case
@@ -366,6 +373,14 @@ $(shlib) $(stlib): $(OBJS) | $(SHLIB_PREREQS)
 
 endif # PORTNAME == aix
 
+else # PORTNAME == haiku
+
+# Haiku case
+$(shlib): $(OBJS)
+	$(LINK.shared) $(LDFLAGS_SL) -o $@ $(OBJS) $(SHLIB_LINK)
+
+endif # PORTNAME == haiku
+
 else # PORTNAME == cygwin || PORTNAME == win32
 
 # Cygwin or Win32 case
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 01024f8..c112664 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -1006,7 +1006,7 @@ reportDependentObjects(const ObjectAddresses *targetObjects,
  * *depRel is the already-open pg_depend relation.
  */
 static void
-deleteOneObject(const ObjectAddress *object, Relation *depRel, int flags)
+deleteOneObject(const ObjectAddress *object, Relation *depRel, int32 flags)
 {
 	ScanKeyData key[3];
 	int			nkeys;
diff --git a/src/backend/executor/nodeMergeAppend.c b/src/backend/executor/nodeMergeAppend.c
index eb108e5..056049a 100644
--- a/src/backend/executor/nodeMergeAppend.c
+++ b/src/backend/executor/nodeMergeAppend.c
@@ -50,7 +50,7 @@
  */
 typedef int32 SlotNumber;
 
-static int	heap_compare_slots(Datum a, Datum b, void *arg);
+static int32	heap_compare_slots(Datum a, Datum b, void *arg);
 
 
 /* ----------------------------------------------------------------
diff --git a/src/backend/main/main.c b/src/backend/main/main.c
index d92883c..5de3ad7 100644
--- a/src/backend/main/main.c
+++ b/src/backend/main/main.c
@@ -362,6 +362,7 @@ help(const char *progname)
 static void
 check_root(const char *progname)
 {
+#ifndef __HAIKU__
 #ifndef WIN32
 	if (geteuid() == 0)
 	{
@@ -397,6 +398,7 @@ check_root(const char *progname)
 		exit(1);
 	}
 #endif   /* WIN32 */
+#endif   /* __HAIKU__ */
 }
 
 
diff --git a/src/backend/port/Makefile b/src/backend/port/Makefile
index 8ebb6d5..ee12631 100644
--- a/src/backend/port/Makefile
+++ b/src/backend/port/Makefile
@@ -29,6 +29,9 @@ endif
 ifeq ($(PORTNAME), win32)
 SUBDIRS += win32
 endif
+ifeq ($(PORTNAME), haiku)
+SUBDIRS += haiku
+endif
 
 include $(top_srcdir)/src/backend/common.mk
 
diff --git a/src/backend/port/dynloader/haiku.c b/src/backend/port/dynloader/haiku.c
new file mode 100644
index 0000000..db24966
--- /dev/null
+++ b/src/backend/port/dynloader/haiku.c
@@ -0,0 +1,6 @@
+/* src/backend/port/dynloader/haiku.c */
+
+/* Dummy file used for nothing at this point
+ *
+ * see haiku.h
+ */
diff --git a/src/backend/port/dynloader/haiku.h b/src/backend/port/dynloader/haiku.h
new file mode 100644
index 0000000..61ffb51
--- /dev/null
+++ b/src/backend/port/dynloader/haiku.h
@@ -0,0 +1,33 @@
+/*-------------------------------------------------------------------------
+ *
+ * haiku.h
+ *	  port-specific prototypes for Haiku
+ *
+ *
+ * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/backend/port/dynloader/haiku.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PORT_PROTOS_H
+#define PORT_PROTOS_H
+
+#include <dlfcn.h>
+#include "utils/dynamic_loader.h"		/* pgrminclude ignore */
+
+/*
+ * Dynamic Loader on Haiku.
+ *
+ * this dynamic loader uses the system dynamic loading interface for shared
+ * libraries (ie. dlopen/dlsym/dlclose). The user must specify a shared
+ * library as the file to be dynamically loaded.
+ */
+
+#define pg_dlopen(f)	dlopen((f), RTLD_NOW | RTLD_GLOBAL)
+#define pg_dlsym		dlsym
+#define pg_dlclose		dlclose
+#define pg_dlerror		dlerror
+
+#endif   /* PORT_PROTOS_H */
diff --git a/src/backend/port/haiku/Makefile b/src/backend/port/haiku/Makefile
new file mode 100644
index 0000000..f0664c0
--- /dev/null
+++ b/src/backend/port/haiku/Makefile
@@ -0,0 +1,14 @@
+#-------------------------------------------------------------------------
+#
+# Makefile--
+#    Makefile for port/haiku
+#
+#-------------------------------------------------------------------------
+
+subdir = src/backend/port/haiku
+top_builddir = ../../../..
+include $(top_builddir)/src/Makefile.global
+
+OBJS = shm.o
+
+include $(top_srcdir)/src/backend/common.mk
diff --git a/src/backend/port/haiku/shm.c b/src/backend/port/haiku/shm.c
new file mode 100644
index 0000000..6b56752
--- /dev/null
+++ b/src/backend/port/haiku/shm.c
@@ -0,0 +1,144 @@
+/*-------------------------------------------------------------------------
+ *
+ * shm.c
+ *	  Haiku System V Shared Memory Emulation
+ *
+ * Copyright (c) 1999-2001, Cyril VELTER
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include <OS.h>
+#include "postgres.h"
+#include <errno.h>
+#include <sys/ipc.h>
+
+/* Emulating SYS shared memory with beos areas. WARNING : fork clone
+areas in copy on write mode */
+
+/* Detach from a shared mem area based on its address */
+int
+shmdt(char *shmaddr)
+{
+	/* Find area id for this address */
+	area_id		s;
+
+	s = area_for(shmaddr);
+
+	/* Delete area */
+	return delete_area(s);
+}
+
+/* Attach to an existing area */
+int *
+shmat(int memId, int m1, int m2)
+{
+	/* Get our team id */
+	thread_info thinfo;
+	team_info	teinfo;
+	area_info	ainfo;
+
+	get_thread_info(find_thread(NULL), &thinfo);
+	get_team_info(thinfo.team, &teinfo);
+
+	/* Get area teamid */
+	if (get_area_info(memId, &ainfo) != B_OK)
+		printf("AREA %d Invalide\n", memId);
+
+	if (ainfo.team == teinfo.team)
+	{
+		/*
+		 * the area is already in our address space, just return the address
+		 */
+		return (int *) ainfo.address;
+	}
+	else
+	{
+		/*
+		 * the area is not in our address space, clone it before and return
+		 * the address
+		 */
+		area_id		narea;
+
+		narea = clone_area(ainfo.name, &(ainfo.address), B_CLONE_ADDRESS, B_READ_AREA | B_WRITE_AREA, memId);
+		get_area_info(narea, &ainfo);
+		return (int *) ainfo.address;
+	}
+}
+
+/* Control a shared mem area */
+int
+shmctl(int shmid, int flag, struct shmid_ds * dummy)
+{
+	if (flag == IPC_RMID)
+	{
+		/* Delete the area */
+		delete_area(shmid);
+		return 0;
+	}
+	if (flag == IPC_STAT)
+	{
+		/* Find any SYSV area with the shmid in its name */
+
+		area_info	inf;
+		team_info	infteam;
+		int32		cookteam = 0;
+		char		name[50];
+
+		sprintf(name, "SYSV_IPC %d", shmid);
+
+		dummy->shm_nattch = 0;
+
+		while (get_next_team_info(&cookteam, &infteam) == B_OK)
+		{
+			int32		cook = 0;
+
+			while (get_next_area_info(infteam.team, &cook, &inf) == B_OK)
+			{
+				if (strcmp(name, inf.name) == 0)
+					dummy->shm_nattch++;
+			}
+		}
+
+		errno = 0;
+		return 0;
+	}
+	errno = EINVAL;
+	return -1;
+}
+
+/* Get an area based on the IPC key */
+int
+shmget(int memKey, int size, int flag)
+{
+	char		nom[50];
+	void	   *Address;
+	area_id		parea;
+	area_id     original;
+	area_id     clone;
+	
+	/* Area name */
+	sprintf(nom, "SYSV_IPC_SHM : %d", memKey);
+
+	/* Find area */
+	parea = find_area(nom);
+
+	/* area exist, just return its id */
+	if (parea != B_NAME_NOT_FOUND)
+		return parea;
+
+	/* area does not exist and no creation is requested : error */
+	if (flag == 0)
+		return -1;
+
+	/*
+	 * area does not exist and its creation is requested, create it (be sure
+	 * to have a 4ko multiple size
+	 */
+	original = create_area(nom, &Address, B_ANY_ADDRESS, ((size / 4096) + 1) * 4096, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
+
+	clone = clone_area(nom, &Address, B_CLONE_ADDRESS, B_READ_AREA | B_WRITE_AREA, original);
+
+	return original;
+
+}
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 6d4d8ac..62e594e 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -4373,7 +4373,7 @@ ShowUsage(const char *title)
 					 (long) user.tv_usec,
 					 (long) sys.tv_sec,
 					 (long) sys.tv_usec);
-#if defined(HAVE_GETRUSAGE)
+#if defined(HAVE_GETRUSAGE) && !defined(__HAIKU__)
 	appendStringInfo(&str,
 					 "!\t%ld/%ld [%ld/%ld] filesystem blocks in/out\n",
 					 r.ru_inblock - Save_r.ru_inblock,
diff --git a/src/backend/tsearch/ts_parse.c b/src/backend/tsearch/ts_parse.c
index 59c0195..9573de5 100644
--- a/src/backend/tsearch/ts_parse.c
+++ b/src/backend/tsearch/ts_parse.c
@@ -355,7 +355,7 @@ LexizeExec(LexizeData *ld, ParsedLex **correspondLexem)
  * prs will be filled in.
  */
 void
-parsetext(Oid cfgId, ParsedText *prs, char *buf, int buflen)
+parsetext(Oid cfgId, ParsedText *prs, char *buf, int32 buflen)
 {
 	int			type,
 				lenlemm;
@@ -524,7 +524,7 @@ addHLParsedLex(HeadlineParsedText *prs, TSQuery query, ParsedLex *lexs, TSLexeme
 }
 
 void
-hlparsetext(Oid cfgId, HeadlineParsedText *prs, TSQuery query, char *buf, int buflen)
+hlparsetext(Oid cfgId, HeadlineParsedText *prs, TSQuery query, char *buf, int32 buflen)
 {
 	int			type,
 				lenlemm;
diff --git a/src/backend/utils/adt/tsquery_cleanup.c b/src/backend/utils/adt/tsquery_cleanup.c
index feda2f3..9154be6 100644
--- a/src/backend/utils/adt/tsquery_cleanup.c
+++ b/src/backend/utils/adt/tsquery_cleanup.c
@@ -182,7 +182,7 @@ clean_NOT_intree(NODE *node)
 }
 
 QueryItem *
-clean_NOT(QueryItem *ptr, int *len)
+clean_NOT(QueryItem *ptr, int32 *len)
 {
 	NODE	   *root = maketree(ptr);
 
@@ -271,7 +271,7 @@ clean_fakeval_intree(NODE *node, char *result)
 }
 
 QueryItem *
-clean_fakeval(QueryItem *ptr, int *len)
+clean_fakeval(QueryItem *ptr, int32 *len)
 {
 	NODE	   *root = maketree(ptr);
 	char		result = V_UNKNOWN;
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index abf1586..3706b3a 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -774,6 +774,8 @@ get_id(void)
 
 	struct passwd *pw;
 
+#ifndef __HAIKU__
+
 	if (geteuid() == 0)			/* 0 is root's uid */
 	{
 		fprintf(stderr,
@@ -785,6 +787,8 @@ get_id(void)
 		exit(1);
 	}
 
+#endif
+
 	pw = getpwuid(geteuid());
 	if (!pw)
 	{
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index b1bcf69..9d6e371 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -21,6 +21,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <sys/select.h>
 #include <signal.h>
 #include <time.h>
 
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 3679103..f435380 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -2042,6 +2042,7 @@ main(int argc, char **argv)
 	 * Disallow running as root, to forestall any possible security holes.
 	 */
 #ifndef WIN32
+#ifndef __HAIKU__
 	if (geteuid() == 0)
 	{
 		write_stderr(_("%s: cannot be run as root\n"
@@ -2052,6 +2053,7 @@ main(int argc, char **argv)
 		exit(1);
 	}
 #endif
+#endif
 
 	/*
 	 * 'Action' can be before or after args so loop over both. Some
diff --git a/src/bin/pg_dump/parallel.c b/src/bin/pg_dump/parallel.c
index 6fe5923..b90eea7 100644
--- a/src/bin/pg_dump/parallel.c
+++ b/src/bin/pg_dump/parallel.c
@@ -24,6 +24,7 @@
 #ifndef WIN32
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <sys/select.h>
 #include "signal.h"
 #include <unistd.h>
 #include <fcntl.h>
diff --git a/src/include/c.h b/src/include/c.h
index 613d87d..8051b4c 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -63,6 +63,7 @@
 #undef errcode
 #endif
 
+
 /*
  * We have to include stdlib.h here because it defines many of these macros
  * on some platforms, and we only want our definitions used if stdlib.h doesn't
@@ -92,6 +93,11 @@
 #include "pg_config_os.h"
 #endif
 
+#if defined(__HAIKU__)
+// Haiku defines int (int8, int64, etc) types in SupportDefs.h
+#include <SupportDefs.h>
+#endif
+
 /* Must be before gettext() games below */
 #include <locale.h>
 
diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h
index 24c5069..94eefcc 100644
--- a/src/include/pg_config_manual.h
+++ b/src/include/pg_config_manual.h
@@ -113,7 +113,7 @@
 /*
  * Define this if your operating system supports link()
  */
-#if !defined(WIN32) && !defined(__CYGWIN__)
+#if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__HAIKU__)
 #define HAVE_WORKING_LINK 1
 #endif
 
diff --git a/src/include/port/haiku.h b/src/include/port/haiku.h
new file mode 100644
index 0000000..772a3fe
--- /dev/null
+++ b/src/include/port/haiku.h
@@ -0,0 +1,16 @@
+/* src/include/port/haiku.h */
+
+/* Haiku doesn't have all the required getrusage fields */
+//#undef HAVE_GETRUSAGE
+
+/* Haiku doesn't implement shared memory as needed*/
+struct shmid_ds
+{
+	int			dummy;
+	int			shm_nattch;
+};
+
+int			shmdt(char *shmaddr);
+int		   *shmat(int memId, int m1, int m2);
+int			shmctl(int shmid, int flag, struct shmid_ds * dummy);
+int			shmget(int memKey, int size, int flag);
diff --git a/src/interfaces/ecpg/pgtypeslib/Makefile b/src/interfaces/ecpg/pgtypeslib/Makefile
index 09b5df3..8424141 100644
--- a/src/interfaces/ecpg/pgtypeslib/Makefile
+++ b/src/interfaces/ecpg/pgtypeslib/Makefile
@@ -24,7 +24,9 @@ override CFLAGS += $(PTHREAD_CFLAGS)
 # Need to recompile any libpgport object files
 LIBS := $(filter-out -lpgport, $(LIBS))
 
+ifneq ($(PORTNAME), haiku)
 SHLIB_LINK += -lm
+endif
 
 SHLIB_EXPORTS = exports.txt
 
diff --git a/src/makefiles/Makefile.haiku b/src/makefiles/Makefile.haiku
new file mode 100644
index 0000000..249d6c3
--- /dev/null
+++ b/src/makefiles/Makefile.haiku
@@ -0,0 +1,7 @@
+AROPT = crs
+
+DLSUFFIX = .so
+
+# Rule for building a shared library from a single .o file
+%.so: %.o
+	$(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ $<
diff --git a/src/template/haiku b/src/template/haiku
new file mode 100644
index 0000000..e69de29
-- 
2.2.2

