2014-04-26  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* README_d/README.pc: Explain that only config.h and Makefile need
	to be copied to srcdir.

	* pc/config.h: Include sys/version.h to enable 2.04 specific features.
	Define HAVE_INTTYPES_H and HAVE_STDINT_H for DJGPP 2.04.  This allows
	to compile with MPFR support.
	Remove double definition of uintmax_t.

	* pc/Makefile: Change dependecy popen.h to pc/popen.h.
	Add popen.o to the list of gawk objects.
	Add definitions for pkgextensiondir, DEFLIBPATH and LOCALEDIR.  For all
	use $(prefix) to define their path.
	Use /dev/env/DJDIR as $(prefix) value.
	Add definition for SHLIBEXT.  It is dxe.
	New target djgpp-mpfr.  Supports high precision arithmetic with MPFR.

	* pc/Makefile.tst (manyfiles): Limit the number of simultaneously
	opened files to 250.
	Set DATE to /dev/env/DJDIR/date.
	Remove DJGPP specific warnings about test failure for certain checks.

	* pc/gawkmisc.pc [__DJGPP__, __DJGPP_MINOR__]: Use unsetenv only if
	compiling with DJGPP 2.03 or less.

	* pc/popen.c: File from djgpp CVS-repository to replace the broken one
	from djgpp 2.04.

	* test/beginfile1.ok: Added "(ENOENT)" and "(EISDIR)" to error message.

	* test/getlndir.ok: Added "(EISDIR)" to error message.

	* test/space.ok: Added "(ENOENT)" to error message.





diff -aprNU5 gawk-4.1.1.orig/README_d/README.pc gawk-4.1.1/README_d/README.pc
--- gawk-4.1.1.orig/README_d/README.pc	2014-04-08 16:11:58 +0200
+++ gawk-4.1.1/README_d/README.pc	2014-04-27 17:34:40 +0200
@@ -23,11 +23,11 @@ The `configure' step takes a long time,
 ************************************************************************
 
 Building gawk
 -------------
 
-Copy the files in the `pc' directory (EXCEPT for `ChangeLog') to the
+Copy the files config.h and Makefile in the `pc' directory to the
 directory with the rest of the gawk sources.  (The subdirectories of 
 `pc' need not be copied.)  The Makefile contains a configuration 
 section with comments, and may need to be edited in order to work
 with your make utility.  If you are building with MinGW, copy the
 file Makefile.ext to extension/Makefile.
diff -aprNU5 gawk-4.1.1.orig/pc/Makefile gawk-4.1.1/pc/Makefile
--- gawk-4.1.1.orig/pc/Makefile	2014-03-31 19:17:46 +0200
+++ gawk-4.1.1/pc/Makefile	2014-04-27 17:35:48 +0200
@@ -19,10 +19,13 @@
 
 default:
 	@echo "Enter $(MAK) target "
 	@echo " where 'target' is chosen from                          "
 	@echo "  djgpp ... DOS 32-bit exe [GNU C, Delorie, v2]         "
+	@echo "  djgpp-mpfr . Like djgpp, but with MPFR                "
+	@echo "   [You will need to have GNU MPFR library installed.]  "
+	@echo "   [Requires to compile with DJGPP 2.04.]               "
 	@echo "  emx ..... OS/2 32-bit exe [emx/gcc; uses emxlibc.dll] "
 	@echo "  emxnt ... NT exe [emx/gcc with RSXNT]                 "
 	@echo "  emxbnd .. OS/2 and DOS 32-bit exe [emx/gcc]           "
 	@echo "  mingw32 . Windows32 exe [Mingw32 GNU C]               "
 	@echo "  mingw32-readline . Like mingw32, but with readline    "
@@ -79,11 +82,14 @@ MAK = $(MAKE) $(MAKEFILE)
 #prefix =
 prefix = c:/gnu
 pkgdatadir = $(prefix)/lib/awk
 pkgextensiondir = $(prefix)/lib/gawk
 DEFLIBPATH = "\"$(pkgextensiondir)\""
+LOCALEDIR="\"$(prefix)/share/locale\""
 SHLIBEXT = "\"dll\""
