4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-28 12:05:47 +08:00

* dlopen.c (dlopen): Return NULL when name is NULL (suggested by

chrisiasci@aol.com).
* cygwin.din: Add a new, internally used export - _check_for_executable.
* dcrt0.cc (dll_crt0_1): Set _check_for_executable for older binaries.  Pass
user_data to premain functions.
* fhandler.cc (fhandler_disk_file::open): Only check for executable if the
linked program is intereested in the executable bit.
(fhandler_disk_file::check_execable_p): Delete.
* fhandler.h (executable_states): New enumeration of various states of
executable bit caring.
(fhandler_base::set_execable_p): New method.
* fhandler_termios.cc (fhandler_termios::line_edit): Flag when a signal has
been sent to the tty.  Return -1 when this is so.
* fhandler_console.cc (fhandler_console::read): Return -1 when signal sending
character encountered.
* path.cc (path_conv::check): Record when path refers to a disk device.  Move
executable extension check here.
(check_sysfile): Accomodate new EXEC path states.
(has_suffix): Remove.
(next_suffix): Remove.
(class suffix_scan): New clas.
(suffix_scan::has): New method.
(suffix_scan:next): New method.
(symlink_info::check): Use suffix_scan method to control for scanning for
suffixes.
* path.h (path_conv::exec_state): New method.
* perprocess.h: Make "C" friendly.
* include/cygwin/version.h: Define CYGWIN_VERSION_CHECK_FOR_S_IEXEC.  Bump
CYGWIN_VERSION_API_MINOR.
* include/sys/cygwin.h: Change premain declarations.
* winsup.h: Move __cplusplus test to after builtin defines.
This commit is contained in:
Christopher Faylor 2001-03-05 06:28:25 +00:00
parent 658b5db941
commit 95a8465ba0
28 changed files with 315 additions and 147 deletions

View File

@ -1,3 +1,42 @@
Mon Mar 5 01:25:03 2001 Christopher Faylor <cgf@cygnus.com>
* dlopen.c (dlopen): Return NULL when name is NULL (suggested by
chrisiasci@aol.com).
* cygwin.din: Add a new, internally used export -
_check_for_executable.
* dcrt0.cc (dll_crt0_1): Set _check_for_executable for older binaries.
Pass user_data to premain functions.
* fhandler.cc (fhandler_disk_file::open): Only check for executable if
the linked program is intereested in the executable bit.
(fhandler_disk_file::check_execable_p): Delete.
* fhandler.h (executable_states): New enumeration of various states of
executable bit caring.
(fhandler_base::set_execable_p): New method.
* fhandler_termios.cc (fhandler_termios::line_edit): Flag when a signal
has been sent to the tty. Return -1 when this is so.
* fhandler_console.cc (fhandler_console::read): Return -1 when signal
sending character encountered.
* path.cc (path_conv::check): Record when path refers to a disk device.
Move executable extension check here.
(check_sysfile): Accomodate new EXEC path states.
(has_suffix): Remove.
(next_suffix): Remove.
(class suffix_scan): New clas.
(suffix_scan::has): New method.
(suffix_scan:next): New method.
(symlink_info::check): Use suffix_scan method to control for scanning
for suffixes.
* path.h (path_conv::exec_state): New method.
* perprocess.h: Make "C" friendly.
* include/cygwin/version.h: Define CYGWIN_VERSION_CHECK_FOR_S_IEXEC.
Bump CYGWIN_VERSION_API_MINOR.
* include/sys/cygwin.h: Change premain declarations.
* winsup.h: Move __cplusplus test to after builtin defines.
2001-03-04 Egor Duda <deo@logos-m.ru> 2001-03-04 Egor Duda <deo@logos-m.ru>
* fhandler.h (class fhandler_tty_common): New mutex and event to * fhandler.h (class fhandler_tty_common): New mutex and event to

View File

@ -8,6 +8,7 @@ __infinity
__main __main
__srget __srget
__swbuf __swbuf
_check_for_executable DATA
; __vc__10pinfo_listi ; __vc__10pinfo_listi
@ALLOCA@ @ALLOCA@
cygwin_stackdump cygwin_stackdump

View File

