@@ -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
@@ -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;
}
@@ -62,6 +62,7 @@
#include "mystring.h"
#include "show.h"
#include "cd.h"
+#include "system.h"
#define CD_PHYSICAL 1
#define CD_PRINT 2
@@ -135,8 +135,12 @@
default:
exerrno = 126;
break;
+#ifdef ELOOP
case ELOOP:
+#endif
+#ifdef ENAMETOOLONG
case ENAMETOOLONG:
+#endif
case ENOENT:
case ENOTDIR:
exerrno = 127;
@@ -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);
@@ -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;
}
}
}
@@ -973,7 +973,11 @@
sigblockall(NULL);
vforked++;
+#ifdef HAVE_VFORK
pid = vfork();
+#else
+ pid = fork();
+#endif
if (!pid) {
forkchild(jp, n, FORK_FG);
@@ -59,6 +59,7 @@
#include "mystring.h"
#include "exec.h"
#include "cd.h"
+#include "system.h"
#define PROFILE 0
@@ -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 */
@@ -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
@@ -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