+infodir = $(prefix)/info
+mandir = $(prefix)/share/man
 #
 # Define the install method. Method 1 is Unix-like (and requires cat
 # and cp); method 2 uses gawk and batch files.
 install = 1
 #------------------------------------------------------------------------
@@ -98,22 +104,34 @@ DO_BIND= $($(BIND))
 #========================================================================
 #========================== DJGPP =======================================
 #========================================================================
 
 ifneq ($(DJGPP),)
-prefix = $(DJDIR)
+prefix = /dev/env/DJDIR
 pkgdatadir = $(prefix)/share/awk
+pkgextensiondir = $(prefix)/lib/gawk
+DEFLIBPATH = "\"$(pkgextensiondir)\""
+LOCALEDIR="\"$(prefix)/share/locale\""
+SHLIBEXT = "\"dxe\""
+infodir = $(prefix)/share/info
+mandir = $(prefix)/share/man
 endif
 LDJG = $(CC) $(LF) -o gawk.exe $(LDRSP) $(LF2)
 BDJG = stubify -g awk.exe | stubedit awk.exe runfile=gawk
 
 djgpp:
 	$(MAK) all \
 	CC=gcc O=.o CF=-O2 \
 	LNK=LDJG LF=-s LF2=-lm \
 	BIND=BDJG
 
+djgpp-mpfr:
+	$(MAK) all \
+	CC=gcc O=.o CF="-O2 -DHAVE_MPFR" \
+	LNK=LDJG LF=-s LF2="-lmpfr -lgmp -lm" \
+	BIND=BDJG
+
 djgpp-debug:
 	$(MAK) all \
 	CC=gcc O=.o CF='-O2 -g' \
 	LNK=LDJG LF2=-lm \
 	BIND=BDJG
@@ -196,11 +214,11 @@ mingw32-readline-mpfr:
 # Define BIND for BINDless compiles, otherwise $($(BIND)) may break.
 BIND = EMPTY
 PBIND = EMPTY
 EMPTY=
 
-CFLAGS = $(CF) -DGAWK -I. -DHAVE_CONFIG_H -DDEFLIBPATH=$(DEFLIBPATH) -DSHLIBEXT=$(SHLIBEXT)
+CFLAGS = $(CF) -DGAWK -I. -DHAVE_CONFIG_H -DDEFLIBPATH=$(DEFLIBPATH) -DSHLIBEXT=$(SHLIBEXT) -DLOCALEDIR=$(LOCALEDIR)
 
 # object files
 AWKOBJS1  = array$O builtin$O eval$O field$O floatcomp$O gawkmisc$O io$O main$O
 AWKOBJS2  = ext$O msg$O node$O profile$O re$O replace$O version$O symbol$O
 AWKOBJS3  = debug$O cint_array$O int_array$O mpfr$O str_array$O command$O
@@ -242,30 +260,44 @@ $(RSPFILE) : $(GAWKOBJS)
 #    included by awk.h.
 # 2. custom.h is not mentioned because pc ports don't use it.
 $(ALLOBJS) $(LIBOBJS): \
   awk.h regex.h config.h gettext.h mbsupport.h protos.h dfa.h getopt.h
 
+ifneq ($(DJGPP),)
+builtin$O:	floatmagic.h random.h pc/popen.h
+
+io$O:		pc/popen.h pc/socket.h pc/in.h
+else
 builtin$O:	floatmagic.h random.h popen.h
 
+io$O:		popen.h socket.h in.h
+endif
+
 random$O:	random.h
 
 node$O:		floatmagic.h
 
 command$O debug$O:	cmd.h
 
 dfa$O:		xalloc.h
 
-gawkmisc$O:	pc/gawkmisc.pc socket.h
+gawkmisc$O:	pc/gawkmisc.pc pc/socket.h
 
 getopt$O getopt1$O :	getopt_int.h
 
-io$O:		popen.h socket.h in.h
-
 regex$O:	regcomp.c regexec.c regex_internal.h
 
 eval$O:		interpret.h
 
+ifneq ($(DJGPP),)
+getid$O:	pc/getid.c
+	$(CC) -c $(CFLAGS) pc/getid.c
+
+popen$O:	pc/popen.c
+	$(CC) -c $(CFLAGS) pc/popen.c
+endif
+
 # A bug in ndmake requires the following rule
 awkgram$O: awk.h awkgram.c
 	$(CC) -c $(CFLAGS) awkgram.c
 
 awkgram.c:	awkgram.y