@ -27,11 +27,11 @@ details. */
#include "child_info.h" #include "child_info.h"
#define NEED_VFORK #define NEED_VFORK
#include "perthread.h" #include "perthread.h"
#include "perprocess.h"
#include "path.h" #include "path.h"
#include "dtable.h" #include "dtable.h"
#include "shared_info.h" #include "shared_info.h"
#include "cygwin_version.h" #include "cygwin_version.h"
#include "perprocess.h"
#include "dll_init.h" #include "dll_init.h"
#include "host_dependent.h" #include "host_dependent.h"
#include "security.h" #include "security.h"
@ -108,7 +108,11 @@ extern "C"
/* resourcelocks */ &_reslock, /* threadinterface */ &_mtinterf, /* resourcelocks */ &_reslock, /* threadinterface */ &_mtinterf,
/* impure_ptr */ &reent_data, /* impure_ptr */ &reent_data,
}; };
BOOL ignore_case_with_glob = FALSE; bool ignore_case_with_glob = FALSE;
int __declspec (dllexport) _check_for_executable = FALSE;
#ifdef DEBUGGING
int pinger = 0;
#endif
}; };
char *old_title = NULL; char *old_title = NULL;
@ -752,6 +756,9 @@ dll_crt0_1 ()
longjmp (fork_info->jmp, fork_info->cygpid); longjmp (fork_info->jmp, fork_info->cygpid);
} }
if (!CYGWIN_VERSION_CHECK_FOR_S_IEXEC)
_check_for_executable = TRUE;
#ifdef DEBUGGING #ifdef DEBUGGING
{ {
extern void fork_init (); extern void fork_init ();
@ -808,7 +815,7 @@ dll_crt0_1 ()
if (user_data->premain[0]) if (user_data->premain[0])
for (unsigned int i = 0; i < PREMAIN_LEN / 2; i++) for (unsigned int i = 0; i < PREMAIN_LEN / 2; i++)
user_data->premain[i] (__argc, __argv); user_data->premain[i] (__argc, __argv, user_data);
/* Set up __progname for getopt error call. */ /* Set up __progname for getopt error call. */
__progname = __argv[0]; __progname = __argv[0];
@ -832,7 +839,7 @@ dll_crt0_1 ()
/* Execute any specified "premain" functions */ /* Execute any specified "premain" functions */
if (user_data->premain[PREMAIN_LEN / 2]) if (user_data->premain[PREMAIN_LEN / 2])
for (unsigned int i = PREMAIN_LEN / 2; i < PREMAIN_LEN; i++) for (unsigned int i = PREMAIN_LEN / 2; i < PREMAIN_LEN; i++)
user_data->premain[i] (__argc, __argv); user_data->premain[i] (__argc, __argv, user_data);
debug_printf ("user_data->main %p", user_data->main); debug_printf ("user_data->main %p", user_data->main);

View File

@ -67,6 +67,7 @@ void __stdcall add_handle (const char *, int, HANDLE, const char *);
BOOL __stdcall close_handle (const char *, int, HANDLE, const char *, BOOL); BOOL __stdcall close_handle (const char *, int, HANDLE, const char *, BOOL);
int __stdcall lpfu (const char *, int, DWORD timeout); int __stdcall lpfu (const char *, int, DWORD timeout);
void __stdcall cygbench (const char *s); void __stdcall cygbench (const char *s);
extern int pinger;
#endif /*DEBUGGING*/ #endif /*DEBUGGING*/
#endif /*_DEBUG_H_*/ #endif /*_DEBUG_H_*/

View File

@ -22,6 +22,7 @@ details. */
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h" #include "cygerrno.h"
#include "fhandler.h" #include "fhandler.h"
#include "perprocess.h"
#include "path.h" #include "path.h"
#include "security.h" #include "security.h"
#include "cygheap.h" #include "cygheap.h"

View File

@ -14,9 +14,9 @@ details. */
#include <unistd.h> #include <unistd.h>
#include <ctype.h> #include <ctype.h>
#include "fhandler.h" #include "fhandler.h"
#include "perprocess.h"
#include "path.h" #include "path.h"
#include "thread.h" #include "thread.h"
#include "perprocess.h"
#include "dlfcn.h" #include "dlfcn.h"
#include "dll_init.h" #include "dll_init.h"
@ -166,19 +166,15 @@ dlopen (const char *name, int)
{ {
SetResourceLock(LOCK_DLL_LIST,READ_LOCK|WRITE_LOCK," dlopen"); SetResourceLock(LOCK_DLL_LIST,READ_LOCK|WRITE_LOCK," dlopen");
void *ret = 0; void *ret;
if (!name) if (!name)
{ ret = (void *) GetModuleHandle (NULL); /* handle for the current module */
/* handle for the current module */
ret = (void *) GetModuleHandle (NULL);
}
else else
{ {
/* handle for the named library */ /* handle for the named library */
const char *fullpath = get_full_path_of_dll (name); const char *fullpath = get_full_path_of_dll (name);
if (fullpath) ret = fullpath ? (void *) LoadLibrary (fullpath) : NULL;
ret = (void *) LoadLibrary (fullpath);
} }
if (!ret) if (!ret)

View File

@ -26,6 +26,7 @@ details. */
#include "pinfo.h" #include "pinfo.h"
#include "cygheap.h" #include "cygheap.h"
#include "cygerrno.h" #include "cygerrno.h"
#include "perprocess.h"
#include "fhandler.h" #include "fhandler.h"
#include "path.h" #include "path.h"
#include "dtable.h" #include "dtable.h"

View File

@ -18,16 +18,16 @@ details. */
#include "sync.h" #include "sync.h"
#include "sigproc.h" #include "sigproc.h"
#include "pinfo.h" #include "pinfo.h"
#include "perprocess.h"
#include "fhandler.h" #include "fhandler.h"
#include "path.h" #include "path.h"
#include "cygerrno.h" #include "cygerrno.h"
#include "cygheap.h" #include "cygheap.h"
#include "registry.h" #include "registry.h"
#include "environ.h" #include "environ.h"
#include "perprocess.h"
extern BOOL allow_glob; extern BOOL allow_glob;
extern BOOL ignore_case_with_glob; extern bool ignore_case_with_glob;
extern BOOL allow_ntea; extern BOOL allow_ntea;
extern BOOL allow_smbntsec; extern BOOL allow_smbntsec;
extern BOOL allow_winsymlinks; extern BOOL allow_winsymlinks;

View File

@ -13,6 +13,7 @@ details. */
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <process.h> #include <process.h>
#include "perprocess.h"
#include "fhandler.h" #include "fhandler.h"
#include "path.h" #include "path.h"
#include "sync.h" #include "sync.h"

View File

@ -17,11 +17,11 @@ details. */
#include <sys/cygwin.h> #include <sys/cygwin.h>
#include <signal.h> #include <signal.h>
#include "cygerrno.h" #include "cygerrno.h"
#include "perprocess.h"
#include "fhandler.h" #include "fhandler.h"
#include "path.h" #include "path.h"
#include "shared_info.h" #include "shared_info.h"
#include "host_dependent.h" #include "host_dependent.h"
#include "perprocess.h"
#include "security.h" #include "security.h"
static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */ static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
@ -1226,9 +1226,6 @@ fhandler_disk_file::open (path_conv& real_path, int flags, mode_t mode)
win32_path_name_ = real_path.get_win32 (); win32_path_name_ = real_path.get_win32 ();
set_no_free_names (); set_no_free_names ();
} }
/* If necessary, do various other things to see if path is a program. */
if (!real_path.isexec ())
real_path.set_exec (check_execable_p (get_win32_name ()));
if (real_path.isbinary ()) if (real_path.isbinary ())
{ {
@ -1264,9 +1261,9 @@ fhandler_disk_file::open (path_conv& real_path, int flags, mode_t mode)
extern BOOL allow_ntea; extern BOOL allow_ntea;
if (!real_path.isexec () && !allow_ntea if (real_path.isdisk ()
&& (!allow_ntsec || !real_path.has_acls ()) && (real_path.exec_state () == dont_know_if_executable)
&& GetFileType (get_handle ()) == FILE_TYPE_DISK) && !allow_ntea && (!allow_ntsec || !real_path.has_acls ()))
{ {
DWORD done; DWORD done;
char magic[3]; char magic[3];
@ -1283,7 +1280,7 @@ fhandler_disk_file::open (path_conv& real_path, int flags, mode_t mode)
SetFilePointer (get_handle(), 0, 0, FILE_END); SetFilePointer (get_handle(), 0, 0, FILE_END);
set_symlink_p (real_path.issymlink ()); set_symlink_p (real_path.issymlink ());
set_execable_p (real_path.isexec ()); set_execable_p (real_path.exec_state ());
set_socket_p (real_path.issocket ()); set_socket_p (real_path.issocket ());
out: out:
@ -1457,21 +1454,6 @@ fhandler_disk_file::lock (int cmd, struct flock *fl)
return 0; return 0;
} }
/* Perform various heuristics on PATH to see if it's a program. */
int
fhandler_disk_file::check_execable_p (const char *path)
{
int len = strlen (path);
const char *ch = path + (len > 4 ? len - 4 : len);
if (strcasematch (".exe", ch)
|| strcasematch (".bat", ch)
|| strcasematch (".com", ch))
return 1;
return 0;
}
/**********************************************************************/ /**********************************************************************/
/* /dev/null */ /* /dev/null */

View File

@ -130,6 +130,14 @@ enum bg_check_types
bg_signalled = 2 bg_signalled = 2
}; };
enum executable_states
{
is_executable,
not_executable,
dont_care_if_executable,
dont_know_if_executable
};
class fhandler_base class fhandler_base
{ {
private: private:
@ -219,7 +227,10 @@ public:
void set_socket_p () { FHSETF (LOCAL); } void set_socket_p () { FHSETF (LOCAL); }
int get_execable_p () { return FHISSETF (EXECABL); } int get_execable_p () { return FHISSETF (EXECABL); }
void set_execable_p (int val) { FHCONDSETF (val, EXECABL); } void set_execable_p (executable_states val)
{
FHCONDSETF (val == is_executable, EXECABL);
}
void set_execable_p () { FHSETF (EXECABL); } void set_execable_p () { FHSETF (EXECABL); }
int get_append_p () { return FHISSETF (APPEND); } int get_append_p () { return FHISSETF (APPEND); }
@ -477,9 +488,6 @@ private:
class fhandler_disk_file: public fhandler_base class fhandler_disk_file: public fhandler_base
{ {
private:
int check_execable_p (const char *path);
public: public:
fhandler_disk_file (const char *name); fhandler_disk_file (const char *name);

View File

@ -178,8 +178,7 @@ fhandler_console::read (void *pv, size_t buflen)
case WAIT_OBJECT_0: case WAIT_OBJECT_0:
break; break;
case WAIT_OBJECT_0 + 1: case WAIT_OBJECT_0 + 1:
set_sig_errno (EINTR); goto sig_exit;
return -1;
default: default:
__seterrno (); __seterrno ();
return -1; return -1;
@ -358,8 +357,14 @@ fhandler_console::read (void *pv, size_t buflen)
continue; continue;
} }
if (toadd && line_edit (toadd, nread)) if (toadd)
{
int res = line_edit (toadd, nread);
if (res < 0)
goto sig_exit;
else if (res)
break; break;
}
#undef ich #undef ich
} }
@ -374,6 +379,10 @@ fhandler_console::read (void *pv, size_t buflen)
#undef buf #undef buf
return copied_chars; return copied_chars;
sig_exit:
set_sig_errno (EINTR);
return -1;
} }
void void

