diff -X ../exclude.txt -urN dash-0.5.12+06-stdbool/configure.ac dash-0.5.12+07-sys-functions/configure.ac
--- dash-0.5.12+06-stdbool/configure.ac	2024-11-10 17:06:18.440583714 +0000
+++ dash-0.5.12+07-sys-functions/configure.ac	2024-11-10 17:29:12.073235300 +0000
@@ -67,6 +67,8 @@
 dnl Some systems lack isblank
 AC_CHECK_DECLS([isblank],,,[#include <ctype.h>])
 
+AC_DECL_SYS_SIGLIST
+
 dnl Check for sizes of types
 AC_CHECK_SIZEOF([intmax_t])
 AC_CHECK_SIZEOF([long long int])
@@ -88,9 +90,22 @@
 
 dnl Checks for library functions.
 AC_CHECK_FUNCS(bsearch faccessat getpwnam getrlimit isalpha killpg \
-	       mempcpy \
+	       mempcpy memmove \
 	       sigsetmask stpcpy strchrnul strsignal strtod strtoimax \
-	       strtoumax sysconf)
+	       strtoumax sysconf \
+	       vfork lstat dup2 getgroups \
+	       strstr stpncpy strcasecmp strerror strdup strtoul \
+	       readdir)
+
+dnl Checks for prototypes
+AC_CHECK_DECLS([malloc, realloc, calloc, free, strdup, strerror, bsearch])
+
+AC_CHECK_DECLS([getpwnam],,,[
+AC_INCLUDES_DEFAULT
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+])
 
 dnl Check whether it's worth working around FreeBSD PR kern/125009.
 dnl The traditional behavior of access/faccessat is crazy, but
diff -X ../exclude.txt -urN dash-0.5.12+06-stdbool/src/bltin/test.c dash-0.5.12+07-sys-functions/src/bltin/test.c
--- dash-0.5.12+06-stdbool/src/bltin/test.c	2024-10-20 08:37:55.798682937 +0000
+++ dash-0.5.12+07-sys-functions/src/bltin/test.c	2024-10-21 10:43:42.395812820 +0000
@@ -22,6 +22,7 @@
 #include <unistd.h>
 #include <stdarg.h>
 #include "bltin.h"
+#include "system.h"
 
 /* test(1) accepts the following grammar:
 	oexpr	::= aexpr | aexpr "-o" oexpr ;
@@ -663,10 +664,12 @@
  */
 static int test_access(const struct stat64 *sp, int stmode)
 {
+#ifdef HAVE_GETGROUPS
 	gid_t *groups;
 	register int n;
-	uid_t euid;
 	int maxgroups;
+#endif
+	uid_t euid;
 
 	/*
 	 * I suppose we could use access() if not running as root and if we are
@@ -685,6 +688,7 @@
 		stmode <<= 6;
 	else if (sp->st_gid == getegid())
 		stmode <<= 3;
+#ifdef HAVE_GETGROUPS
 	else {
 		/* XXX stolen almost verbatim from ksh93.... */
 		/* on some systems you can be in several groups */
@@ -698,6 +702,7 @@
 			}
 		}
 	}
+#endif
 
 	return sp->st_mode & stmode;
 }
diff -X ../exclude.txt -urN dash-0.5.12+06-stdbool/src/cd.c dash-0.5.12+07-sys-functions/src/cd.c
--- dash-0.5.12+06-stdbool/src/cd.c	2024-10-20 08:37:55.802683032 +0000
+++ dash-0.5.12+07-sys-functions/src/cd.c	2024-11-10 11:14:26.988743365 +0000
@@ -62,6 +62,7 @@
 #include "mystring.h"
 #include "show.h"
 #include "cd.h"
+#include "system.h"
 
 #define CD_PHYSICAL 1
 #define CD_PRINT 2
diff -X ../exclude.txt -urN dash-0.5.12+06-stdbool/src/exec.c dash-0.5.12+07-sys-functions/src/exec.c
--- dash-0.5.12+06-stdbool/src/exec.c	2024-10-20 08:37:55.802683032 +0000
+++ dash-0.5.12+07-sys-functions/src/exec.c	2024-10-20 21:19:22.613459913 +0000
@@ -135,8 +135,12 @@
 	default:
 		exerrno = 126;
 		break;
+#ifdef ELOOP
 	case ELOOP:
+#endif
+#ifdef ENAMETOOLONG
 	case ENAMETOOLONG:
+#endif
 	case ENOENT:
 	case ENOTDIR:
 		exerrno = 127;