diff -aprNU5 gawk-4.1.1.orig/pc/Makefile.tst gawk-4.1.1/pc/Makefile.tst
--- gawk-4.1.1.orig/pc/Makefile.tst	2014-03-31 19:17:46 +0200
+++ gawk-4.1.1/pc/Makefile.tst	2014-04-27 17:34:40 +0200
@@ -95,11 +95,11 @@ PGAWK = ../gawk.exe -p
 CMP = diff -u
 #CMP = gcmp
 
 # cmp replacement program for PC where the error messages aren't
 # exactly the same.  Should run even on old awk.
-TESTOUTCMP = $(AWK) -f ../testoutcmp.awk
+TESTOUTCMP = $(AWK) -f ../pc/testoutcmp.awk
 
 # Set your "cp," "mv," and "mkdir" commands here.  Note: DOS's copy must take
 # forward slashes.
 CP = cp
 #CP = : && command -c copy
@@ -113,11 +113,11 @@ MV = cmd.exe /c ren
 #MKDIR = : && command -c mkdir
 MKDIR  = command.com /c mkdir
 
 # Set your unix-style date function here
 #DATE = date
-DATE = gdate
+DATE = /dev/env/DJDIR/bin/date
 
 # MS-DOS and OS/2 use ; as a PATH delimiter
 PATH_SEPARATOR = ;
 
 # Non-default GREP_OPTIONS might fail the badargs test
@@ -385,11 +385,11 @@ regtest::
 
 manyfiles::
 	@echo manyfiles
 	@rm -rf junk
 	@mkdir junk
-	@$(AWK) 'BEGIN { for (i = 1; i <= 1030; i++) print i, i}' >_$@
+	@$(AWK) 'BEGIN { for (i = 1; i <= 245; i++) print i, i}' >_$@
 	@$(AWK) -f "$(srcdir)"/manyfiles.awk _$@ _$@
 	@wc -l junk/* | $(AWK) '$$1 != 2' | wc -l | sed "s/  *//g" > _$@
 	@rm -rf junk
 	@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
 
@@ -2162,11 +2162,10 @@ gensub2:
 	@AWKPATH="$(srcdir)" $(AWK) -f $@.awk  >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
 	@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
 
 getlndir:
 	@echo $@
-	@echo Expect getlndir to fail with DJGPP.
 	@AWKPATH="$(srcdir)" $(AWK) -f $@.awk  >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
 	@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
 
 gnuops2:
 	@echo $@
diff -aprNU5 gawk-4.1.1.orig/pc/config.h gawk-4.1.1/pc/config.h
--- gawk-4.1.1.orig/pc/config.h	2014-04-08 17:36:36 +0200
+++ gawk-4.1.1/pc/config.h	2014-04-27 17:34:40 +0200
@@ -1,8 +1,13 @@
 /* configh.in.  Generated from configure.ac by autoheader.  */
 /* pc/config.h.  Generated automatically by pc/config.sed.  */
 
+#ifdef __DJGPP__
+/*  gcc no longer includes this by default.  */
+# include <sys/version.h>
+#endif
+
 /* dynamic loading is possible */
 #ifdef _WIN32
 #define DYNAMIC 1
 #endif
 
@@ -82,11 +87,11 @@
 #ifdef __MINGW32__
 #define HAVE_INTMAX_T 1
 #endif
 
 /* Define to 1 if you have the <inttypes.h> header file. */
-#ifdef __MINGW32__
+#if defined(__MINGW32__) || (defined(__DJGPP__) && __DJGPP__ == 2 && __DJGPP_MINOR__ > 3)
 #define HAVE_INTTYPES_H 1
 #endif
 
 /* Define to 1 if you have the `isascii' function. */
 #ifdef __MINGW32__
@@ -231,11 +236,11 @@
 #ifdef __GNUC__
 #define HAVE_STDDEF_H 1
 #endif
 
 /* Define to 1 if you have the <stdint.h> header file. */
-#ifdef __MINGW32__
+#if defined(__MINGW32__) || (defined(__DJGPP__) && __DJGPP__ == 2 && __DJGPP_MINOR__ > 3)
 #define HAVE_STDINT_H 1
 #endif
 
 /* Define to 1 if you have the <stdlib.h> header file. */
 #ifdef __MINGW32__
