Blame pc/gawkmisc.pc

Packit Service f629e6
/* gawkmisc.c --- miscellaneous gawk routines that are OS specific. -*-C-*- */
Packit Service f629e6
Packit Service f629e6
/* 
Packit Service f629e6
 * Copyright (C) 1986, 1988, 1989, 1991 - 2003, 2012, 2016
Packit Service f629e6
 * the Free Software Foundation, Inc.
Packit Service f629e6
 * 
Packit Service f629e6
 * This file is part of GAWK, the GNU implementation of the
Packit Service f629e6
 * AWK Progamming Language.
Packit Service f629e6
 * 
Packit Service f629e6
 * GAWK is free software; you can redistribute it and/or modify
Packit Service f629e6
 * it under the terms of the GNU General Public License as published by
Packit Service f629e6
 * the Free Software Foundation; either version 3 of the License, or
Packit Service f629e6
 * (at your option) any later version.
Packit Service f629e6
 * 
Packit Service f629e6
 * GAWK is distributed in the hope that it will be useful,
Packit Service f629e6
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service f629e6
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service f629e6
 * GNU General Public License for more details.
Packit Service f629e6
 * 
Packit Service f629e6
 * You should have received a copy of the GNU General Public License
Packit Service f629e6
 * along with this program; if not, write to the Free Software
Packit Service f629e6
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
Packit Service f629e6
 */
