mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Delete some more unneeded Make code
This commit is contained in:
parent
58d74ede4c
commit
ce9bdbb0bf
13 changed files with 46 additions and 1300 deletions
|
@ -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
48
third_party/make/ar.c
vendored
|
@ -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;
|
||||
|
||||
|
|
6
third_party/make/commands.c
vendored
6
third_party/make/commands.c
vendored
|
@ -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)
|
||||
|
|
21
third_party/make/config.h
vendored
21
third_party/make/config.h
vendored
|
@ -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 */
|
||||
|
|
70
third_party/make/file.c
vendored
70
third_party/make/file.c
vendored
|
@ -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, ×pec) == 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);
|
||||
}
|
||||
|
|
80
third_party/make/function.c
vendored
80
third_party/make/function.c
vendored
|
@ -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
468
third_party/make/job.c
vendored
|
@ -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 */
|
||||
}
|
||||
|
||||
|
||||
|
|
8
third_party/make/job.h
vendored
8
third_party/make/job.h
vendored
|
@ -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. */ \
|
||||
|
|
230
third_party/make/load.c
vendored
230
third_party/make/load.c
vendored
|
@ -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 */
|
||||
|
|
34
third_party/make/main.c
vendored
34
third_party/make/main.c
vendored
|
@ -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. */
|
||||
|
|
47
third_party/make/makeint.h
vendored
47
third_party/make/makeint.h
vendored
|
@ -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
|
||||
|
|
14
third_party/make/remake.c
vendored
14
third_party/make/remake.c
vendored
|
@ -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
|
||||
|
|
315
third_party/make/variable.c
vendored
315
third_party/make/variable.c
vendored
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue