OSDN Git Service

* dlopen.c (dlopen): Return NULL when name is NULL (suggested by
authorcgf <cgf>
Mon, 5 Mar 2001 06:28:23 +0000 (06:28 +0000)
committercgf <cgf>
Mon, 5 Mar 2001 06:28:23 +0000 (06:28 +0000)
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.

28 files changed:
winsup/cygwin/ChangeLog
winsup/cygwin/cygwin.din
winsup/cygwin/dcrt0.cc
winsup/cygwin/debug.h
winsup/cygwin/dir.cc
winsup/cygwin/dlfcn.cc
winsup/cygwin/dtable.cc
winsup/cygwin/environ.cc
winsup/cygwin/exec.cc
winsup/cygwin/fhandler.cc
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_console.cc
winsup/cygwin/fhandler_raw.cc
winsup/cygwin/fhandler_tape.cc
winsup/cygwin/fhandler_termios.cc
winsup/cygwin/fhandler_tty.cc
winsup/cygwin/include/cygwin/version.h
winsup/cygwin/include/sys/cygwin.h
winsup/cygwin/include/sys/file.h
winsup/cygwin/lib/_cygwin_S_IEXEC.cc [new file with mode: 0644]
winsup/cygwin/net.cc
winsup/cygwin/path.cc
winsup/cygwin/path.h
winsup/cygwin/perprocess.h
winsup/cygwin/security.cc
winsup/cygwin/spawn.cc
winsup/cygwin/syscalls.cc
winsup/cygwin/winsup.h

index 35b7fa5..38ea288 100644 (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>
 
        * fhandler.h (class fhandler_tty_common): New mutex and event to
index 184c10b..fb6364c 100644 (file)
@@ -8,6 +8,7 @@ __infinity
 __main
 __srget
 __swbuf
+_check_for_executable DATA
 ; __vc__10pinfo_listi
 @ALLOCA@
 cygwin_stackdump
index 7206fa1..a76e9e5 100644 (file)
@@ -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);
 
index 2f06286..02289ee 100644 (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);
 int __stdcall lpfu (const char *, int, DWORD timeout);
 void __stdcall cygbench (const char *s);
+extern int pinger;
 
 #endif /*DEBUGGING*/
 #endif /*_DEBUG_H_*/
index aa4092b..3c10dfa 100644 (file)
@@ -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"
index 73c44f1..f553ef8 100644 (file)
@@ -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)
index 1d0b9cb..f20effc 100644 (file)
@@ -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"
index df4c60f..77cf8da 100644 (file)
@@ -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;
index 6438d16..e7131cc 100644 (file)
@@ -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"
index 40aa508..82fa034 100644 (file)
@@ -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 */
 
index 73aa294..3196f21 100644 (file)
@@ -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);
 
index 7ef1237..6e8c76c 100644 (file)
@@ -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
index d8ecf61..f307fb5 100644 (file)
@@ -18,6 +18,7 @@
 #include <sys/mtio.h>
 #include "cygheap.h"
 #include "cygerrno.h"
+#include "perprocess.h"
 #include "fhandler.h"
 #include "path.h"
 
index d1c2c85..57d782a 100644 (file)
@@ -18,6 +18,7 @@ details. */
 #include <sys/mtio.h>
 #include "cygheap.h"
 #include "cygerrno.h"
+#include "perprocess.h"
 #include "fhandler.h"
 #include "path.h"
 
index 1d04913..0461999 100644 (file)
@@ -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 ();
 
index c316528..909264d 100644 (file)
@@ -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;
 }
 
index 1095aac..60ffe1c 100644 (file)
@@ -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
index 2b3370c..daab779 100644 (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 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 */
index 79f5f65..dacf334 100644 (file)
 
 
 #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 (file)
index 0000000..eeb12f4
--- /dev/null
@@ -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__;
index fcada7b..837f3b9 100644 (file)
@@ -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"
index 5355f19..cf026fe 100644 (file)
@@ -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;
 }
-\f
 
 /* 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;
index 6d0a195..40b8eec 100644 (file)
@@ -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;}
 
index a649ece..c0a5559 100644 (file)
@@ -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
index bef29d2..a922365 100644 (file)
@@ -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"
index 75c3a8d..e9d3659 100644 (file)
@@ -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"
index eedf59a..2497d8b 100644 (file)
@@ -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));
index a7bc086..1578cdf 100644 (file)
@@ -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