Packit Service f629e6
Packit Service f629e6
char quote = '\'';
Packit Service f629e6
char envsep = ';';
Packit Service f629e6
Packit Service f629e6
# ifdef DEFPATH
Packit Service f629e6
char *defpath = DEFPATH;
Packit Service f629e6
# else
Packit Service f629e6
char *defpath = ".;c:\\lib\\awk;c:\\gnu\\lib\\awk";
Packit Service f629e6
# endif
Packit Service f629e6
/* the Makefile should define DEFLIBPATH */
Packit Service f629e6
char *deflibpath = DEFLIBPATH;
Packit Service f629e6
Packit Service f629e6
#ifdef __EMX__
Packit Service f629e6
#include<io.h>
Packit Service f629e6
Packit Service f629e6
static int _os2_is_abs_path(const char *dirname);
Packit Service f629e6
static char* _os2_unixroot(const char *path);
Packit Service f629e6
static const char* _os2_unixroot_path(const char *path);
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
#ifdef __MINGW32__
Packit Service f629e6
#ifdef HAVE_SOCKETS
Packit Service f629e6
#include <socket.h>
Packit Service f629e6
Packit Service f629e6
#undef socket
Packit Service f629e6
#undef setsockopt
Packit Service f629e6
#undef bind
Packit Service f629e6
#undef connect
Packit Service f629e6
#undef listen
Packit Service f629e6
#undef accept
Packit Service f629e6
#undef recvfrom
Packit Service f629e6
#undef shutdown
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
#define WIN32_LEAN_AND_MEAN
Packit Service f629e6
#include <windows.h>
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
/* gawk_name --- pull out the "gawk" part from how the OS called us */
Packit Service f629e6
Packit Service f629e6
char *
Packit Service f629e6
gawk_name(filespec)
Packit Service f629e6
const char *filespec;
Packit Service f629e6
{
Packit Service f629e6
	char *p, *q;
Packit Service f629e6
Packit Service f629e6
	p = (char *) filespec;  /* Sloppy... */
Packit Service f629e6
Packit Service f629e6
	/* OS/2 allows / for directory separator too */
Packit Service f629e6
	if ((q = strrchr(p, '\\')) != NULL)
Packit Service f629e6
		p = q + 1;
Packit Service f629e6
	if ((q = strrchr(p, '/')) != NULL
Packit Service f629e6
	    && (p == NULL || q > p)) /* support mixed d:\foo/bar\gawk.exe */
Packit Service f629e6
		p = q + 1;
Packit Service f629e6
	if ((q = strchr(p, '.')) != NULL)
Packit Service f629e6
		*q = '\0';
Packit Service f629e6
	return strlwr(p);
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
Packit Service f629e6
/*
Packit Service f629e6
 * memcpy_long() & memset_ulong() are 32-bit replacements for MSC which
Packit Service f629e6
 * has a 16-bit size_t.
Packit Service f629e6
 */
Packit Service f629e6
char *
Packit Service f629e6
memcpy_ulong (dest, src, l)
Packit Service f629e6
register char *dest;
Packit Service f629e6
register const char *src;
Packit Service f629e6
register unsigned long l;
Packit Service f629e6
{
Packit Service f629e6
	register char *ret = dest;
Packit Service f629e6
Packit Service f629e6
	while (l--)
Packit Service f629e6
		*dest++ = *src++;
Packit Service f629e6
Packit Service f629e6
	return ret;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
Packit Service f629e6
void *
Packit Service f629e6
memset_ulong(dest, val, l)
Packit Service f629e6
void *dest;
Packit Service f629e6
register int val;
Packit Service f629e6
register unsigned long l;
Packit Service f629e6
{
Packit Service f629e6
	register char *ret = dest;
Packit Service f629e6
	register char *d = dest;
Packit Service f629e6
Packit Service f629e6
	while (l--)
Packit Service f629e6
		*d++ = val;
Packit Service f629e6
Packit Service f629e6
	return ((void *) ret);
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
Packit Service f629e6
/* os_arg_fixup --- fixup the command line */
Packit Service f629e6
Packit Service f629e6
void
Packit Service f629e6
os_arg_fixup(argcp, argvp)
Packit Service f629e6
int *argcp;
Packit Service f629e6
char ***argvp;
Packit Service f629e6
{
Packit Service f629e6
#ifdef __EMX__
Packit Service f629e6
# ifdef initialize_main
Packit Service f629e6
	initialize_main(argcp, argvp);
Packit Service f629e6
# else
Packit Service f629e6
	_wildcard(argcp, argvp);
Packit Service f629e6
	_response(argcp, argvp);
Packit Service f629e6
# endif
Packit Service f629e6
Packit Service f629e6
	setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
Packit Service f629e6
	defpath = (char*) _os2_unixroot_path(defpath);
Packit Service f629e6
#endif /* __EMX__ */
Packit Service f629e6
	return;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
/* os_devopen --- open special per-OS devices */
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
os_devopen(name, flag)
Packit Service f629e6
const char *name;
Packit Service f629e6
int flag;
Packit Service f629e6
{
Packit Service f629e6
#ifdef __EMX__
Packit Service f629e6
	/* do not use open(name, flag) here !!! */
Packit Service f629e6
	return -1;
Packit Service f629e6
#else
Packit Service f629e6
	if (strcmp(name, "/dev/null") == 0)
Packit Service f629e6
		return open("NUL", flag);
Packit Service f629e6
	/* FIXME: */
Packit Service f629e6
	/* else if (strcmp(name, "/dev/tty") == 0)
Packit Service f629e6
	 * 	return open("???", flag);
Packit Service f629e6
	 */
Packit Service f629e6
	return -1;
Packit Service f629e6
#endif
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
/* optimal_bufsize --- determine optimal buffer size */
Packit Service f629e6
Packit Service f629e6
size_t
Packit Service f629e6
optimal_bufsize(fd, stb)
Packit Service f629e6
int fd;
Packit Service f629e6
struct stat *stb;
Packit Service f629e6
{
Packit Service f629e6
	/* force all members to zero in case OS doesn't use all of them. */
Packit Service f629e6
	memset(stb, '\0', sizeof(struct stat));
Packit Service f629e6
Packit Service f629e6
	/*
Packit Service f629e6
	 * DOS doesn't have the file system block size in the
Packit Service f629e6
	 * stat structure. So we have to make some sort of reasonable
Packit Service f629e6
	 * guess. We use stdio's BUFSIZ, since that is what it was
Packit Service f629e6
	 * meant for in the first place.
Packit Service f629e6
	 */
Packit Service f629e6
#define	DEFBLKSIZE	BUFSIZ
Packit Service f629e6
Packit Service f629e6
	if (fstat(fd, stb) == -1)
Packit Service f629e6
		fatal("can't stat fd %d (%s)", fd, strerror(errno));
Packit Service f629e6
	if (S_ISREG(stb->st_mode)
Packit Service f629e6
	    && 0 < stb->st_size && stb->st_size < DEFBLKSIZE) /* small file */
Packit Service f629e6
		return stb->st_size;
Packit Service f629e6
	return DEFBLKSIZE;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
/* ispath --- return true if path has directory components */
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
ispath(file)
Packit Service f629e6
const char *file;
Packit Service f629e6
{
Packit Service f629e6
#ifdef __EMX__
Packit Service f629e6
	return (strpbrk(file, "/\\") != NULL ||
Packit Service f629e6
		(toupper(file[0]) >= 'A' && toupper(file[0]) <= 'Z' && file[1] == ':'));
Packit Service f629e6
#else
Packit Service f629e6
	for (; *file; file++) {
Packit Service f629e6
		switch (*file) {
Packit Service f629e6
		case '/':
Packit Service f629e6
		case '\\':
Packit Service f629e6
		case ':':
Packit Service f629e6
			return 1;
Packit Service f629e6
		}
Packit Service f629e6
	}
Packit Service f629e6
	return 0;
Packit Service f629e6
#endif
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
/* isdirpunct --- return true if char is a directory separator */
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
isdirpunct(c)
Packit Service f629e6
int c;
Packit Service f629e6
{
Packit Service f629e6
	return (strchr(":\\/", c) != NULL);
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
/* os_close_on_exec --- set close on exec flag, print warning if fails */
Packit Service f629e6
Packit Service f629e6
void
Packit Service f629e6
os_close_on_exec(fd, name, what, dir)
Packit Service f629e6
int fd;
Packit Service f629e6
const char *name, *what, *dir;
Packit Service f629e6
{
Packit Service f629e6
#if (defined(__DJGPP__) && (__DJGPP__ > 2 || __DJGPP_MINOR__ >= 4)) || defined __EMX__
Packit Service f629e6
	if (fd <= 2)	/* sanity */
Packit Service f629e6
		return;
Packit Service f629e6
Packit Service f629e6
	if (fcntl(fd, F_SETFD, 1) < 0)
Packit Service f629e6
		warning("%s %s `%s': could not set close-on-exec: %s",
Packit Service f629e6
			what, dir, name, strerror(errno));
Packit Service f629e6
#endif
Packit Service f629e6
#ifdef __MINGW32__
Packit Service f629e6
	HANDLE fh = (HANDLE)_get_osfhandle(fd);
Packit Service f629e6
Packit Service f629e6
	if (fh && fh != INVALID_HANDLE_VALUE)
Packit Service f629e6
		SetHandleInformation(fh, HANDLE_FLAG_INHERIT, 0);
Packit Service f629e6
#endif
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
/* os_isdir --- is this an fd on a directory? */
Packit Service f629e6
Packit Service f629e6
#if ! defined(S_ISDIR) && defined(S_IFDIR)
Packit Service f629e6
#define	S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
os_isdir(fd)
Packit Service f629e6
int fd;
Packit Service f629e6
{
Packit Service f629e6
	struct stat sbuf;
Packit Service f629e6
Packit Service f629e6
	return (fstat(fd, &sbuf) == 0 && S_ISDIR(sbuf.st_mode));
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
/* os_isreadable --- fd can be read from */
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
os_isreadable(const awk_input_buf_t *iobuf, bool *isdir)
Packit Service f629e6
{
Packit Service f629e6
	*isdir = false;
Packit Service f629e6
Packit Service f629e6
	switch (iobuf->sbuf.st_mode & S_IFMT) {
Packit Service f629e6
	case S_IFREG:
Packit Service f629e6
	case S_IFCHR:	/* ttys, /dev/null, .. */
Packit Service f629e6
#ifdef S_IFSOCK
Packit Service f629e6
	case S_IFSOCK:
Packit Service f629e6
#endif
Packit Service f629e6
#ifdef S_IFIFO
Packit Service f629e6
	case S_IFIFO:
Packit Service f629e6
#endif
Packit Service f629e6
		return true;
Packit Service f629e6
	case S_IFDIR:
Packit Service f629e6
		*isdir = true;
Packit Service f629e6
		/* fall through */
Packit Service f629e6
	default:
Packit Service f629e6
		return false;
Packit Service f629e6
	}
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
/* os_is_setuid --- true if running setuid root */
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
os_is_setuid()
Packit Service f629e6
{
Packit Service f629e6
#ifdef __EMX__
Packit Service f629e6
      	long uid, euid;
Packit Service f629e6
Packit Service f629e6
	uid = getuid();
Packit Service f629e6
	euid = geteuid();
Packit Service f629e6
Packit Service f629e6
	return (euid == 0 && euid != uid);
Packit Service f629e6
#else
Packit Service f629e6
	return 0;
Packit Service f629e6
#endif
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
/* os_setbinmode --- set binary mode on file */
Packit Service f629e6
Packit Service f629e6
#ifdef __DJGPP__
Packit Service f629e6
#include <sys/exceptn.h>
Packit Service f629e6
#include <io.h>
Packit Service f629e6
#endif
Packit Service f629e6
static int orig_tty_mode = -1;
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
os_setbinmode(fd, mode)
Packit Service f629e6
int fd, mode;
Packit Service f629e6
{
Packit Service f629e6
	int prev_mode = setmode(fd, mode);
Packit Service f629e6
Packit Service f629e6
#ifdef __DJGPP__
Packit Service f629e6
	if ((mode & O_BINARY) != 0)
Packit Service f629e6
		__djgpp_set_ctrl_c(1); /* allow to interrupt with Ctrl-C */
Packit Service f629e6
#endif
Packit Service f629e6
	/* Save the original tty mode as we found it.  */
Packit Service f629e6
	if (orig_tty_mode == -1 && fd >= 0 && fd <= 2)
Packit Service f629e6
		orig_tty_mode = prev_mode;
Packit Service f629e6
	return prev_mode;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
/* os_restore_mode --- restore the original mode of the console device */
Packit Service f629e6
Packit Service f629e6
void
Packit Service f629e6
os_restore_mode (fd)
Packit Service f629e6
int fd;
Packit Service f629e6
{
Packit Service f629e6
	if (orig_tty_mode != -1) {
Packit Service f629e6
		setmode(fd, orig_tty_mode);
Packit Service f629e6
	}
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
/* os_isatty --- return true if fd is a tty */
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
os_isatty(int fd)
Packit Service f629e6
{
Packit Service f629e6
#if defined(__MINGW32__) || defined(_MSC_VER)
Packit Service f629e6
	return (isatty(fd) && lseek(fd, SEEK_CUR, 0) == -1);
Packit Service f629e6
#else
Packit Service f629e6
	return isatty(fd);
Packit Service f629e6
#endif
Packit Service f629e6
}
Packit Service f629e6
 
Packit Service f629e6
/* files_are_same --- return true if files are identical */
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
files_are_same(char *path, SRCFILE *src)
Packit Service f629e6
{
Packit Service f629e6
	struct stat st;
Packit Service f629e6
	size_t pathlen;
Packit Service f629e6
	char *p, *s;
Packit Service f629e6
Packit Service f629e6
	if (stat (path, & st) == 0) {
Packit Service f629e6
		/* If they have a working `stat', honor that.  */
Packit Service f629e6
		if (!(st.st_dev == src->sbuf.st_dev
Packit Service f629e6
		      && st.st_ino == src->sbuf.st_ino))
Packit Service f629e6
			return 0;
Packit Service f629e6
Packit Service f629e6
		/* Compare modification times.  */
Packit Service f629e6
		if (st.st_mtime != src->mtime)
Packit Service f629e6
			return 0;
Packit Service f629e6
Packit Service f629e6
		/* Compare absolute file names case-insensitively, and
Packit Service f629e6
		   treat forward- and back-slashes as equal.  */
Packit Service f629e6
		pathlen = strlen(path);
Packit Service f629e6
		for (p = path, s = src->fullpath;
Packit Service f629e6
		     p <= path + pathlen;
Packit Service f629e6
		     p++, s++) {
Packit Service f629e6
			if (tolower(*p) != tolower(*s)
Packit Service f629e6
			    && !((*p == '/' || *p == '\\')
Packit Service f629e6
				 && (*s == '/' || *s == '\\')))
Packit Service f629e6
				return 0;
Packit Service f629e6
		}
Packit Service f629e6
		return 1;
Packit Service f629e6
	}
Packit Service f629e6
	return 0;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
Packit Service f629e6
#ifdef __EMX__ 
Packit Service f629e6
# ifndef PATH_SEPARATOR
Packit Service f629e6
#  define PATH_SEPARATOR ';'
Packit Service f629e6
# endif
Packit Service f629e6
Packit Service f629e6
/* result is 0 if dirname is no absolute path, 1 otherwise */
Packit Service f629e6
Packit Service f629e6
static int
Packit Service f629e6
_os2_is_abs_path(const char *dirname)
Packit Service f629e6
{
Packit Service f629e6
  int result = 0;
Packit Service f629e6
  if (dirname != NULL && dirname[0] != '\0') {
Packit Service f629e6
    /* if dirname contains a valid drive letter like "c:" */
Packit Service f629e6
    if (((dirname[0] >= 'A' && dirname[0] <= 'Z') || (dirname[0] >= 'a' && dirname[0] <= 'z'))
Packit Service f629e6
        && dirname[1] == ':') dirname += 2; /* remove the drive letter */
Packit Service f629e6
Packit Service f629e6
    if (dirname[0] == '/' || dirname[0] == '\\') result = 1; /* asbolute path */
Packit Service f629e6
  }
Packit Service f629e6
Packit Service f629e6
  return result;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
Packit Service f629e6
/* path is assumed to be a list of directories separated by PATH_SEPARATOR.
Packit Service f629e6
   This function determines if the first directory of path is on the
Packit Service f629e6
   drive specified by the environment variable UNIXROOT.
Packit Service f629e6
   If it is the case, NULL is returned, otherwise a new directory name
Packit Service f629e6
   is allocated using the drive letter from UNIXROOT and returned as result.
Packit Service f629e6
   If the first directory is a relative path NULL is returned, too.
Packit Service f629e6
   The new directory name is allocated by malloc().
Packit Service f629e6
   Example (UNIXROOT is set to "e:"):
Packit Service f629e6
     "c:/usr/share" -> "e:/usr/share"
Packit Service f629e6
     "e:/usr/share" -> NULL             (already on the $UNIXROOT drive)
Packit Service f629e6
     "/usr/share"   -> "e:/usr/share"
Packit Service f629e6
     "."            -> NULL             (not an absolute path)
Packit Service f629e6
     "usr/share"    -> NULL             (not an absolute path)
Packit Service f629e6
     "c:usr/share"  -> NULL             (not an absolute path)
Packit Service f629e6
     "c:/usr/share;d:/etc" -> "e:/usr/share" (only the first directory in path is used) */
Packit Service f629e6
Packit Service f629e6
static char*
Packit Service f629e6
_os2_unixroot(const char *path)
Packit Service f629e6
{
Packit Service f629e6
  static const char *unixroot = NULL;
Packit Service f629e6
  static int unixroot_init = 0; 
Packit Service f629e6
  char *result = NULL; 
Packit Service f629e6
Packit Service f629e6
  if (unixroot_init == 0) {
Packit Service f629e6
    /* get $UNIXROOT only one time */
Packit Service f629e6
    unixroot = getenv("UNIXROOT");
Packit Service f629e6
Packit Service f629e6
    /* check whether unixroot is valid (must be "x:") */
Packit Service f629e6
    if (unixroot != NULL) {
Packit Service f629e6
      int drive = toupper(unixroot[0]);
Packit Service f629e6
      if (drive < 'A' || drive > 'Z' || unixroot[1] != ':' || unixroot[2] != '\0')
Packit Service f629e6
        unixroot = NULL; /* unixroot not valid */
Packit Service f629e6
    }
Packit Service f629e6
Packit Service f629e6
    unixroot_init = 1; /* initialized */
Packit Service f629e6
  }
Packit Service f629e6
Packit Service f629e6
  /* note: if unixroot != NULL then it contains a valid drive letter */
Packit Service f629e6
  if (unixroot != NULL && _os2_is_abs_path(path)) {
Packit Service f629e6
    /* dirname is an absolute path and unixroot is a drive letter, "c:" for example */
Packit Service f629e6
    size_t old_path_len = strlen(path);
Packit Service f629e6
Packit Service f629e6
    /* end points to the first ';' in path or to NULL */
Packit Service f629e6
    const char *end = strchr(path, PATH_SEPARATOR);
Packit Service f629e6
Packit Service f629e6
    /* dir_len is the length of the first directory in path */
Packit Service f629e6
    size_t dir_len = (end) ? end - path : old_path_len;
Packit Service f629e6
Packit Service f629e6
    if (toupper(unixroot[0]) != toupper(path[0]) || path[1] != ':') {
Packit Service f629e6
      /* the first directory of path does not start with the string $UNIXROOT */
Packit Service f629e6
      if (path[1] == ':') {
Packit Service f629e6
        /* if there is a drive letter remove it */
Packit Service f629e6
        dir_len -= 2;
Packit Service f629e6
        path += 2;
Packit Service f629e6
      } 
Packit Service f629e6
Packit Service f629e6
      result = malloc(dir_len + 3);
Packit Service f629e6
      if (result) { /* do nothing if we are out of memory */
Packit Service f629e6
        result[0] = unixroot[0];
Packit Service f629e6
        result[1] = unixroot[1];
Packit Service f629e6
        memcpy(result + 2, path, dir_len);
Packit Service f629e6
        result[dir_len + 2] = '\0';
Packit Service f629e6
      }
Packit Service f629e6
    }
Packit Service f629e6
  }
Packit Service f629e6
  return result;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
/* path is assumed to be a list of directories separated by PATH_SEPARATOR.
Packit Service f629e6
   Every directory is processed. _os2_unixroot() is used to find out whether
Packit Service f629e6
   these directories are on the drive specified by the environment variable
Packit Service f629e6
   UNIXROOT. If this is not the case the same directory on the UNIXROOT drive
Packit Service f629e6
   is added to the end of path. If path is a valid path this function returns a valid path, too.
Packit Service f629e6
   Example ($UNIXROOT is set to "e:"):
Packit Service f629e6
   ".;c:/usr/local;d:/usr/local;d:/etc;e:/etc"
Packit Service f629e6
   -> ".;c:/usr/local;d:/usr/local;d:/etc;e:/etc;e:/usr/local;e:/usr/local;e:/etc" */
Packit Service f629e6
Packit Service f629e6
static const char*
Packit Service f629e6
_os2_unixroot_path(const char *path)
Packit Service f629e6
{
Packit Service f629e6
  char *result = NULL;
Packit Service f629e6
  const char *p = path;
Packit Service f629e6
  unsigned dir_count = 1;
Packit Service f629e6
Packit Service f629e6
  if (path == NULL || path[0] == '\0') return NULL; /* empty path */
Packit Service f629e6
Packit Service f629e6
  /* save number of path components in dir_count */
Packit Service f629e6
  while(*p) {
Packit Service f629e6
    if (*p++ == PATH_SEPARATOR && *p != '\0' && *p != PATH_SEPARATOR)
Packit Service f629e6
      dir_count += 1;
Packit Service f629e6
  }
Packit Service f629e6
Packit Service f629e6
  {
Packit Service f629e6
    const char *list[dir_count]; /* list of char pointers */
Packit Service f629e6
    size_t dir_len[dir_count]; /* the according directory length */
Packit Service f629e6
    size_t old_path_len = strlen(path); /* the old path length */
Packit Service f629e6
    size_t total_len;
Packit Service f629e6
    unsigned i = 0;
Packit Service f629e6
Packit Service f629e6
    if (path[old_path_len - 1] == PATH_SEPARATOR) /* last character is ';' */
Packit Service f629e6
      old_path_len--;
Packit Service f629e6
Packit Service f629e6
    list[0] = p = path; /* first directory */
Packit Service f629e6
Packit Service f629e6
    while(*p) {
Packit Service f629e6
    if (*p++ == PATH_SEPARATOR && *p != '\0' && *p != PATH_SEPARATOR)
Packit Service f629e6
      list[++i] = p;
Packit Service f629e6
    }
Packit Service f629e6
    /* now list[i] contains the ith directory of path (no 0-terminated strings!!!) */
Packit Service f629e6
Packit Service f629e6
    /* determine the total length for the new path */
Packit Service f629e6
    total_len = old_path_len;
Packit Service f629e6
Packit Service f629e6
    for(i = 0; i < dir_count; i++) {
Packit Service f629e6
      list[i] = _os2_unixroot(list[i]);
Packit Service f629e6
      if (list[i] != NULL) {
Packit Service f629e6
        dir_len[i] = strlen(list[i]);
Packit Service f629e6
        total_len += dir_len[i] + 1; /* one character for ';' or '\0' */
Packit Service f629e6
      }
Packit Service f629e6
      else dir_len[i] = 0;
Packit Service f629e6
    }
Packit Service f629e6
    /* now list[] contains the according directories on the UNIXROOT drive or NULL
Packit Service f629e6
       total_len contains the total length for the new path */
Packit Service f629e6
    result = malloc(total_len + 1);
Packit Service f629e6
Packit Service f629e6
    if (result) {
Packit Service f629e6
      /* copy the old path and the new directories into the new path */
Packit Service f629e6
      char *q = result;
Packit Service f629e6
      memcpy(q, path, old_path_len);
Packit Service f629e6
      q += old_path_len;
Packit Service f629e6
Packit Service f629e6
      for(i = 0; i < dir_count; i++) {
Packit Service f629e6
        if (dir_len[i] != 0) {
Packit Service f629e6
          *q++ = PATH_SEPARATOR;
Packit Service f629e6
          memcpy(q, list[i], dir_len[i]);
Packit Service f629e6
          q += dir_len[i];
Packit Service f629e6
        }
Packit Service f629e6
      }
Packit Service f629e6
Packit Service f629e6
      *q = '\0'; /* terminating '\0' */
Packit Service f629e6
    }
Packit Service f629e6
Packit Service f629e6
    for(i = 0; i < dir_count; i++) free((void*) list[i]);
Packit Service f629e6
  }
Packit Service f629e6
Packit Service f629e6
  return (result) ? (const char*) result : path;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
/* limit a length of DLL name up to 8 characters. If dst is not enough for
Packit Service f629e6
   a fixed dll name, it is truncated. */
Packit Service f629e6
char *os2_fixdllname(char *dst, const char *src, size_t n)
Packit Service f629e6
{
Packit Service f629e6
    char drive[_MAX_DRIVE];
Packit Service f629e6
    char dir[_MAX_DIR];
Packit Service f629e6
    char name[_MAX_FNAME];
Packit Service f629e6
    char ext[_MAX_EXT];
Packit Service f629e6
    char dll_file[_MAX_PATH];
Packit Service f629e6
Packit Service f629e6
    _splitpath(src, drive, dir, name, ext);
Packit Service f629e6
    if (strlen(name) > 8)
Packit Service f629e6
        name[8] = '\0';
Packit Service f629e6
    _makepath(dll_file, drive, dir, name, ext);
Packit Service f629e6
Packit Service f629e6
    strncpy(dst, dll_file, n);
Packit Service f629e6
    dst[n - 1] = '\0';
Packit Service f629e6
Packit Service f629e6
    return dst;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
#ifdef __KLIBC__
Packit Service f629e6
Packit Service f629e6
/* replacement of dlopen(). This limits a length of a base name up to 8
Packit Service f629e6
   characters. */
Packit Service f629e6
void *os2_dlopen(const char *file, int mode)
Packit Service f629e6
{
Packit Service f629e6
    char dll_file[strlen(file) + 1];
Packit Service f629e6
Packit Service f629e6
    return (dlopen)(os2_fixdllname(dll_file, file, sizeof(dll_file)), mode);
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
/* replacement of dlsym(). This prepends '_' to name. */
Packit Service f629e6
void *os2_dlsym(void *handle, const char *name)
Packit Service f629e6
{
Packit Service f629e6
    char sym[strlen(name) + 1 + 1]; /* 1 for '_', 1 for NUL */
Packit Service f629e6
Packit Service f629e6
    sym[0] = '_';
Packit Service f629e6
    strcpy(sym + 1, name);
Packit Service f629e6
Packit Service f629e6
    return (dlsym)(handle, sym);
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
#endif /* __KLIBC__ */
Packit Service f629e6
Packit Service f629e6
#endif /* __EMX__ */
Packit Service f629e6
Packit Service f629e6
#ifdef __MINGW32__
Packit Service f629e6
Packit Service f629e6
extern void *xmalloc (size_t);
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
setenv (const char *name, const char *value, int rewrite)
Packit Service f629e6
{
Packit Service f629e6
  char *entry;
Packit Service f629e6
Packit Service f629e6
  if (*value == '=')
Packit Service f629e6
    ++value;
Packit Service f629e6
Packit Service f629e6
  if (getenv (name) && !rewrite)
Packit Service f629e6
    return 0;
Packit Service f629e6
Packit Service f629e6
  entry = xmalloc (strlen (name) + 1 + strlen (value) + 1);
Packit Service f629e6
  strcat (strcat (strcpy (entry, name), "="), value);
Packit Service f629e6
  if (putenv (entry) != 0)
Packit Service f629e6
    {
Packit Service f629e6
      free (entry);
Packit Service f629e6
      return -1;
Packit Service f629e6
    }
Packit Service f629e6
  return 0;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
unsetenv (const char *name)
Packit Service f629e6
{
Packit Service f629e6
  if (!name || !*name || strchr (name, '=') != NULL)
Packit Service f629e6
    return -1;
Packit Service f629e6
Packit Service f629e6
  return setenv (name, "", 1);
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
/* MinGW 3.21 and later defines usleep as an inline function in
Packit Service f629e6
   unistd.h, which conflicts with the version below.  */
Packit Service f629e6
#if __MINGW32_MAJOR_VERSION + (__MINGW32_MINOR_VERSION > 20) < 4
Packit Service f629e6
int
Packit Service f629e6
usleep(unsigned int usec)
Packit Service f629e6
{
Packit Service f629e6
  double msecf = usec / 1000.0;
Packit Service f629e6
Packit Service f629e6
  Sleep ((DWORD)msecf);
Packit Service f629e6
Packit Service f629e6
  return usec - msecf * 1000 < 0 ? 0 : (int)(usec - msecf * 1000);
Packit Service f629e6
}
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
/* The implementation of wctob in the MS runtime is problematic
Packit Service f629e6
   because it doesn't allow to distinguish between WEOF and 0xff, due
Packit Service f629e6
   to integer sign extension.  It also causes failures in dfa.c when
Packit Service f629e6
   characters with the 8th bit set are involved.  This replacement
Packit Service f629e6
   version fixes that.  */
Packit Service f629e6
Packit Service f629e6
#include <wchar.h>
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
wctob (wint_t wc)
Packit Service f629e6
{
Packit Service f629e6
  char buf[64];
Packit Service f629e6
Packit Service f629e6
  if (!(MB_CUR_MAX <= sizeof (buf)))
Packit Service f629e6
    abort ();
Packit Service f629e6
  /* Handle the case where WEOF is a value that does not fit in a wchar_t.  */
Packit Service f629e6
  if (wc == (wchar_t)wc)
Packit Service f629e6
    if (wctomb (buf, (wchar_t)wc) == 1)
Packit Service f629e6
      return (unsigned char) buf[0];
Packit Service f629e6
  return EOF;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
Packit Service f629e6
#undef setlocale
Packit Service f629e6
#include <locale.h>
Packit Service f629e6
Packit Service f629e6
/* On Posix systems, 'setlocale' looks at LC_* variables in the
Packit Service f629e6
   environment, and Gawk users might expect that on Windows as well.
Packit Service f629e6
   The replacement implementation below does that, and also fixes a
Packit Service f629e6
   few additional quirks with locales on Windows.  */
Packit Service f629e6
static const char *
Packit Service f629e6
lc_var (int category)
Packit Service f629e6
{
Packit Service f629e6
  static const char *loc_name[LC_MAX - LC_MIN + 1] = {
Packit Service f629e6
    "LC_ALL", "LC_COLLATE", "LC_CTYPE", "LC_MONETARY", "LC_NUMERIC", "LC_TIME"
Packit Service f629e6
  };
Packit Service f629e6
Packit Service f629e6
  /* This function assumes LC_* categories are small numbers between 0
Packit Service f629e6
     and 5, as shown above, so if that changes at some point, complain
Packit Service f629e6
     vociferously.  */
Packit Service f629e6
  if (LC_ALL != 0 || LC_CTYPE != 2 || LC_TIME != 5)
Packit Service f629e6
    abort ();
Packit Service f629e6
  /* Ensured by the caller, so should never happen.  */
Packit Service f629e6
  if (category < LC_MIN || category > LC_MAX)
Packit Service f629e6
    return "????";
Packit Service f629e6
  return loc_name[category];
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
char *
Packit Service f629e6
w32_setlocale (int category, const char *value)
Packit Service f629e6
{
Packit Service f629e6
  const char *new_locale = value;
Packit Service f629e6
Packit Service f629e6
  if (LC_MIN <= category && category <= LC_MAX
Packit Service f629e6
      && value && *value == '\0')
Packit Service f629e6
    {
Packit Service f629e6
      const char *lc_val = getenv ("LC_ALL");
Packit Service f629e6
Packit Service f629e6
      if (!lc_val)
Packit Service f629e6
	lc_val = getenv (lc_var (category));
Packit Service f629e6
      if (!lc_val)
Packit Service f629e6
	lc_val = getenv ("LANG");
Packit Service f629e6
      if (lc_val)
Packit Service f629e6
	new_locale = lc_val;
Packit Service f629e6
    }
Packit Service f629e6
Packit Service f629e6
  /* If VALUE includes a codeset, i.e. a Windows codepage number, we
Packit Service f629e6
     must also set the LC_CTYPE locale to the same value, because
Packit Service f629e6
     LC_CTYPE is the only category which is documented to be able to
Packit Service f629e6
     change the codepage.  */
Packit Service f629e6
  if (category != LC_ALL && category != LC_CTYPE)
Packit Service f629e6
    {
Packit Service f629e6
      const char *p = strchr (new_locale, '.');
Packit Service f629e6
Packit Service f629e6
      if (p && isdigit (p[1]))
Packit Service f629e6
	setlocale (LC_CTYPE, new_locale);
Packit Service f629e6
    }
Packit Service f629e6
  return setlocale (category, new_locale);
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
/*
Packit Service f629e6
 * On MS-Windows with MinGW, execvp causes the shell and the re-exec'ed
Packit Service f629e6
 * dgawk to compete for the keyboard input.
Packit Service f629e6
 *
Packit Service f629e6
 * This will need work if we ever need a real version of execvp.
Packit Service f629e6
 */
Packit Service f629e6
int execvp(const char *file, const char *const *argv)
Packit Service f629e6
{
Packit Service f629e6
	if (_spawnvp(_P_WAIT, file, (const char * const *)argv) != -1)
Packit Service f629e6
		exit(EXIT_SUCCESS);
Packit Service f629e6
Packit Service f629e6
	return -1;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
#ifdef DYNAMIC
Packit Service f629e6
Packit Service f629e6
#include <dlfcn.h>
Packit Service f629e6
Packit Service f629e6
static DWORD last_err;
Packit Service f629e6
Packit Service f629e6
void *
Packit Service f629e6
dlopen (const char *file, int mode)
Packit Service f629e6
{
Packit Service f629e6
  char dllfn[MAX_PATH], *p;
Packit Service f629e6
  HANDLE dllhandle;
Packit Service f629e6
Packit Service f629e6
  if (mode != RTLD_LAZY)
Packit Service f629e6
    {
Packit Service f629e6
      errno = EINVAL;
Packit Service f629e6
      last_err = ERROR_INVALID_PARAMETER;
Packit Service f629e6
      return NULL;
Packit Service f629e6
    }
Packit Service f629e6
Packit Service f629e6
  /* MSDN says to be sure to use backslashes in the DLL file name.  */
Packit Service f629e6
  strcpy (dllfn, file);
Packit Service f629e6
  for (p = dllfn; *p; p++)
Packit Service f629e6
    if (*p == '/')
Packit Service f629e6
      *p = '\\';
Packit Service f629e6
Packit Service f629e6
  dllhandle = LoadLibrary (dllfn);
Packit Service f629e6
  if (!dllhandle)
Packit Service f629e6
    last_err = GetLastError ();
Packit Service f629e6
Packit Service f629e6
  return dllhandle;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
char *
Packit Service f629e6
dlerror (void)
Packit Service f629e6
{
Packit Service f629e6
  static char errbuf[1024];
Packit Service f629e6
  DWORD ret;
Packit Service f629e6
Packit Service f629e6
  if (!last_err)
Packit Service f629e6
    return NULL;
Packit Service f629e6
Packit Service f629e6
  ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
Packit Service f629e6
		       | FORMAT_MESSAGE_IGNORE_INSERTS,
Packit Service f629e6
		       NULL, last_err, 0, errbuf, sizeof (errbuf), NULL);
Packit Service f629e6
  while (ret > 0 && (errbuf[ret - 1] == '\n' || errbuf[ret - 1] == '\r'))
Packit Service f629e6
    --ret;
Packit Service f629e6
Packit Service f629e6
  errbuf[ret] = '\0';
Packit Service f629e6
  if (!ret)
Packit Service f629e6
    sprintf (errbuf, "Error code %lu", last_err);
Packit Service f629e6
Packit Service f629e6
  last_err = 0;
Packit Service f629e6
  return errbuf;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
dlclose (void *handle)
Packit Service f629e6
{
Packit Service f629e6
  if (!handle || handle == INVALID_HANDLE_VALUE)
Packit Service f629e6
    return -1;
Packit Service f629e6
  if (!FreeLibrary (handle))
Packit Service f629e6
    return -1;
Packit Service f629e6
Packit Service f629e6
  return 0;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
void *
Packit Service f629e6
dlsym (void *handle, const char *name)
Packit Service f629e6
{
Packit Service f629e6
  FARPROC addr = NULL;
Packit Service f629e6
Packit Service f629e6
  if (!handle || handle == INVALID_HANDLE_VALUE)
Packit Service f629e6
    {
Packit Service f629e6
      last_err = ERROR_INVALID_PARAMETER;
Packit Service f629e6
      return NULL;
Packit Service f629e6
    }
Packit Service f629e6
Packit Service f629e6
  addr = GetProcAddress (handle, name);
Packit Service f629e6
  if (!addr)
Packit Service f629e6
    last_err = GetLastError ();
Packit Service f629e6
Packit Service f629e6
  return (void *)addr;
Packit Service f629e6
}
Packit Service f629e6
#endif	/* DYNAMIC */
Packit Service f629e6
Packit Service f629e6
#ifdef HAVE_SOCKETS
Packit Service f629e6
int
Packit Service f629e6
socket_to_fd(SOCKET s)
Packit Service f629e6
{
Packit Service f629e6
  return (s == INVALID_SOCKET
Packit Service f629e6
	  ? INVALID_HANDLE
Packit Service f629e6
	  : _open_osfhandle (s, O_BINARY | O_NOINHERIT));
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
w32_socket(int family, int type, int protocol)
Packit Service f629e6
{
Packit Service f629e6
  /* We need to use WSASocket rather than socket, since the latter
Packit Service f629e6
     creates overlapped sockets that cannot be used in file I/O
Packit Service f629e6
     APIs.  */
Packit Service f629e6
  SOCKET s = WSASocket (family, type, protocol, NULL, 0, 0);
Packit Service f629e6
Packit Service f629e6
  if (s == INVALID_SOCKET)
Packit Service f629e6
    {
Packit Service f629e6
      switch (WSAGetLastError ())
Packit Service f629e6
	{
Packit Service f629e6
	  case WSAEMFILE:
Packit Service f629e6
	    errno = EMFILE;
Packit Service f629e6
	    break;
Packit Service f629e6
	  case WSANOTINITIALISED:
Packit Service f629e6
	  case WSAENETDOWN:
Packit Service f629e6
	    errno = EACCES;
Packit Service f629e6
	    break;
Packit Service f629e6
	  case WSAENOBUFS:
Packit Service f629e6
	    errno = ENOMEM;
Packit Service f629e6
	    break;
Packit Service f629e6
	  case WSAEFAULT:
Packit Service f629e6
	    errno = EFAULT;
Packit Service f629e6
	    break;
Packit Service f629e6
	  default:
Packit Service f629e6
	    errno = EINVAL;
Packit Service f629e6
	    break;
Packit Service f629e6
	}
Packit Service f629e6
    }
Packit Service f629e6
Packit Service f629e6
  return socket_to_fd (s);
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
w32_setsockopt (int fd, int level, int optname, const char *optval, int optlen)
Packit Service f629e6
{
Packit Service f629e6
  SOCKET s = FD_TO_SOCKET (fd);
Packit Service f629e6
Packit Service f629e6
  return setsockopt (s, level, optname, optval, optlen);
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
w32_bind (int fd, const struct sockaddr *name, int namelen)
Packit Service f629e6
{
Packit Service f629e6
  SOCKET s = FD_TO_SOCKET (fd);
Packit Service f629e6
Packit Service f629e6
  return bind (s, name, namelen);
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
w32_connect (int fd, const struct sockaddr *name, int namelen)
Packit Service f629e6
{
Packit Service f629e6
  SOCKET s = FD_TO_SOCKET (fd);
Packit Service f629e6
Packit Service f629e6
  return connect (s, name, namelen);
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
w32_listen (int fd, int backlog)
Packit Service f629e6
{
Packit Service f629e6
  SOCKET s = FD_TO_SOCKET (fd);
Packit Service f629e6
Packit Service f629e6
  return listen (s, backlog);
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
w32_accept (int fd, struct sockaddr *addr, int *addrlen)
Packit Service f629e6
{
Packit Service f629e6
  SOCKET s = FD_TO_SOCKET (fd);
Packit Service f629e6
Packit Service f629e6
  return socket_to_fd (accept (s, addr, addrlen));
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
SOCKET
Packit Service f629e6
valid_socket (int fd)
Packit Service f629e6
{
Packit Service f629e6
  SOCKET s = FD_TO_SOCKET (fd);
Packit Service f629e6
  int ov, ol = 4;
Packit Service f629e6
Packit Service f629e6
  if (s == INVALID_SOCKET
Packit Service f629e6
      || (getsockopt (s, SOL_SOCKET, SO_TYPE, (char *)&ov, &ol) == SOCKET_ERROR
Packit Service f629e6
	  && WSAGetLastError() == WSAENOTSOCK))
Packit Service f629e6
    return (SOCKET)0;
Packit Service f629e6
  return s;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
w32_closesocket (int fd)
Packit Service f629e6
{
Packit Service f629e6
  SOCKET s = valid_socket (fd);
Packit Service f629e6
  int res1, res2 = 0;
Packit Service f629e6
Packit Service f629e6
  if (!s && fd == FAKE_FD_VALUE)
Packit Service f629e6
    return 0;
Packit Service f629e6
Packit Service f629e6
  res1 = close (fd);
Packit Service f629e6
  if (s)
Packit Service f629e6
    res2 = closesocket (s);
Packit Service f629e6
Packit Service f629e6
  if (res1 == -1 || res2 == SOCKET_ERROR)
Packit Service f629e6
    return -1;
Packit Service f629e6
  return 0;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
w32_recvfrom (int fd, char *buf, int len, int flags,
Packit Service f629e6
	      struct sockaddr *from, int *fromlen)
Packit Service f629e6
{
Packit Service f629e6
  SOCKET s = FD_TO_SOCKET (fd);
Packit Service f629e6
Packit Service f629e6
  return recvfrom (s, buf, len, flags, from, fromlen);
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
w32_shutdown (int fd, int how)
Packit Service f629e6
{
Packit Service f629e6
  SOCKET s = FD_TO_SOCKET (fd);
Packit Service f629e6
Packit Service f629e6
  return shutdown (s, how);
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
#endif	/* HAVE_SOCKETS */
Packit Service f629e6
Packit Service f629e6
/* Translate abnormal exit status of Windows programs into the signal
Packit Service f629e6
   that terminated the program.  This is required to support scm_kill
Packit Service f629e6
   and WTERMSIG.  */
Packit Service f629e6
Packit Service f629e6
#include <signal.h>
Packit Service f629e6
Packit Service f629e6
struct signal_and_status {
Packit Service f629e6
  int sig;
Packit Service f629e6
  unsigned status;
Packit Service f629e6
};
Packit Service f629e6
Packit Service f629e6
static const struct signal_and_status sigtbl[] = {
Packit Service f629e6
  {SIGSEGV, 0xC0000005},	/* access to invalid address */
Packit Service f629e6
  {SIGSEGV, 0xC0000008},	/* invalid handle */
Packit Service f629e6
  {SIGILL,  0xC000001D},	/* illegal instruction */
Packit Service f629e6
  {SIGILL,  0xC0000025},	/* non-continuable instruction */
Packit Service f629e6
  {SIGSEGV, 0xC000008C},	/* array bounds exceeded */
Packit Service f629e6
  {SIGFPE,  0xC000008D},	/* float denormal */
Packit Service f629e6
  {SIGFPE,  0xC000008E},	/* float divide by zero */
Packit Service f629e6
  {SIGFPE,  0xC000008F},	/* float inexact */
Packit Service f629e6
  {SIGFPE,  0xC0000090},	/* float invalid operation */
Packit Service f629e6
  {SIGFPE,  0xC0000091},	/* float overflow */
Packit Service f629e6
  {SIGFPE,  0xC0000092},	/* float stack check */
Packit Service f629e6
  {SIGFPE,  0xC0000093},	/* float underflow */
Packit Service f629e6
  {SIGFPE,  0xC0000094},	/* integer divide by zero */
Packit Service f629e6
  {SIGFPE,  0xC0000095},	/* integer overflow */
Packit Service f629e6
  {SIGILL,  0xC0000096},	/* privileged instruction */
Packit Service f629e6
  {SIGSEGV, 0xC00000FD},	/* stack overflow */
Packit Service f629e6
  {SIGTERM, 0xC000013A},	/* Ctrl-C exit */
Packit Service f629e6
  {SIGINT,  0xC000013A}
Packit Service f629e6
};
Packit Service f629e6
Packit Service f629e6
int
Packit Service f629e6
w32_status_to_termsig (unsigned status)
Packit Service f629e6
{
Packit Service f629e6
  int i;
Packit Service f629e6
Packit Service f629e6
  for (i = 0; i < sizeof (sigtbl) / sizeof (sigtbl[0]); i++)
Packit Service f629e6
    if (status == sigtbl[i].status)
Packit Service f629e6
      return sigtbl[i].sig;
Packit Service f629e6
Packit Service f629e6
  return SIGTERM;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
void
Packit Service f629e6
w32_maybe_set_errno (void)
Packit Service f629e6
{
Packit Service f629e6
  DWORD w32err = GetLastError ();
Packit Service f629e6
Packit Service f629e6
  switch (w32err)
Packit Service f629e6
    {
Packit Service f629e6
      /* When stdout is redirected to a pipe, and the program that
Packit Service f629e6
	 reads the pipe (e.g., a pager) exits, Windows doesn't set
Packit Service f629e6
	 errno to a useful value.  Help it DTRT.  */
Packit Service f629e6
      case ERROR_BAD_PIPE:
Packit Service f629e6
      case ERROR_PIPE_BUSY:
Packit Service f629e6
      case ERROR_NO_DATA:
Packit Service f629e6
      case ERROR_PIPE_NOT_CONNECTED:
Packit Service f629e6
	errno = EPIPE;
Packit Service f629e6
	break;
Packit Service f629e6
      default:
Packit Service f629e6
	errno = EINVAL;
Packit Service f629e6
	break;
Packit Service f629e6
    }
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
#endif	/* __MINGW32__ */
Packit Service f629e6
Packit Service f629e6
#if defined(__DJGPP__) || defined(__MINGW32__) || defined(__EMX__)
Packit Service f629e6
Packit Service f629e6
void
Packit Service f629e6
init_sockets(void)
Packit Service f629e6
{
Packit Service f629e6
#if defined(HAVE_SOCKETS) && !defined(__EMX__)
Packit Service f629e6
  WSADATA  winsockData;
Packit Service f629e6
  int errcode;
Packit Service f629e6
Packit Service f629e6
  if ((errcode = WSAStartup (0x101, &winsockData)) != 0
Packit Service f629e6
      || winsockData.wVersion != 0x101)
Packit Service f629e6
    fatal(_("cannot start Winsock (%d)"), errcode);
Packit Service f629e6
#endif
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
#endif	/* __DJGPP__ || __MINGW32__ */
Packit Service f629e6
Packit Service f629e6
#ifdef __DJGPP__
Packit Service f629e6
Packit Service f629e6
# if __DJGPP__ == 2 && __DJGPP_MINOR__ < 4 
Packit Service f629e6
int
Packit Service f629e6
unsetenv (const char *name)
Packit Service f629e6
{
Packit Service f629e6
  if (!name || !*name || strchr (name, '=') != NULL)
Packit Service f629e6
    return -1;
Packit Service f629e6
Packit Service f629e6
  return putenv (name);
Packit Service f629e6
}
Packit Service f629e6
#endif
Packit Service f629e6
Packit Service f629e6
/* This is needed to defeat too-clever GCC warnings in dfa.c about
Packit Service f629e6
   comparison being always false due to limited range of data type.  */
Packit Service f629e6
wint_t
Packit Service f629e6
btowc (int c)
Packit Service f629e6
{
Packit Service f629e6
  return c;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
wint_t
Packit Service f629e6
putwc(wchar_t wc, FILE *stream)
Packit Service f629e6
{
Packit Service f629e6
  return MB_CUR_MAX == 1 && wc > 0 && wc <= UCHAR_MAX
Packit Service f629e6
         && putc((unsigned char)wc, stream) != EOF ? (wint_t)wc : WEOF;
Packit Service f629e6
}
Packit Service f629e6
Packit Service f629e6
#endif /* __DJGPP__ */