@@ -350,13 +355,15 @@
 
 /* Define to 1 if the system has the type `uintmax_t'. */
 #if defined(__DJGPP__) || defined(__MINGW32__)
 #define HAVE_UINTMAX_T 1
 #ifdef __DJGPP__
+#ifndef HAVE_STDINT_H
 #define uintmax_t unsigned long long
 #endif
 #endif
+#endif
 
 /* Define to 1 if you have the <unistd.h> header file. */
 #if defined(__DJGPP__) || defined(__MINGW32__)
 #define HAVE_UNISTD_H 1
 #endif
@@ -550,12 +557,14 @@
 #endif
 
 /* Define to the widest signed integer type if <stdint.h> and <inttypes.h> do
    not define. */
 #ifdef __DJGPP__
+#ifndef HAVE_STDINT_H
 #define intmax_t long long
 #endif
+#endif
 
 /* Define to `int' if <sys/types.h> does not define. */
 #undef pid_t
 
 /* Define to the equivalent of the C99 'restrict' keyword, or to
@@ -584,16 +593,10 @@
 #undef ssize_t
 
 /* Define to `int' if <sys/types.h> doesn't define. */
 #undef uid_t
 
-/* Define to the widest unsigned integer type if <stdint.h> and <inttypes.h>
-   do not define. */
-#ifdef __DJGPP__
-#define uintmax_t unsigned long long
-#endif
-
 #include "custom.h"
 /* Library search path */
 #if defined(__DJGPP__) && (__DJGPP__ > 2 || __DJGPP_MINOR__ >= 3)
 # define DEFPATH  ".;/dev/env/DJDIR/share/awk"
 #else
@@ -603,15 +606,17 @@
 #ifndef __DJGPP__
 #define HAVE_POPEN_H 1
 #endif
 
 #if defined(__DJGPP__)
+#ifndef HAVE_STDINT_H
 typedef unsigned int uint32_t;
 typedef int int32_t;
 #define INT32_MAX INT_MAX
 #define INT32_MIN INT_MIN
 #endif
+#endif
 
 #if defined(__EMX__)
 #define strcasecmp stricmp
 #define strncasecmp strnicmp
 #endif
diff -aprNU5 gawk-4.1.1.orig/pc/gawkmisc.pc gawk-4.1.1/pc/gawkmisc.pc
--- gawk-4.1.1.orig/pc/gawkmisc.pc	2014-01-20 19:53:00 +0100
+++ gawk-4.1.1/pc/gawkmisc.pc	2014-04-27 17:34:40 +0200
@@ -867,18 +867,20 @@ init_sockets(void)
 
 #endif	/* __DJGPP__ || __MINGW32__ */
 
 #ifdef __DJGPP__
 
+# if __DJGPP__ == 2 && __DJGPP_MINOR__ < 4 
 int
 unsetenv (const char *name)
 {
   if (!name || !*name || strchr (name, '=') != NULL)
     return -1;
 
   return putenv (name);
 }
+#endif
 
 /* This is needed to defeat too-clever GCC warnings in dfa.c about
    comparison being always false due to limited range of data type.  */
 wint_t
 btowc (int c)