View File

@ -18,6 +18,7 @@
#include <sys/mtio.h> #include <sys/mtio.h>
#include "cygheap.h" #include "cygheap.h"
#include "cygerrno.h" #include "cygerrno.h"
#include "perprocess.h"
#include "fhandler.h" #include "fhandler.h"
#include "path.h" #include "path.h"

View File

@ -18,6 +18,7 @@ details. */
#include <sys/mtio.h> #include <sys/mtio.h>
#include "cygheap.h" #include "cygheap.h"
#include "cygerrno.h" #include "cygerrno.h"
#include "perprocess.h"
#include "fhandler.h" #include "fhandler.h"
#include "path.h" #include "path.h"

View File

@ -165,6 +165,7 @@ fhandler_termios::line_edit (const char *rptr, int nread, int always_accept)
{ {
char c; char c;
int input_done = 0; int input_done = 0;
bool sawsig = FALSE;
int iscanon = tc->ti.c_lflag & ICANON; int iscanon = tc->ti.c_lflag & ICANON;
while (nread-- > 0) while (nread-- > 0)
@ -210,6 +211,7 @@ fhandler_termios::line_edit (const char *rptr, int nread, int always_accept)
termios_printf ("got interrupt %d, sending signal %d", c, sig); termios_printf ("got interrupt %d, sending signal %d", c, sig);
kill_pgrp (tc->getpgid (), sig); kill_pgrp (tc->getpgid (), sig);
tc->ti.c_lflag &= ~FLUSHO; tc->ti.c_lflag &= ~FLUSHO;
sawsig = 1;
goto restart_output; goto restart_output;
} }
not_a_sig: not_a_sig:
@ -296,6 +298,11 @@ fhandler_termios::line_edit (const char *rptr, int nread, int always_accept)
if (!iscanon || always_accept) if (!iscanon || always_accept)
set_input_done (ralen > 0); set_input_done (ralen > 0);
if (sawsig)
{
// tc->write_error = EINTR;
input_done = -1;
}
if (input_done) if (input_done)
(void) accept_input (); (void) accept_input ();

