Delete some more unneeded Make code

This commit is contained in:
Justine Tunney 2022-04-06 01:22:30 -07:00
parent 58d74ede4c
commit ce9bdbb0bf
13 changed files with 46 additions and 1300 deletions

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/str/path.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
@ -25,6 +26,7 @@ TEST(isabspath, testUniversal) {
}
TEST(isabspath, testDosPaths) {
if (!SupportsWindows()) return;
ASSERT_FALSE(_isabspath("C:"));
ASSERT_FALSE(_isabspath("C:foo.txt"));
ASSERT_TRUE(_isabspath("C:/"));
@ -34,15 +36,18 @@ TEST(isabspath, testDosPaths) {
}
TEST(isabspath, testWin32Paths) {
if (!SupportsWindows()) return;
ASSERT_TRUE(_isabspath("\\\\?\\C:\\.."));
ASSERT_TRUE(_isabspath("\\\\.\\C:\\Users\\jart\\foo.txt"));
}
TEST(isabspath, testNtPaths) {
if (!SupportsWindows()) return;
ASSERT_TRUE(_isabspath("\\??\\C:\\Users\\jart\\foo.txt"));
}
TEST(_classifypath, test) {
if (!SupportsWindows()) return;
EXPECT_EQ(0, _classifypath(""));
EXPECT_EQ(0, _classifypath("xyz"));
EXPECT_EQ(_PATH_DOS | _PATH_DEV, _classifypath("CON"));

48
third_party/make/ar.c vendored
View file

@ -115,14 +115,6 @@ ar_member_date (const char *name)
/* Set the archive-member NAME's modtime to now. */
#ifdef VMS
int
ar_touch (const char *name)
{
O (error, NILF, _("touch archive member is not available on VMS"));
return -1;
}
#else
int
ar_touch (const char *name)
{
@ -167,7 +159,7 @@ ar_touch (const char *name)
return val;
}
#endif /* !VMS */
/* State of an 'ar_glob' run, passed to 'ar_glob_match'. */
@ -182,9 +174,6 @@ struct ar_glob_state
{
const char *arname;
const char *pattern;
#ifdef VMS
char *suffix;
#endif
size_t size;
struct nameseq *chain;
unsigned int n;
@ -205,12 +194,6 @@ ar_glob_match (int desc UNUSED, const char *mem, int truncated UNUSED,
{
/* We have a match. Add it to the chain. */
struct nameseq *new = xcalloc (state->size);
#ifdef VMS
if (state->suffix)
new->name = strcache_add(
concat(5, state->arname, "(", mem, state->suffix, ")"));
else
#endif
new->name = strcache_add(concat(4, state->arname, "(", mem, ")"));
new->next = state->chain;
state->chain = new;
@ -263,9 +246,7 @@ ar_glob (const char *arname, const char *member_pattern, size_t size)
struct nameseq *n;
const char **names;
unsigned int i;
#ifdef VMS
char *vms_member_pattern;
#endif
if (! ar_glob_pattern_p (member_pattern, 1))
return 0;
@ -273,36 +254,11 @@ ar_glob (const char *arname, const char *member_pattern, size_t size)
ar_glob_match will accumulate them in STATE.chain. */
state.arname = arname;
state.pattern = member_pattern;
#ifdef VMS
{
/* In a copy of the pattern, find the suffix, save it and remove it from
the pattern */
char *lastdot;
vms_member_pattern = xstrdup(member_pattern);
lastdot = strrchr(vms_member_pattern, '.');
state.suffix = lastdot;
if (lastdot)
{
state.suffix = xstrdup(lastdot);
*lastdot = 0;
}
state.pattern = vms_member_pattern;
}
#endif
state.size = size;
state.chain = 0;
state.n = 0;
ar_scan (arname, ar_glob_match, &state);
#ifdef VMS
/* Deallocate any duplicated string */
free(vms_member_pattern);
if (state.suffix)
{
free(state.suffix);
}
#endif
if (state.chain == 0)
return 0;

View file

@ -518,12 +518,8 @@ fatal_error_signal (int sig)
wanted to kill make, remove pending targets. */
if (sig == SIGTERM || sig == SIGINT
#ifdef SIGHUP
|| sig == SIGHUP
#endif
#ifdef SIGQUIT
|| sig == SIGQUIT
#endif
)
{
struct child *c;
@ -551,12 +547,10 @@ fatal_error_signal (int sig)
remove_intermediates (1);
#ifdef SIGQUIT
if (sig == SIGQUIT)
/* We don't want to send ourselves SIGQUIT, because it will
cause a core dump. Just exit instead. */
exit (MAKE_TROUBLE);
#endif
#ifdef WINDOWS32
if (main_thread)

View file

@ -223,9 +223,6 @@
the CoreFoundation framework. */
/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */
/* Define to 1 if you have the clock_gettime function. */
/* #undef HAVE_CLOCK_GETTIME */
/* Define if the GNU dcgettext() function is already present or preinstalled.
*/
/* #undef HAVE_DCGETTEXT */
@ -589,12 +586,6 @@
/* Define if you have a global __progname variable */
/* #undef HAVE_VAR___PROGNAME */
/* Define to 1 if you have the `vfork' function. */
#define HAVE_VFORK 1
/* Define to 1 if you have the <vfork.h> header file. */
/* #undef HAVE_VFORK_H */
/* Define to 1 if you have the `wait3' function. */
#define HAVE_WAIT3 1
@ -622,9 +613,6 @@
/* Define to 1 if O_NOFOLLOW works. */
#define HAVE_WORKING_O_NOFOLLOW 0
/* Define to 1 if `vfork' works. */
#define HAVE_WORKING_VFORK 1
/* Define to 1 if the system has the type `_Bool'. */
#define HAVE__BOOL 1
@ -638,9 +626,6 @@
/* TODO(jart): make it work */
/* #define MAKE_JOBSERVER 1 */
/* Define to 1 to enable 'load' support in GNU make. */
/* #define MAKE_LOAD 1 */
/* Define to 1 to enable symbolic link timestamp checking. */
#define MAKE_SYMLINKS 1
@ -733,9 +718,6 @@
<sys/cpustats.h>. */
/* #undef UMAX4_3 */
/* Define to 1 to use posix_spawn(). */
/* #undef USE_POSIX_SPAWN */
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
#define _ALL_SOURCE 1
@ -1123,6 +1105,3 @@
#else
#define _GL_ATTRIBUTE_MALLOC /* empty */
#endif
/* Define as `fork' if `vfork' does not work. */
/* #undef vfork */

View file

@ -24,7 +24,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "third_party/make/variable.h"
#include "third_party/make/debug.h"
#include "libc/assert.h"
#include "libc/assert.h"
#include "libc/sysv/consts/clock.h"
#include "third_party/make/hash.h"
@ -73,38 +73,9 @@ lookup_file (const char *name)
{
struct file *f;
struct file file_key;
#ifdef VMS
int want_vmsify;
#ifndef WANT_CASE_SENSITIVE_TARGETS
char *lname;
#endif
#endif
assert (*name != '\0');
/* This is also done in parse_file_seq, so this is redundant
for names read from makefiles. It is here for names passed
on the command line. */
#ifdef VMS
want_vmsify = (strpbrk (name, "]>:^") != NULL);
# ifndef WANT_CASE_SENSITIVE_TARGETS
if (*name != '.')
{
const char *n;
char *ln;
lname = xstrdup (name);
for (n = name, ln = lname; *n != '\0'; ++n, ++ln)
*ln = isupper ((unsigned char)*n) ? tolower ((unsigned char)*n) : *n;
*ln = '\0';
name = lname;
}
# endif
while (name[0] == '[' && name[1] == ']' && name[2] != '\0')
name += 2;
while (name[0] == '<' && name[1] == '>' && name[2] != '\0')
name += 2;
#endif
while (name[0] == '.'
#ifdef HAVE_DOS_PATHS
&& (name[1] == '/' || name[1] == '\\')
@ -126,23 +97,10 @@ lookup_file (const char *name)
if (*name == '\0')
{
/* It was all slashes after a dot. */
#if defined(_AMIGA)
name = "";
#else
name = "./";
#endif
#if defined(VMS)
/* TODO - This section is probably not needed. */
if (want_vmsify)
name = "[]";
#endif
}
file_key.hname = name;
f = hash_find_item (&files, &file_key);
#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
if (*name != '.')
free (lname);
#endif
return f;
}
@ -163,24 +121,6 @@ enter_file (const char *name)
assert (*name != '\0');
assert (! verify_flag || strcache_iscached (name));
#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
if (*name != '.')
{
const char *n;
char *lname, *ln;
lname = xstrdup (name);
for (n = name, ln = lname; *n != '\0'; ++n, ++ln)
if (isupper ((unsigned char)*n))
*ln = tolower ((unsigned char)*n);
else
*ln = *n;
*ln = '\0';
name = strcache_add (lname);
free (lname);
}
#endif
file_key.hname = name;
file_slot = (struct file **) hash_find_slot (&files, &file_key);
f = *file_slot;
@ -892,8 +832,6 @@ file_timestamp_now (int *resolution)
/* Don't bother with high-resolution clocks if file timestamps have
only one-second resolution. The code below should work, but it's
not worth the hassle of debugging it on hosts where it fails. */
#if FILE_TIMESTAMP_HI_RES
# if HAVE_CLOCK_GETTIME && defined CLOCK_REALTIME
{
struct timespec timespec;
if (clock_gettime (CLOCK_REALTIME, &timespec) == 0)
@ -904,8 +842,6 @@ file_timestamp_now (int *resolution)
goto got_time;
}
}
# endif
# if HAVE_GETTIMEOFDAY
{
struct timeval timeval;
if (gettimeofday (&timeval, 0) == 0)
@ -916,16 +852,12 @@ file_timestamp_now (int *resolution)
goto got_time;
}
}
# endif
#endif
r = 1000000000;
s = time ((time_t *) 0);
ns = 0;
#if FILE_TIMESTAMP_HI_RES
got_time:
#endif
*resolution = r;
return file_timestamp_cons (0, s, ns);
}

View file

@ -590,31 +590,11 @@ func_basename_dir (char *o, char **argv, const char *funcname)
o = variable_buffer_output (o, p2, 2);
#endif
else if (is_dir)
#ifdef VMS
{
extern int vms_report_unix_paths;
if (vms_report_unix_paths)
o = variable_buffer_output (o, "./", 2);
else
o = variable_buffer_output (o, "[]", 2);
}
#else
#ifndef _AMIGA
o = variable_buffer_output (o, "./", 2);
#else
; /* Just a nop... */
#endif /* AMIGA */
#endif /* !VMS */
else
/* The entire name is the basename. */
o = variable_buffer_output (o, p2, len);
#ifdef VMS
if (vms_comma_separator)
o = variable_buffer_output (o, ",", 1);
else
#endif
o = variable_buffer_output (o, " ", 1);
o = variable_buffer_output (o, " ", 1);
doneany = 1;
}
@ -1338,12 +1318,8 @@ func_and (char *o, char **argv, const char *funcname UNUSED)
static char *
func_wildcard (char *o, char **argv, const char *funcname UNUSED)
{
#ifdef _AMIGA
o = wildcard_expansion (argv[0], o);
#else
char *p = string_glob (argv[0]);
o = variable_buffer_output (o, p, strlen (p));
#endif
return o;
}
@ -1574,60 +1550,6 @@ windows32_openpipe (int *pipedes, int errfd, pid_t *pid_p, char **command_argv,
#endif
#ifdef __MSDOS__
FILE *
msdos_openpipe (int* pipedes, int *pidp, char *text)
{
FILE *fpipe=0;
/* MSDOS can't fork, but it has 'popen'. */
struct variable *sh = lookup_variable ("SHELL", 5);
int e;
extern int dos_command_running, dos_status;
/* Make sure not to bother processing an empty line. */
NEXT_TOKEN (text);
if (*text == '\0')
return 0;
if (sh)
{
char buf[PATH_MAX + 7];
/* This makes sure $SHELL value is used by $(shell), even
though the target environment is not passed to it. */
sprintf (buf, "SHELL=%s", sh->value);
putenv (buf);
}
e = errno;
errno = 0;
dos_command_running = 1;
dos_status = 0;
/* If dos_status becomes non-zero, it means the child process
was interrupted by a signal, like SIGINT or SIGQUIT. See
fatal_error_signal in commands.c. */
fpipe = popen (text, "rt");
dos_command_running = 0;
if (!fpipe || dos_status)
{
pipedes[0] = -1;
*pidp = -1;
if (dos_status)
errno = EINTR;
else if (errno == 0)
errno = ENOMEM;
if (fpipe)
pclose (fpipe);
shell_completed (127, 0);
}
else
{
pipedes[0] = fileno (fpipe);
*pidp = 42; /* Yes, the Meaning of Life, the Universe, and Everything! */
errno = e;
}
return fpipe;
}
#endif
/*
Do shell spawning, with the naughty bits for different OSes.

468
third_party/make/job.c vendored
View file

@ -49,10 +49,6 @@ pid2str (pid_t pid)
return pidstring;
}
#ifndef HAVE_GETLOADAVG
int getloadavg (double loadavg[], int nelem);
#endif
static void free_child (struct child *);
static void start_job_command (struct child *child);
static int load_too_high (void);
@ -258,7 +254,6 @@ is_bourne_compatible_shell (const char *path)
return 0;
}
#ifdef POSIX
extern sigset_t fatal_signal_set;
static void
@ -281,39 +276,6 @@ unblock_all_sigs ()
sigprocmask (SIG_SETMASK, &empty, (sigset_t *) 0);
}
#elif defined(HAVE_SIGSETMASK)
extern int fatal_signal_mask;
static void
block_sigs ()
{
sigblock (fatal_signal_mask);
}
static void
unblock_sigs ()
{
sigsetmask (siggetmask (0) & ~fatal_signal_mask)
}
void
unblock_all_sigs ()
{
sigsetmask (0);
}
#else
#define block_sigs()
#define unblock_sigs()
void
unblock_all_sigs ()
{
}
#endif
/* Write an error message describing the exit status given in
EXIT_CODE, EXIT_SIG, and COREDUMP, for the target TARGET_NAME.
@ -404,9 +366,7 @@ extern pid_t shell_function_pid;
void
reap_children (int block, int err)
{
#ifndef WINDOWS32
WAIT_T status;
#endif
/* Initially, assume we have some. */
int reap_more = 1;
@ -496,15 +456,12 @@ reap_children (int block, int err)
else if (pid < 0)
{
/* A remote status command failed miserably. Punt. */
#if !defined(__MSDOS__) && !defined(_AMIGA) && !defined(WINDOWS32)
remote_status_lose:
#endif
pfatal_with_name ("remote_status");
}
else
{
/* No remote children. Check for local children. */
#if !defined(__MSDOS__) && !defined(_AMIGA) && !defined(WINDOWS32)
if (any_local)
{
if (!block)
@ -546,75 +503,7 @@ reap_children (int block, int err)
/* We got a remote child. */
remote = 1;
}
#endif /* !__MSDOS__, !Amiga, !WINDOWS32. */
#ifdef WINDOWS32
{
HANDLE hPID;
HANDLE hcTID, hcPID;
DWORD dwWaitStatus = 0;
exit_code = 0;
exit_sig = 0;
coredump = 0;
/* Record the thread ID of the main process, so that we
could suspend it in the signal handler. */
if (!main_thread)
{
hcTID = GetCurrentThread ();
hcPID = GetCurrentProcess ();
if (!DuplicateHandle (hcPID, hcTID, hcPID, &main_thread, 0,
FALSE, DUPLICATE_SAME_ACCESS))
{
DWORD e = GetLastError ();
fprintf (stderr,
"Determine main thread ID (Error %ld: %s)\n",
e, map_windows32_error_to_string (e));
}
else
DB (DB_VERBOSE, ("Main thread handle = %p\n", main_thread));
}
/* wait for anything to finish */
hPID = process_wait_for_any (block, &dwWaitStatus);
if (hPID)
{
/* was an error found on this process? */
int werr = process_last_err (hPID);
/* get exit data */
exit_code = process_exit_code (hPID);
/* the extra tests of exit_code are here to prevent
map_windows32_error_to_string from calling 'fatal',
which will then call reap_children again */
if (werr && exit_code > 0 && exit_code < WSABASEERR)
fprintf (stderr, "make (e=%d): %s", exit_code,
map_windows32_error_to_string (exit_code));
/* signal */
exit_sig = process_signal (hPID);
/* cleanup process */
process_cleanup (hPID);
coredump = 0;
}
else if (dwWaitStatus == WAIT_FAILED)
{
/* The WaitForMultipleObjects() failed miserably. Punt. */
pfatal_with_name ("WaitForMultipleObjects");
}
else if (dwWaitStatus == WAIT_TIMEOUT)
{
/* No child processes are finished. Give up waiting. */
reap_more = 0;
break;
}
pid = (pid_t) hPID;
}
#endif /* WINDOWS32 */
}
/* Check if this is the child of the 'shell' function. */
@ -646,35 +535,6 @@ reap_children (int block, int err)
process_child:
#if defined(USE_POSIX_SPAWN)
/* Some versions of posix_spawn() do not detect errors such as command
not found until after they fork. In that case they will exit with a
code of 127. Try to detect that and provide a useful error message.
Otherwise we'll just show the error below, as normal. */
if (exit_sig == 0 && exit_code == 127 && c->cmd_name)
{
const char *e = NULL;
struct stat st;
int r;
/* There are various ways that this will show a different error than
fork/exec. To really get the right error we'd have to fall back
to fork/exec but I don't want to bother with that. Just do the
best we can. */
EINTRLOOP(r, stat(c->cmd_name, &st));
if (r < 0)
e = strerror (errno);
else if (S_ISDIR(st.st_mode) || !(st.st_mode & S_IXUSR))
e = strerror (EACCES);
else if (st.st_size == 0)
e = strerror (ENOEXEC);
if (e)
OSS(error, NILF, "%s: %s", c->cmd_name, e);
}
#endif
/* Determine the failure status: 0 for success, 1 for updating target in
question mode, 2 for anything else. */
if (exit_sig == 0 && exit_code == 0)
@ -1044,13 +904,8 @@ start_job_command (struct child *child)
performed some action (makes a difference as to what messages are
printed, etc. */
#if !defined(VMS) && !defined(_AMIGA)
if (
#if defined __MSDOS__ || defined (__EMX__)
unixy_shell /* the test is complicated and we already did it */
#else
(argv[0] && is_bourne_compatible_shell (argv[0]))
#endif
&& (argv[1] && argv[1][0] == '-'
&&
((argv[1][1] == 'c' && argv[1][2] == '\0')
@ -1062,7 +917,6 @@ start_job_command (struct child *child)
FREE_ARGV (argv);
goto next_command;
}
#endif /* !VMS && !_AMIGA */
/* If -n was given, recurse to get the next line in the sequence. */
@ -1094,8 +948,6 @@ start_job_command (struct child *child)
if (child->environment == 0)
child->environment = target_environment (child->file);
#if !defined(__MSDOS__) && !defined(_AMIGA) && !defined(WINDOWS32)
/* start_waiting_job has set CHILD->remote if we can start a remote job. */
if (child->remote)
{
@ -1121,77 +973,18 @@ start_job_command (struct child *child)
else
{
/* Fork the child process. */
char **parent_environ;
run_local:
block_sigs ();
child->remote = 0;
parent_environ = environ;
jobserver_pre_child (flags & COMMANDS_RECURSE);
child->pid = child_execute_job ((struct childbase *)child,
child->good_stdin, argv);
environ = parent_environ; /* Restore value child may have clobbered. */
jobserver_post_child (flags & COMMANDS_RECURSE);
}
#else /* __MSDOS__ or Amiga or WINDOWS32 */
#ifdef WINDOWS32
{
HANDLE hPID;
char* arg0;
int outfd = FD_STDOUT;
int errfd = FD_STDERR;
/* make UNC paths safe for CreateProcess -- backslash format */
arg0 = argv[0];
if (arg0 && arg0[0] == '/' && arg0[1] == '/')
for ( ; arg0 && *arg0; arg0++)
if (*arg0 == '/')
*arg0 = '\\';
/* make sure CreateProcess() has Path it needs */
sync_Path_environment ();
#ifndef NO_OUTPUT_SYNC
/* Divert child output if output_sync in use. */
if (child->output.syncout)
{
if (child->output.out >= 0)
outfd = child->output.out;
if (child->output.err >= 0)
errfd = child->output.err;
}
#else
outfd = errfd = -1;
#endif
hPID = process_easy (argv, child->environment, outfd, errfd);
if (hPID != INVALID_HANDLE_VALUE)
child->pid = (pid_t) hPID;
else
{
int i;
unblock_sigs ();
fprintf (stderr,
_("process_easy() failed to launch process (e=%ld)\n"),
process_last_err (hPID));
for (i = 0; argv[i]; i++)
fprintf (stderr, "%s ", argv[i]);
fprintf (stderr, _("\nCounted %d args in failed launch\n"), i);
child->pid = -1;
}
}
#endif /* WINDOWS32 */
#endif /* __MSDOS__ or Amiga or WINDOWS32 */
/* Bump the number of jobs started in this second. */
if (child->pid >= 0)
++job_counter;
@ -1770,10 +1563,6 @@ start_waiting_jobs (void)
return;
}
#ifndef WINDOWS32
/* EMX: Start a child process. This function returns the new pid. */
#if !defined (_AMIGA) && !defined (__MSDOS__) && !defined (VMS)
/* POSIX:
Create a child process executing the command in ARGV.
@ -1786,12 +1575,6 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
int fderr = FD_STDERR;
pid_t pid;
int r;
#if defined(USE_POSIX_SPAWN)
char *cmd;
posix_spawnattr_t attr;
posix_spawn_file_actions_t fa;
short flags = 0;
#endif
/* Divert child output if we want to capture it. */
if (child->output.syncout)
@ -1802,8 +1585,6 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
fderr = child->output.err;
}
#if !defined(USE_POSIX_SPAWN)
pid = vfork();
if (pid != 0)
return pid;
@ -1811,11 +1592,9 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
/* We are the child. */
unblock_all_sigs ();
#ifdef SET_STACK_SIZE
/* Reset limits, if necessary. */
if (stack_limit.rlim_cur)
setrlimit (RLIMIT_STACK, &stack_limit);
#endif
/* For any redirected FD, dup2() it to the standard FD.
They are all marked close-on-exec already. */
@ -1829,198 +1608,18 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
/* Run the command. */
exec_command (argv, child->environment);
#else /* USE_POSIX_SPAWN */
if ((r = posix_spawnattr_init (&attr)) != 0)
goto done;
if ((r = posix_spawn_file_actions_init (&fa)) != 0)
{
posix_spawnattr_destroy (&attr);
goto done;
}
/* Unblock all signals. */
#ifdef HAVE_POSIX_SPAWNATTR_SETSIGMASK
{
sigset_t mask;
sigemptyset (&mask);
r = posix_spawnattr_setsigmask (&attr, &mask);
if (r != 0)
goto cleanup;
flags |= POSIX_SPAWN_SETSIGMASK;
}
#endif /* have posix_spawnattr_setsigmask() */
/* USEVFORK can give significant speedup on systems where it's available. */
#ifdef POSIX_SPAWN_USEVFORK
flags |= POSIX_SPAWN_USEVFORK;
#endif
/* For any redirected FD, dup2() it to the standard FD.
They are all marked close-on-exec already. */
if (fdin >= 0 && fdin != FD_STDIN)
if ((r = posix_spawn_file_actions_adddup2 (&fa, fdin, FD_STDIN)) != 0)
goto cleanup;
if (fdout != FD_STDOUT)
if ((r = posix_spawn_file_actions_adddup2 (&fa, fdout, FD_STDOUT)) != 0)
goto cleanup;
if (fderr != FD_STDERR)
if ((r = posix_spawn_file_actions_adddup2 (&fa, fderr, FD_STDERR)) != 0)
goto cleanup;
/* Be the user, permanently. */
flags |= POSIX_SPAWN_RESETIDS;
/* Apply the spawn flags. */
if ((r = posix_spawnattr_setflags (&attr, flags)) != 0)
goto cleanup;
/* Look up the program on the child's PATH, if needed. */
{
const char *p = NULL;
char **pp;
for (pp = child->environment; *pp != NULL; ++pp)
if ((*pp)[0] == 'P' && (*pp)[1] == 'A' && (*pp)[2] == 'T'
&& (*pp)[3] == 'H' &&(*pp)[4] == '=')
{
p = (*pp) + 5;
break;
}
cmd = (char *)find_in_given_path (argv[0], p, 0);
}
if (!cmd)
{
r = errno;
goto cleanup;
}
/* Start the program. */
while ((r = posix_spawn (&pid, cmd, &fa, &attr, argv,
child->environment)) == EINTR)
;
/* posix_spawn() doesn't provide sh fallback like exec() does; implement
it here. POSIX doesn't specify the path to sh so use the default. */
if (r == ENOEXEC)
{
char **nargv;
char **pp;
size_t l = 0;
for (pp = argv; *pp != NULL; ++pp)
++l;
nargv = xmalloc (sizeof (char *) * (l + 3));
nargv[0] = (char *)default_shell;
nargv[1] = cmd;
memcpy (&nargv[2], &argv[1], sizeof (char *) * l);
while ((r = posix_spawn (&pid, nargv[0], &fa, &attr, nargv,
child->environment)) == EINTR)
;
free (nargv);
}
if (r == 0)
{
/* Spawn succeeded but may fail later: remember the command. */
free (child->cmd_name);
if (cmd != argv[0])
child->cmd_name = cmd;
else
child->cmd_name = xstrdup(cmd);
}
cleanup:
posix_spawn_file_actions_destroy (&fa);
posix_spawnattr_destroy (&attr);
done:
if (r != 0)
pid = -1;
#endif /* USE_POSIX_SPAWN */
if (pid < 0)
OSS (error, NILF, "%s: %s", argv[0], strerror (r));
return pid;
}
#endif /* !AMIGA && !__MSDOS__ && !VMS */
#endif /* !WINDOWS32 */
/* 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. */
void
exec_command (char **argv, char **envp)
{
#ifdef WINDOWS32
HANDLE hPID;
HANDLE hWaitPID;
int exit_code = EXIT_FAILURE;
/* make sure CreateProcess() has Path it needs */
sync_Path_environment ();
/* launch command */
hPID = process_easy (argv, envp, -1, -1);
/* make sure launch ok */
if (hPID == INVALID_HANDLE_VALUE)
{
int i;
fprintf (stderr, _("process_easy() failed to launch process (e=%ld)\n"),
process_last_err (hPID));
for (i = 0; argv[i]; i++)
fprintf (stderr, "%s ", argv[i]);
fprintf (stderr, _("\nCounted %d args in failed launch\n"), i);
exit (EXIT_FAILURE);
}
/* wait and reap last child */
hWaitPID = process_wait_for_any (1, 0);
while (hWaitPID)
{
/* was an error found on this process? */
int err = process_last_err (hWaitPID);
/* get exit data */
exit_code = process_exit_code (hWaitPID);
if (err)
fprintf (stderr, "make (e=%d, rc=%d): %s",
err, exit_code, map_windows32_error_to_string (err));
/* cleanup process */
process_cleanup (hWaitPID);
/* expect to find only last pid, warn about other pids reaped */
if (hWaitPID == hPID)
break;
else
{
char *pidstr = xstrdup (pid2str ((pid_t)hWaitPID));
fprintf (stderr,
_("make reaped child pid %s, still waiting for pid %s\n"),
pidstr, pid2str ((pid_t)hPID));
free (pidstr);
}
}
/* return child's exit code as our exit code */
exit (exit_code);
#else /* !WINDOWS32 */
/* Be the user, permanently. */
child_access ();
@ -2028,44 +1627,41 @@ exec_command (char **argv, char **envp)
environ = envp;
execvp (argv[0], argv);
if(errno == ENOENT)
OSS (error, NILF, "%s: %s", argv[0], strerror (errno));
else if(errno == ENOEXEC)
{
/* The file was not a program. Try it as a shell script. */
const char *shell;
char **new_argv;
int argc;
int i=1;
shell = getenv ("SHELL");
if (shell == 0)
shell = default_shell;
argc = 1;
while (argv[argc] != 0)
++argc;
new_argv = alloca ((1 + argc + 1) * sizeof (char *));
new_argv[0] = (char *)shell;
new_argv[i] = argv[0];
while (argc > 0)
{
if(errno == ENOENT)
OSS (error, NILF, "%s: %s", argv[0], strerror (errno));
else if(errno == ENOEXEC)
{
/* The file was not a program. Try it as a shell script. */
const char *shell;
char **new_argv;
int argc;
int i=1;
shell = getenv ("SHELL");
if (shell == 0)
shell = default_shell;
argc = 1;
while (argv[argc] != 0)
++argc;
new_argv = alloca ((1 + argc + 1) * sizeof (char *));
new_argv[0] = (char *)shell;
new_argv[i] = argv[0];
while (argc > 0)
{
new_argv[i + argc] = argv[argc];
--argc;
}
execvp (shell, new_argv);
OSS (error, NILF, "%s: %s", new_argv[0], strerror (errno));
}
OSS (error, NILF, "%s: %s", argv[0], strerror (errno));
new_argv[i + argc] = argv[argc];
--argc;
}
execvp (shell, new_argv);
OSS (error, NILF, "%s: %s", new_argv[0], strerror (errno));
}
OSS (error, NILF, "%s: %s", argv[0], strerror (errno));
_exit (127);
#endif /* !WINDOWS32 */
}

View file

@ -19,15 +19,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Structure describing a running or dead child process. */
#ifdef VMS
#define VMSCHILD \
char *comname; /* Temporary command file name */ \
int efn; /* Completion event flag number */ \
int cstatus; /* Completion status */ \
int vms_launch_status; /* non-zero if lib$spawn, etc failed */
#else
#define VMSCHILD
#endif
#define CHILDBASE \
char *cmd_name; /* Alloced copy of command run. */ \

View file

@ -17,234 +17,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "third_party/make/makeint.h"
#if MAKE_LOAD
#include "libc/runtime/dlfcn.h"
#define SYMBOL_EXTENSION "_gmk_setup"
#include "third_party/make/debug.h"
#include "third_party/make/filedef.h"
#include "third_party/make/variable.h"
/* Tru64 V4.0 does not have this flag */
#ifndef RTLD_GLOBAL
# define RTLD_GLOBAL 0
#endif
struct load_list
{
struct load_list *next;
const char *name;
void *dlp;
};
static struct load_list *loaded_syms = NULL;
static load_func_t
load_object (const floc *flocp, int noerror, const char *ldname,
const char *symname)
{
static void *global_dl = NULL;
load_func_t symp;
if (! global_dl)
{
global_dl = dlopen (NULL, RTLD_NOW|RTLD_GLOBAL);
if (! global_dl)
{
const char *err = dlerror ();
OS (fatal, flocp, _("Failed to open global symbol table: %s"), err);
}
}
symp = (load_func_t) dlsym (global_dl, symname);
if (! symp)
{
struct load_list *new;
void *dlp = NULL;
/* If the path has no "/", try the current directory first. */
if (! strchr (ldname, '/')
#ifdef HAVE_DOS_PATHS
&& ! strchr (ldname, '\\')
#endif
)
dlp = dlopen (concat (2, "./", ldname), RTLD_LAZY|RTLD_GLOBAL);
/* If we haven't opened it yet, try the default search path. */
if (! dlp)
dlp = dlopen (ldname, RTLD_LAZY|RTLD_GLOBAL);
/* Still no? Then fail. */
if (! dlp)
{
const char *err = dlerror ();
if (noerror)
DB (DB_BASIC, ("%s", err));
else
OS (error, flocp, "%s", err);
return NULL;
}
/* Assert that the GPL license symbol is defined. */
symp = (load_func_t) dlsym (dlp, "plugin_is_GPL_compatible");
if (! symp)
OS (fatal, flocp,
_("Loaded object %s is not declared to be GPL compatible"),
ldname);
symp = (load_func_t) dlsym (dlp, symname);
if (! symp)
{
const char *err = dlerror ();
OSSS (fatal, flocp, _("Failed to load symbol %s from %s: %s"),
symname, ldname, err);
}
/* Add this symbol to a trivial lookup table. This is not efficient but
it's highly unlikely we'll be loading lots of objects, and we only
need it to look them up on unload, if we rebuild them. */
new = xmalloc (sizeof (struct load_list));
new->name = xstrdup (ldname);
new->dlp = dlp;
new->next = loaded_syms;
loaded_syms = new;
}
return symp;
}
int
load_file (const floc *flocp, const char **ldname, int noerror)
{
size_t nmlen = strlen (*ldname);
char *new = alloca (nmlen + CSTRLEN (SYMBOL_EXTENSION) + 1);
char *symname = NULL;
char *loaded;
const char *fp;
int r;
load_func_t symp;
/* Break the input into an object file name and a symbol name. If no symbol
name was provided, compute one from the object file name. */
fp = strchr (*ldname, '(');
if (fp)
{
const char *ep;
/* There's an open paren, so see if there's a close paren: if so use
that as the symbol name. We can't have whitespace: it would have
been chopped up before this function is called. */
ep = strchr (fp+1, ')');
if (ep && ep[1] == '\0')
{
size_t l = fp - *ldname;;
++fp;
if (fp == ep)
OS (fatal, flocp, _("Empty symbol name for load: %s"), *ldname);
/* Make a copy of the ldname part. */
memcpy (new, *ldname, l);
new[l] = '\0';
*ldname = new;
nmlen = l;
/* Make a copy of the symbol name part. */
symname = new + l + 1;
memcpy (symname, fp, ep - fp);
symname[ep - fp] = '\0';
}
}
/* Add this name to the string cache so it can be reused later. */
*ldname = strcache_add (*ldname);
/* If this object has been loaded, we're done. */
loaded = allocated_variable_expand ("$(.LOADED)");
fp = strstr (loaded, *ldname);
r = fp && (fp==loaded || fp[-1]==' ') && (fp[nmlen]=='\0' || fp[nmlen]==' ');
if (r)
goto exit;
/* If we didn't find a symbol name yet, construct it from the ldname. */
if (! symname)
{
char *p = new;
fp = strrchr (*ldname, '/');
#ifdef HAVE_DOS_PATHS
if (fp)
{
const char *fp2 = strchr (fp, '\\');
if (fp2 > fp)
fp = fp2;
}
else
fp = strrchr (*ldname, '\\');
/* The (improbable) case of d:foo. */
if (fp && *fp && fp[1] == ':')
fp++;
#endif
if (!fp)
fp = *ldname;
else
++fp;
while (isalnum (*fp) || *fp == '_')
*(p++) = *(fp++);
strcpy (p, SYMBOL_EXTENSION);
symname = new;
}
DB (DB_VERBOSE, (_("Loading symbol %s from %s\n"), symname, *ldname));
/* Load it! */
symp = load_object (flocp, noerror, *ldname, symname);
if (! symp)
return 0;
/* Invoke the symbol. */
r = (*symp) (flocp);
/* If it succeeded, add the load file to the loaded variable. */
if (r > 0)
{
size_t loadlen = strlen (loaded);
char *newval = alloca (loadlen + strlen (*ldname) + 2);
/* Don't add a space if it's empty. */
if (loadlen)
{
memcpy (newval, loaded, loadlen);
newval[loadlen++] = ' ';
}
strcpy (&newval[loadlen], *ldname);
do_variable_definition (flocp, ".LOADED", newval, o_default, f_simple, 0);
}
exit:
free (loaded);
return r;
}
void
unload_file (const char *name)
{
struct load_list *d;
for (d = loaded_syms; d != NULL; d = d->next)
if (streq (d->name, name) && d->dlp)
{
if (dlclose (d->dlp))
perror_with_name ("dlclose: ", d->name);
d->dlp = NULL;
break;
}
}
#else
int
load_file (const floc *flocp, const char **ldname UNUSED, int noerror)
{
@ -260,5 +32,3 @@ unload_file (const char *name UNUSED)
{
O (fatal, NILF, "INTERNAL: Cannot unload when load is not supported!");
}
#endif /* MAKE_LOAD */

View file

@ -27,6 +27,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "libc/runtime/stack.h"
#include "libc/limits.h"
#include "libc/sysv/consts/sig.h"
#include "libc/log/log.h"
#include "third_party/make/getopt.h"
STATIC_STACK_SIZE(0x200000); // 2mb stack
@ -176,9 +177,7 @@ static struct stringlist *makefiles = 0;
/* Size of the stack when we started. */
#ifdef SET_STACK_SIZE
struct rlimit stack_limit;
#endif
/* Number of job slots for parallelism. */
@ -506,16 +505,8 @@ struct output make_sync;
/* Mask of signals that are being caught with fatal_error_signal. */
#if defined(POSIX)
sigset_t fatal_signal_set;
#elif defined(HAVE_SIGSETMASK)
int fatal_signal_mask;
#endif
#if !HAVE_DECL_BSD_SIGNAL && !defined bsd_signal
# if !defined HAVE_SIGACTION
# define bsd_signal signal
# else
typedef RETSIGTYPE (*bsd_signal_ret_t) (int);
static bsd_signal_ret_t
@ -530,8 +521,6 @@ bsd_signal (int sig, bsd_signal_ret_t func)
return SIG_ERR;
return oact.sa_handler;
}
# endif
#endif
static void
initialize_global_hash_tables (void)
@ -990,7 +979,6 @@ main (int argc, char **argv, char **envp)
initialize_stopchar_map();
#ifdef SET_STACK_SIZE
/* Get rid of any avoidable limit on stack size. */
{
struct rlimit rlim;
@ -1006,7 +994,6 @@ main (int argc, char **argv, char **envp)
else
stack_limit.rlim_cur = 0;
}
#endif
/* Needed for OS/2 */
initialize_main (&argc, &argv);
@ -1023,18 +1010,9 @@ main (int argc, char **argv, char **envp)
(void)bindtextdomain (PACKAGE, LOCALEDIR);
(void)textdomain (PACKAGE);
#ifdef POSIX
sigemptyset (&fatal_signal_set);
#define ADD_SIG(sig) sigaddset (&fatal_signal_set, sig)
#else
#ifdef HAVE_SIGSETMASK
fatal_signal_mask = 0;
#define ADD_SIG(sig) fatal_signal_mask |= sigmask (sig)
#else
#define ADD_SIG(sig) (void)sig
#endif
#endif
#define ADD_SIG(sig) sigaddset (&fatal_signal_set, sig)
#define FATAL_SIG(sig) \
if (bsd_signal (sig, fatal_error_signal) == SIG_IGN) \
bsd_signal (sig, SIG_IGN); \
@ -1155,12 +1133,6 @@ main (int argc, char **argv, char **envp)
#ifdef MAKE_SYMLINKS
" check-symlink"
#endif
#ifdef HAVE_GUILE
" guile"
#endif
#ifdef MAKE_LOAD
" load"
#endif
#ifdef MAKE_MAINTAINER_MODE
" maintainer"
#endif
@ -2152,11 +2124,9 @@ main (int argc, char **argv, char **envp)
/* The exec'd "child" will be another make, of course. */
jobserver_pre_child(1);
#ifdef SET_STACK_SIZE
/* Reset limits, if necessary. */
if (stack_limit.rlim_cur)
setrlimit (RLIMIT_STACK, &stack_limit);
#endif
exec_command ((char **)nargv, environ);
/* We shouldn't get here but just in case. */

View file

@ -31,6 +31,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "libc/fmt/fmt.h"
#include "libc/limits.h"
#include "libc/log/log.h"
#include "libc/macros.internal.h"
#include "libc/mem/alloca.h"
#include "libc/mem/mem.h"
#include "libc/runtime/stack.h"
@ -67,6 +68,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Specify we want GNU source code. This must be defined before any
system headers are included. */
#define POSIX 1
#define _GNU_SOURCE 1
/* Disable assert() unless we're a maintainer.
@ -300,11 +302,7 @@ extern int unixy_shell;
/* The set of characters which are directory separators is OS-specific. */
#define MAP_DIRSEP 0x8000
#ifdef VMS
# define MAP_VMSCOMMA MAP_COMMA
#else
# define MAP_VMSCOMMA 0x0000
#endif
#define MAP_VMSCOMMA 0x0000
#define MAP_SPACE (MAP_BLANK|MAP_NEWLINE)
@ -342,12 +340,7 @@ extern int unixy_shell;
#define END_OF_TOKEN(s) while (! STOP_SET (*(s), MAP_SPACE|MAP_NUL)) ++(s)
/* We can't run setrlimit when using posix_spawn. */
#if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) && !defined(USE_POSIX_SPAWN)
# define SET_STACK_SIZE
#endif
#ifdef SET_STACK_SIZE
extern struct rlimit stack_limit;
#endif
#define NILF ((floc *)0)
@ -623,46 +616,12 @@ extern unsigned int commands_started;
extern int handling_fatal_signal;
#ifndef MIN
#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b))
#endif
#ifndef MAX
#define MAX(_a,_b) ((_a)>(_b)?(_a):(_b))
#endif
#define MAKE_SUCCESS 0
#define MAKE_TROUBLE 1
#define MAKE_FAILURE 2
/* Set up heap debugging library dmalloc. */
#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 !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

View file

@ -1327,13 +1327,7 @@ f_mtime (struct file *file, int search)
/* If we found it in VPATH, see if it's in GPATH too; if so,
change the name right now; if not, defer until after the
dependencies are updated. */
#ifndef VMS
name_len = strlen (name) - strlen (file->name) - 1;
#else
name_len = strlen (name) - strlen (file->name);
if (name[name_len - 1] == '/')
name_len--;
#endif
if (gpath_search (name, name_len))
{
rename_file (file, name);
@ -1374,14 +1368,6 @@ 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

View file

@ -17,16 +17,12 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "third_party/make/makeint.h"
#include "third_party/make/filedef.h"
#include "third_party/make/dep.h"
#include "third_party/make/job.h"
#include "third_party/make/commands.h"
#include "third_party/make/variable.h"
#include "third_party/make/rule.h"
#ifdef WINDOWS32
// #include "pathstuff.h"
#endif
#include "third_party/make/hash.h"
/* Incremented every time we add or remove a global variable. */
@ -210,34 +206,6 @@ define_variable_in_set (const char *name, size_t length,
var_slot = (struct variable **) hash_find_slot (&set->table, &var_key);
v = *var_slot;
#ifdef VMS
/* VMS does not populate envp[] with DCL symbols and logical names which
historically are mapped to environent variables.
If the variable is not yet defined, then we need to check if getenv()
can find it. Do not do this for origin == o_env to avoid infinte
recursion */
if (HASH_VACANT (v) && (origin != o_env))
{
struct variable * vms_variable;
char * vname = alloca (length + 1);
char * vvalue;
strncpy (vname, name, length);
vvalue = getenv(vname);
/* Values starting with '$' are probably foreign commands.
We want to treat them as Shell aliases and not look them up here */
if ((vvalue != NULL) && (vvalue[0] != '$'))
{
vms_variable = lookup_variable(name, length);
/* Refresh the slot */
var_slot = (struct variable **) hash_find_slot (&set->table,
&var_key);
v = *var_slot;
}
}
#endif
if (env_overrides && origin == o_env)
origin = o_env_override;
@ -474,62 +442,6 @@ lookup_variable (const char *name, size_t length)
is_parent |= setlist->next_is_parent;
}
#ifdef VMS
/* VMS does not populate envp[] with DCL symbols and logical names which
historically are mapped to enviroment varables and returned by getenv() */
{
char *vname = alloca (length + 1);
char *value;
strncpy (vname, name, length);
vname[length] = 0;
value = getenv (vname);
if (value != 0)
{
char *sptr;
int scnt;
sptr = value;
scnt = 0;
while ((sptr = strchr (sptr, '$')))
{
scnt++;
sptr++;
}
if (scnt > 0)
{
char *nvalue;
char *nptr;
nvalue = alloca (strlen (value) + scnt + 1);
sptr = value;
nptr = nvalue;
while (*sptr)
{
if (*sptr == '$')
{
*nptr++ = '$';
*nptr++ = '$';
}
else
{
*nptr++ = *sptr;
}
sptr++;
}
*nptr = '\0';
return define_variable (vname, length, nvalue, o_env, 1);
}
return define_variable (vname, length, value, o_env, 1);
}
}
#endif /* VMS */
return 0;
}
@ -841,84 +753,9 @@ define_automatic_variables (void)
define_variable_cname ("MAKE_VERSION", buf, o_default, 0);
define_variable_cname ("MAKE_HOST", make_host, o_default, 0);
#ifdef __MSDOS__
/* Allow to specify a special shell just for Make,
and use $COMSPEC as the default $SHELL when appropriate. */
{
static char shell_str[] = "SHELL";
const int shlen = sizeof (shell_str) - 1;
struct variable *mshp = lookup_variable ("MAKESHELL", 9);
struct variable *comp = lookup_variable ("COMSPEC", 7);
/* $(MAKESHELL) overrides $(SHELL) even if -e is in effect. */
if (mshp)
(void) define_variable (shell_str, shlen,
mshp->value, o_env_override, 0);
else if (comp)
{
/* $(COMSPEC) shouldn't override $(SHELL). */
struct variable *shp = lookup_variable (shell_str, shlen);
if (!shp)
(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 will provide one if there
isn't one there. */
v = define_variable_cname ("SHELL", default_shell, o_default, 0);
#ifdef __MSDOS__
v->export = v_export; /* Export always SHELL. */
#endif
/* 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.
@ -1284,137 +1121,6 @@ do_variable_definition (const floc *flocp, const char *varname,
}
}
#ifdef __MSDOS__
/* Many Unix Makefiles include a line saying "SHELL=/bin/sh", but
non-Unix systems don't conform to this default configuration (in
fact, most of them don't even have '/bin'). On the other hand,
$SHELL in the environment, if set, points to the real pathname of
the shell.
Therefore, we generally won't let lines like "SHELL=/bin/sh" from
the Makefile override $SHELL from the environment. But first, we
look for the basename of the shell in the directory where SHELL=
points, and along the $PATH; if it is found in any of these places,
we define $SHELL to be the actual pathname of the shell. Thus, if
you have bash.exe installed as d:/unix/bash.exe, and d:/unix is on
your $PATH, then SHELL=/usr/local/bin/bash will have the effect of
defining SHELL to be "d:/unix/bash.exe". */
if ((origin == o_file || origin == o_override)
&& strcmp (varname, "SHELL") == 0)
{
PATH_VAR (shellpath);
extern char * __dosexec_find_on_path (const char *, char *[], char *);
/* See if we can find "/bin/sh.exe", "/bin/sh.com", etc. */
if (__dosexec_find_on_path (p, NULL, shellpath))
{
char *tp;
for (tp = shellpath; *tp; tp++)
if (*tp == '\\')
*tp = '/';
v = define_variable_loc (varname, strlen (varname),
shellpath, origin, flavor == f_recursive,
flocp);
}
else
{
const char *shellbase, *bslash;
struct variable *pathv = lookup_variable ("PATH", 4);
char *path_string;
char *fake_env[2];
size_t pathlen = 0;
shellbase = strrchr (p, '/');
bslash = strrchr (p, '\\');
if (!shellbase || bslash > shellbase)
shellbase = bslash;
if (!shellbase && p[1] == ':')
shellbase = p + 1;
if (shellbase)
shellbase++;
else
shellbase = p;
/* Search for the basename of the shell (with standard
executable extensions) along the $PATH. */
if (pathv)
pathlen = strlen (pathv->value);
path_string = xmalloc (5 + pathlen + 2 + 1);
/* On MSDOS, current directory is considered as part of $PATH. */
sprintf (path_string, "PATH=.;%s", pathv ? pathv->value : "");
fake_env[0] = path_string;
fake_env[1] = 0;
if (__dosexec_find_on_path (shellbase, fake_env, shellpath))
{
char *tp;
for (tp = shellpath; *tp; tp++)
if (*tp == '\\')
*tp = '/';
v = define_variable_loc (varname, strlen (varname),
shellpath, origin,
flavor == f_recursive, flocp);
}
else
v = lookup_variable (varname, strlen (varname));
free (path_string);
}
}
else
#endif /* __MSDOS__ */
#ifdef WINDOWS32
if ((origin == o_file || origin == o_override || origin == o_command)
&& streq (varname, "SHELL"))
{
extern const char *default_shell;
/* Call shell locator function. If it returns TRUE, then
set no_default_sh_exe to indicate sh was found and
set new value for SHELL variable. */
if (find_and_set_default_shell (p))
{
v = define_variable_in_set (varname, strlen (varname), default_shell,
origin, flavor == f_recursive,
(target_var
? current_variable_set_list->set
: NULL),
flocp);
no_default_sh_exe = 0;
}
else
{
char *tp = alloc_value;
alloc_value = allocated_variable_expand (p);
if (find_and_set_default_shell (alloc_value))
{
v = define_variable_in_set (varname, strlen (varname), p,
origin, flavor == f_recursive,
(target_var
? current_variable_set_list->set
: NULL),
flocp);
no_default_sh_exe = 0;
}
else
v = lookup_variable (varname, strlen (varname));
free (tp);
}
}
else
v = NULL;
/* If not $SHELL, or if $SHELL points to a program we didn't find,
just process this variable "as usual". */
if (!v)
#endif
/* If we are defining variables inside an $(eval ...), we might have a
different variable context pushed, not the global context (maybe we're
inside a $(call ...) or something. Since this function is only ever
@ -1803,24 +1509,3 @@ print_target_variables (const struct file *file)
hash_map_arg (&file->variables->set->table, print_noauto_variable, t);
}
}
#ifdef WINDOWS32
void
sync_Path_environment (void)
{
char *path = allocated_variable_expand ("$(PATH)");
static char *environ_path = NULL;
if (!path)
return;
/* If done this before, free the previous entry before allocating new one. */
free (environ_path);
/* Create something WINDOWS32 world can grok. */
convert_Path_to_windows32 (path, ';');
environ_path = xstrdup (concat (3, "PATH", "=", path));
putenv (environ_path);
free (path);
}
#endif