diff -X ../exclude.txt -urN dash-0.5.12+06-stdbool/src/expand.c dash-0.5.12+07-sys-functions/src/expand.c
--- dash-0.5.12+06-stdbool/src/expand.c	2024-10-20 21:03:17.122588883 +0000
+++ dash-0.5.12+07-sys-functions/src/expand.c	2024-10-20 21:19:22.613459913 +0000
@@ -136,6 +136,35 @@
 /* holds expanded arg list */
 static struct arglist exparg;
 
+#ifndef HAVE_READDIR
+
+#include <fcntl.h>
+DIR *opendir(const char *filename) {
+        DIR *dirp;
+        int fd = open(filename, O_RDONLY);
+        if(fd < 0)
+                return 0;
+        dirp = (DIR *)calloc(1, sizeof(DIR));
+        dirp->fd = fd;
+        return dirp;
+}
+
+struct dirent *readdir(DIR *dirp) {
+        int n = read(dirp->fd, &dirp->entry, 16);
+        if(n <= 0)
+                return 0;
+        dirp->entry.d_name[14]='\0'; /* Terminating null */
+        return &dirp->entry;
+}
+
+int closedir(DIR* dirp) {
+        close(dirp->fd);
+        free(dirp);
+        return 0;
+}
+
+#endif
+
 static char *argstr(char *p, int flag);
 static char *exptilde(char *startp, int flag);
 static char *expari(char *start, int flag);
diff -X ../exclude.txt -urN dash-0.5.12+06-stdbool/src/input.c dash-0.5.12+07-sys-functions/src/input.c
--- dash-0.5.12+06-stdbool/src/input.c	2024-10-20 08:37:55.806683126 +0000
+++ dash-0.5.12+07-sys-functions/src/input.c	2024-10-21 10:43:42.395812820 +0000
@@ -59,6 +59,7 @@
 #ifndef SMALL
 #include "myhistedit.h"
 #endif
+#include "system.h"
 
 #define IBUFSIZ (BUFSIZ + 1)
 
@@ -200,17 +201,21 @@
 		nr = read(parsefile->fd, buf, IBUFSIZ - 1);
 
 