View File

@ -194,7 +194,7 @@ process_input (void *)
{ {
int nraw = tty_master->console->read ((void *) rawbuf, int nraw = tty_master->console->read ((void *) rawbuf,
(size_t) INP_BUFFER_SIZE); (size_t) INP_BUFFER_SIZE);
tty_master->line_edit (rawbuf, nraw); (void) tty_master->line_edit (rawbuf, nraw);
} }
} }
@ -1000,7 +1000,7 @@ fhandler_pty_master::close ()
int int
fhandler_pty_master::write (const void *ptr, size_t len) fhandler_pty_master::write (const void *ptr, size_t len)
{ {
line_edit ((char *) ptr, len); (void) line_edit ((char *) ptr, len);
return len; return len;
} }

View File

@ -79,7 +79,9 @@ details. */
(CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) <= \ (CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) <= \
20) 20)
#define CYGWIN_VERSION_CHECK_FOR_S_IEXEC \
(CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) >= \
36)
/* We used to use the DLL major/minor to track /* We used to use the DLL major/minor to track
non-backward-compatible interface changes to the API. Now we non-backward-compatible interface changes to the API. Now we
use an API major/minor number for this purpose. */ use an API major/minor number for this purpose. */
@ -127,10 +129,11 @@ details. */
34: Separated out mount table 34: Separated out mount table
35: Export drand48, erand48, jrand48, lcong48, lrand48, 35: Export drand48, erand48, jrand48, lcong48, lrand48,
mrand48, nrand48, seed48, and srand48. mrand48, nrand48, seed48, and srand48.
36: Added _cygwin_S_IEXEC, et al
*/ */
#define CYGWIN_VERSION_API_MAJOR 0 #define CYGWIN_VERSION_API_MAJOR 0
#define CYGWIN_VERSION_API_MINOR 35 #define CYGWIN_VERSION_API_MINOR 36
/* There is also a compatibity version number associated with the /* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible shared memory regions. It is incremented when incompatible

View File

@ -31,11 +31,6 @@ extern int cygwin_conv_to_full_posix_path (const char *, char *);
extern int cygwin_posix_path_list_p (const char *); extern int cygwin_posix_path_list_p (const char *);
extern void cygwin_split_path (const char *, char *, char *); extern void cygwin_split_path (const char *, char *, char *);
extern void cygwin_premain0 (int argc, char **argv);
extern void cygwin_premain1 (int argc, char **argv);
extern void cygwin_premain2 (int argc, char **argv);
extern void cygwin_premain3 (int argc, char **argv);
struct __cygwin_perfile struct __cygwin_perfile
{ {
const char *name; const char *name;
@ -149,7 +144,7 @@ struct per_process
void *(*calloc)(size_t, size_t); void *(*calloc)(size_t, size_t);
/* For future expansion of values set by the app. */ /* For future expansion of values set by the app. */
void (*premain[4]) (int, char **); void (*premain[4]) (int, char **, struct per_process *);
/* The rest are *internal* to cygwin.dll. /* The rest are *internal* to cygwin.dll.
Those that are here because we want the child to inherit the value from Those that are here because we want the child to inherit the value from
@ -165,7 +160,7 @@ struct per_process
void *heapptr; /* current index into heap */ void *heapptr; /* current index into heap */
void *heaptop; /* current top of heap */ void *heaptop; /* current top of heap */
DWORD unused1; /* unused */ DWORD unused1;
/* Non-zero means the task was forked. The value is the pid. /* Non-zero means the task was forked. The value is the pid.
Inherited from parent. */ Inherited from parent. */
@ -190,6 +185,11 @@ struct per_process
}; };
#define per_process_overwrite ((unsigned) &(((struct per_process *) NULL)->resourcelocks)) #define per_process_overwrite ((unsigned) &(((struct per_process *) NULL)->resourcelocks))
extern void cygwin_premain0 (int argc, char **argv, struct per_process *);
extern void cygwin_premain1 (int argc, char **argv, struct per_process *);
extern void cygwin_premain2 (int argc, char **argv, struct per_process *);
extern void cygwin_premain3 (int argc, char **argv, struct per_process *);
extern void cygwin_set_impersonation_token (const HANDLE); extern void cygwin_set_impersonation_token (const HANDLE);
/* included if <windows.h> is included */ /* included if <windows.h> is included */

View File

@ -24,7 +24,13 @@
#define F_OK 0 /* does file exist */ #define F_OK 0 /* does file exist */
#define X_OK 1 /* is it executable by caller */ #define _X_OK 1 /* is it executable by caller */
#if defined (__CYGWIN__) || defined (__INSIDE_CYGWIN__)
# define X_OK _X_OK /* Check for execute permission. */
#else
extern const unsigned _cygwin_X_OK;
# define X_OK _cygwin_X_OK
#endif
#define W_OK 2 /* is it writable by caller */ #define W_OK 2 /* is it writable by caller */
#define R_OK 4 /* is it readable by caller */ #define R_OK 4 /* is it readable by caller */

View File

