mirror of
https://github.com/mirror/make.git
synced 2025-02-26 03:45:41 +08:00
Add support for OS/2, contributed by Andreas Buening <andreas.buening@nexgo.de>
Also a small patch from Hartmut Becker <Hartmut.Becker@compaq.com> for VMS.
This commit is contained in:
parent
1fa3db1468
commit
4068c5e4a3
49
ChangeLog
49
ChangeLog
@ -1,3 +1,52 @@
|
||||
2003-02-25 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
Port to OS/2 (__EMX__) by Andreas Buening <andreas.buening@nexgo.de>.
|
||||
|
||||
* job.c (_is_unixy_shell) [OS/2]: New function.
|
||||
Set default shell to /bin/sh.
|
||||
(reap_children): Close the job_rfd pipe here since we don't use a
|
||||
SIGCHLD handler.
|
||||
(set_child_handler_action_flags): define this to empty on OS/2.
|
||||
(start_job_command): Close the jobserver pipe and use
|
||||
child_execute_job() instead of fork/exec.
|
||||
(child_execute_job): Rewrite to handle stdin/stdout FDs and spawn
|
||||
rather than exec'ing, then reconfigure stdin/stdout.
|
||||
(exec_command): Rewrite to use spawn instead of exec. Return the
|
||||
PID of the child.
|
||||
|
||||
* main.c (main) [OS/2]: Call initialize_main(). Handle argv[0] as
|
||||
in DOS. Handle the TEMP environment variable as in DOS. Don't
|
||||
use a SIGCHLD handler on OS/2. Choose a shell as in DOS. Don't
|
||||
use -j in DOS mode. Use child_execute_job() instead of
|
||||
exec_command().
|
||||
|
||||
* function.c (func_shell) [OS/2]: Can't use fork/exec on OS/2: use
|
||||
spawn() instead.
|
||||
|
||||
* job.h [OS/2]: Move CLOSE_ON_EXEC here from job.c. Add
|
||||
prototypes that return values.
|
||||
|
||||
* remake.c (f_mtime) [OS/2]: Handle FAT timestamp offsets for OS/2.
|
||||
|
||||
* read.c (readline) [OS/2]: Don't handle CRLF specially on OS/2.
|
||||
* default.c (default_suffixes) [OS/2]: Set proper default suffixes
|
||||
for OS/2.
|
||||
* vpath.c (construct_vpath_list) [OS/2]: Handle OS/2 paths like
|
||||
DOS paths.
|
||||
|
||||
2003-02-24 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* default.c [VMS]: New default rules for .cxx -> .obj compiles.
|
||||
* job.c (child_execute_job) [VMS]: New code for handling spawn().
|
||||
(child_execute_job) [VMS]: Handle error status properly.
|
||||
Patches provided by Hartmut Becker <Hartmut.Becker@compaq.com>.
|
||||
|
||||
* function.c (func_shell): Use EINTRLOOP() while reading from the
|
||||
subshell pipe (Fixes bug #2502).
|
||||
* job.c (free_child): Use EINTRLOOP() while writing tokens to the
|
||||
jobserver pipe.
|
||||
* main.c (main): Ditto.
|
||||
|
||||
2003-01-30 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* read.c (eval): eval() was not fully reentrant, because the
|
||||
|
@ -27,7 +27,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Define GCC_IS_NATIVE if gcc is the native development environment on
|
||||
your system (gcc/bison/flex vs cc/yacc/lex). */
|
||||
#ifdef __MSDOS__
|
||||
#if defined(__MSDOS__) || defined(__EMX__)
|
||||
# define GCC_IS_NATIVE
|
||||
#endif
|
||||
|
||||
@ -41,6 +41,10 @@ static char default_suffixes[]
|
||||
= ".exe .olb .ln .obj .c .cxx .cc .pas .p .for .f .r .y .l .mar \
|
||||
.s .ss .i .ii .mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo \
|
||||
.w .ch .cweb .web .com .sh .elc .el";
|
||||
#elif defined(__EMX__)
|
||||
= ".out .a .ln .o .c .cc .C .cpp .p .f .F .r .y .l .s .S \
|
||||
.mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo \
|
||||
.w .ch .web .sh .elc .el .obj .exe .dll .lib";
|
||||
#else
|
||||
= ".out .a .ln .o .c .cc .C .cpp .p .f .F .r .y .l .s .S \
|
||||
.mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo \
|
||||
@ -153,6 +157,8 @@ static char *default_suffix_rules[] =
|
||||
"$(COMPILE.cc)/noprep/noobj/machine /list=$@ $<",
|
||||
".cc.obj",
|
||||
"$(COMPILE.cc) /obj=$@ $<",
|
||||
".cxx.obj",
|
||||
"$(COMPILE.cxx) /obj=$@ $<",
|
||||
".for.obj",
|
||||
"$(COMPILE.for) /obj=$@ $<",
|
||||
".pas.obj",
|
||||
|
4
dir.c
4
dir.c
@ -589,6 +589,10 @@ dir_contents_file_exists_p (struct directory_contents *dir, char *filename)
|
||||
filename = downcase (filename);
|
||||
#endif
|
||||
|
||||
#ifdef __EMX__
|
||||
_fnlwr(filename); /* lower case for FAT drives */
|
||||
#endif
|
||||
|
||||
#ifdef VMS
|
||||
filename = vmsify (filename,0);
|
||||
#endif
|
||||
|
30
function.c
30
function.c
@ -1450,6 +1450,7 @@ func_shell (char *o, char **argv, const char *funcname)
|
||||
error_prefix = "";
|
||||
|
||||
#ifdef WINDOWS32
|
||||
|
||||
windows32_openpipe (pipedes, &pid, command_argv, envp);
|
||||
|
||||
if (pipedes[0] < 0) {
|
||||
@ -1458,31 +1459,46 @@ func_shell (char *o, char **argv, const char *funcname)
|
||||
|
||||
return o;
|
||||
} else
|
||||
#else /* WINDOWS32 */
|
||||
|
||||
# ifdef __MSDOS__
|
||||
#elif defined(__MSDOS__)
|
||||
|
||||
fpipe = msdos_openpipe (pipedes, &pid, argv[0]);
|
||||
if (pipedes[0] < 0)
|
||||
{
|
||||
perror_with_name (error_prefix, "pipe");
|
||||
return o;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if (pipe (pipedes) < 0)
|
||||
{
|
||||
perror_with_name (error_prefix, "pipe");
|
||||
return o;
|
||||
}
|
||||
|
||||
# ifdef __EMX__
|
||||
|
||||
/* close some handles that are unnecessary for the child process */
|
||||
CLOSE_ON_EXEC(pipedes[1]);
|
||||
CLOSE_ON_EXEC(pipedes[0]);
|
||||
/* Never use fork()/exec() here! Use spawn() instead in exec_command() */
|
||||
pid = child_execute_job (0, pipedes[1], command_argv, envp);
|
||||
if (pid < 0)
|
||||
perror_with_name (error_prefix, "spawn");
|
||||
|
||||
# else /* ! __EMX__ */
|
||||
|
||||
pid = vfork ();
|
||||
if (pid < 0)
|
||||
perror_with_name (error_prefix, "fork");
|
||||
else if (pid == 0)
|
||||
child_execute_job (0, pipedes[1], command_argv, envp);
|
||||
else
|
||||
# endif /* ! __MSDOS__ */
|
||||
|
||||
#endif /* WINDOWS32 */
|
||||
# endif
|
||||
|
||||
#endif
|
||||
{
|
||||
/* We are the parent. */
|
||||
|
||||
@ -1517,7 +1533,7 @@ func_shell (char *o, char **argv, const char *funcname)
|
||||
buffer = (char *) xrealloc (buffer, maxlen + 1);
|
||||
}
|
||||
|
||||
cc = read (pipedes[0], &buffer[i], maxlen - i);
|
||||
EINTRLOOP (cc, read (pipedes[0], &buffer[i], maxlen - i));
|
||||
if (cc <= 0)
|
||||
break;
|
||||
}
|
||||
@ -1531,8 +1547,8 @@ func_shell (char *o, char **argv, const char *funcname)
|
||||
(void) close (pipedes[0]);
|
||||
#endif
|
||||
|
||||
/* Loop until child_handler sets shell_function_completed
|
||||
to the status of our child shell. */
|
||||
/* Loop until child_handler or reap_children() sets
|
||||
shell_function_completed to the status of our child shell. */
|
||||
while (shell_function_completed == 0)
|
||||
reap_children (1, 0);
|
||||
|
||||
|
477
job.c
477
job.c
@ -32,31 +32,43 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Default shell to use. */
|
||||
#ifdef WINDOWS32
|
||||
|
||||
char *default_shell = "sh.exe";
|
||||
int no_default_sh_exe = 1;
|
||||
int batch_mode_shell = 1;
|
||||
#else /* WINDOWS32 */
|
||||
# ifdef _AMIGA
|
||||
|
||||
#elif defined (_AMIGA)
|
||||
|
||||
char default_shell[] = "";
|
||||
extern int MyExecute (char **);
|
||||
# else /* _AMIGA */
|
||||
# ifdef __MSDOS__
|
||||
int batch_mode_shell = 0;
|
||||
|
||||
#elif defined (__MSDOS__)
|
||||
|
||||
/* The default shell is a pointer so we can change it if Makefile
|
||||
says so. It is without an explicit path so we get a chance
|
||||
to search the $PATH for it (since MSDOS doesn't have standard
|
||||
directories we could trust). */
|
||||
char *default_shell = "command.com";
|
||||
# else /* __MSDOS__ */
|
||||
# ifdef VMS
|
||||
int batch_mode_shell = 0;
|
||||
|
||||
#elif defined (__EMX__)
|
||||
|
||||
const char *default_shell = "/bin/sh";
|
||||
int batch_mode_shell = 0;
|
||||
|
||||
#elif defined (VMS)
|
||||
|
||||
# include <descrip.h>
|
||||
char default_shell[] = "";
|
||||
# else
|
||||
char default_shell[] = "/bin/sh";
|
||||
# endif /* VMS */
|
||||
# endif /* __MSDOS__ */
|
||||
int batch_mode_shell = 0;
|
||||
# endif /* _AMIGA */
|
||||
#endif /* WINDOWS32 */
|
||||
|
||||
#else
|
||||
|
||||
char default_shell[] = "/bin/sh";
|
||||
int batch_mode_shell = 0;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __MSDOS__
|
||||
# include <process.h>
|
||||
@ -91,9 +103,7 @@ static int amiga_batch_file;
|
||||
# include "pathstuff.h"
|
||||
#endif /* WINDOWS32 */
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#else
|
||||
#ifdef __EMX__
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
|
||||
@ -157,17 +167,6 @@ extern int wait ();
|
||||
|
||||
#endif /* Don't have `union wait'. */
|
||||
|
||||
/* How to set close-on-exec for a file descriptor. */
|
||||
|
||||
#if !defined F_SETFD
|
||||
# define CLOSE_ON_EXEC(_d)
|
||||
#else
|
||||
# ifndef FD_CLOEXEC
|
||||
# define FD_CLOEXEC 1
|
||||
# endif
|
||||
# define CLOSE_ON_EXEC(_d) (void) fcntl ((_d), F_SETFD, FD_CLOEXEC)
|
||||
#endif
|
||||
|
||||
#ifdef VMS
|
||||
static int vms_jobsefnmask = 0;
|
||||
#endif /* !VMS */
|
||||
@ -228,11 +227,57 @@ int unixy_shell = 1;
|
||||
/*
|
||||
* The macro which references this function is defined in make.h.
|
||||
*/
|
||||
int w32_kill(int pid, int sig)
|
||||
int
|
||||
w32_kill(int pid, int sig)
|
||||
{
|
||||
return ((process_kill(pid, sig) == TRUE) ? 0 : -1);
|
||||
}
|
||||
#endif /* WINDOWS32 */
|
||||
|
||||
#ifdef __EMX__
|
||||
/* returns whether path is assumed to be a unix like shell. */
|
||||
int
|
||||
_is_unixy_shell (const char *path)
|
||||
{
|
||||
/* list of non unix shells */
|
||||
const char *known_os2shells[] = {
|
||||
"cmd.exe",
|
||||
"cmd",
|
||||
"4os2.exe",
|
||||
"4os2",
|
||||
"4dos.exe",
|
||||
"4dos",
|
||||
"command.com",
|
||||
"command",
|
||||
NULL
|
||||
};
|
||||
|
||||
/* find the rightmost '/' or '\\' */
|
||||
const char *name = strrchr (path, '/');
|
||||
const char *p = strrchr (path, '\\');
|
||||
unsigned i;
|
||||
|
||||
if (name && p) /* take the max */
|
||||
name = (name > p) ? name : p;
|
||||
else if (p) /* name must be 0 */
|
||||
name = p;
|
||||
else if (!name) /* name and p must be 0 */
|
||||
name = path;
|
||||
|
||||
if (*name == '/' || *name == '\\') name++;
|
||||
|
||||
i = 0;
|
||||
while (known_os2shells[i] != NULL) {
|
||||
if (stricmp (name, known_os2shells[i]) == 0) /* strcasecmp() */
|
||||
return 0; /* not a unix shell */
|
||||
i++;
|
||||
}
|
||||
|
||||
/* in doubt assume a unix like shell */
|
||||
return 1;
|
||||
}
|
||||
#endif /* __EMX__ */
|
||||
|
||||
|
||||
/* Write an error message describing the exit status given in
|
||||
EXIT_CODE, EXIT_SIG, and COREDUMP, for the target TARGET_NAME.
|
||||
@ -384,6 +429,7 @@ handle_apos (char *p)
|
||||
|
||||
static unsigned int dead_children = 0;
|
||||
|
||||
#ifndef __EMX__ /* Don't use SIGCHLD handler on OS/2. */
|
||||
RETSIGTYPE
|
||||
child_handler (int sig)
|
||||
{
|
||||
@ -397,7 +443,7 @@ child_handler (int sig)
|
||||
|
||||
DB (DB_JOBS, (_("Got a SIGCHLD; %u unreaped children.\n"), dead_children));
|
||||
}
|
||||
|
||||
#endif /* !__EMX__ */
|
||||
|
||||
extern int shell_function_pid, shell_function_completed;
|
||||
|
||||
@ -527,6 +573,18 @@ reap_children (int block, int err)
|
||||
exit_code = WEXITSTATUS (status);
|
||||
exit_sig = WIFSIGNALED (status) ? WTERMSIG (status) : 0;
|
||||
coredump = WCOREDUMP (status);
|
||||
|
||||
#ifdef __EMX__
|
||||
/* the SIGCHLD handler must not be used on OS/2 because, unlike
|
||||
on UNIX systems, it had to call wait() itself. Therefore
|
||||
job_rfd has to be closed here. */
|
||||
if (job_rfd >= 0)
|
||||
{
|
||||
close (job_rfd);
|
||||
job_rfd = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -773,10 +831,12 @@ free_child (struct child *child)
|
||||
if (job_fds[1] >= 0 && children)
|
||||
{
|
||||
char token = '+';
|
||||
int r;
|
||||
|
||||
/* Write a job token back to the pipe. */
|
||||
|
||||
if (write (job_fds[1], &token, 1) != 1)
|
||||
EINTRLOOP (r, write (job_fds[1], &token, 1));
|
||||
if (r != 1)
|
||||
pfatal_with_name (_("write jobserver"));
|
||||
|
||||
DB (DB_JOBS, (_("Released token for child 0x%08lx (%s).\n"),
|
||||
@ -832,6 +892,10 @@ unblock_sigs (void)
|
||||
#endif
|
||||
|
||||
#ifdef MAKE_JOBSERVER
|
||||
# ifdef __EMX__
|
||||
/* Never install the SIGCHLD handler for EMX!!! */
|
||||
# define set_child_handler_action_flags(x)
|
||||
# else
|
||||
/* Set the child handler action flags to FLAGS. */
|
||||
static void
|
||||
set_child_handler_action_flags (int flags)
|
||||
@ -847,6 +911,7 @@ set_child_handler_action_flags (int flags)
|
||||
sigaction (SIGCLD, &sa, NULL);
|
||||
#endif
|
||||
}
|
||||
#endif /* !__EMX__ */
|
||||
#endif
|
||||
|
||||
|
||||
@ -996,7 +1061,7 @@ start_job_command (struct child *child)
|
||||
|
||||
#if !defined(VMS) && !defined(_AMIGA)
|
||||
if (
|
||||
#ifdef __MSDOS__
|
||||
#if defined __MSDOS__ || defined (__EMX__)
|
||||
unixy_shell /* the test is complicated and we already did it */
|
||||
#else
|
||||
(argv[0] && !strcmp (argv[0], "/bin/sh"))
|
||||
@ -1119,6 +1184,40 @@ start_job_command (struct child *child)
|
||||
#else
|
||||
|
||||
parent_environ = environ;
|
||||
|
||||
# ifdef __EMX__
|
||||
/* If we aren't running a recursive command and we have a jobserver
|
||||
pipe, close it before exec'ing. */
|
||||
if (!(flags & COMMANDS_RECURSE) && job_fds[0] >= 0)
|
||||
{
|
||||
CLOSE_ON_EXEC (job_fds[0]);
|
||||
CLOSE_ON_EXEC (job_fds[1]);
|
||||
}
|
||||
if (job_rfd >= 0)
|
||||
CLOSE_ON_EXEC (job_rfd);
|
||||
|
||||
/* Never use fork()/exec() here! Use spawn() instead in exec_command() */
|
||||
child->pid = child_execute_job (child->good_stdin ? 0 : bad_stdin, 1,
|
||||
argv, child->environment);
|
||||
if (child->pid < 0)
|
||||
{
|
||||
/* spawn failed! */
|
||||
unblock_sigs ();
|
||||
perror_with_name ("spawn", "");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* undo CLOSE_ON_EXEC() after the child process has been started */
|
||||
if (!(flags & COMMANDS_RECURSE) && job_fds[0] >= 0)
|
||||
{
|
||||
fcntl (job_fds[0], F_SETFD, 0);
|
||||
fcntl (job_fds[1], F_SETFD, 0);
|
||||
}
|
||||
if (job_rfd >= 0)
|
||||
fcntl (job_rfd, F_SETFD, 0);
|
||||
|
||||
#else /* !__EMX__ */
|
||||
|
||||
child->pid = vfork ();
|
||||
environ = parent_environ; /* Restore value child may have clobbered. */
|
||||
if (child->pid == 0)
|
||||
@ -1146,6 +1245,7 @@ start_job_command (struct child *child)
|
||||
perror_with_name ("vfork", "");
|
||||
goto error;
|
||||
}
|
||||
# endif /* !__EMX__ */
|
||||
#endif /* !VMS */
|
||||
}
|
||||
|
||||
@ -2175,10 +2275,13 @@ child_execute_job (char *argv, struct child *child)
|
||||
&child->pid, &child->cstatus, &child->efn,
|
||||
0, 0,
|
||||
0, 0, 0);
|
||||
if (status & 1)
|
||||
{
|
||||
pidToAbort= child->pid;
|
||||
status= sys$waitfr (child->efn);
|
||||
pidToAbort= 0;
|
||||
vmsHandleChildTerm(child);
|
||||
}
|
||||
#else
|
||||
status = lib$spawn (&cmddsc,
|
||||
(ifiledsc.dsc$w_length == 0)?0:&ifiledsc,
|
||||
@ -2194,6 +2297,14 @@ child_execute_job (char *argv, struct child *child)
|
||||
{
|
||||
printf (_("Error spawning, %d\n") ,status);
|
||||
fflush (stdout);
|
||||
switch (status)
|
||||
{
|
||||
case 0x1c:
|
||||
errno = EPROCLIM;
|
||||
break;
|
||||
default:
|
||||
errno = EFAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (comname && !ISDB (DB_JOBS))
|
||||
@ -2204,12 +2315,60 @@ child_execute_job (char *argv, struct child *child)
|
||||
|
||||
#else /* !VMS */
|
||||
|
||||
#if !defined (_AMIGA) && !defined (__MSDOS__)
|
||||
/* EMX: Start a child process. This function returns the new pid. */
|
||||
# if defined __MSDOS__ || defined __EMX__
|
||||
int
|
||||
child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp)
|
||||
{
|
||||
int pid;
|
||||
/* stdin_fd == 0 means: nothing to do for stdin;
|
||||
stdout_fd == 1 means: nothing to do for stdout */
|
||||
int save_stdin = (stdin_fd != 0) ? dup (0) : 0;
|
||||
int save_stdout = (stdout_fd != 1) ? dup (1): 1;
|
||||
|
||||
/* < 0 only if dup() failed */
|
||||
if (save_stdin < 0)
|
||||
fatal (NILF, _("could not duplicate stdin\n"));
|
||||
if (save_stdout < 0)
|
||||
fatal (NILF, _("could not duplicate stdout\n"));
|
||||
|
||||
/* Close unnecessary file handles for the child. */
|
||||
if (save_stdin != 0)
|
||||
CLOSE_ON_EXEC (save_stdin);
|
||||
if (save_stdout != 1)
|
||||
CLOSE_ON_EXEC (save_stdout);
|
||||
|
||||
/* Connect the pipes to the child process. */
|
||||
if (stdin_fd != 0)
|
||||
(void) dup2 (stdin_fd, 0);
|
||||
if (stdout_fd != 1)
|
||||
(void) dup2 (stdout_fd, 1);
|
||||
|
||||
/* stdin_fd and stdout_fd must be closed on exit because we are
|
||||
still in the parent process */
|
||||
if (stdin_fd != 0)
|
||||
CLOSE_ON_EXEC (stdin_fd);
|
||||
if (stdout_fd != 1)
|
||||
CLOSE_ON_EXEC (stdout_fd);
|
||||
|
||||
/* Run the command. */
|
||||
pid = exec_command (argv, envp);
|
||||
|
||||
/* Restore stdout/stdin of the parent process. */
|
||||
if (stdin_fd != 0 && dup2 (save_stdin, 0) != 0)
|
||||
fatal (NILF, _("restoring of stdin failed\n"));
|
||||
if (stdout_fd != 1 && dup2 (save_stdout, 1) != 1)
|
||||
fatal (NILF, _("restoring of stdout failed\n"));
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
#elif !defined (_AMIGA) && !defined (__MSDOS__)
|
||||
|
||||
/* UNIX:
|
||||
Replace the current process with one executing the command in ARGV.
|
||||
STDIN_FD and STDOUT_FD are used as the process's stdin and stdout; ENVP is
|
||||
the environment of the new program. This function does not return. */
|
||||
|
||||
void
|
||||
child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp)
|
||||
{
|
||||
@ -2233,7 +2392,12 @@ child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp)
|
||||
/* Replace the current process with one running the command in ARGV,
|
||||
with environment ENVP. This function does not return. */
|
||||
|
||||
/* EMX: This function returns the pid of the child process. */
|
||||
# ifdef __EMX__
|
||||
int
|
||||
# else
|
||||
void
|
||||
# endif
|
||||
exec_command (char **argv, char **envp)
|
||||
{
|
||||
#ifdef VMS
|
||||
@ -2301,13 +2465,33 @@ exec_command (char **argv, char **envp)
|
||||
|
||||
#else /* !WINDOWS32 */
|
||||
|
||||
# ifdef __EMX__
|
||||
int pid;
|
||||
# endif
|
||||
|
||||
/* Be the user, permanently. */
|
||||
child_access ();
|
||||
|
||||
# ifdef __EMX__
|
||||
|
||||
/* Run the program. */
|
||||
pid = spawnvpe (P_NOWAIT, argv[0], argv, envp);
|
||||
|
||||
if (pid >= 0)
|
||||
return pid;
|
||||
|
||||
/* the file might have a strange shell extension */
|
||||
if (errno == ENOENT)
|
||||
errno = ENOEXEC;
|
||||
|
||||
# else
|
||||
|
||||
/* Run the program. */
|
||||
environ = envp;
|
||||
execvp (argv[0], argv);
|
||||
|
||||
# endif /* !__EMX__ */
|
||||
|
||||
switch (errno)
|
||||
{
|
||||
case ENOENT:
|
||||
@ -2321,7 +2505,14 @@ exec_command (char **argv, char **envp)
|
||||
char **new_argv;
|
||||
int argc;
|
||||
|
||||
# ifdef __EMX__
|
||||
/* Do not use $SHELL from the environment */
|
||||
shell = lookup_variable ("SHELL", 5);
|
||||
if (shell)
|
||||
shell = shell->value;
|
||||
# else
|
||||
shell = getenv ("SHELL");
|
||||
# endif
|
||||
if (shell == 0)
|
||||
shell = default_shell;
|
||||
|
||||
@ -2338,7 +2529,13 @@ exec_command (char **argv, char **envp)
|
||||
--argc;
|
||||
}
|
||||
|
||||
# ifdef __EMX__
|
||||
pid = spawnvpe (P_NOWAIT, shell, new_argv, envp);
|
||||
if (pid >= 0)
|
||||
break;
|
||||
# else
|
||||
execvp (shell, new_argv);
|
||||
# endif
|
||||
if (errno == ENOENT)
|
||||
error (NILF, _("%s: Shell program not found"), shell);
|
||||
else
|
||||
@ -2346,12 +2543,23 @@ exec_command (char **argv, char **envp)
|
||||
break;
|
||||
}
|
||||
|
||||
# ifdef __EMX__
|
||||
case EINVAL:
|
||||
/* this nasty error was driving me nuts :-( */
|
||||
error (NILF, _("spawnvpe: environment space might be exhausted"));
|
||||
/* FALLTHROUGH */
|
||||
# endif
|
||||
|
||||
default:
|
||||
perror_with_name ("execvp: ", argv[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
# ifdef __EMX__
|
||||
return pid;
|
||||
# else
|
||||
_exit (127);
|
||||
# endif
|
||||
#endif /* !WINDOWS32 */
|
||||
#endif /* !VMS */
|
||||
}
|
||||
@ -2428,16 +2636,43 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
|
||||
|
||||
char *sh_chars;
|
||||
char **sh_cmds;
|
||||
#else
|
||||
#ifdef _AMIGA
|
||||
#elif defined (__EMX__)
|
||||
static char sh_chars_dos[] = "*?[];|<>%^&()";
|
||||
static char *sh_cmds_dos[] = { "break", "call", "cd", "chcp", "chdir", "cls",
|
||||
"copy", "ctty", "date", "del", "dir", "echo",
|
||||
"erase", "exit", "for", "goto", "if", "md",
|
||||
"mkdir", "path", "pause", "prompt", "rd",
|
||||
"rmdir", "rem", "ren", "rename", "set",
|
||||
"shift", "time", "type", "ver", "verify",
|
||||
"vol", ":", 0 };
|
||||
|
||||
static char sh_chars_os2[] = "*?[];|<>%^()\"'&";
|
||||
static char *sh_cmds_os2[] = { "call", "cd", "chcp", "chdir", "cls", "copy",
|
||||
"date", "del", "detach", "dir", "echo",
|
||||
"endlocal", "erase", "exit", "for", "goto", "if",
|
||||
"keys", "md", "mkdir", "move", "path", "pause",
|
||||
"prompt", "rd", "rem", "ren", "rename", "rmdir",
|
||||
"set", "setlocal", "shift", "start", "time",
|
||||
"type", "ver", "verify", "vol", ":", 0 };
|
||||
|
||||
static char sh_chars_sh[] = "#;\"*?[]&|<>(){}$`^";
|
||||
static char *sh_cmds_sh[] = { "echo", "cd", "eval", "exec", "exit", "login",
|
||||
"logout", "set", "umask", "wait", "while",
|
||||
"for", "case", "if", ":", ".", "break",
|
||||
"continue", "export", "read", "readonly",
|
||||
"shift", "times", "trap", "switch", "unset",
|
||||
0 };
|
||||
char *sh_chars;
|
||||
char **sh_cmds;
|
||||
|
||||
#elif defined (_AMIGA)
|
||||
static char sh_chars[] = "#;\"|<>()?*$`";
|
||||
static char *sh_cmds[] = { "cd", "eval", "if", "delete", "echo", "copy",
|
||||
"rename", "set", "setenv", "date", "makedir",
|
||||
"skip", "else", "endif", "path", "prompt",
|
||||
"unset", "unsetenv", "version",
|
||||
0 };
|
||||
#else
|
||||
#ifdef WINDOWS32
|
||||
#elif defined (WINDOWS32)
|
||||
static char sh_chars_dos[] = "\"|&<>";
|
||||
static char *sh_cmds_dos[] = { "break", "call", "cd", "chcp", "chdir", "cls",
|
||||
"copy", "ctty", "date", "del", "dir", "echo",
|
||||
@ -2464,8 +2699,6 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
|
||||
"case", "if", ":", ".", "break", "continue",
|
||||
"export", "read", "readonly", "shift", "times",
|
||||
"trap", "switch", 0 };
|
||||
#endif /* WINDOWS32 */
|
||||
#endif /* Amiga */
|
||||
#endif /* __MSDOS__ */
|
||||
register int i;
|
||||
register char *p;
|
||||
@ -2513,7 +2746,7 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
|
||||
if (slow_flag)
|
||||
goto slow;
|
||||
#else /* not WINDOWS32 */
|
||||
#ifdef __MSDOS__
|
||||
#if defined (__MSDOS__) || defined (__EMX__)
|
||||
else if (stricmp (shell, default_shell))
|
||||
{
|
||||
extern int _is_unixy_shell (const char *_path);
|
||||
@ -2521,6 +2754,10 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
|
||||
message (1, _("$SHELL changed (was `%s', now `%s')"), default_shell, shell);
|
||||
unixy_shell = _is_unixy_shell (shell);
|
||||
default_shell = shell;
|
||||
/* we must allocate a copy of shell: construct_command_argv() will free
|
||||
* shell after this function returns. */
|
||||
default_shell = xmalloc (strlen (shell) + 1);
|
||||
strcpy (default_shell, shell);
|
||||
}
|
||||
if (unixy_shell)
|
||||
{
|
||||
@ -2531,11 +2768,17 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
|
||||
{
|
||||
sh_chars = sh_chars_dos;
|
||||
sh_cmds = sh_cmds_dos;
|
||||
# ifdef __EMX__
|
||||
if (_osmode == OS2_MODE)
|
||||
{
|
||||
sh_chars = sh_chars_os2;
|
||||
sh_cmds = sh_cmds_os2;
|
||||
}
|
||||
#else /* not __MSDOS__ */
|
||||
# endif
|
||||
#else /* !__MSDOS__ */
|
||||
else if (strcmp (shell, default_shell))
|
||||
goto slow;
|
||||
#endif /* not __MSDOS__ */
|
||||
#endif /* !__MSDOS__ && !__EMX__ */
|
||||
#endif /* not WINDOWS32 */
|
||||
|
||||
if (ifs != 0)
|
||||
@ -2838,6 +3081,11 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
|
||||
+ (line_len * 2) + 1);
|
||||
char *command_ptr = NULL; /* used for batch_mode_shell mode */
|
||||
|
||||
# ifdef __EMX__ /* is this necessary? */
|
||||
if (!unixy_shell)
|
||||
minus_c[1] = '/'; /* " /c " */
|
||||
# endif
|
||||
|
||||
ap = new_line;
|
||||
bcopy (shell, ap, shell_len);
|
||||
ap += shell_len;
|
||||
@ -2951,7 +3199,107 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
|
||||
new_argv = construct_command_argv_internal (new_line, (char **) NULL,
|
||||
(char *) 0, (char *) 0,
|
||||
(char **) 0);
|
||||
#ifdef __MSDOS__
|
||||
# ifdef __EMX__
|
||||
else if (!unixy_shell)
|
||||
{
|
||||
/* new_line is local, must not be freed therefore */
|
||||
char *p, *q;
|
||||
int quote;
|
||||
size_t index;
|
||||
size_t len;
|
||||
|
||||
/* handle quotes
|
||||
We have to remove all double quotes and to split the line
|
||||
into distinct arguments because of the strange handling
|
||||
of builtin commands by cmd: 'echo "bla"' prints "bla"
|
||||
(with quotes) while 'c:\bin\echo.exe "bla"' prints bla
|
||||
(without quotes). Some programs like autoconf rely
|
||||
on the second behaviour. */
|
||||
|
||||
len = strlen (new_line) + 1;
|
||||
|
||||
/* More than 1 arg per character is impossible. */
|
||||
new_argv = (char **) xmalloc (len * sizeof (char *));
|
||||
|
||||
/* All the args can fit in a buffer as big as new_line is. */
|
||||
new_argv[0] = (char *) xmalloc (len);
|
||||
|
||||
index = 0;
|
||||
quote = 0;
|
||||
q = new_line;
|
||||
p = new_argv[index];
|
||||
while(*q != '\0')
|
||||
{
|
||||
/* searching for closing quote */
|
||||
if (quote)
|
||||
{
|
||||
if (*q == quote)
|
||||
{
|
||||
/* remove the quote */
|
||||
while(*q == quote) /* do not ask */
|
||||
q++;
|
||||
quote = 0;
|
||||
}
|
||||
else /* normal character: copy it */
|
||||
*p++ = *q++;
|
||||
}
|
||||
|
||||
/* searching for opening quote */
|
||||
else if (*q == '\"'
|
||||
# ifndef NO_CMD_DEFAULT
|
||||
|| *q == '\''
|
||||
# endif
|
||||
)
|
||||
{
|
||||
/* remove opening quote */
|
||||
quote = *q;
|
||||
while(*q == quote) /* do not ask */
|
||||
q++;
|
||||
}
|
||||
|
||||
/* spaces outside of a quoted string: remove them
|
||||
and start a new argument */
|
||||
else if (*q == ' ' || *q == '\t')
|
||||
{
|
||||
*p++ = '\0'; /* trailing '\0' for last argument */
|
||||
|
||||
/* remove all successive spaces */
|
||||
do
|
||||
{
|
||||
q++;
|
||||
}
|
||||
while(*q == ' ' || *q == '\t');
|
||||
|
||||
/* start new argument */
|
||||
index++;
|
||||
new_argv[index] = p;
|
||||
}
|
||||
|
||||
/* normal character (no space) outside a quoted string*/
|
||||
else
|
||||
*p++ = *q++;
|
||||
} /* end while() */
|
||||
|
||||
*p = '\0'; /* trailing '\0' for the last argument */
|
||||
new_argv[index + 1] = NULL;
|
||||
|
||||
# ifndef NO_CMD_DEFAULT
|
||||
/* special case: echo x="y"
|
||||
(e.g. autoconf uses this to determine whether make works)
|
||||
this is pure idioty but cmd works this way:
|
||||
if 'echo' and 'x="y"' are two different arguments cmd
|
||||
will print '"x="y""' but if they are only one argument
|
||||
cmd will print 'bla="blurb"' as it should be
|
||||
note: if we do not allow cmd to be the default shell
|
||||
we do not need this kind of voodoo */
|
||||
if (index == 3 && strcasecmp(new_argv[2], "echo") == 0)
|
||||
{
|
||||
new_argv[2][4] = ' ';
|
||||
new_argv[3] = NULL;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
#elif defined(__MSDOS__)
|
||||
else
|
||||
{
|
||||
/* With MSDOS shells, we must construct the command line here
|
||||
@ -3053,6 +3401,51 @@ construct_command_argv (char *line, char **restp, struct file *file,
|
||||
strcpy (shell, p);
|
||||
}
|
||||
#endif
|
||||
#ifdef __EMX__
|
||||
{
|
||||
static const char *unixroot = NULL;
|
||||
static const char *last_shell = "";
|
||||
static int init = 0;
|
||||
if (init == 0)
|
||||
{
|
||||
unixroot = getenv ("UNIXROOT");
|
||||
/* unixroot must be NULL or not empty */
|
||||
if (unixroot && unixroot[0] == '\0') unixroot = NULL;
|
||||
init = 1;
|
||||
}
|
||||
|
||||
/* if we have an unixroot drive and if shell is not default_shell
|
||||
(which means it's either cmd.exe or the test has already been
|
||||
performed) and if shell is an absolute path without drive letter,
|
||||
try whether it exists e.g.: if "/bin/sh" does not exist use
|
||||
"$UNIXROOT/bin/sh" instead. */
|
||||
if (unixroot && shell && strcmp (shell, last_shell) != 0
|
||||
&& (shell[0] == '/' || shell[0] == '\\'))
|
||||
{
|
||||
/* trying a new shell, check whether it exists */
|
||||
size_t size = strlen (shell);
|
||||
char *buf = xmalloc (size + 7);
|
||||
memcpy (buf, shell, size);
|
||||
memcpy (buf + size, ".exe", 5); /* including the trailing '\0' */
|
||||
if (access (shell, F_OK) != 0 && access (buf, F_OK) != 0)
|
||||
{
|
||||
/* try the same for the unixroot drive */
|
||||
memmove (buf + 2, buf, size + 5);
|
||||
buf[0] = unixroot[0];
|
||||
buf[1] = unixroot[1];
|
||||
if (access (buf, F_OK) == 0)
|
||||
/* we have found a shell! */
|
||||
/* free(shell); */
|
||||
shell = buf;
|
||||
else
|
||||
free (buf);
|
||||
}
|
||||
else
|
||||
free (buf);
|
||||
}
|
||||
}
|
||||
#endif __EMX__
|
||||
|
||||
ifs = allocated_variable_expand_for_file ("$(IFS)", file);
|
||||
|
||||
warn_undefined_variables_flag = save;
|
||||
|
21
job.h
21
job.h
@ -20,6 +20,23 @@ Boston, MA 02111-1307, USA. */
|
||||
#ifndef SEEN_JOB_H
|
||||
#define SEEN_JOB_H
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#else
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
|
||||
/* How to set close-on-exec for a file descriptor. */
|
||||
|
||||
#if !defined F_SETFD
|
||||
# define CLOSE_ON_EXEC(_d)
|
||||
#else
|
||||
# ifndef FD_CLOEXEC
|
||||
# define FD_CLOEXEC 1
|
||||
# endif
|
||||
# define CLOSE_ON_EXEC(_d) (void) fcntl ((_d), F_SETFD, FD_CLOEXEC)
|
||||
#endif
|
||||
|
||||
/* Structure describing a running or dead child process. */
|
||||
|
||||
struct child
|
||||
@ -57,11 +74,15 @@ extern void start_waiting_jobs PARAMS ((void));
|
||||
extern char **construct_command_argv PARAMS ((char *line, char **restp, struct file *file, char** batch_file));
|
||||
#ifdef VMS
|
||||
extern int child_execute_job PARAMS ((char *argv, struct child *child));
|
||||
#elif defined(__EMX__)
|
||||
extern int child_execute_job PARAMS ((int stdin_fd, int stdout_fd, char **argv, char **envp));
|
||||
#else
|
||||
extern void child_execute_job PARAMS ((int stdin_fd, int stdout_fd, char **argv, char **envp));
|
||||
#endif
|
||||
#ifdef _AMIGA
|
||||
extern void exec_command PARAMS ((char **argv));
|
||||
#elif defined(__EMX__)
|
||||
extern int exec_command PARAMS ((char **argv, char **envp));
|
||||
#else
|
||||
extern void exec_command PARAMS ((char **argv, char **envp));
|
||||
#endif
|
||||
|
59
main.c
59
main.c
@ -37,6 +37,10 @@ MA 02111-1307, USA. */
|
||||
#include <windows.h>
|
||||
#include "pathstuff.h"
|
||||
#endif
|
||||
#ifdef __EMX__
|
||||
# include <sys/types.h>
|
||||
# include <sys/wait.h>
|
||||
#endif
|
||||
#if defined(MAKE_JOBSERVER) && defined(HAVE_FCNTL_H)
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
@ -846,6 +850,9 @@ main (int argc, char **argv, char **envp)
|
||||
no_default_sh_exe = 1;
|
||||
#endif
|
||||
|
||||
/* Needed for OS/2 */
|
||||
initialize_main(&argc, &argv);
|
||||
|
||||
default_goal_file = 0;
|
||||
reading_file = 0;
|
||||
|
||||
@ -952,7 +959,7 @@ main (int argc, char **argv, char **envp)
|
||||
#else
|
||||
program = strrchr (argv[0], '/');
|
||||
#endif
|
||||
#ifdef __MSDOS__
|
||||
#if defined(__MSDOS__) || defined(__EMX__)
|
||||
if (program == 0)
|
||||
program = strrchr (argv[0], '\\');
|
||||
else
|
||||
@ -1136,7 +1143,7 @@ main (int argc, char **argv, char **envp)
|
||||
strneq(argv[0], "//", 2))
|
||||
argv[0] = xstrdup(w32ify(argv[0],1));
|
||||
#else /* WINDOWS32 */
|
||||
#ifdef __MSDOS__
|
||||
#if defined (__MSDOS__) || defined (__EMX__)
|
||||
if (strchr (argv[0], '\\'))
|
||||
{
|
||||
char *p;
|
||||
@ -1325,7 +1332,7 @@ main (int argc, char **argv, char **envp)
|
||||
#define DEFAULT_TMPFILE "GmXXXXXX"
|
||||
|
||||
if (((tmpdir = getenv ("TMPDIR")) == NULL || *tmpdir == '\0')
|
||||
#if defined __MSDOS__ || defined(WINDOWS32)
|
||||
#if defined (__MSDOS__) || defined (WINDOWS32) || defined (__EMX__)
|
||||
/* These are also used commonly on these platforms. */
|
||||
&& ((tmpdir = getenv ("TEMP")) == NULL || *tmpdir == '\0')
|
||||
&& ((tmpdir = getenv ("TMP")) == NULL || *tmpdir == '\0')
|
||||
@ -1376,6 +1383,7 @@ main (int argc, char **argv, char **envp)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __EMX__ /* Don't use a SIGCHLD handler for OS/2 */
|
||||
#if defined(MAKE_JOBSERVER) || !defined(HAVE_WAIT_NOHANG)
|
||||
/* Set up to handle children dying. This must be done before
|
||||
reading in the makefiles so that `shell' function calls will work.
|
||||
@ -1398,6 +1406,7 @@ main (int argc, char **argv, char **envp)
|
||||
bsd_signal (SIGCLD, child_handler);
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Let the user send us SIGUSR1 to toggle the -d flag during the run. */
|
||||
@ -1448,7 +1457,7 @@ main (int argc, char **argv, char **envp)
|
||||
}
|
||||
#endif /* WINDOWS32 */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#if defined (__MSDOS__) || defined (__EMX__)
|
||||
/* We need to know what kind of shell we will be using. */
|
||||
{
|
||||
extern int _is_unixy_shell (const char *_path);
|
||||
@ -1468,7 +1477,7 @@ main (int argc, char **argv, char **envp)
|
||||
default_shell = shell_path;
|
||||
}
|
||||
}
|
||||
#endif /* __MSDOS__ */
|
||||
#endif /* __MSDOS__ || __EMX__ */
|
||||
|
||||
/* Decode switches again, in case the variables were set by the makefile. */
|
||||
decode_env_switches ("MAKEFLAGS", 9);
|
||||
@ -1476,8 +1485,12 @@ main (int argc, char **argv, char **envp)
|
||||
decode_env_switches ("MFLAGS", 6);
|
||||
#endif
|
||||
|
||||
#ifdef __MSDOS__
|
||||
if (job_slots != 1)
|
||||
#if defined (__MSDOS__) || defined (__EMX__)
|
||||
if (job_slots != 1
|
||||
# ifdef __EMX__
|
||||
&& _osmode != OS2_MODE /* turn off -j if we are in DOS mode */
|
||||
# endif
|
||||
)
|
||||
{
|
||||
error (NILF,
|
||||
_("Parallel jobs (-j) are not supported on this platform."));
|
||||
@ -1557,8 +1570,13 @@ main (int argc, char **argv, char **envp)
|
||||
want job_slots to be 0 to indicate we're using the jobserver. */
|
||||
|
||||
while (--job_slots)
|
||||
if (write (job_fds[1], &c, 1) != 1)
|
||||
{
|
||||
int r;
|
||||
|
||||
EINTRLOOP (r, write (job_fds[1], &c, 1));
|
||||
if (r != 1)
|
||||
pfatal_with_name (_("init jobserver pipe"));
|
||||
}
|
||||
|
||||
/* Fill in the jobserver_fds struct for our children. */
|
||||
|
||||
@ -1880,11 +1898,30 @@ main (int argc, char **argv, char **envp)
|
||||
if (job_rfd >= 0)
|
||||
close (job_rfd);
|
||||
|
||||
#ifndef _AMIGA
|
||||
exec_command (nargv, environ);
|
||||
#else
|
||||
#ifdef _AMIGA
|
||||
exec_command (nargv);
|
||||
exit (0);
|
||||
#elif defined (__EMX__)
|
||||
{
|
||||
/* It is not possible to use execve() here because this
|
||||
would cause the parent process to be terminated with
|
||||
exit code 0 before the child process has been terminated.
|
||||
Therefore it may be the best solution simply to spawn the
|
||||
child process including all file handles and to wait for its
|
||||
termination. */
|
||||
int pid;
|
||||
int status;
|
||||
pid = child_execute_job(0, 1, nargv, environ);
|
||||
|
||||
/* is this loop really necessary? */
|
||||
do {
|
||||
pid = wait(&status);
|
||||
} while(pid <= 0);
|
||||
/* use the exit code of the child process */
|
||||
exit(WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE);
|
||||
}
|
||||
#else
|
||||
exec_command (nargv, environ);
|
||||
#endif
|
||||
/* NOTREACHED */
|
||||
|
||||
|
43
make.h
43
make.h
@ -349,16 +349,13 @@ extern int strcmpi (const char *,const char *);
|
||||
#define S_(msg1,msg2,num) ngettext (msg1,msg2,num)
|
||||
|
||||
/* Handle other OSs. */
|
||||
|
||||
#if defined(__MSDOS__) || defined(WINDOWS32)
|
||||
#if defined(HAVE_DOS_PATHS)
|
||||
# define PATH_SEPARATOR_CHAR ';'
|
||||
#else
|
||||
# if defined(VMS)
|
||||
#elif defined(VMS)
|
||||
# define PATH_SEPARATOR_CHAR ','
|
||||
#else
|
||||
# define PATH_SEPARATOR_CHAR ':'
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS32
|
||||
# include <fcntl.h>
|
||||
@ -538,6 +535,42 @@ extern int handling_fatal_signal;
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
|
||||
#ifndef initialize_main
|
||||
# ifdef __EMX__
|
||||
# define initialize_main(pargc, pargv) \
|
||||
{ _wildcard(pargc, pargv); _response(pargc, pargv); }
|
||||
# else
|
||||
# define initialize_main(pargc, pargv)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __EMX__
|
||||
# if !HAVE_STRCASECMP
|
||||
# define strcasecmp stricmp
|
||||
# endif
|
||||
|
||||
# if !defined chdir
|
||||
# define chdir _chdir2
|
||||
# endif
|
||||
# if !defined getcwd
|
||||
# define getcwd _getcwd2
|
||||
# endif
|
||||
|
||||
/* NO_CHDIR2 causes make not to use _chdir2() and _getcwd2() instead of
|
||||
chdir() and getcwd(). This avoids some error messages for the
|
||||
make testsuite but restricts the drive letter support. */
|
||||
# ifdef NO_CHDIR2
|
||||
# warning NO_CHDIR2: usage of drive letters restricted
|
||||
# undef chdir
|
||||
# undef getcwd
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef initialize_main
|
||||
# define initialize_main(pargc, pargv)
|
||||
#endif
|
||||
|
||||
|
||||
/* Some systems (like Solaris, PTX, etc.) do not support the SA_RESTART flag
|
||||
properly according to POSIX. So, we try to wrap common system calls with
|
||||
|
12
read.c
12
read.c
@ -561,12 +561,16 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
}
|
||||
}
|
||||
|
||||
/* This line is not a shell command line. Don't worry about tabs. */
|
||||
/* This line is not a shell command line. Don't worry about tabs.
|
||||
Get more space if we need it; we don't need to preserve the current
|
||||
contents of the buffer. */
|
||||
|
||||
if (collapsed_length < linelen+1)
|
||||
{
|
||||
collapsed_length = linelen+1;
|
||||
collapsed = (char *) xrealloc (collapsed, collapsed_length);
|
||||
if (collapsed)
|
||||
free ((char *)collapsed);
|
||||
collapsed = (char *) xmalloc (collapsed_length);
|
||||
}
|
||||
strcpy (collapsed, line);
|
||||
/* Collapse continuation lines. */
|
||||
@ -1150,7 +1154,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
|
||||
do {
|
||||
check_again = 0;
|
||||
/* For DOS paths, skip a "C:\..." or a "C:/..." */
|
||||
/* For DOS-style paths, skip a "C:\..." or a "C:/..." */
|
||||
if (p != 0 && (p[1] == '\\' || p[1] == '/') &&
|
||||
isalpha ((unsigned char)p[-1]) &&
|
||||
(p == p2 + 1 || strchr (" \t:(", p[-2]) != 0)) {
|
||||
@ -2559,7 +2563,7 @@ readline (struct ebuffer *ebuf)
|
||||
/* We got a newline, so add one to the count of lines. */
|
||||
++nlines;
|
||||
|
||||
#if !defined(WINDOWS32) && !defined(__MSDOS__)
|
||||
#if !defined(WINDOWS32) && !defined(__MSDOS__) && !defined(__EMX__)
|
||||
/* Check to see if the line was really ended with CRLF; if so ignore
|
||||
the CR. */
|
||||
if ((p - start) > 1 && p[-2] == '\r')
|
||||
|
8
remake.c
8
remake.c
@ -1200,6 +1200,14 @@ f_mtime (struct file *file, int search)
|
||||
FILE_TIMESTAMP adjustment = FAT_ADJ_OFFSET << FILE_TIMESTAMP_LO_BITS;
|
||||
if (ORDINARY_MTIME_MIN + adjustment <= adjusted_mtime)
|
||||
adjusted_mtime -= adjustment;
|
||||
#elif defined(__EMX__)
|
||||
/* FAT filesystems round time to the nearest even second!
|
||||
Allow for any file (NTFS or FAT) to perhaps suffer from this
|
||||
brain damage. */
|
||||
FILE_TIMESTAMP adjustment = (((FILE_TIMESTAMP_S (adjusted_mtime) & 1) == 0
|
||||
&& FILE_TIMESTAMP_NS (adjusted_mtime) == 0)
|
||||
? (FILE_TIMESTAMP) 1 << FILE_TIMESTAMP_LO_BITS
|
||||
: 0);
|
||||
#endif
|
||||
|
||||
/* If the file's time appears to be in the future, update our
|
||||
|
56
variable.c
56
variable.c
@ -544,7 +544,7 @@ merge_variable_set_lists (struct variable_set_list **setlist0,
|
||||
void
|
||||
define_automatic_variables (void)
|
||||
{
|
||||
#ifdef WINDOWS32
|
||||
#if defined(WINDOWS32) || defined(__EMX__)
|
||||
extern char* default_shell;
|
||||
#else
|
||||
extern char default_shell[];
|
||||
@ -585,6 +585,54 @@ define_automatic_variables (void)
|
||||
(void) define_variable (shell_str, shlen, comp->value, o_env, 0);
|
||||
}
|
||||
}
|
||||
#elif defined(__EMX__)
|
||||
{
|
||||
static char shell_str[] = "SHELL";
|
||||
const int shlen = sizeof (shell_str) - 1;
|
||||
struct variable *shell = lookup_variable (shell_str, shlen);
|
||||
struct variable *replace = lookup_variable ("MAKESHELL", 9);
|
||||
|
||||
/* if $MAKESHELL is defined in the environment assume o_env_override */
|
||||
if (replace && *replace->value && replace->origin == o_env)
|
||||
replace->origin = o_env_override;
|
||||
|
||||
/* if $MAKESHELL is not defined use $SHELL but only if the variable
|
||||
did not come from the environment */
|
||||
if (!replace || !*replace->value)
|
||||
if (shell && *shell->value && (shell->origin == o_env
|
||||
|| shell->origin == o_env_override))
|
||||
{
|
||||
/* overwrite whatever we got from the environment */
|
||||
free(shell->value);
|
||||
shell->value = xstrdup (default_shell);
|
||||
shell->origin = o_default;
|
||||
}
|
||||
|
||||
/* Some people do not like cmd to be used as the default
|
||||
if $SHELL is not defined in the Makefile.
|
||||
With -DNO_CMD_DEFAULT you can turn off this behaviour */
|
||||
# ifndef NO_CMD_DEFAULT
|
||||
/* otherwise use $COMSPEC */
|
||||
if (!replace || !*replace->value)
|
||||
replace = lookup_variable ("COMSPEC", 7);
|
||||
|
||||
/* otherwise use $OS2_SHELL */
|
||||
if (!replace || !*replace->value)
|
||||
replace = lookup_variable ("OS2_SHELL", 9);
|
||||
# else
|
||||
# warning NO_CMD_DEFAULT: GNU make will not use CMD.EXE as default shell
|
||||
# endif
|
||||
|
||||
if (replace && *replace->value)
|
||||
/* overwrite $SHELL */
|
||||
(void) define_variable (shell_str, shlen, replace->value,
|
||||
replace->origin, 0);
|
||||
else
|
||||
/* provide a definition if there is none */
|
||||
(void) define_variable (shell_str, shlen, default_shell,
|
||||
o_default, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* This won't override any definition, but it
|
||||
@ -594,8 +642,10 @@ define_automatic_variables (void)
|
||||
|
||||
/* On MSDOS we do use SHELL from environment, since
|
||||
it isn't a standard environment variable on MSDOS,
|
||||
so whoever sets it, does that on purpose. */
|
||||
#ifndef __MSDOS__
|
||||
so whoever sets it, does that on purpose.
|
||||
On OS/2 we do not use SHELL from environment but
|
||||
we have already handled that problem above. */
|
||||
#if !defined(__MSDOS__) && !defined(__EMX__)
|
||||
/* Don't let SHELL come from the environment. */
|
||||
if (*v->value == '\0' || v->origin == o_env || v->origin == o_env_override)
|
||||
{
|
||||
|
2
vpath.c
2
vpath.c
@ -247,7 +247,7 @@ construct_vpath_list (char *pattern, char *dirpath)
|
||||
len = p - v;
|
||||
/* Make sure there's no trailing slash,
|
||||
but still allow "/" as a directory. */
|
||||
#ifdef __MSDOS__
|
||||
#if defined(__MSDOS__) || defined(__EMX__)
|
||||
/* We need also to leave alone a trailing slash in "d:/". */
|
||||
if (len > 3 || (len > 1 && v[1] != ':'))
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user