diff -aprNU5 gawk-4.1.1.orig/pc/popen.c gawk-4.1.1/pc/popen.c
--- gawk-4.1.1.orig/pc/popen.c	2014-02-20 18:49:14 +0100
+++ gawk-4.1.1/pc/popen.c	2014-04-27 17:34:40 +0200
@@ -1,305 +1,255 @@
+/* Copyright (C) 2014 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+/*
+   This is popen() and pclose() for MSDOS.  They were developed using
+   Microsoft C, but should port easily to DOS C any compiler.
+   
+   Original author: pacetti@fl-ngnet.army.mil
+
+   These routines are hacks, that is they SIMULATE their UNIX
+   counterparts.  Since MSDOS and won't allow concurrent process spawning,
+   you can't really pipe.  I came up with this nearly stupid way around
+   piping because I wanted to have some portability between UNIX and MSDOS.
+   I'm probably not the first person to have this idea or implement it, but
+   I think I'm the first to give it away for free (no points?!).
+
+   The functions simulate popen() and pclose() by redirecting stdin or
+   stdout, then spawning a child process via system().
+
+   If you popen() for read, the stdout is redirected to a temporary
+   file, and the child is spawned.  The stdout is reopened via dup2(), the
+   temporary file is opened for read and a file pointer to it is returned.
+
+   If you popen() for write, a temporary file is opened for write, and
+   a file pointer to it is returned.  When you pclose(), the stdin is
+   redirected to the temporary file and the child is spawned.
+
+   In both cases, pclose() closes and unlinks the temporary file.
+
+   A static linked list of C structures is built to store necessary
+   info for all popen()ed files so you can popen() more than one file at
+   a time.
+
+   The popen() function will return NULL on an error, or a valid FILE
+   *pointer on a successful open.  The pclose() function will return
+   negative one (-1) on an error or zero (0) on a successful close.
+
+   The function prototypes are:
+
+   FILE *popen(command, mode)
+        char *command, char *mode;
+
+   int pclose(pp)
+       FILE *pp;
+
+   Where command is a character string equivilant to a MSDOS command
+   line, mode is "r" for read or "w" for write, and pp is a pointer to a
+   file opened through popen().
+ */
+
+#include <libc/stubs.h>
+#include <io.h>
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <io.h>
 #include <string.h>
-#include <process.h>
-#include <errno.h>
-#include "popen.h"
-#undef popen
-#undef pclose
-#undef system
-
-#ifndef _NFILE
-#define _NFILE 40
-#endif
-
-static struct {
-  char *command;
-  char *name;
-  char pmode[4];
-} pipes[_NFILE];
+#include <unistd.h>
+#include <libc/file.h>
 
+/* hold file pointer, command, mode, and the status of the command */
+struct pipe_list {
+  FILE *fp;
+  int exit_status;
+  char *command, mode[10];
+  struct pipe_list *next;
+};
 
-/*
- * For systems where system() and popen() do not follow SHELL:
- *  1. Write command to temp file.  Temp filename must have slashes
- *     compatible with SHELL (if set) or COMSPEC.
- *  2. Convert slashes in SHELL (if present) to be compatible with COMSPEC.
- * Currently, only MSC (running under DOS) and MINGW versions are managed.
- */
+/* static, global list pointer */
+static struct pipe_list *pl = NULL;
 
