* exceptions.cc (interruptible): Allocate slightly more space for directory
name check. Windows 95 seems to null-terminate the directory otherwise. (interrupt_on_return): Issue a fatal error if we can't find the caller's stack. * spawn.cc (find_exec): Accept a path_conv argument rather than a buffer so that the caller can find things out about a translated path. (perhaps_suffix): Ditto. (spawn_guts): Allocate path_conv stuff here so that we can find out stuff about the translated path (this is work in progress). * environ.cc (environ_init): Accept an as-yet unused argument indicating whether we were invoked from a cygwin parent or not. (winenv): Ditto. (posify): Accept an argument indicating whether the path has already been translated. * dlfcn.cc (check_access): Provide a path_conv buffer to find_exec. * exec.cc (sexecvpe): Ditto. * path.cc (path_conv::check): Rename from path_conv::path_conv. (mount_item::getmntent): Recognize "Cygwin executable" bit. (symlink_info::check): Remove debugging statements. * path.h (class path_conv): Add iscygexec method. Rewrite constructor to call "check" method to allow multiple operations on a path_conv variable. * pinfo.cc (pinfo_init): Pass argument to environ_init. * shared.h: Bump PROC_MAGIC. * winsup.h: Reflect above changes to function arguments. * include/sys/mount.h: Add MOUNT_CYGWIN_EXEC type.
This commit is contained in:
parent
47eaa6c421
commit
55fc91b9d6
|
@ -1,3 +1,36 @@
|
|||
Wed Apr 26 01:07:16 2000 Christopher Faylor <cgf@cygnus.com>
|
||||
|
||||
* exceptions.cc (interruptible): Allocate slightly more space for
|
||||
directory name check. Windows 95 seems to null-terminate the directory
|
||||
otherwise.
|
||||
(interrupt_on_return): Issue a fatal error if we can't find the
|
||||
caller's stack.
|
||||
|
||||
Tue Apr 25 16:50:54 2000 Christopher Faylor <cgf@cygnus.com>
|
||||
|
||||
* spawn.cc (find_exec): Accept a path_conv argument rather than a
|
||||
buffer so that the caller can find things out about a translated path.
|
||||
(perhaps_suffix): Ditto.
|
||||
(spawn_guts): Allocate path_conv stuff here so that we can find out
|
||||
stuff about the translated path (this is work in progress).
|
||||
* environ.cc (environ_init): Accept an as-yet unused argument
|
||||
indicating whether we were invoked from a cygwin parent or not.
|
||||
(winenv): Ditto.
|
||||
(posify): Accept an argument indicating whether the path has already
|
||||
been translated.
|
||||
* dlfcn.cc (check_access): Provide a path_conv buffer to find_exec.
|
||||
* exec.cc (sexecvpe): Ditto.
|
||||
* path.cc (path_conv::check): Rename from path_conv::path_conv.
|
||||
(mount_item::getmntent): Recognize "Cygwin executable" bit.
|
||||
(symlink_info::check): Remove debugging statements.
|
||||
* path.h (class path_conv): Add iscygexec method. Rewrite constructor
|
||||
to call "check" method to allow multiple operations on a path_conv
|
||||
variable.
|
||||
* pinfo.cc (pinfo_init): Pass argument to environ_init.
|
||||
* shared.h: Bump PROC_MAGIC.
|
||||
* winsup.h: Reflect above changes to function arguments.
|
||||
* include/sys/mount.h: Add MOUNT_CYGWIN_EXEC type.
|
||||
|
||||
Thu Apr 25 21:35:00 2000 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* syscalls.cc (stat_worker): Previous patch failed to stat
|
||||
|
|
|
@ -60,7 +60,7 @@ check_access (const char *dir, const char *name)
|
|||
static const char * __stdcall
|
||||
check_path_access (const char *mywinenv, const char *name)
|
||||
{
|
||||
static char buf[MAX_PATH];
|
||||
path_conv buf;
|
||||
return find_exec (name, buf, mywinenv, TRUE);
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ getwinenv (const char *env, const char *in_posix)
|
|||
/* Convert windows path specs to POSIX, if appropriate.
|
||||
*/
|
||||
static void __stdcall
|
||||
posify (char **here, const char *value)
|
||||
posify (int already_posix, char **here, const char *value)
|
||||
{
|
||||
char *src = *here;
|
||||
win_env *conv;
|
||||
|
@ -103,17 +103,22 @@ posify (char **here, const char *value)
|
|||
if (!(conv = getwinenv (src)))
|
||||
return;
|
||||
|
||||
/* Turn all the items from c:<foo>;<bar> into their
|
||||
mounted equivalents - if there is one. */
|
||||
if (already_posix)
|
||||
conv->add_cache (value, NULL);
|
||||
else
|
||||
{
|
||||
/* Turn all the items from c:<foo>;<bar> into their
|
||||
mounted equivalents - if there is one. */
|
||||
|
||||
char *outenv = (char *) malloc (1 + len + conv->posix_len (value));
|
||||
memcpy (outenv, src, len);
|
||||
conv->toposix (value, outenv + len);
|
||||
conv->add_cache (outenv + len, value);
|
||||
char *outenv = (char *) malloc (1 + len + conv->posix_len (value));
|
||||
memcpy (outenv, src, len);
|
||||
conv->toposix (value, outenv + len);
|
||||
conv->add_cache (outenv + len, value);
|
||||
|
||||
debug_printf ("env var converted to %s", outenv);
|
||||
*here = outenv;
|
||||
free (src);
|
||||
debug_printf ("env var converted to %s", outenv);
|
||||
*here = outenv;
|
||||
free (src);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -435,7 +440,7 @@ regopt (const char *name)
|
|||
* environment variable and set appropriate options from it.
|
||||
*/
|
||||
void
|
||||
environ_init (void)
|
||||
environ_init (int already_posix)
|
||||
{
|
||||
const char * const rawenv = GetEnvironmentStrings ();
|
||||
int envsize, i;
|
||||
|
@ -479,7 +484,7 @@ environ_init (void)
|
|||
if (strncmp (newp, "CYGWIN=", sizeof("CYGWIN=") - 1) == 0)
|
||||
parse_options (newp + sizeof("CYGWIN=") - 1);
|
||||
if (*eq)
|
||||
posify (envp + i, *++eq ? eq : --eq);
|
||||
posify (already_posix, envp + i, *++eq ? eq : --eq);
|
||||
debug_printf ("%s", envp[i]);
|
||||
}
|
||||
|
||||
|
@ -509,7 +514,7 @@ env_sort (const void *a, const void *b)
|
|||
* prior to placing them in the string.
|
||||
*/
|
||||
char * __stdcall
|
||||
winenv (const char * const *envp)
|
||||
winenv (const char * const *envp, int keep_posix)
|
||||
{
|
||||
int len, n, tl;
|
||||
const char * const *srcp;
|
||||
|
@ -520,12 +525,14 @@ winenv (const char * const *envp)
|
|||
|
||||
const char *newenvp[n + 1];
|
||||
|
||||
debug_printf ("envp %p, keep_posix %d", envp, keep_posix);
|
||||
|
||||
for (tl = 0, srcp = envp, dstp = newenvp; *srcp; srcp++, dstp++)
|
||||
{
|
||||
len = strcspn (*srcp, "=") + 1;
|
||||
win_env *conv;
|
||||
|
||||
if ((conv = getwinenv (*srcp, *srcp + len)))
|
||||
if (!keep_posix && (conv = getwinenv (*srcp, *srcp + len)))
|
||||
*dstp = conv->native;
|
||||
else
|
||||
*dstp = *srcp;
|
||||
|
|
|
@ -568,13 +568,13 @@ interruptible (DWORD pc)
|
|||
if (!VirtualQuery ((LPCVOID) pc, &m, sizeof m))
|
||||
sigproc_printf ("couldn't get memory info, %E");
|
||||
|
||||
char *checkdir = (char *) alloca (windows_system_directory_length);
|
||||
char *checkdir = (char *) alloca (windows_system_directory_length + 2);
|
||||
# define h ((HMODULE) m.AllocationBase)
|
||||
if (h == user_data->hmodule)
|
||||
res = 1;
|
||||
else if (h == cygwin_hmodule)
|
||||
res = 0;
|
||||
else if (!GetModuleFileName (h, checkdir, windows_system_directory_length))
|
||||
else if (!GetModuleFileName (h, checkdir, windows_system_directory_length + 2))
|
||||
res = 0;
|
||||
else
|
||||
res = !strncasematch (windows_system_directory, checkdir,
|
||||
|
@ -642,10 +642,11 @@ interrupt_on_return (DWORD ebp, int sig, struct sigaction& siga, void *handler)
|
|||
interrupt_setup (sig, siga, handler, *addr_retaddr, addr_retaddr);
|
||||
*addr_retaddr = (DWORD) sigdelayed;
|
||||
}
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
api_fatal ("couldn't send signal %d", sig);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void __stdcall
|
||||
|
|
|
@ -198,7 +198,7 @@ int
|
|||
sexecvpe (HANDLE hToken, const char *file, const char * const *argv,
|
||||
const char *const *envp)
|
||||
{
|
||||
char buf[MAXNAMLEN];
|
||||
path_conv buf;
|
||||
MALLOC_CHECK;
|
||||
return sexecve (hToken, find_exec (file, buf), argv, envp);
|
||||
}
|
||||
|
|
|
@ -6,13 +6,15 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
MOUNT_SYMLINK = 1, /* "mount point" is a symlink */
|
||||
MOUNT_BINARY = 2, /* "binary" format read/writes */
|
||||
MOUNT_SYSTEM = 8, /* mount point came from system table */
|
||||
MOUNT_EXEC = 16, /* Any file in the mounted directory gets 'x' bit */
|
||||
MOUNT_AUTO = 32 /* mount point refers to auto device mount */
|
||||
};
|
||||
{
|
||||
MOUNT_SYMLINK = 1, /* "mount point" is a symlink */
|
||||
MOUNT_BINARY = 2, /* "binary" format read/writes */
|
||||
MOUNT_SYSTEM = 8, /* mount point came from system table */
|
||||
MOUNT_EXEC = 16, /* Any file in the mounted directory gets 'x' bit */
|
||||
MOUNT_AUTO = 32, /* mount point refers to auto device mount */
|
||||
MOUNT_CYGWIN_EXEC = 64/* file or directory is or contains a cygwin
|
||||
executable */
|
||||
};
|
||||
|
||||
int mount (const char *, const char *, unsigned __flags);
|
||||
int umount (const char *);
|
||||
|
|
|
@ -186,8 +186,9 @@ path_prefix_p_ (const char *path1, const char *path2, int len1)
|
|||
SYMLINK_CONTENTS - just return symlink contents
|
||||
*/
|
||||
|
||||
path_conv::path_conv (const char *src, symlink_follow follow_mode,
|
||||
int use_full_path, const suffix_info *suffixes)
|
||||
void
|
||||
path_conv::check (const char *src, symlink_follow follow_mode,
|
||||
int use_full_path, const suffix_info *suffixes)
|
||||
{
|
||||
/* This array is used when expanding symlinks. It is MAX_PATH * 2
|
||||
in length so that we can hold the expanded symlink plus a
|
||||
|
@ -1891,9 +1892,12 @@ mount_item::getmntent ()
|
|||
else
|
||||
strcpy (cygwin_shared->mount.mnt_opts, (char *) "binmode");
|
||||
|
||||
if (flags & MOUNT_EXEC)
|
||||
if (flags & MOUNT_CYGWIN_EXEC)
|
||||
strcat (cygwin_shared->mount.mnt_opts, (char *) ",cygexec");
|
||||
else if (flags & MOUNT_EXEC)
|
||||
strcat (cygwin_shared->mount.mnt_opts, (char *) ",exec");
|
||||
|
||||
|
||||
ret.mnt_opts = cygwin_shared->mount.mnt_opts;
|
||||
|
||||
ret.mnt_freq = 1;
|
||||
|
@ -2190,9 +2194,6 @@ symlink_info::check (const char *in_path, const suffix_info *suffixes)
|
|||
|
||||
h = CreateFileA (path, GENERIC_READ, FILE_SHARE_READ, &sec_none_nih, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, 0);
|
||||
|
||||
syscall_printf ("opened '%s'(%p)", path, h);
|
||||
|
||||
res = -1;
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
__seterrno ();
|
||||
|
@ -2201,7 +2202,6 @@ syscall_printf ("opened '%s'(%p)", path, h);
|
|||
char cookie_buf[sizeof (SYMLINK_COOKIE) - 1];
|
||||
DWORD got;
|
||||
|
||||
syscall_printf ("ReadFile");
|
||||
if (! ReadFile (h, cookie_buf, sizeof (cookie_buf), &got, 0))
|
||||
set_errno (EIO);
|
||||
else if (got == sizeof (cookie_buf)
|
||||
|
@ -2238,18 +2238,16 @@ syscall_printf ("ReadFile");
|
|||
else
|
||||
{
|
||||
/* Not a symlink, see if executable. */
|
||||
if (!(pflags & PATH_EXEC) && got >= 2 &&
|
||||
if (!(pflags & (PATH_EXEC | PATH_CYGWIN_EXEC)) && got >= 2 &&
|
||||
((cookie_buf[0] == '#' && cookie_buf[1] == '!') ||
|
||||
(cookie_buf[0] == ':' && cookie_buf[1] == '\n')))
|
||||
pflags |= PATH_EXEC;
|
||||
close_and_return:
|
||||
syscall_printf ("close_and_return");
|
||||
CloseHandle (h);
|
||||
goto file_not_symlink;
|
||||
}
|
||||
}
|
||||
|
||||
syscall_printf ("breaking from loop");
|
||||
CloseHandle (h);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ enum
|
|||
PATH_SYMLINK = MOUNT_SYMLINK,
|
||||
PATH_BINARY = MOUNT_BINARY,
|
||||
PATH_EXEC = MOUNT_EXEC,
|
||||
PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC,
|
||||
PATH_SOCKET = 0x40000000,
|
||||
PATH_HASACLS = 0x80000000
|
||||
};
|
||||
|
@ -49,6 +50,7 @@ class path_conv
|
|||
int issymlink () {return path_flags & PATH_SYMLINK;}
|
||||
int issocket () {return path_flags & PATH_SOCKET;}
|
||||
int isexec () {return path_flags & PATH_EXEC;}
|
||||
int iscygexec () {return path_flags & PATH_CYGWIN_EXEC;}
|
||||
|
||||
void set_binary () {path_flags |= PATH_BINARY;}
|
||||
void set_symlink () {path_flags |= PATH_SYMLINK;}
|
||||
|
@ -63,8 +65,16 @@ class path_conv
|
|||
|
||||
DWORD fileattr;
|
||||
|
||||
path_conv (const char * const, symlink_follow follow_mode = SYMLINK_FOLLOW,
|
||||
int use_full_path = 0, const suffix_info *suffixes = NULL);
|
||||
void check (const char *src, symlink_follow follow_mode = SYMLINK_FOLLOW,
|
||||
int use_full_path = 0, const suffix_info *suffixes = NULL);
|
||||
path_conv (const char *src, symlink_follow follow_mode = SYMLINK_FOLLOW,
|
||||
int use_full_path = 0, const suffix_info *suffixes = NULL)
|
||||
{
|
||||
check (src, follow_mode, use_full_path, suffixes);
|
||||
}
|
||||
|
||||
path_conv (): path_flags (0), known_suffix (NULL), error (0), devn (0), unit (0), fileattr (0xffffffff) {path[0] = '\0';}
|
||||
|
||||
inline char *get_win32 () { return path; }
|
||||
operator char *() {return path; }
|
||||
BOOL is_device () {return devn != FH_BAD;}
|
||||
|
|
|
@ -77,7 +77,7 @@ pinfo_init (LPBYTE info)
|
|||
{
|
||||
/* The process was execed. Reuse entry from the original
|
||||
owner of this pid. */
|
||||
environ_init (); /* Needs myself but affects calls below */
|
||||
environ_init (0); /* Needs myself but affects calls below */
|
||||
|
||||
/* spawn has already set up a pid structure for us so we'll use that */
|
||||
|
||||
|
@ -100,7 +100,7 @@ pinfo_init (LPBYTE info)
|
|||
myself->ctty = -1;
|
||||
myself->uid = USHRT_MAX;
|
||||
|
||||
environ_init (); /* call after myself has been set up */
|
||||
environ_init (0); /* call after myself has been set up */
|
||||
}
|
||||
|
||||
debug_printf ("pid %d, pgid %d", myself->pid, myself->pgid);
|
||||
|
|
|
@ -187,7 +187,7 @@ pinfo *__stdcall procinfo (int n);
|
|||
|
||||
enum
|
||||
{
|
||||
PROC_MAGIC = 0xaf05f000,
|
||||
PROC_MAGIC = 0xaf06f000,
|
||||
PROC_FORK = PROC_MAGIC + 1,
|
||||
PROC_EXEC = PROC_MAGIC + 2,
|
||||
PROC_SPAWN = PROC_MAGIC + 3,
|
||||
|
|
|
@ -38,22 +38,21 @@ suffix_info std_suffixes[] =
|
|||
Returns (possibly NULL) suffix */
|
||||
|
||||
static const char *
|
||||
perhaps_suffix (const char *prog, char *buf)
|
||||
perhaps_suffix (const char *prog, path_conv &buf)
|
||||
{
|
||||
char *ext;
|
||||
|
||||
debug_printf ("prog '%s'", prog);
|
||||
path_conv temp (prog, SYMLINK_FOLLOW, 1, std_suffixes);
|
||||
strcpy (buf, temp.get_win32 ());
|
||||
buf.check (prog, SYMLINK_FOLLOW, 1, std_suffixes);
|
||||
|
||||
if (temp.file_attributes () & FILE_ATTRIBUTE_DIRECTORY)
|
||||
if (buf.file_attributes () & FILE_ATTRIBUTE_DIRECTORY)
|
||||
ext = NULL;
|
||||
else if (temp.known_suffix)
|
||||
ext = buf + (temp.known_suffix - temp.get_win32 ());
|
||||
else if (buf.known_suffix)
|
||||
ext = buf + (buf.known_suffix - buf.get_win32 ());
|
||||
else
|
||||
ext = strchr (buf, '\0');
|
||||
|
||||
debug_printf ("buf %s, suffix found '%s'", buf, ext);
|
||||
debug_printf ("buf %s, suffix found '%s'", (char *) buf, ext);
|
||||
return ext;
|
||||
}
|
||||
|
||||
|
@ -66,7 +65,7 @@ perhaps_suffix (const char *prog, char *buf)
|
|||
is undefined and NULL is returned. */
|
||||
|
||||
const char * __stdcall
|
||||
find_exec (const char *name, char *buf, const char *mywinenv,
|
||||
find_exec (const char *name, path_conv& buf, const char *mywinenv,
|
||||
int null_if_notfound, const char **known_suffix)
|
||||
{
|
||||
const char *suffix = "";
|
||||
|
@ -120,10 +119,10 @@ errout:
|
|||
if (null_if_notfound)
|
||||
retval = NULL;
|
||||
else
|
||||
strcpy (buf, path_conv (name).get_win32 ());
|
||||
buf.check (name);
|
||||
|
||||
out:
|
||||
debug_printf ("%s = find_exec (%s)", buf, name);
|
||||
debug_printf ("%s = find_exec (%s)", (char *) buf, name);
|
||||
if (known_suffix)
|
||||
*known_suffix = suffix ?: strchr (buf, '\0');
|
||||
return retval;
|
||||
|
@ -257,7 +256,7 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
|
|||
/* nothing */;
|
||||
|
||||
char *real_path;
|
||||
char real_path_buf[MAX_PATH];
|
||||
path_conv real_path_buf;
|
||||
|
||||
linebuf one_line;
|
||||
|
||||
|
@ -274,15 +273,13 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
|
|||
goto skip_arg_parsing;
|
||||
}
|
||||
|
||||
MALLOC_CHECK;
|
||||
|
||||
real_path = real_path_buf;
|
||||
|
||||
const char *saved_prog_arg;
|
||||
const char *newargv0, **firstarg;
|
||||
const char *ext;
|
||||
|
||||
if ((ext = perhaps_suffix (prog_arg, real_path)) == NULL)
|
||||
if ((ext = perhaps_suffix (prog_arg, real_path_buf)) == NULL)
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
return -1;
|
||||
|
@ -381,7 +378,7 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
|
|||
one_line.prepend (" \"", 2);
|
||||
}
|
||||
|
||||
find_exec (pgm, real_path, "PATH=", 0, &ext);
|
||||
find_exec (pgm, real_path_buf, "PATH=", 0, &ext);
|
||||
cygwin_conv_to_posix_path (real_path, buf2);
|
||||
one_line.prepend (buf2, strlen (buf2));
|
||||
|
||||
|
@ -500,10 +497,8 @@ skip_arg_parsing:
|
|||
if (mode == _P_DETACH || !set_console_state_for_spawn ())
|
||||
flags |= DETACHED_PROCESS;
|
||||
|
||||
MALLOC_CHECK;
|
||||
/* Build windows style environment list */
|
||||
char *envblock = winenv (envp);
|
||||
MALLOC_CHECK;
|
||||
char *envblock = winenv (envp, 0);
|
||||
|
||||
/* Preallocated buffer for `sec_user' call */
|
||||
char sa_buf[1024];
|
||||
|
@ -977,6 +972,6 @@ int
|
|||
spawnvpe (int mode, const char *file, const char * const *argv,
|
||||
const char * const *envp)
|
||||
{
|
||||
char buf[MAXNAMLEN];
|
||||
path_conv buf;
|
||||
return _spawnve (NULL, mode, find_exec (file, buf), argv, envp);
|
||||
}
|
||||
|
|
|
@ -373,7 +373,7 @@ extern "C" int dll_noncygwin_dllcrt0 (HMODULE, per_process *);
|
|||
extern "C" void __stdcall do_exit (int) __attribute__ ((noreturn));
|
||||
|
||||
/* Initialize the environment */
|
||||
void environ_init (void);
|
||||
void environ_init (int);
|
||||
|
||||
/* Heap management. */
|
||||
void heap_init (void);
|
||||
|
@ -411,7 +411,7 @@ extern "C" int try_to_debug ();
|
|||
|
||||
/**************************** Miscellaneous ******************************/
|
||||
|
||||
const char * __stdcall find_exec (const char *name, char *buf, const char *winenv = "PATH=",
|
||||
const char * __stdcall find_exec (const char *name, path_conv& buf, const char *winenv = "PATH=",
|
||||
int null_if_notfound = 0, const char **known_suffix = NULL);
|
||||
|
||||
/* File manipulation */
|
||||
|
@ -556,7 +556,7 @@ struct win_env
|
|||
|
||||
win_env * __stdcall getwinenv (const char *name, const char *posix = NULL);
|
||||
|
||||
char * __stdcall winenv (const char * const *);
|
||||
char * __stdcall winenv (const char * const *, int);
|
||||
extern char **__cygwin_environ;
|
||||
|
||||
/* The title on program start. */
|
||||
|
|
Loading…
Reference in New Issue