summaryrefslogtreecommitdiff
path: root/Build/source/libs/libgnuw32/gnuw32.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/libgnuw32/gnuw32.c')
-rw-r--r--Build/source/libs/libgnuw32/gnuw32.c523
1 files changed, 523 insertions, 0 deletions
diff --git a/Build/source/libs/libgnuw32/gnuw32.c b/Build/source/libs/libgnuw32/gnuw32.c
new file mode 100644
index 00000000000..abbc1c43db3
--- /dev/null
+++ b/Build/source/libs/libgnuw32/gnuw32.c
@@ -0,0 +1,523 @@
+/* Libc replacement functions for win32.
+
+Copyright (C) 1998, 99 Free Software Foundation, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ This does make sense only under WIN32.
+ Functions:
+ - popen() rewritten
+ - pclose() rewritten
+ - stat() wrapper for _stat(), removing trailing slashes
+ */
+
+#ifdef 0
+
+#include <fcntl.h>
+#include <io.h>
+#include <sys/stat.h>
+#include <direct.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <gnuw32.h>
+
+
+
+
+#if 0
+#endif
+
+
+#if 0
+
+
+Thanks. DJGPP startup code has a full-blown wildcard globber in its
+startup code as well, and it expands wildcards Unix style (i.e., it
+supports [a-z] etc.). So I don't think we need any more functionality...
+
+Here's the relevant parts from DJGPP's system.c module. I omitted some
+functions with obvious names like `emiterror', to avoid cluttering the
+code with too many irrelevant details. `system1' (also omitted) is the
+place where the command line, after being stripped from redirection and
+pipe parts, is actually broken into separate argv[] parts and passed to
+the child (via `spawnve' in the case of DJGPP); I assume that you already
+have something like that. I did include the two functions which are used
+to support quoting of command-line arguments, in case you are interested,
+but note that some of their subtleties know how the startup code on the
+child side will process quoted arguments (e.g., the case of 'foo bar'
+with single quotes), so caveat emptor.
+
+The only part that is really relevant to processing pipes and redirection
+is the loop which begins with the following lines:
+
+ tmp = alloca(L_tmpnam);
+ prog = alloca (L_tmpnam);
+
+ s = strcpy (alloca (strlen (cmdline) + 1), cmdline);
+ while (!done && result >= 0)
+ {
+
+Have fun!
+
+------------------------------------------------------------------
+/* Return a copy of a word between BEG and (excluding) END with all
+ quoting characters removed from it. */
+
+static char *
+__unquote (char *to, const char *beg, const char *end)
+{
+ const char *s = beg;
+ char *d = to;
+ int quote = 0;
+
+ while (s < end)
+ {
+ switch (*s)
+ {
+ case '"':
+ case '\'':
+ if (!quote)
+ quote = *s;
+ else if (quote == *s)
+ quote = 0;
+ s++;
+ break;
+ case '\\':
+ if (s[1] == '"' || s[1] == '\''
+ || (s[1] == ';'
+ && (__system_flags & __system_allow_multiple_cmds)))
+ s++;
+ /* Fall-through. */
+ default:
+ *d++ = *s++;
+ break;
+ }
+ }
+
+ *d = 0;
+ return to;
+}
+
+/* A poor-man's lexical analyzer for simplified command processing.
+
+ It only knows about these:
+
+ redirection and pipe symbols
+ semi-colon `;' (that possibly ends a command)
+ argument quoting rules with quotes and `\'
+ whitespace delimiters of words (except in quoted args)
+
+ Returns the type of next symbol and pointers to its first and (one
+ after) the last characters.
+
+ Only `get_sym' and `unquote' should know about quoting rules. */
+
+static cmd_sym_t
+get_sym (char *s, char **beg, char **end)
+{
+ int in_a_word = 0;
+
+ while (isspace (*s))
+ s++;
+
+ *beg = s;
+
+ do {
+ *end = s + 1;
+
+ if (in_a_word
+ && (!*s || strchr ("<>| \t\n", *s)
+ || ((sys_flags & __system_allow_multiple_cmds) && *s == ';')))
+ {
+ --*end;
+ return WORD;
+ }
+
+ switch (*s)
+ {
+ case '<':
+ return REDIR_INPUT;
+ case '>':
+ if (**end == '>')
+ {
+ ++*end;
+ return REDIR_APPEND;
+ }
+ return REDIR_OUTPUT;
+ case '|':
+ return PIPE;
+ case ';':
+ if (sys_flags & __system_allow_multiple_cmds)
+ return SEMICOLON;
+ else
+ in_a_word = 1;
+ break;
+ case '\0':
+ --*end;
+ return EOL;
+ case '\\':
+ if (s[1] == '"' || s[1] == '\''
+ || (s[1] == ';' && (sys_flags & __system_allow_multiple_cmds)))
+ s++;
+ in_a_word = 1;
+ break;
+ case '\'':
+ case '"':
+ {
+ char quote = *s++;
+
+ while (*s && *s != quote)
+ {
+ if (*s++ == '\\' && (*s == '"' || *s == '\''))
+ s++;
+ }
+ *end = s;
+ if (!*s)
+ return UNMATCHED_QUOTE;
+ in_a_word = 1;
+ break;
+ }
+ default:
+ in_a_word = 1;
+ break;
+ }
+
+ s++;
+
+ } while (1);
+}
+
+/* This function handles redirection and passes the rest to system1
+ or to the shell. */
+int
+system (const char *cmdline)
+{
+ /* Set the feature bits for this run: either from the
+ environment or from global variable. */
+ const char *envflags = getenv ("DJSYSFLAGS");
+ const char *comspec = getenv ("COMSPEC");
+ const char *shell = 0;
+ int call_shell;
+
+ sys_flags = __system_flags;
+ if (envflags && *envflags)
+ {
+ char *stop;
+ long flags = strtol (envflags, &stop, 0);
+
+ if (*stop == '\0')
+ sys_flags = flags;
+ }
+
+ if (sys_flags & __system_use_shell)
+ shell = getenv ("SHELL");
+ if (!shell)
+ shell = comspec;
+ if (!shell)
+ shell = command_com;
+
+ call_shell =
+ (sys_flags & __system_call_cmdproc)
+ || (!(sys_flags & __system_emulate_command) && _is_unixy_shell (shell));
+
+ /* Special case: NULL means return non-zero if the command
+ interpreter is available. This is ANSI C requirement.
+
+ If we will call the shell to do everything, we need to see
+ whether it exists. But if most of the work will be done by us
+ anyway (like it usually is with stock DOS shell), return non-zero
+ without checking, since our emulation is always ``available''. */
+ if (cmdline == 0)
+ {
+ if (!call_shell)
+ return 1;
+ else
+ {
+ char full_path[FILENAME_MAX];
+
+ return __dosexec_find_on_path (shell, (char **)0, full_path) ? 1 : 0;
+ }
+ }
+
+ /* Strip initial spaces (so that if the command is empty, we
+ know it right here). */
+ while (isspace(*cmdline))
+ cmdline++;
+
+ /* Call the shell if:
+
+ the command line is empty
+ or
+ they want to always do it via command processor
+ or
+ $SHELL or $COMSPEC point to a unixy shell */
+ if (!*cmdline || call_shell)
+ return _shell_command ("", cmdline);
+ else
+ {
+ char *f_in = 0, *f_out = 0;
+ int rm_in = 0, rm_out = 0;
+ /* Assigned to silence -Wall */
+ int h_in = 0, h_inbak = 0, h_out = 0, h_outbak = 0;
+ char *s, *t, *u, *v, *tmp, *cmdstart;
+ int result = 0, done = 0;
+ int append_out = 0;
+ cmd_sym_t token;
+ char *prog;
+
+ tmp = alloca(L_tmpnam);
+ prog = alloca (L_tmpnam);
+
+ s = strcpy (alloca (strlen (cmdline) + 1), cmdline);
+ while (!done && result >= 0)
+ {
+ char **fp = &f_in;
+ /* Assignments pacify -Wall */
+ int hin_err = 0, hbak_err = 0, hout_err = 0;
+ int needcmd = 1;
+ int again;
+
+ if (rm_in)
+ remove (f_in);
+ f_in = f_out; /* Piping. */
+ rm_in = rm_out;
+ f_out = 0;
+ rm_out = 0;
+ append_out = 0;
+
+ cmdstart = s;
+
+ do {
+ again = 0;
+ token = get_sym (s, &t, &u); /* get next symbol */
+
+ /* Weed out extra whitespace, leaving only a single
+ whitespace character between any two tokens.
+ This way, if we eventually pass the command to a
+ shell, it won't fail due to length > 126 chars
+ unless it really *is* that long. */
+
+ if (s == cmdstart)
+ v = s; /* don't need blank at beginning of cmdline */
+ else
+ v = s + 1;
+ if (t > v)
+ {
+ strcpy (v, t);
+ u -= t - v;
+ t = v;
+ }
+
+ switch (token)
+ {
+ case WORD:
+ /* First word we see is the program to run. */
+ if (needcmd)
+ {
+ __unquote (prog, t, u); /* unquote and copy to prog */
+ /* We can't grok commands in parentheses, so assume they
+ use a shell that knows about these, like 4DOS or `sh'.
+
+ FIXME: if the parenthesized group is NOT the first command
+ in a pipe, the commands that preceed it will be run twice. */
+ if (prog[0] == '(')
+ return _shell_command ("", cmdline);
+ strcpy (s, u); /* remove program name from cmdline */
+ needcmd = 0;
+ }
+ else
+ s = u;
+ again = 1;
+ break;
+ case REDIR_INPUT:
+ case REDIR_OUTPUT:
+ case REDIR_APPEND:
+ if (!(sys_flags & __system_redirect))
+ return _shell_command ("", cmdline);
+ if (token == REDIR_INPUT)
+ {
+ if (f_in)
+ {
+ result = emiterror ("Ambiguous input redirect.", 0);
+ errno = EINVAL;
+ goto leave;
+ }
+ fp = &f_in;
+ }
+ else if (token == REDIR_OUTPUT || token == REDIR_APPEND)
+ {
+ if (f_out)
+ {
+ result = emiterror ("Ambiguous output redirect.", 0);
+ errno = EINVAL;
+ goto leave;
+ }
+ fp = &f_out;
+ if (token == REDIR_APPEND)
+ append_out = 1;
+ }
+ if (get_sym (u, &u, &v) != WORD)
+ {
+ result = emiterror ("Target of redirect is not a filename.", 0);
+ errno = EINVAL;
+ goto leave;
+ }
+ *fp = memcpy ((char *)alloca (v - u + 1), u, v - u);
+ (*fp)[v - u] = 0;
+ strcpy (t, v);
+ again = 1;
+ break;
+ case PIPE:
+ if (!(sys_flags & __system_redirect))
+ return _shell_command ("", cmdline);
+ if (f_out)
+ {
+ result = emiterror ("Ambiguous output redirect.", 0);
+ errno = EINVAL;
+ goto leave;
+ }
+
+ /* tmpnam guarantees unique names */
+ tmpnam(tmp);
+ f_out = strcpy (alloca (L_tmpnam), tmp);
+ rm_out = 1;
+ /* Fall through. */
+ case SEMICOLON:
+ case EOL:
+ if (needcmd)
+ {
+ result = emiterror ("No command name seen.", 0);
+ errno = EINVAL;
+ goto leave;
+ }
+
+ /* Remove extra whitespace at end of command. */
+ while (s > cmdstart && isspace (s[-1])) s--;
+ while (t > s && isspace (t[-1])) t--;
+ *t = 0;
+
+#ifdef TEST
+ fprintf (stderr, "Input from: %s\nOutput%s to: %s\n",
+ f_in ? f_in : "<stdin>",
+ append_out ? " appended" : "",
+ f_out ? f_out : "<stdout>");
+ fflush (stderr);
+#endif
+ if (f_in)
+ {
+ int e = errno;
+
+ errno = 0;
+ h_in = open (f_in, O_RDONLY | O_BINARY);
+ hin_err = errno;
+ errno = 0;
+ h_inbak = dup (0);
+ hbak_err = errno;
+ dup2 (h_in, 0);
+ errno = e;
+ }
+ if (f_out)
+ {
+ int e = errno;
+
+ errno = 0;
+ h_out = open (f_out,
+ O_WRONLY | O_BINARY | O_CREAT
+ | (append_out ? O_APPEND: O_TRUNC),
+ S_IREAD | S_IWRITE);
+ hout_err = errno;
+ errno = 0;
+ h_outbak = dup (1);
+ hbak_err = errno;
+ fflush(stdout); /* so any buffered chars will be written out */
+ dup2 (h_out, 1);
+ errno = e;
+ }
+ if (f_in && h_in < 0)
+ result = emiterror ("Cannot redirect input", hin_err);
+ else if ((f_in && h_inbak < 0) || (f_out && h_outbak < 0))
+ result = emiterror ("Out of file handles in redirect", hbak_err);
+ else if (f_out && h_out < 0)
+ result = emiterror ("Cannot redirect output", hout_err);
+
+ if (!result)
+ {
+#ifdef TEST
+ fprintf (stderr, "system1 (\"%s\", \"%s\")\n", prog, cmdstart);
+ fflush (stderr);
+#endif
+ /* Tell `__spawnve' it was invoked by `system', so it would
+ know how to deal with command-line arguments' quoting. */
+ __dosexec_in_system = 1;
+ result = system1 (prog, cmdstart);
+ __dosexec_in_system = 0;
+ }
+ if (f_in)
+ {
+ dup2 (h_inbak, 0);
+ close (h_in);
+ close (h_inbak);
+ }
+ if (f_out)
+ {
+ dup2 (h_outbak, 1);
+ close (h_out);
+ close (h_outbak);
+ }
+
+ if (token == EOL)
+ done = 1;
+ else
+ {
+ if (token == SEMICOLON)
+ f_in = f_out = 0;
+ s = u;
+ }
+ break;
+ case UNMATCHED_QUOTE:
+ result = emiterror ("Unmatched quote character.", 0);
+ errno = EINVAL;
+ goto leave;
+ default:
+ result = emiterror ("I cannot grok this.", 0);
+ errno = EINVAL;
+ goto leave;
+ }
+ } while (again);
+ }
+ leave:
+ if (rm_in)
+ remove (f_in);
+ if (rm_out)
+ remove (f_out);
+
+ return result;
+ }
+}
+#endif
+
+#if NEW_KPSE
+
+
+
+
+
+
+
+#endif
+#endif
+