Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2001-03-05 09:28:25 +0300
committerChristopher Faylor <me@cgf.cx>2001-03-05 09:28:25 +0300
commit95a8465ba0fb3ea0fb9033e4823b1f65c4554f27 (patch)
tree1d9cd02f71759975598d27cf3728af23592c90b0
parent658b5db941bcace10daa2d17e8c1158030a4fc8c (diff)
* 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.
-rw-r--r--winsup/cygwin/ChangeLog39
-rw-r--r--winsup/cygwin/cygwin.din1
-rw-r--r--winsup/cygwin/dcrt0.cc15
-rw-r--r--winsup/cygwin/debug.h1
-rw-r--r--winsup/cygwin/dir.cc1
-rw-r--r--winsup/cygwin/dlfcn.cc12
-rw-r--r--winsup/cygwin/dtable.cc1
-rw-r--r--winsup/cygwin/environ.cc4
-rw-r--r--winsup/cygwin/exec.cc1
-rw-r--r--winsup/cygwin/fhandler.cc28
-rw-r--r--winsup/cygwin/fhandler.h16
-rw-r--r--winsup/cygwin/fhandler_console.cc17
-rw-r--r--winsup/cygwin/fhandler_raw.cc1
-rw-r--r--winsup/cygwin/fhandler_tape.cc1
-rw-r--r--winsup/cygwin/fhandler_termios.cc7
-rw-r--r--winsup/cygwin/fhandler_tty.cc4
-rw-r--r--winsup/cygwin/include/cygwin/version.h7
-rw-r--r--winsup/cygwin/include/sys/cygwin.h14
-rw-r--r--winsup/cygwin/include/sys/file.h8
-rw-r--r--winsup/cygwin/lib/_cygwin_S_IEXEC.cc29
-rw-r--r--winsup/cygwin/net.cc1
-rw-r--r--winsup/cygwin/path.cc214
-rw-r--r--winsup/cygwin/path.h18
-rw-r--r--winsup/cygwin/perprocess.h12
-rw-r--r--winsup/cygwin/security.cc1
-rw-r--r--winsup/cygwin/spawn.cc1
-rw-r--r--winsup/cygwin/syscalls.cc4
-rw-r--r--winsup/cygwin/winsup.h4
28 files changed, 315 insertions, 147 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 35b7fa5df..38ea288c0 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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>
* fhandler.h (class fhandler_tty_common): New mutex and event to
diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din
index 184c10b06..fb6364c3d 100644
--- a/winsup/cygwin/cygwin.din
+++ b/winsup/cygwin/cygwin.din
@@ -8,6 +8,7 @@ __infinity
__main
__srget
__swbuf
+_check_for_executable DATA
; __vc__10pinfo_listi
@ALLOCA@
cygwin_stackdump
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 7206fa116..a76e9e5ca 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -27,11 +27,11 @@ details. */
#include "child_info.h"
#define NEED_VFORK
#include "perthread.h"
+#include "perprocess.h"
#include "path.h"
#include "dtable.h"
#include "shared_info.h"
#include "cygwin_version.h"
-#include "perprocess.h"
#include "dll_init.h"
#include "host_dependent.h"
#include "security.h"
@@ -108,7 +108,11 @@ extern "C"
/* resourcelocks */ &_reslock, /* threadinterface */ &_mtinterf,
/* 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;
@@ -752,6 +756,9 @@ dll_crt0_1 ()
longjmp (fork_info->jmp, fork_info->cygpid);
}
+ if (!CYGWIN_VERSION_CHECK_FOR_S_IEXEC)
+ _check_for_executable = TRUE;
+
#ifdef DEBUGGING
{
extern void fork_init ();
@@ -808,7 +815,7 @@ dll_crt0_1 ()
if (user_data->premain[0])
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. */
__progname = __argv[0];
@@ -832,7 +839,7 @@ dll_crt0_1 ()
/* Execute any specified "premain" functions */
if (user_data->premain[PREMAIN_LEN / 2])
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);
diff --git a/winsup/cygwin/debug.h b/winsup/cygwin/debug.h
index 2f06286c7..02289eeb5 100644
--- a/winsup/cygwin/debug.h
+++ b/winsup/cygwin/debug.h
@@ -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);
int __stdcall lpfu (const char *, int, DWORD timeout);
void __stdcall cygbench (const char *s);
+extern int pinger;
#endif /*DEBUGGING*/
#endif /*_DEBUG_H_*/
diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc
index aa4092b95..3c10dfa73 100644
--- a/winsup/cygwin/dir.cc
+++ b/winsup/cygwin/dir.cc
@@ -22,6 +22,7 @@ details. */
#include "pinfo.h"
#include "cygerrno.h"
#include "fhandler.h"
+#include "perprocess.h"
#include "path.h"
#include "security.h"
#include "cygheap.h"
diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc
index 73c44f12d..f553ef877 100644
--- a/winsup/cygwin/dlfcn.cc
+++ b/winsup/cygwin/dlfcn.cc
@@ -14,9 +14,9 @@ details. */
#include <unistd.h>
#include <ctype.h>
#include "fhandler.h"
+#include "perprocess.h"
#include "path.h"
#include "thread.h"
-#include "perprocess.h"
#include "dlfcn.h"
#include "dll_init.h"
@@ -166,19 +166,15 @@ dlopen (const char *name, int)
{
SetResourceLock(LOCK_DLL_LIST,READ_LOCK|WRITE_LOCK," dlopen");
- void *ret = 0;
+ void *ret;
if (!name)
- {
- /* handle for the current module */
- ret = (void *) GetModuleHandle (NULL);
- }
+ ret = (void *) GetModuleHandle (NULL); /* handle for the current module */
else
{
/* handle for the named library */
const char *fullpath = get_full_path_of_dll (name);
- if (fullpath)
- ret = (void *) LoadLibrary (fullpath);
+ ret = fullpath ? (void *) LoadLibrary (fullpath) : NULL;
}
if (!ret)
diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
index 1d0b9cb9a..f20effcc4 100644
--- a/winsup/cygwin/dtable.cc
+++ b/winsup/cygwin/dtable.cc
@@ -26,6 +26,7 @@ details. */
#include "pinfo.h"
#include "cygheap.h"
#include "cygerrno.h"
+#include "perprocess.h"
#include "fhandler.h"
#include "path.h"
#include "dtable.h"
diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc
index df4c60fc8..77cf8da8d 100644
--- a/winsup/cygwin/environ.cc
+++ b/winsup/cygwin/environ.cc
@@ -18,16 +18,16 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
+#include "perprocess.h"
#include "fhandler.h"
#include "path.h"
#include "cygerrno.h"
#include "cygheap.h"
#include "registry.h"
#include "environ.h"
-#include "perprocess.h"
extern BOOL allow_glob;
-extern BOOL ignore_case_with_glob;
+extern bool ignore_case_with_glob;
extern BOOL allow_ntea;
extern BOOL allow_smbntsec;
extern BOOL allow_winsymlinks;
diff --git a/winsup/cygwin/exec.cc b/winsup/cygwin/exec.cc
index 6438d16e2..e7131ccde 100644
--- a/winsup/cygwin/exec.cc
+++ b/winsup/cygwin/exec.cc
@@ -13,6 +13,7 @@ details. */
#include <stdlib.h>
#include <errno.h>
#include <process.h>
+#include "perprocess.h"
#include "fhandler.h"
#include "path.h"
#include "sync.h"
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 40aa50849..82fa034cd 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -17,11 +17,11 @@ details. */
#include <sys/cygwin.h>
#include <signal.h>
#include "cygerrno.h"
+#include "perprocess.h"
#include "fhandler.h"
#include "path.h"
#include "shared_info.h"
#include "host_dependent.h"
-#include "perprocess.h"
#include "security.h"
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 ();
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 ())
{
@@ -1264,9 +1261,9 @@ fhandler_disk_file::open (path_conv& real_path, int flags, mode_t mode)
extern BOOL allow_ntea;
- if (!real_path.isexec () && !allow_ntea
- && (!allow_ntsec || !real_path.has_acls ())
- && GetFileType (get_handle ()) == FILE_TYPE_DISK)
+ if (real_path.isdisk ()
+ && (real_path.exec_state () == dont_know_if_executable)
+ && !allow_ntea && (!allow_ntsec || !real_path.has_acls ()))
{
DWORD done;
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);
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 ());
out:
@@ -1457,21 +1454,6 @@ fhandler_disk_file::lock (int cmd, struct flock *fl)
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 */
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 73aa294a6..3196f2114 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -130,6 +130,14 @@ enum bg_check_types
bg_signalled = 2
};
+enum executable_states
+{
+ is_executable,
+ not_executable,
+ dont_care_if_executable,
+ dont_know_if_executable
+};
+
class fhandler_base
{
private:
@@ -219,7 +227,10 @@ public:
void set_socket_p () { FHSETF (LOCAL); }
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); }
int get_append_p () { return FHISSETF (APPEND); }
@@ -477,9 +488,6 @@ private:
class fhandler_disk_file: public fhandler_base
{
-private:
- int check_execable_p (const char *path);
-
public:
fhandler_disk_file (const char *name);
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index 7ef123784..6e8c76c1c 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -178,8 +178,7 @@ fhandler_console::read (void *pv, size_t buflen)
case WAIT_OBJECT_0:
break;
case WAIT_OBJECT_0 + 1:
- set_sig_errno (EINTR);
- return -1;
+ goto sig_exit;
default:
__seterrno ();
return -1;
@@ -358,8 +357,14 @@ fhandler_console::read (void *pv, size_t buflen)
continue;
}
- if (toadd && line_edit (toadd, nread))
- break;
+ if (toadd)
+ {
+ int res = line_edit (toadd, nread);
+ if (res < 0)
+ goto sig_exit;
+ else if (res)
+ break;
+ }
#undef ich
}
@@ -374,6 +379,10 @@ fhandler_console::read (void *pv, size_t buflen)
#undef buf
return copied_chars;
+
+ sig_exit:
+ set_sig_errno (EINTR);
+ return -1;
}
void
diff --git a/winsup/cygwin/fhandler_raw.cc b/winsup/cygwin/fhandler_raw.cc
index d8ecf61ea..f307fb514 100644
--- a/winsup/cygwin/fhandler_raw.cc
+++ b/winsup/cygwin/fhandler_raw.cc
@@ -18,6 +18,7 @@
#include <sys/mtio.h>
#include "cygheap.h"
#include "cygerrno.h"
+#include "perprocess.h"
#include "fhandler.h"
#include "path.h"
diff --git a/winsup/cygwin/fhandler_tape.cc b/winsup/cygwin/fhandler_tape.cc
index d1c2c8572..57d782a4c 100644
--- a/winsup/cygwin/fhandler_tape.cc
+++ b/winsup/cygwin/fhandler_tape.cc
@@ -18,6 +18,7 @@ details. */
#include <sys/mtio.h>
#include "cygheap.h"
#include "cygerrno.h"
+#include "perprocess.h"
#include "fhandler.h"
#include "path.h"
diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc
index 1d0491379..046199903 100644
--- a/winsup/cygwin/fhandler_termios.cc
+++ b/winsup/cygwin/fhandler_termios.cc
@@ -165,6 +165,7 @@ fhandler_termios::line_edit (const char *rptr, int nread, int always_accept)
{
char c;
int input_done = 0;
+ bool sawsig = FALSE;
int iscanon = tc->ti.c_lflag & ICANON;
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);
kill_pgrp (tc->getpgid (), sig);
tc->ti.c_lflag &= ~FLUSHO;
+ sawsig = 1;
goto restart_output;
}
not_a_sig:
@@ -296,6 +298,11 @@ fhandler_termios::line_edit (const char *rptr, int nread, int always_accept)
if (!iscanon || always_accept)
set_input_done (ralen > 0);
+ if (sawsig)
+ {
+ // tc->write_error = EINTR;
+ input_done = -1;
+ }
if (input_done)
(void) accept_input ();
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index c3165285e..909264dc9 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -194,7 +194,7 @@ process_input (void *)
{
int nraw = tty_master->console->read ((void *) rawbuf,
(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
fhandler_pty_master::write (const void *ptr, size_t len)
{
- line_edit ((char *) ptr, len);
+ (void) line_edit ((char *) ptr, len);
return len;
}
diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h
index 1095aac3b..60ffe1cb4 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -79,7 +79,9 @@ details. */
(CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) <= \
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
non-backward-compatible interface changes to the API. Now we
use an API major/minor number for this purpose. */
@@ -127,10 +129,11 @@ details. */
34: Separated out mount table
35: Export drand48, erand48, jrand48, lcong48, lrand48,
mrand48, nrand48, seed48, and srand48.
+ 36: Added _cygwin_S_IEXEC, et al
*/
#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
shared memory regions. It is incremented when incompatible
diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h
index 2b3370cfa..daab7795d 100644
--- a/winsup/cygwin/include/sys/cygwin.h
+++ b/winsup/cygwin/include/sys/cygwin.h
@@ -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 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
{
const char *name;
@@ -149,7 +144,7 @@ struct per_process
void *(*calloc)(size_t, size_t);
/* 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.
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 *heaptop; /* current top of heap */
- DWORD unused1; /* unused */
+ DWORD unused1;
/* Non-zero means the task was forked. The value is the pid.
Inherited from parent. */
@@ -190,6 +185,11 @@ struct per_process
};
#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);
/* included if <windows.h> is included */
diff --git a/winsup/cygwin/include/sys/file.h b/winsup/cygwin/include/sys/file.h
index 79f5f65f5..dacf33429 100644
--- a/winsup/cygwin/include/sys/file.h
+++ b/winsup/cygwin/include/sys/file.h
@@ -24,7 +24,13 @@
#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 R_OK 4 /* is it readable by caller */
diff --git a/winsup/cygwin/lib/_cygwin_S_IEXEC.cc b/winsup/cygwin/lib/_cygwin_S_IEXEC.cc
new file mode 100644
index 000000000..eeb12f4a2
--- /dev/null
+++ b/winsup/cygwin/lib/_cygwin_S_IEXEC.cc
@@ -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__;
diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc
index fcada7b7f..837f3b9ff 100644
--- a/winsup/cygwin/net.cc
+++ b/winsup/cygwin/net.cc
@@ -25,6 +25,7 @@ details. */
#include <winsock2.h>
#include "cygheap.h"
#include "cygerrno.h"
+#include "perprocess.h"
#include "fhandler.h"
#include "path.h"
#include "dtable.h"
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 5355f1982..cf026fe82 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -64,6 +64,7 @@ details. */
#include <sys/cygwin.h>
#include <cygwin/version.h>
#include "cygerrno.h"
+#include "perprocess.h"
#include "fhandler.h"
#include "path.h"
#include "sync.h"
@@ -412,6 +413,7 @@ out:
}
else
{
+ set_isdisk ();
debug_printf ("GetVolumeInformation(%s) = OK, full_path(%s), set_has_acls(%d)",
tmp_buf, full_path, volflags & FS_PERSISTENT_ACLS);
if (!allow_smbntsec
@@ -428,6 +430,16 @@ out:
if (saw_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 (!error)
{
@@ -565,7 +577,7 @@ get_device_number (const char *name, int &unit, BOOL from_conv)
else if (deveq ("tcp") || deveq ("udp") || deveq ("streamsocket")
|| deveq ("dgsocket"))
devn = FH_SOCKET;
- else if (! from_conv)
+ else if (!from_conv)
devn = get_raw_device_number (name - 5,
path_conv (name - 5,
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);
return 0;
}
-
/* 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)
{
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;
/* SRC_PATH is in the mount table. */
@@ -1387,7 +1398,7 @@ mount_info::read_mounts (reg_key& r)
posix_path_size = MAX_PATH;
/* 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
- over 256 but is under MAX_PATH! */
+ over 256 but is under MAX_PATH. */
res = RegEnumKeyEx (key, i, posix_path, &posix_path_size, 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++;
}
- return 0; /* Success! */
+ return 0; /* Success */
err:
__seterrno_from_win_error (res);
return -1;
@@ -1542,7 +1553,7 @@ mount_info::del_reg_mount (const char * posix_path, unsigned flags)
return -1;
}
- return 0; /* Success! */
+ return 0; /* Success */
}
/* 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
`silent' here; it's a magic internal thing. */
- if (! (flags & MOUNT_BINARY))
+ if (!(flags & MOUNT_BINARY))
strcpy (mount_table->mnt_opts, (char *) "textmode");
else
strcpy (mount_table->mnt_opts, (char *) "binmode");
@@ -2333,36 +2344,6 @@ done:
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
check_sysfile (const char *path, DWORD fileattr, HANDLE h,
char *contents, int *error, unsigned *pflags)
@@ -2371,7 +2352,7 @@ check_sysfile (const char *path, DWORD fileattr, HANDLE h,
DWORD got;
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");
*error = EIO;
@@ -2408,12 +2389,107 @@ check_sysfile (const char *path, DWORD fileattr, HANDLE h,
else
{
/* 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;
- }
+ else
+ *pflags |= PATH_NOTEXEC;
+ }
+ syscall_printf ("%d = symlink.check_sysfile (%s, %s) (%p)",
+ res, path, contents, *pflags);
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.
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. */
int
-symlink_info::check (const char *in_path, const suffix_info *suffixes)
+symlink_info::check (const char *path, const suffix_info *suffixes)
{
HANDLE h;
int res = 0;
- char extbuf[MAX_PATH + 5];
- 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');
- }
+ suffix_scan suffix;
is_symlink = TRUE;
+ known_suffix = suffix.has (path, suffixes, &ext_here);
- error = 0;
- do
+ while (suffix.next ())
{
- if (!next_suffix (ext_here, suffixes))
- break;
error = 0;
- fileattr = GetFileAttributesA (path);
+ fileattr = GetFileAttributesA (suffix.path);
if (fileattr == (DWORD) -1)
{
/* The GetFileAttributesA call can fail for reasons that don't
matter, so we just return 0. For example, getting the
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);
continue;
}
@@ -2479,7 +2537,7 @@ restart:
goto file_not_symlink;
/* Windows shortcuts are treated as symlinks. */
- if (!strcasecmp (path + strlen (path) - 4, ".lnk"))
+ if (suffix.lnk_match ())
sym_check = 1;
/* The old Cygwin method creating symlinks: */
@@ -2493,27 +2551,27 @@ restart:
/* 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);
res = -1;
if (h == INVALID_HANDLE_VALUE)
goto file_not_symlink;
else if (sym_check == 1
- && !(res = check_shortcut (path, fileattr, h,
+ && !(res = check_shortcut (suffix.path, fileattr, h,
contents, &error, &pflags)))
{
CloseHandle (h);
/* If searching for `foo' and then finding a `foo.lnk' which is
no shortcut, return the same as if file not found. */
- if (check_lnk)
+ if (suffix.lnk_match ())
{
fileattr = (DWORD)-1;
- goto out;
+ break;
}
goto file_not_symlink;
}
else if (sym_check == 2 &&
- !(res = check_sysfile (path, fileattr, h,
+ !(res = check_sysfile (suffix.path, fileattr, h,
contents, &error, &pflags)))
{
CloseHandle (h);
@@ -2521,14 +2579,7 @@ restart:
}
CloseHandle (h);
- goto out;
- }
- while (suffixes);
- if (!check_lnk)
- {
- suffixes = lnk_suffixes;
- check_lnk = TRUE;
- goto restart;
+ break;
}
goto out;
@@ -2539,8 +2590,7 @@ file_not_symlink:
out:
syscall_printf ("%d = symlink.check (%s, %p) (%p)",
- res, path, contents, pflags);
-
+ res, suffix.path, contents, pflags);
return res;
}
@@ -2846,7 +2896,7 @@ extern "C"
int
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;
}
@@ -2946,7 +2996,7 @@ cygwin_split_path (const char *path, char *dir, char *file)
*dir++ = *path++;
*dir++ = *path++;
*dir++ = '/';
- if (! *path)
+ if (!*path)
{
*dir = 0;
*file = 0;
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index 6d0a195e3..40b8eec5b 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -37,6 +37,8 @@ enum path_types
PATH_EXEC = MOUNT_EXEC,
PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC,
PATH_ALL_EXEC = PATH_CYGWIN_EXEC | PATH_EXEC,
+ PATH_ISDISK = 0x04000000,
+ PATH_NOTEXEC = 0x08000000,
PATH_HAS_SYMLINKS = 0x10000000,
PATH_HASBUGGYOPEN = 0x20000000,
PATH_SOCKET = 0x40000000,
@@ -50,6 +52,7 @@ class path_conv
unsigned path_flags;
+ int isdisk () {return path_flags & PATH_ISDISK;}
int has_acls () {return path_flags & PATH_HASACLS;}
int has_symlinks () {return path_flags & PATH_HAS_SYMLINKS;}
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 issymlink () {return path_flags & PATH_SYMLINK;}
int issocket () {return path_flags & PATH_SOCKET;}
- int isexec () {return path_flags & PATH_ALL_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_symlink () {path_flags |= PATH_SYMLINK;}
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_buggy_open (int x = 1) {path_flags |= x ? PATH_HASBUGGYOPEN : PATH_NOTHING;}
diff --git a/winsup/cygwin/perprocess.h b/winsup/cygwin/perprocess.h
index a649ece74..c0a555983 100644
--- a/winsup/cygwin/perprocess.h
+++ b/winsup/cygwin/perprocess.h
@@ -1,6 +1,6 @@
/* per_process.h: main Cygwin header file.
- Copyright 2000 Red Hat, Inc.
+ Copyright 2000, 2001 Red Hat, Inc.
This file is part of Cygwin.
@@ -10,11 +10,19 @@ details. */
#include <sys/cygwin.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* 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)
/* We use the following to test that sizeof hasn't changed. When adding
or deleting members, insert fillers or use the reserved entries.
Do not change this value. */
#define SIZEOF_PER_PROCESS (42 * 4)
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc
index bef29d2cf..a92236549 100644
--- a/winsup/cygwin/security.cc
+++ b/winsup/cygwin/security.cc
@@ -25,6 +25,7 @@ details. */
#include <wingdi.h>
#include <winuser.h>
#include "cygerrno.h"
+#include "perprocess.h"
#include "fhandler.h"
#include "path.h"
#include "dtable.h"
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 75c3a8d14..e9d3659b2 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -21,6 +21,7 @@ details. */
#include <ctype.h>
#include "cygerrno.h"
#include <sys/cygwin.h>
+#include "perprocess.h"
#include "fhandler.h"
#include "path.h"
#include "dtable.h"
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index eedf59ace..2497d8bf8 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -26,6 +26,7 @@ details. */
#include <cygwin/version.h>
#include <sys/cygwin.h>
#include "cygerrno.h"
+#include "perprocess.h"
#include "fhandler.h"
#include "path.h"
#include "dtable.h"
@@ -34,7 +35,6 @@ details. */
#include "pinfo.h"
#include <unistd.h>
#include "shared_info.h"
-#include "perprocess.h"
#include "security.h"
#include "cygheap.h"
@@ -1071,7 +1071,7 @@ stat_worker (const char *caller, const char *name, struct stat *buf,
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 ());
dtype = GetDriveType (rootdir (root));
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index a7bc08687..1578cdfca 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -14,8 +14,6 @@ details. */
#define __INSIDE_CYGWIN__
-#ifdef __cplusplus
-
#define alloca __builtin_alloca
#define strlen __builtin_strlen
#define strcmp __builtin_strcmp
@@ -26,6 +24,8 @@ details. */
# define memset __builtin_memset
#endif
+#ifdef __cplusplus
+
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ >= 199900L
#define NEW_MACRO_VARARGS
#endif