-#if defined(__MINGW32__)
+FILE *popen(const char *cm, const char *md) /* program name, pipe mode */
+{
+  struct pipe_list *l1;
+  char *temp_name;
 
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
+  /* make new node */
+  if ((l1 = malloc(sizeof(*l1))) == NULL)
+    return NULL;
 
-#if 0
-static int
-unixshell(char *p)
-{
-  static char *shell[] = {"sh", "bash", "csh", "tcsh", "sh32", "sh16", "ksh", NULL};
-  char **shellp = shell, *s, *q;
+  /* if empty list - just grab new node */
+  l1->next = pl;
+  pl = l1;
 
-  if (p == NULL) return (0);
-  s = p = strdup(p);
-  if ((q = strrchr(p, '\\')) != NULL)
-    p = q + 1;
-  if ((q = strrchr(p, '/')) != NULL)
-    p = q + 1;
-  if ((q = strchr(p, '.')) != NULL)
-    *q = '\0';
-  strlwr(p);
-  do {
-    if (strcmp(*shellp, p) == 0) break;
-  } while (*++shellp);
-  free(s);
-  return(*shellp ? 1 : 0);
-}
+  /* stick in elements we know already */
+  l1->command = NULL;
 
-static char *
-slashify(char *p, char *s)
-{
-  if (unixshell(s))
-    while (s = strchr(p, '\\')) *s = '/';
-  else
-    while (s = strchr(p, '/')) *s = '\\';
-  return(p);
-}
+  if ((temp_name = malloc(L_tmpnam)) == NULL)
+    goto error;
 
-static char *
-scriptify(const char *command)
-{
-  FILE *fp;
-  char *cmd, *name, *s, *p;
-  int i;
+  if (tmpnam(temp_name) == NULL)
+    goto error;
 
-  if((name = tempnam(".", "pip")) == NULL) return(NULL);
-  p = getenv("COMSPEC"); s = getenv("SHELL");
-  cmd = malloc(strlen(name) + (s ? strlen(s) : 0) + 9); *cmd = '\0';
-  if (s) {
-    slashify(strcpy(cmd, s), p);
-    p = s;
-  }
-  slashify(name, p);
-  if (! (i = unixshell(p))) {
-    char *p = (char *) realloc(name, strlen(name) + 5);
-    if (p == NULL) {
-	free(cmd);
-	return NULL;
-    }
-    name = p;
-    strcat(name, ".bat");
+  strcpy(l1->mode, md);
+
+  if (l1->mode[0] == 'r')
+  /* caller wants to read */
+  {
+    int fd;
+
+    /* dup stdout */
+    if ((fd = dup(fileno(stdout))) == -1)
+      goto error;
+
+    /* redirect stdout */
+    if (!freopen(temp_name, "wb", stdout))
+      goto error;
+
+    /* make sure file is removed on abnormal exit */
+    stdout->_flag |= _IORMONCL;
+    stdout->_name_to_remove = temp_name;
+
+    /* execute command */
+    l1->exit_status = system(cm);
+
+    /* don't remove file */
+    stdout->_flag &= ~_IORMONCL;
+    stdout->_name_to_remove = NULL;
+
+    /* flush file just in case */
+    fflush(stdout);
+
+    /* reopen real stdout */
+    if (dup2(fd, fileno(stdout)) == -1)
+      goto error;
+
+    /* close duplicate stdout */
+    close(fd);
+
+    /* if cmd couldn't be run, make sure we return NULL */
+    if (l1->exit_status == -1)
+      goto error;
   }
-  if (s) sprintf(cmd + strlen(cmd), " %cc ", unixshell(s) ? '-' : '/');
-  strcpy(p = cmd + strlen(cmd), name); free(name);
+  else if (l1->mode[0] == 'w')
+  /* caller wants to write */
+  {
+    /* if can save the program name, build temp file */
+    if (!(l1->command = malloc(strlen(cm) + 1)))
+      goto error;
 
-  if ((fp = fopen(p, i ? "wb" : "w")) != NULL) {
-    if (! i) fputs("@echo off\n", fp);
-    i = strlen(command);
-    if ((fwrite(command, 1, i, fp) < i) || (fputc('\n', fp) == EOF)) {
-      free(cmd);
-      cmd = NULL;
-    }
-  } else {
-    free(cmd);
-    cmd = NULL;
+    strcpy(l1->command, cm);
   }
-  if (fp) fclose(fp); 
-  return(cmd);
-}
+  else
+    /* unknown mode */
+    goto error;
 
-static void
-unlink_and_free(char *cmd)
-{
-  char *s;
+  /* open file for caller */
+  l1->fp = fopen(temp_name, l1->mode);
 
-  if (s = strrchr(cmd, ' '))
-    s++;
-  else
-    s = cmd;
-  unlink(s); free(cmd);
-}
-#endif
+  /* make sure file is removed on abnormal exit */
+  l1->fp->_flag |= _IORMONCL;
+  l1->fp->_name_to_remove = temp_name;
 
-int
-os_system(const char *cmd)
-{
-  char *cmdexe = getenv("ComSpec");
-  char *cmd1 = quote_cmd(cmd);
-  int i = spawnl(P_WAIT, cmdexe, "cmd.exe", "/c", cmd1, NULL);
+  return l1->fp;
+
+ error:
+
+  if (temp_name)
+    free(temp_name);
+
+  pl = l1->next;
+  free(l1);
 
-  free(cmd1);
-  return(i);
+  return NULL;
 }
 
-#ifndef PIPES_SIMULATED
-int
-kill (int pid, int sig)
+int pclose(FILE *pp)
 {
-  HANDLE ph;
-  int retval = 0;
+  struct pipe_list *l1, **l2;	/* list pointers */
+  char *temp_name;		/* file name */
+  int retval = -1;		/* function return value */
 
-  /* We only support SIGKILL.  */
-  if (sig != SIGKILL)
-    {
-      errno = ENOSYS;
-      return -1;
-    }
+  for (l2 = &pl; *l2; l2 = &(*l2)->next)
+    if ((*l2)->fp == pp)
+      break;
 
-  ph = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
-  if (ph)
-    {
-      BOOL status = TerminateProcess(ph, -1);
+  if (!*l2)
+    return -1;
 
-      if (!status)
-	{
-	  errno = EPERM;
-	  retval = -1;
-	}
-    }
+  l1 = *l2;
+  *l2 = l1->next;
+
+  if (!(l1->fp->_flag & _IORMONCL))
+    /* file wasn't popen()ed */
+    return -1;
   else
-    {
-      /* If we cannot open the process, it means we eaither aren't
-	 allowed to (e.g., a process of another user), or such a
-	 process doesn't exist.  */
-      switch (GetLastError ())
-	{
-	  case ERROR_ACCESS_DENIED:
-	    errno = EPERM;
-	    break;
-	  default:
-	    errno = ESRCH;
-	    break;
-	}
-      retval = -1;
-    }
-  CloseHandle (ph);
-  return retval;
-}
+    temp_name = l1->fp->_name_to_remove;
 
-char *
-quote_cmd(const char *cmd)
-{
-  char *quoted;
+  /* if pipe was opened to write */
+  if (l1->mode[0] == 'w')
+  {
+    int fd;
 
-  /* The command will be invoked via cmd.exe, whose behavior wrt
-     quoted commands is to remove the first and the last quote
-     characters, and leave the rest (including any quote characters
-     inside the outer pair) intact.  */
-  quoted = malloc(strlen (cmd) + 2 + 1);
-  sprintf(quoted, "\"%s\"", cmd);
+    /* don't remove file while closing */
+    l1->fp->_flag &= ~_IORMONCL;
+    l1->fp->_name_to_remove = NULL;
 
-  return quoted;
-}
-#endif
+    /* close the (hopefully) popen()ed file */
+    fclose(l1->fp);
 
-#else  /* !__MINGW32__ */
-#define os_system(cmd) system(cmd)
-#endif
+    /* dup stdin */
+    if ((fd = dup(fileno(stdin))) == -1)
+      goto exit;
 
+    /* redirect stdin */
+    if (!freopen(temp_name, "rb", stdin))
+      goto exit;
 
-FILE *
-os_popen(const char *command, const char *mode )
-{
-    FILE *current;
-    char *name;
-    int cur;
-    char curmode[4];
-
-    if (*mode != 'r' && *mode != 'w')
-      return NULL;
-    strncpy(curmode, mode, 3); curmode[3] = '\0';
-
-#if defined(__MINGW32__)
-    current = popen(command, mode);
-    cur = fileno(current);
-    strcpy(pipes[cur].pmode, curmode);
-    return(current);
-#endif
-
-    /*
-    ** get a name to use.
-    */
-    if((name = tempnam(".","pip"))==NULL)
-        return NULL;
-    /*
-    ** If we're reading, just call system to get a file filled with
-    ** output.
-    */
-    if (*curmode == 'r') {
-        FILE *fp;
-        if ((cur = dup(fileno(stdout))) == -1)
-	    return NULL;
-	*curmode = 'w';
-        if ((current = freopen(name, curmode, stdout)) == NULL)
-	    return NULL;
-        os_system(command);
-        if (dup2(cur, fileno(stdout)) == -1)
-	    return NULL;
-	close(cur);
-	*curmode = 'r';
-        if ((current = fopen(name, curmode)) == NULL)
-            return NULL;
-    } else {
-        if ((current = fopen(name, curmode)) == NULL)
-            return NULL;
-    }
-    cur = fileno(current);
-    pipes[cur].name = name;
-    strcpy(pipes[cur].pmode, curmode);
-    pipes[cur].command = strdup(command);
-    return current;
-}
+    /* make sure file is removed on abnormal exit */
+    stdin->_flag |= _IORMONCL;
+    stdin->_name_to_remove = temp_name;
 
-int
-os_pclose( FILE * current)
-{
-    int cur = fileno(current);
-    int fd, rval;
+    /* execute command */
+    retval = system(l1->command);
+
+    /* don't remove file */
+    stdin->_flag &= ~_IORMONCL;
+    stdin->_name_to_remove = NULL;
+
+    /* close and remove file */
+    close(fileno(stdin));
+    remove(temp_name);
 
-#if defined(__MINGW32__)
-    rval = pclose(current);
-    *pipes[cur].pmode = '\0';
-    return rval;
-#endif
-
-    /*
-    ** check for an open file.
-    */
-    switch (*pipes[cur].pmode) {
-    case 'r':
-        /*
-        ** input pipes are just files we're done with.
-        */
-        rval = fclose(current);
-        unlink(pipes[cur].name);
-	break;
-    case 'w':
-        /*
-        ** output pipes are temporary files we have
-        ** to cram down the throats of programs.
-        */
-        fclose(current);
-	rval = -1;
-	if ((fd = dup(fileno(stdin))) != -1) {
-	  char *mode = pipes[cur].pmode; *mode = 'r';
-	  if (current = freopen(pipes[cur].name, mode, stdin)) {
-	    rval = os_system(pipes[cur].command);
-	    fclose(current);
-	    if (dup2(fd, fileno(stdin)) == -1) rval = -1;
-	    close(fd);
-	  }
-	}
-        unlink(pipes[cur].name);
-	break;
-    default:
-      return -1;
+    /* reopen real stdin */
+    if (dup2(fd, fileno(stdin)) == -1)
+    {
+      retval = -1;
+      goto exit;
     }
-    /*
-    ** clean up current pipe.
-    */
-    *pipes[cur].pmode = '\0';
-    free(pipes[cur].name);
-    free(pipes[cur].command);
-    return rval;
+
+    /* close duplicate stdin */
+    close(fd);
+
+  exit:
+
+    free(l1->command);
+  }
+  /* if pipe was opened to read, return the exit status we saved */
+  else if (l1->mode[0] == 'r')
+  {
+    retval = l1->exit_status;
+
+    /* close and remove file */
+    fclose(l1->fp);
+  }
+  else
+    /* invalid mode */
+    retval = -1;
+
+  free(l1);
+
+  return retval;
 }
diff -aprNU5 gawk-4.1.1.orig/test/beginfile1.ok gawk-4.1.1/test/beginfile1.ok
--- gawk-4.1.1.orig/test/beginfile1.ok	2014-01-20 19:53:00 +0100
+++ gawk-4.1.1/test/beginfile1.ok	2014-04-27 17:34:40 +0200
@@ -2,13 +2,13 @@ In BEGINFILE:
 	FILENAME = beginfile1.awk, FNR = 0, ERRNO = ""
 processing beginfile1.awk
 In ENDFILE:
 	FILENAME = beginfile1.awk, FNR = 2, ERRNO = ""
 In BEGINFILE:
-	FILENAME = ., FNR = 0, ERRNO = "Is a directory"
+	FILENAME = ., FNR = 0, ERRNO = "Is a directory (EISDIR)"
 In BEGINFILE:
-	FILENAME = file, FNR = 0, ERRNO = "No such file or directory"
+	FILENAME = file, FNR = 0, ERRNO = "No such file or directory (ENOENT)"
 In BEGINFILE:
-	FILENAME = Makefile, FNR = 0, ERRNO = ""
+	FILENAME = Makefile, FNR = 0, ERRNO = "No such file or directory (ENOENT)"
 processing Makefile
 In ENDFILE:
 	FILENAME = Makefile, FNR = 2, ERRNO = ""
diff -aprNU5 gawk-4.1.1.orig/test/getlndir.ok gawk-4.1.1/test/getlndir.ok
--- gawk-4.1.1.orig/test/getlndir.ok	2012-05-03 18:13:56 +0200
+++ gawk-4.1.1/test/getlndir.ok	2014-04-27 17:34:40 +0200
@@ -1 +1 @@
-4, -1, Is a directory
+4, -1, Is a directory (EISDIR)
diff -aprNU5 gawk-4.1.1.orig/test/space.ok gawk-4.1.1/test/space.ok
--- gawk-4.1.1.orig/test/space.ok	2012-05-03 18:13:56 +0200
+++ gawk-4.1.1/test/space.ok	2014-04-27 17:34:40 +0200
@@ -1,2 +1,2 @@
-gawk: fatal: can't open source file ` ' for reading (No such file or directory)
+gawk: fatal: can't open source file ` ' for reading (No such file or directory (ENOENT))
 EXIT CODE: 2