-	if (nr < 0) {
-		if (errno == EINTR)
-			goto retry;
-		if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
-			int flags = fcntl(0, F_GETFL, 0);
-			if (flags >= 0 && flags & O_NONBLOCK) {
-				flags &=~ O_NONBLOCK;
-				if (fcntl(0, F_SETFL, flags) >= 0) {
-					out2str("sh: turning off NDELAY mode\n");
-					goto retry;
-				}
+	if (nr < 0 && errno == EINTR)
+		goto retry;
+	if (parsefile->fd == 0 &&
+#ifdef EWOULDBLOCK
+	    (nr < 0 && errno == EWOULDBLOCK)
+#else
+	    nr == 0
+#endif
+	    ) {
+		int flags = fcntl(0, F_GETFL, 0);
+		if (flags >= 0 && flags & O_NONBLOCK) {
+			flags &=~ O_NONBLOCK;
+			if (fcntl(0, F_SETFL, flags) >= 0) {
+				out2str("sh: turning off NDELAY mode\n");
+				goto retry;
 			}
 		}
 	}
diff -X ../exclude.txt -urN dash-0.5.12+06-stdbool/src/jobs.c dash-0.5.12+07-sys-functions/src/jobs.c
--- dash-0.5.12+06-stdbool/src/jobs.c	2024-10-27 20:11:25.698058831 +0000
+++ dash-0.5.12+07-sys-functions/src/jobs.c	2024-10-27 20:11:14.193784131 +0000
@@ -973,7 +973,11 @@
 	sigblockall(NULL);
 	vforked++;
 
+#ifdef HAVE_VFORK
 	pid = vfork();
+#else
+	pid = fork();
+#endif
 
 	if (!pid) {
 		forkchild(jp, n, FORK_FG);
diff -X ../exclude.txt -urN dash-0.5.12+06-stdbool/src/main.c dash-0.5.12+07-sys-functions/src/main.c
--- dash-0.5.12+06-stdbool/src/main.c	2022-01-20 05:54:13.000000000 +0000
+++ dash-0.5.12+07-sys-functions/src/main.c	2024-10-21 10:43:42.395812820 +0000
@@ -59,6 +59,7 @@
 #include "mystring.h"
 #include "exec.h"
 #include "cd.h"
+#include "system.h"
 
 #define PROFILE 0
 
diff -X ../exclude.txt -urN dash-0.5.12+06-stdbool/src/redir.c dash-0.5.12+07-sys-functions/src/redir.c
--- dash-0.5.12+06-stdbool/src/redir.c	2024-10-20 08:37:55.818683409 +0000
+++ dash-0.5.12+07-sys-functions/src/redir.c	2024-10-21 10:43:42.395812820 +0000
@@ -58,6 +58,7 @@
 #include "memalloc.h"
 #include "error.h"
 #include "trap.h"
+#include "system.h"
 
 
 #define EMPTY -2		/* marks an unused slot in redirtab */
diff -X ../exclude.txt -urN dash-0.5.12+06-stdbool/src/system.c dash-0.5.12+07-sys-functions/src/system.c
--- dash-0.5.12+06-stdbool/src/system.c	2024-11-10 10:42:15.087283480 +0000
+++ dash-0.5.12+07-sys-functions/src/system.c	2024-11-10 16:54:50.528225292 +0000
@@ -56,6 +56,10 @@
 
 #include <signal.h>
 #include <string.h>
+#include <fcntl.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
 
 #include "error.h"
 #include "output.h"
@@ -77,6 +81,26 @@
 }
 #endif
 
+#ifndef HAVE_STPNCPY
+char *stpncpy(char *dst, const char *src, size_t len)
+{
+	int i,nullSeen=0;
+	char *ret=dst+len;
+	for(i=0; i<len; i++) {
+		if(nullSeen)
+			dst[i] = '\0';
+		else {
+			dst[i] = src[i];
+			if(dst[i] == '\0') {
+				nullSeen = 1;
+				ret = dst+i;
+			}
+		}
+	}
+	return ret;
+}
+#endif
+
 #ifndef HAVE_STRCHRNUL
 char *strchrnul(const char *s, int c)
 {
@@ -92,6 +116,10 @@
 {
 	static char buf[19];
 
+#if !HAVE_DECL_SYS_SIGLIST
+	extern char *signal_names[];
+# define sys_siglist signal_names
+#endif
 	if ((unsigned)sig < NSIG && sys_siglist[sig])
 		return (char *)sys_siglist[sig];
 	fmtstr(buf, sizeof(buf), "Signal %d", sig); 
@@ -197,3 +225,119 @@
 	return c == ' ' || c == '\t';
 }
 #endif
+
+#ifndef HAVE_DUP2
+int dup2(int a, int b)
+{
+	close(b);
+	return fcntl(a, F_DUPFD, b);
+}
+#endif
+
+#include <stdio.h>
+
+#ifndef HAVE_STRSTR
+char * strstr (const char* haystack, const char *needle)
+{
+	const char *start;
+	int i;
+	if (!haystack) return 0;
+	for(start=haystack; *start;start++) {
+		for(i=0; start[i] && needle[i]; i++)
+			if(start[i] != needle[i])
+				break;
+		if(!needle[i])
+			return (char *)start;
+	}
+	return NULL;
+}
+#endif
+
+#ifndef HAVE_STRDUP
+char *strdup(const char *str)
+{
+    char *nstr;
+
+    if (str == (char*)0)
+        return 0;
+
+    nstr = (char*)malloc((strlen(str) + 1));
+
+    if (nstr == (char*)0)
+    {
+        (void)fprintf(stderr, "strdup(): not enough memory to duplicate `%s'\n",
+		      str);
+	exit(1);
+    }
+
+    (void)strcpy(nstr, str);
+
+    return nstr;
+}
+#endif
+
+#ifndef HAVE_STRCASECMP
+int strcasecmp(const char *s1, const char *s2)
+{
+  register const unsigned char *p1 = (const unsigned char *) s1;
+  register const unsigned char *p2 = (const unsigned char *) s2;
+  unsigned char c1, c2;
+
+  if (p1 == p2)
+    return 0;
+
+  do
+    {
+      c1 = tolower (*p1++);
+      c2 = tolower (*p2++);
+      if (c1 == '\0')
+	break;
+    }
+  while (c1 == c2);
+
+  return c1 - c2;
+}
+#endif
+
+#ifndef HAVE_STRTOUL
+unsigned long strtoul(const char *string, char **eptr, int base)
+{
+	return (unsigned long) strtol(string, eptr, base);
+}
+#endif
+
+#ifndef HAVE_STRERROR
+char *strerror(int x) {
+	extern char *sys_errlist[];
+	return sys_errlist[x];
+}
+#endif
+
+#ifndef HAVE_MEMMOVE
+/* memmove.c -- copy memory.
+   This snippet is in the public domain.  */
+
+/* Written by David MacKenzie <djm@gnu.ai.mit.edu>.  */
+
+#include <stddef.h>
+
+/* Copy LENGTH bytes from SOURCE to DEST.  Does not null-terminate.  */
+
+void *
+memmove (void *dest0, void const *source0, size_t length)
+{
+  char *dest = dest0;
+  char const *source = source0;
+  if (source < dest)
+    /* Moving from low mem to hi mem; start at end.  */
+    for (source += length, dest += length; length; --length)
+      *--dest = *--source;
+  else if (source != dest)
+    {
+      /* Moving from hi mem to low mem; start at beginning.  */
+      for (; length; --length)
+        *dest++ = *source++;
+    }
+  return dest0;
+}
+#endif
diff -X ../exclude.txt -urN dash-0.5.12+06-stdbool/src/system.h dash-0.5.12+07-sys-functions/src/system.h
--- dash-0.5.12+06-stdbool/src/system.h	2024-11-10 14:53:00.358427612 +0000
+++ dash-0.5.12+07-sys-functions/src/system.h	2024-11-10 16:26:50.144230900 +0000
@@ -62,6 +62,10 @@
 char *stpcpy(char *, const char *);
 #endif
 
+#ifndef HAVE_STPNCPY
+char *stpncpy(char *, const char *, size_t);
+#endif
+
 #ifndef HAVE_STRCHRNUL
 char *strchrnul(const char *, int);
 #endif
@@ -79,14 +83,22 @@
 #endif
 
 #ifndef HAVE_STRTOIMAX
+#if SIZEOF_INTMAX_T > SIZEOF_LONG_INT
 #define strtoimax strtoll
+#else
+#define strtoimax strtol
+#endif
 #endif
 
 #ifndef HAVE_STRTOUMAX
+#if SIZEOF_INTMAX_T > SIZEOF_LONG_INT
 #define strtoumax strtoull
+#else
+#define strtoumax strtoul
+#endif
 #endif
 
-#ifndef HAVE_BSEARCH
+#if !HAVE_DECL_BSEARCH
 void *bsearch(const void *, const void *, size_t, size_t,
 	      int (*)(const void *, const void *));
 #endif
@@ -111,12 +123,52 @@
 int isblank(int c);
 #endif
 
+#if !HAVE_DECL_STRERROR
+char *strerror(int errnum);
+#endif
+
+#if !HAVE_DECL_MALLOC
+void *malloc(size_t size);
+#endif
+
+#if !HAVE_DECL_REALLOC
+void *realloc(void *ptr, size_t size);
+#endif
+
+#if !HAVE_DECL_FREE
+void free(void *ptr);
+#endif
+
+#if !HAVE_DECL_STRDUP
+char *strdup(const char *s);
+#endif
+
+#if !HAVE_DECL_GETPWNAM
+struct passwd *getpwnam(const char *name);
+#endif
+
 /*
  * A trick to suppress uninitialized variable warning without generating any
  * code
  */
 #define uninitialized_var(x) x = x
 
+#if (defined O_NDELAY && !defined O_NONBLOCK)
+# define O_NONBLOCK O_NDELAY
+#endif
+
+#ifndef FD_CLOEXEC
+# define FD_CLOEXEC 1
+#endif
+
+#ifndef HAVE_STRSTR
+extern char * strstr (const char* haystack, const char *needle);
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
 #ifndef NAME_MAX
 /* NAME_MAX is only used in expand.c to make sure that we have a
    buffer big enough to append the next local file part into during
@@ -124,3 +176,41 @@
    rather than smaller, in order to prevent buffer overflow */
 # define NAME_MAX PATH_MAX
 #endif
+
+#ifndef S_ISREG
+#define S_ISREG(x) ((x) & S_IFREG)
+#endif
+#ifndef S_ISDIR
+#define S_ISDIR(x) ((x) & S_IFDIR)
+#endif
+#ifndef S_ISCHR
+#define S_ISCHR(x) ((x) & S_IFCHR)
+#endif
+#ifndef S_ISBLK
+#define S_ISBLK(x) ((x) & S_IFBLK)
+#endif
+
+#ifndef S_IFFIFO
+#define S_IFFIFO 0
+#endif
+#ifndef S_ISFIFO
+#define S_ISFIFO(x) ((x) & S_IFFIFO)
+#endif
+
+#ifndef S_IFSOCK
+#define S_IFSOCK 0
+#endif
+#ifndef S_ISSOCK
+#define S_ISSOCK(x) ((x) & S_IFSOCK)
+#endif
+
+#ifndef S_IFLNK
+#define S_IFLNK 0
+#endif
+#ifndef S_ISLNK
+#define S_ISLNK(x) ((x) & S_IFLNK)
+#endif
+
+#ifndef HAVE_LSTAT
+#define lstat stat
+#endif