@ -0,0 +1,29 @@
/* _cygwin_S_IEXEC.cc: stat helper stuff
Copyright 2001 Red Hat, Inc.
This file is part of Cygwin.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#if 0
#include "windows.h"
#include <sys/cygwin.h>
#include "perprocess.h"
#endif
#include <sys/stat.h>
#include <sys/unistd.h>
const unsigned _cygwin_S_IEXEC = S_IEXEC;
const unsigned _cygwin_S_IXUSR = S_IXUSR;
const unsigned _cygwin_S_IXGRP = S_IXGRP;
const unsigned _cygwin_S_IXOTH = S_IXOTH;
const unsigned _cygwin_X_OK = X_OK;
extern int __declspec (dllimport) _check_for_executable;
struct _cygwin_bob__
{
_cygwin_bob__ () {_check_for_executable = 1;}
} _cygwin_dummy_bob__;

View File

@ -25,6 +25,7 @@ details. */
#include <winsock2.h> #include <winsock2.h>
#include "cygheap.h" #include "cygheap.h"
#include "cygerrno.h" #include "cygerrno.h"
#include "perprocess.h"
#include "fhandler.h" #include "fhandler.h"
#include "path.h" #include "path.h"
#include "dtable.h" #include "dtable.h"

View File

@ -64,6 +64,7 @@ details. */
#include <sys/cygwin.h> #include <sys/cygwin.h>
#include <cygwin/version.h> #include <cygwin/version.h>
#include "cygerrno.h" #include "cygerrno.h"
#include "perprocess.h"
#include "fhandler.h" #include "fhandler.h"
#include "path.h" #include "path.h"
#include "sync.h" #include "sync.h"
@ -412,6 +413,7 @@ out:
} }
else else
{ {
set_isdisk ();
debug_printf ("GetVolumeInformation(%s) = OK, full_path(%s), set_has_acls(%d)", debug_printf ("GetVolumeInformation(%s) = OK, full_path(%s), set_has_acls(%d)",
tmp_buf, full_path, volflags & FS_PERSISTENT_ACLS); tmp_buf, full_path, volflags & FS_PERSISTENT_ACLS);
if (!allow_smbntsec if (!allow_smbntsec
@ -428,6 +430,16 @@ out:
if (saw_symlinks) if (saw_symlinks)
set_has_symlinks (); set_has_symlinks ();
if (!error && !(path_flags & (PATH_ALL_EXEC | PATH_NOTEXEC)))
{
const char *p = strchr (path, '\0') - 4;
if (p >= path &&
(strcasematch (".exe", p) ||
strcasematch (".bat", p) ||
strcasematch (".com", p)))
path_flags |= PATH_EXEC;
}
#if 0 #if 0
if (!error) if (!error)
{ {
@ -565,7 +577,7 @@ get_device_number (const char *name, int &unit, BOOL from_conv)
else if (deveq ("tcp") || deveq ("udp") || deveq ("streamsocket") else if (deveq ("tcp") || deveq ("udp") || deveq ("streamsocket")
|| deveq ("dgsocket")) || deveq ("dgsocket"))
devn = FH_SOCKET; devn = FH_SOCKET;
else if (! from_conv) else if (!from_conv)
devn = get_raw_device_number (name - 5, devn = get_raw_device_number (name - 5,
path_conv (name - 5, path_conv (name - 5,
PC_SYM_IGNORE).get_win32 (), PC_SYM_IGNORE).get_win32 (),
@ -821,7 +833,6 @@ normalize_win32_path (const char *src, char *dst)
debug_printf ("%s = normalize_win32_path (%s)", dst_start, src_start); debug_printf ("%s = normalize_win32_path (%s)", dst_start, src_start);
return 0; return 0;
} }
/* Various utilities. */ /* Various utilities. */
@ -1303,7 +1314,7 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
for (int i = 0; i < nmounts; ++i) for (int i = 0; i < nmounts; ++i)
{ {
mount_item &mi = mount[native_sorted[i]]; mount_item &mi = mount[native_sorted[i]];
if (! path_prefix_p (mi.native_path, pathbuf, mi.native_pathlen)) if (!path_prefix_p (mi.native_path, pathbuf, mi.native_pathlen))
continue; continue;
/* SRC_PATH is in the mount table. */ /* SRC_PATH is in the mount table. */
@ -1387,7 +1398,7 @@ mount_info::read_mounts (reg_key& r)
posix_path_size = MAX_PATH; posix_path_size = MAX_PATH;
/* FIXME: if maximum posix_path_size is 256, we're going to /* FIXME: if maximum posix_path_size is 256, we're going to
run into problems if we ever try to store a mount point that's run into problems if we ever try to store a mount point that's
over 256 but is under MAX_PATH! */ over 256 but is under MAX_PATH. */
res = RegEnumKeyEx (key, i, posix_path, &posix_path_size, NULL, res = RegEnumKeyEx (key, i, posix_path, &posix_path_size, NULL,
NULL, NULL, NULL); NULL, NULL, NULL);
@ -1503,7 +1514,7 @@ mount_info::add_reg_mount (const char * native_path, const char * posix_path, un
cygwin_shared->sys_mount_table_counter++; cygwin_shared->sys_mount_table_counter++;
} }
return 0; /* Success! */ return 0; /* Success */
err: err:
__seterrno_from_win_error (res); __seterrno_from_win_error (res);
return -1; return -1;
@ -1542,7 +1553,7 @@ mount_info::del_reg_mount (const char * posix_path, unsigned flags)
return -1; return -1;
} }
return 0; /* Success! */ return 0; /* Success */
} }
/* read_cygdrive_info_from_registry: Read the default prefix and flags /* read_cygdrive_info_from_registry: Read the default prefix and flags
@ -2060,7 +2071,7 @@ mount_item::getmntent ()
binary or textmode, or exec. We don't print binary or textmode, or exec. We don't print
`silent' here; it's a magic internal thing. */ `silent' here; it's a magic internal thing. */
if (! (flags & MOUNT_BINARY)) if (!(flags & MOUNT_BINARY))
strcpy (mount_table->mnt_opts, (char *) "textmode"); strcpy (mount_table->mnt_opts, (char *) "textmode");
else else
strcpy (mount_table->mnt_opts, (char *) "binmode"); strcpy (mount_table->mnt_opts, (char *) "binmode");
@ -2333,36 +2344,6 @@ done:
return res; return res;
} }
static __inline char *
has_suffix (const char *path, const suffix_info *suffixes)
{
assert (path);
char *ext = strrchr (path, '.');
if (ext)
for (const suffix_info *ex = suffixes; ex->name != NULL; ex++)
if (strcasematch (ext, ex->name))
return ext;
return NULL;
}
static __inline__ int
next_suffix (char *ext_here, const suffix_info *&suffixes)
{
if (!suffixes)
return 1;
while (suffixes && suffixes->name)
if (!suffixes->addon)
suffixes++;
else
{
strcpy (ext_here, suffixes->name);
suffixes++;
return 1;
}
return 0;
}
static int static int
check_sysfile (const char *path, DWORD fileattr, HANDLE h, check_sysfile (const char *path, DWORD fileattr, HANDLE h,
char *contents, int *error, unsigned *pflags) char *contents, int *error, unsigned *pflags)
@ -2371,7 +2352,7 @@ check_sysfile (const char *path, DWORD fileattr, HANDLE h,
DWORD got; DWORD got;
int res = 0; int res = 0;
if (! ReadFile (h, cookie_buf, sizeof (cookie_buf), &got, 0)) if (!ReadFile (h, cookie_buf, sizeof (cookie_buf), &got, 0))
{ {
debug_printf ("ReadFile1 failed"); debug_printf ("ReadFile1 failed");
*error = EIO; *error = EIO;
@ -2408,12 +2389,107 @@ check_sysfile (const char *path, DWORD fileattr, HANDLE h,
else else
{ {
/* Not a symlink, see if executable. */ /* Not a symlink, see if executable. */
if (!(*pflags & PATH_ALL_EXEC) && has_exec_chars (cookie_buf, got)) if (*pflags & PATH_ALL_EXEC)
/* Nothing to do */;
else if (has_exec_chars (cookie_buf, got))
*pflags |= PATH_EXEC; *pflags |= PATH_EXEC;
else
*pflags |= PATH_NOTEXEC;
} }
syscall_printf ("%d = symlink.check_sysfile (%s, %s) (%p)",
res, path, contents, *pflags);
return res; return res;
} }
#define SCAN_BEG 0
#define SCAN_LNK 1
#define SCAN_TERM1 2
#define SCAN_JUSTCHECK 3
class suffix_scan
{
char *ext_here;
const suffix_info *suffixes;
int state;
int nullterm;
public:
const char *path;
char *has (const char *, const suffix_info *, char **);
int next ();
int lnk_match () {return state == SCAN_LNK + 1;}
};
char *
suffix_scan::has (const char *in_path, const suffix_info *in_suffixes, char **ext_where)
{
path = in_path;
suffixes = in_suffixes;
nullterm = 0;
state = SCAN_BEG;
if (suffixes)
{
ext_here = *ext_where = strrchr (in_path, '.');
if (ext_here)
{
/* Check if the extension matches a known extension */
for (const suffix_info *ex = in_suffixes; ex->name != NULL; ex++)
if (strcasematch (ext_here, ex->name))
{
state = SCAN_JUSTCHECK;
goto known_suffix;
}
/* Didn't match. Use last resort -- .lnk. */
if (strcasematch (ext_here, ".lnk"))
{
state = SCAN_LNK;
goto known_suffix;
}
}
}
/* Didn't find a matching suffix. */
ext_here = *ext_where = strchr (path, '\0');
nullterm = 1;
return NULL;
known_suffix:
suffixes = NULL; /* Has an extension so don't scan for one. */
return ext_here;
}
int
suffix_scan::next ()
{
if (suffixes)
{
while (suffixes && suffixes->name)
if (!suffixes->addon)
suffixes++;
else
{
strcpy (ext_here, suffixes->name);
suffixes++;
return 1;
}
suffixes = NULL;
state++;
}
switch (state++)
{
case SCAN_LNK:
strcpy (ext_here, ".lnk");
/* fall through */
case SCAN_BEG:
case SCAN_JUSTCHECK:
return 1;
default:
if (nullterm && ext_here)
*ext_here = '\0';
return 0;
}
}
/* Check if PATH is a symlink. PATH must be a valid Win32 path name. /* Check if PATH is a symlink. PATH must be a valid Win32 path name.
If PATH is a symlink, put the value of the symlink--the file to If PATH is a symlink, put the value of the symlink--the file to
@ -2432,43 +2508,25 @@ check_sysfile (const char *path, DWORD fileattr, HANDLE h,
stored into BUF if PATH is a symlink. */ stored into BUF if PATH is a symlink. */
int int
symlink_info::check (const char *in_path, const suffix_info *suffixes) symlink_info::check (const char *path, const suffix_info *suffixes)
{ {
HANDLE h; HANDLE h;
int res = 0; int res = 0;
char extbuf[MAX_PATH + 5]; suffix_scan suffix;
const char *path = in_path;
BOOL check_lnk = FALSE;
if (!suffixes)
ext_here = NULL;
else if ((known_suffix = has_suffix (in_path, suffixes)) != NULL)
{
suffixes = NULL;
ext_here = NULL;
}
else
{
restart:
path = strcpy (extbuf, in_path);
ext_here = strchr (path, '\0');
}
is_symlink = TRUE; is_symlink = TRUE;
known_suffix = suffix.has (path, suffixes, &ext_here);
error = 0; while (suffix.next ())
do
{ {
if (!next_suffix (ext_here, suffixes))
break;
error = 0; error = 0;
fileattr = GetFileAttributesA (path); fileattr = GetFileAttributesA (suffix.path);
if (fileattr == (DWORD) -1) if (fileattr == (DWORD) -1)
{ {
/* The GetFileAttributesA call can fail for reasons that don't /* The GetFileAttributesA call can fail for reasons that don't
matter, so we just return 0. For example, getting the matter, so we just return 0. For example, getting the
attributes of \\HOST will typically fail. */ attributes of \\HOST will typically fail. */
debug_printf ("GetFileAttributesA (%s) failed", path); debug_printf ("GetFileAttributesA (%s) failed", suffix.path);
error = geterrno_from_win_error (GetLastError (), EACCES); error = geterrno_from_win_error (GetLastError (), EACCES);
continue; continue;
} }
@ -2479,7 +2537,7 @@ restart:
goto file_not_symlink; goto file_not_symlink;
/* Windows shortcuts are treated as symlinks. */ /* Windows shortcuts are treated as symlinks. */
if (!strcasecmp (path + strlen (path) - 4, ".lnk")) if (suffix.lnk_match ())
sym_check = 1; sym_check = 1;
/* The old Cygwin method creating symlinks: */ /* The old Cygwin method creating symlinks: */
@ -2493,27 +2551,27 @@ restart:
/* Open the file. */ /* Open the file. */
h = CreateFileA (path, GENERIC_READ, FILE_SHARE_READ, &sec_none_nih, OPEN_EXISTING, h = CreateFileA (suffix.path, GENERIC_READ, FILE_SHARE_READ, &sec_none_nih, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0); FILE_ATTRIBUTE_NORMAL, 0);
res = -1; res = -1;
if (h == INVALID_HANDLE_VALUE) if (h == INVALID_HANDLE_VALUE)
goto file_not_symlink; goto file_not_symlink;
else if (sym_check == 1 else if (sym_check == 1
&& !(res = check_shortcut (path, fileattr, h, && !(res = check_shortcut (suffix.path, fileattr, h,
contents, &error, &pflags))) contents, &error, &pflags)))
{ {
CloseHandle (h); CloseHandle (h);
/* If searching for `foo' and then finding a `foo.lnk' which is /* If searching for `foo' and then finding a `foo.lnk' which is
no shortcut, return the same as if file not found. */ no shortcut, return the same as if file not found. */
if (check_lnk) if (suffix.lnk_match ())
{ {
fileattr = (DWORD)-1; fileattr = (DWORD)-1;
goto out; break;
} }
goto file_not_symlink; goto file_not_symlink;
} }
else if (sym_check == 2 && else if (sym_check == 2 &&
!(res = check_sysfile (path, fileattr, h, !(res = check_sysfile (suffix.path, fileattr, h,
contents, &error, &pflags))) contents, &error, &pflags)))
{ {
CloseHandle (h); CloseHandle (h);
@ -2521,14 +2579,7 @@ restart:
} }
CloseHandle (h); CloseHandle (h);
goto out; break;
}
while (suffixes);
if (!check_lnk)
{
suffixes = lnk_suffixes;
check_lnk = TRUE;
goto restart;
} }
goto out; goto out;
@ -2539,8 +2590,7 @@ file_not_symlink:
out: out:
syscall_printf ("%d = symlink.check (%s, %p) (%p)", syscall_printf ("%d = symlink.check (%s, %p) (%p)",
res, path, contents, pflags); res, suffix.path, contents, pflags);
return res; return res;
} }
@ -2846,7 +2896,7 @@ extern "C"
int int
cygwin_posix_path_list_p (const char *path) cygwin_posix_path_list_p (const char *path)
{ {
int posix_p = ! (strchr (path, ';') || isdrive (path)); int posix_p = !(strchr (path, ';') || isdrive (path));
return posix_p; return posix_p;
} }
@ -2946,7 +2996,7 @@ cygwin_split_path (const char *path, char *dir, char *file)
*dir++ = *path++; *dir++ = *path++;
*dir++ = *path++; *dir++ = *path++;
*dir++ = '/'; *dir++ = '/';
if (! *path) if (!*path)
{ {
*dir = 0; *dir = 0;
*file = 0; *file = 0;

View File

@ -37,6 +37,8 @@ enum path_types
PATH_EXEC = MOUNT_EXEC, PATH_EXEC = MOUNT_EXEC,
PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC, PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC,
PATH_ALL_EXEC = PATH_CYGWIN_EXEC | PATH_EXEC, PATH_ALL_EXEC = PATH_CYGWIN_EXEC | PATH_EXEC,
PATH_ISDISK = 0x04000000,
PATH_NOTEXEC = 0x08000000,
PATH_HAS_SYMLINKS = 0x10000000, PATH_HAS_SYMLINKS = 0x10000000,
PATH_HASBUGGYOPEN = 0x20000000, PATH_HASBUGGYOPEN = 0x20000000,
PATH_SOCKET = 0x40000000, PATH_SOCKET = 0x40000000,
@ -50,6 +52,7 @@ class path_conv
unsigned path_flags; unsigned path_flags;
int isdisk () {return path_flags & PATH_ISDISK;}
int has_acls () {return path_flags & PATH_HASACLS;} int has_acls () {return path_flags & PATH_HASACLS;}
int has_symlinks () {return path_flags & PATH_HAS_SYMLINKS;} int has_symlinks () {return path_flags & PATH_HAS_SYMLINKS;}
int hasgood_inode () {return path_flags & PATH_HASACLS;} // Not strictly correct int hasgood_inode () {return path_flags & PATH_HASACLS;} // Not strictly correct
@ -57,13 +60,24 @@ class path_conv
int isbinary () {return path_flags & PATH_BINARY;} int isbinary () {return path_flags & PATH_BINARY;}
int issymlink () {return path_flags & PATH_SYMLINK;} int issymlink () {return path_flags & PATH_SYMLINK;}
int issocket () {return path_flags & PATH_SOCKET;} int issocket () {return path_flags & PATH_SOCKET;}
int isexec () {return path_flags & PATH_ALL_EXEC;}
int iscygexec () {return path_flags & PATH_CYGWIN_EXEC;} int iscygexec () {return path_flags & PATH_CYGWIN_EXEC;}
executable_states exec_state ()
{
extern int _check_for_executable;
if (path_flags & PATH_ALL_EXEC)
return is_executable;
if (path_flags & PATH_NOTEXEC)
return not_executable;
if (!_check_for_executable)
return dont_care_if_executable;
return dont_know_if_executable;
}
void set_binary () {path_flags |= PATH_BINARY;} void set_binary () {path_flags |= PATH_BINARY;}
void set_symlink () {path_flags |= PATH_SYMLINK;} void set_symlink () {path_flags |= PATH_SYMLINK;}
void set_has_symlinks () {path_flags |= PATH_HAS_SYMLINKS;} void set_has_symlinks () {path_flags |= PATH_HAS_SYMLINKS;}
void set_exec (int x = 1) {path_flags |= x ? PATH_EXEC : PATH_NOTHING;} void set_isdisk () {path_flags |= PATH_ISDISK;}
void set_exec (int x = 1) {path_flags |= x ? PATH_EXEC : PATH_NOTEXEC;}
void set_has_acls (int x = 1) {path_flags |= x ? PATH_HASACLS : PATH_NOTHING;} void set_has_acls (int x = 1) {path_flags |= x ? PATH_HASACLS : PATH_NOTHING;}
void set_has_buggy_open (int x = 1) {path_flags |= x ? PATH_HASBUGGYOPEN : PATH_NOTHING;} void set_has_buggy_open (int x = 1) {path_flags |= x ? PATH_HASBUGGYOPEN : PATH_NOTHING;}

View File

@ -1,6 +1,6 @@
/* per_process.h: main Cygwin header file. /* per_process.h: main Cygwin header file.
Copyright 2000 Red Hat, Inc. Copyright 2000, 2001 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -10,11 +10,19 @@ details. */
#include <sys/cygwin.h> #include <sys/cygwin.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Pointer into application's static data */ /* Pointer into application's static data */
extern "C" per_process __cygwin_user_data; extern struct per_process __cygwin_user_data;
#define user_data (&__cygwin_user_data) #define user_data (&__cygwin_user_data)
/* We use the following to test that sizeof hasn't changed. When adding /* We use the following to test that sizeof hasn't changed. When adding
or deleting members, insert fillers or use the reserved entries. or deleting members, insert fillers or use the reserved entries.
Do not change this value. */ Do not change this value. */
#define SIZEOF_PER_PROCESS (42 * 4) #define SIZEOF_PER_PROCESS (42 * 4)
#ifdef __cplusplus
}
#endif

View File

@ -25,6 +25,7 @@ details. */
#include <wingdi.h> #include <wingdi.h>
#include <winuser.h> #include <winuser.h>
#include "cygerrno.h" #include "cygerrno.h"
#include "perprocess.h"
#include "fhandler.h" #include "fhandler.h"
#include "path.h" #include "path.h"
#include "dtable.h" #include "dtable.h"

View File

@ -21,6 +21,7 @@ details. */
#include <ctype.h> #include <ctype.h>
#include "cygerrno.h" #include "cygerrno.h"
#include <sys/cygwin.h> #include <sys/cygwin.h>
#include "perprocess.h"
#include "fhandler.h" #include "fhandler.h"
#include "path.h" #include "path.h"
#include "dtable.h" #include "dtable.h"

View File

@ -26,6 +26,7 @@ details. */
#include <cygwin/version.h> #include <cygwin/version.h>
#include <sys/cygwin.h> #include <sys/cygwin.h>
#include "cygerrno.h" #include "cygerrno.h"
#include "perprocess.h"
#include "fhandler.h" #include "fhandler.h"
#include "path.h" #include "path.h"
#include "dtable.h" #include "dtable.h"
@ -34,7 +35,6 @@ details. */
#include "pinfo.h" #include "pinfo.h"
#include <unistd.h> #include <unistd.h>
#include "shared_info.h" #include "shared_info.h"
#include "perprocess.h"
#include "security.h" #include "security.h"
#include "cygheap.h" #include "cygheap.h"
@ -1071,7 +1071,7 @@ stat_worker (const char *caller, const char *name, struct stat *buf,
atts = real_path.file_attributes (); atts = real_path.file_attributes ();
debug_printf ("%d = GetFileAttributesA (%s)", atts, real_path.get_win32 ()); debug_printf ("%d = file_attributes for '%s'", atts, real_path.get_win32 ());
strcpy (root, real_path.get_win32 ()); strcpy (root, real_path.get_win32 ());
dtype = GetDriveType (rootdir (root)); dtype = GetDriveType (rootdir (root));

View File

@ -14,8 +14,6 @@ details. */
#define __INSIDE_CYGWIN__ #define __INSIDE_CYGWIN__
#ifdef __cplusplus
#define alloca __builtin_alloca #define alloca __builtin_alloca
#define strlen __builtin_strlen #define strlen __builtin_strlen
#define strcmp __builtin_strcmp #define strcmp __builtin_strcmp
@ -26,6 +24,8 @@ details. */
# define memset __builtin_memset # define memset __builtin_memset
#endif #endif
#ifdef __cplusplus
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ >= 199900L #if !defined(__STDC_VERSION__) || __STDC_VERSION__ >= 199900L
#define NEW_MACRO_VARARGS #define NEW_MACRO_VARARGS
#endif #endif