OSDN Git Service

Throughout, change 'tty_attached' to 'real_tty_attached', for clarity.
authorcgf <cgf>
Sat, 28 Apr 2001 23:48:27 +0000 (23:48 +0000)
committercgf <cgf>
Sat, 28 Apr 2001 23:48:27 +0000 (23:48 +0000)
Throughout, change 'OutputStopped' to 'output_stopped', for consistency.
* dtable.cc (stdio_init): Set controlling tty if not set by stdio opens.
* exceptions.cc (ctrl_c_handler): Avoid special pgid checking if no tty is
associated with the process.
(Suggested by Tim Baker <dbaker@direct.ca>)
* external.cc (fillout_pinfo): Return actual tty number for ctty.
* fhandler_console.cc (get_tty_stuff): Set ctty when shared memory is
allocated.  Accept flags input from open().
(set_console_ctty): New function.
(fhandler_console::open): Pass flags to get_tty_stuff and rely on this function
to set the ctty, if appropriate.
* fhandler_termios.cc (fhandler_termios::set_ctty): Move to tty_min class.
* fhandler_tty.cc (fhandler_tty_slave::open): Use tc field to access
set_ctty().
* tty.h (TTY_CONSOLE): Move to include/sys/cygwin.h.
(tty_min): Add set_ctty class here.
* include/sys/cygwin.h (TTY_CONSOLE): New home here.
* path.cc (symlink_info): Make contents an actual buffer.  Pass more flags to
case_check.
(path_conv::check): Reorganize to do parsing based on posix path rather than
native path.
(symlink_info::check): Expect posix path as input.  Translate to native path
here.  Accept path_conv flags.  Stop parsing if not a symlink regardless of
whether previous path was a symlink.

14 files changed:
winsup/cygwin/ChangeLog
winsup/cygwin/dcrt0.cc
winsup/cygwin/dtable.cc
winsup/cygwin/exceptions.cc
winsup/cygwin/external.cc
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_console.cc
winsup/cygwin/fhandler_termios.cc
winsup/cygwin/fhandler_tty.cc
winsup/cygwin/include/sys/cygwin.h
winsup/cygwin/path.cc
winsup/cygwin/syscalls.cc
winsup/cygwin/tty.cc
winsup/cygwin/tty.h

index 81ae2a8..ce9b2d0 100644 (file)
@@ -1,3 +1,35 @@
+Sat Apr 28 19:36:13 2001  Christopher Faylor <cgf@cygnus.com>
+
+       Throughout, change 'tty_attached' to 'real_tty_attached', for clarity.
+       Throughout, change 'OutputStopped' to 'output_stopped', for
+       consistency.
+       * dtable.cc (stdio_init): Set controlling tty if not set by stdio
+       opens.
+       * exceptions.cc (ctrl_c_handler): Avoid special pgid checking if no tty
+       is associated with the process.
+       (Suggested by Tim Baker <dbaker@direct.ca>)
+       * external.cc (fillout_pinfo): Return actual tty number for ctty.
+       * fhandler_console.cc (get_tty_stuff): Set ctty when shared memory is
+       allocated.  Accept flags input from open().
+       (set_console_ctty): New function.
+       (fhandler_console::open): Pass flags to get_tty_stuff and rely on this
+       function to set the ctty, if appropriate.
+       * fhandler_termios.cc (fhandler_termios::set_ctty): Move to tty_min
+       class.
+       * fhandler_tty.cc (fhandler_tty_slave::open): Use tc field to access
+       set_ctty().
+       * tty.h (TTY_CONSOLE): Move to include/sys/cygwin.h.
+       (tty_min): Add set_ctty class here.
+       * include/sys/cygwin.h (TTY_CONSOLE): New home here.
+
+       * path.cc (symlink_info): Make contents an actual buffer.  Pass more
+       flags to case_check.
+       (path_conv::check): Reorganize to do parsing based on posix path rather
+       than native path.
+       (symlink_info::check): Expect posix path as input.  Translate to native
+       path here.  Accept path_conv flags.  Stop parsing if not a symlink
+       regardless of whether previous path was a symlink.
+
 2001-04-27  Kazuhiro Fujieda  <fujieda@jaist.ac.jp>
 
        * thread.cc (thread_init_wrapper): Use _REENT_INIT to initialize the
index a56f628..e25c311 100644 (file)
@@ -1034,7 +1034,7 @@ do_exit (int status)
        }
 
       /* Kill the foreground process group on session leader exit */
-      if (getpgrp () > 0 && myself->pid == myself->sid && tty_attached (myself))
+      if (getpgrp () > 0 && myself->pid == myself->sid && real_tty_attached (myself))
        {
          tty *tp = cygwin_shared->tty[myself->ctty];
          sigproc_printf ("%d == sid %d, send SIGHUP to children",
index 88c3adc..19a589b 100644 (file)
@@ -87,6 +87,7 @@ dtable::extend (int howmuch)
 void
 stdio_init (void)
 {
+  extern void set_console_ctty ();
   /* Set these before trying to output anything from strace.
      Also, always set them even if we're to pick up our parent's fds
      in case they're missed.  */
@@ -117,6 +118,10 @@ stdio_init (void)
 
       cygheap->fdtab.init_std_file_from_handle (1, out, GENERIC_WRITE, "{stdout}");
       cygheap->fdtab.init_std_file_from_handle (2, err, GENERIC_WRITE, "{stderr}");
+      /* Assign the console as the controlling tty for this process if we actually
+        have a console and no other controlling tty has been assigned. */
+      if (myself->ctty < 0 && GetConsoleCP () > 0)
+       set_console_ctty ();
     }
 }
 
index 8cd60a8..6e80b6b 100644 (file)
@@ -890,7 +890,7 @@ setup_handler (int sig, void *handler, struct sigaction& siga)
 #error "Need to supply machine dependent setup_handler"
 #endif
 
-/* Keyboard interrupt handler.  */
+/* CGF Keyboard interrupt handler.  */
 static BOOL WINAPI
 ctrl_c_handler (DWORD type)
 {
@@ -908,7 +908,7 @@ ctrl_c_handler (DWORD type)
   tty_min *t = cygwin_shared->tty.get_tty (myself->ctty);
   /* Ignore this if we're not the process group lead since it should be handled
      *by* the process group leader. */
-  if (t->getpgid () != myself->pid ||
+  if (!t->getpgid () || t->getpgid () != myself->pid ||
       (GetTickCount () - t->last_ctrl_c) < MIN_CTRL_C_SLOP)
     return TRUE;
   else
index ffcf915..9f46835 100644 (file)
@@ -57,7 +57,7 @@ fillout_pinfo (pid_t pid, int winpid)
        }
       else if (nextpid || p->pid == pid || (winpid && thispid == (DWORD) pid))
        {
-         ep.ctty = tty_attached (p) ? p->ctty : -1;
+         ep.ctty = p->ctty;
          ep.pid = p->pid;
          ep.ppid = p->ppid;
          ep.hProcess = p->hProcess;
index ac000ba..73aadd6 100644 (file)
@@ -595,7 +595,6 @@ public:
   virtual int is_tty () { return 1; }
   int tcgetpgrp ();
   int tcsetpgrp (int pid);
-  void set_ctty (int ttynum, int flags);
   bg_check_types bg_check (int sig);
   virtual DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms) {return 1;}
   virtual void __release_output_mutex (const char *fn, int ln) {}
index 7a340fe..01d90fe 100644 (file)
@@ -97,10 +97,10 @@ static tty_min NO_COPY *shared_console_info = NULL;
 
 /* Allocate and initialize the shared record for the current console.
    Returns a pointer to shared_console_info. */
-static __inline tty_min *
-get_tty_stuff (int force = 0)
+static tty_min *
+get_tty_stuff (int flags = 0)
 {
-  if (shared_console_info && !force)
+  if (shared_console_info)
     return shared_console_info;
 
   shared_console_info = (tty_min *) open_shared (NULL, cygheap->console_h,
@@ -109,9 +109,16 @@ get_tty_stuff (int force = 0)
   ProtectHandle (cygheap->console_h);
   shared_console_info->setntty (TTY_CONSOLE);
   shared_console_info->setsid (myself->sid);
+  shared_console_info->set_ctty (TTY_CONSOLE, flags);
   return shared_console_info;
 }
 
+void
+set_console_ctty ()
+{
+  (void) get_tty_stuff ();
+}
+
 /* Return the tty structure associated with a given tty number.  If the
    tty number is < 0, just return a dummy record. */
 tty_min *
@@ -517,7 +524,7 @@ fhandler_console::open (const char *, int flags, mode_t)
 {
   HANDLE h;
 
-  tcinit (get_tty_stuff ());
+  tcinit (get_tty_stuff (flags));
 
   set_io_handle (INVALID_HANDLE_VALUE);
   set_output_handle (INVALID_HANDLE_VALUE);
@@ -561,7 +568,6 @@ fhandler_console::open (const char *, int flags, mode_t)
     }
 
   TTYCLEARF (RSTCONS);
-  set_ctty (TTY_CONSOLE, flags);
   set_open_status ();
   debug_printf ("opened conin$ %p, conout$ %p",
                get_io_handle (), get_output_handle ());
index 6d4e4e9..058410d 100644 (file)
@@ -82,28 +82,28 @@ fhandler_termios::tcgetpgrp ()
 }
 
 void
-fhandler_termios::set_ctty (int ttynum, int flags)
+tty_min::set_ctty (int ttynum, int flags)
 {
   if ((myself->ctty < 0 || myself->ctty == ttynum) && !(flags & O_NOCTTY))
     {
       myself->ctty = ttynum;
       syscall_printf ("attached tty%d sid %d, pid %d, tty->pgid %d, tty->sid %d",
-                     ttynum, myself->sid, myself->pid, tc->pgid, tc->getsid ());
+                     ttynum, myself->sid, myself->pid, pgid, getsid ());
 
-      pinfo p (tc->getsid ());
+      pinfo p (getsid ());
       if (myself->sid == myself->pid &&
          (p == myself || !proc_exists (p)))
        {
          paranoid_printf ("resetting tty%d sid.  Was %d, now %d.  pgid was %d, now %d.",
-                          ttynum, tc->getsid(), myself->sid, tc->getpgid (), myself->pgid);
+                          ttynum, getsid(), myself->sid, getpgid (), myself->pgid);
          /* We are the session leader */
-         tc->setsid (myself->sid);
-         tc->setpgid (myself->pgid);
+         setsid (myself->sid);
+         setpgid (myself->pgid);
        }
       else
-       myself->sid = tc->getsid ();
-      if (tc->getpgid () == 0)
-       tc->setpgid (myself->pgid);
+       myself->sid = getsid ();
+      if (getpgid () == 0)
+       setpgid (myself->pgid);
     }
 }
 
@@ -220,9 +220,9 @@ fhandler_termios::line_edit (const char *rptr, int nread, int always_accept)
        {
          if (c == tc->ti.c_cc[VSTOP])
            {
-             if (!tc->OutputStopped)
+             if (!tc->output_stopped)
                {
-                 tc->OutputStopped = 1;
+                 tc->output_stopped = 1;
                  acquire_output_mutex (INFINITE);
                }
              continue;
@@ -230,11 +230,11 @@ fhandler_termios::line_edit (const char *rptr, int nread, int always_accept)
          else if (c == tc->ti.c_cc[VSTART])
            {
     restart_output:
-             tc->OutputStopped = 0;
+             tc->output_stopped = 0;
              release_output_mutex ();
              continue;
            }
-         else if ((tc->ti.c_iflag & IXANY) && tc->OutputStopped)
+         else if ((tc->ti.c_iflag & IXANY) && tc->output_stopped)
            goto restart_output;
        }
       if (tc->ti.c_lflag & IEXTEN && c == tc->ti.c_cc[VDISCARD])
index acb10a9..1a6ffb4 100644 (file)
@@ -254,7 +254,7 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
     {
       /* We need to return a left over \n character, resulting from
         \r\n conversion.  Note that we already checked for FLUSHO and
-        OutputStopped at the time that we read the character, so we
+        output_stopped at the time that we read the character, so we
         don't check again here.  */
       buf[0] = '\n';
       need_nl = 0;
@@ -464,7 +464,7 @@ fhandler_tty_slave::open (const char *, int flags, mode_t)
   tcinit (cygwin_shared->tty[ttynum]);
 
   attach_tty (ttynum);
-  set_ctty (ttynum, flags);
+  tc->set_ctty (ttynum, flags);
 
   set_flags (flags);
   /* Create synchronisation events */
index bca09f7..6b0dc91 100644 (file)
@@ -67,7 +67,7 @@ typedef enum
     CW_GET_CYGDRIVE_INFO
   } cygwin_getinfo_types;
 
-#define CW_NEXTPID 0x80000000  // or with pid to get next one
+#define CW_NEXTPID     0x80000000      // or with pid to get next one
 
 /* Flags associated with process_state */
 enum
@@ -208,6 +208,8 @@ extern int cygwin_attach_handle_to_fd (char *, int, HANDLE, mode_t, DWORD);
 
 #include <sys/resource.h>
 
+#define TTY_CONSOLE    0x40000000
+
 struct external_pinfo
   {
   pid_t pid;
index c218a16..a0e8640 100644 (file)
@@ -93,19 +93,18 @@ static int path_prefix_p_ (const char *path1, const char *path2, int len1);
 
 struct symlink_info
 {
-  char buf[3 + MAX_PATH * 3];
+  char contents[MAX_PATH + 4];
   char *ext_here;
   int extn;
-  char *contents;
   unsigned pflags;
   DWORD fileattr;
   int is_symlink;
   bool ext_tacked_on;
   int error;
   BOOL case_clash;
-  symlink_info (): contents (buf + MAX_PATH + 1) {}
   int check (const char *path, const suffix_info *suffixes,
-            char *orig_path, BOOL sym_ignore);
+            char *orig_path, unsigned opt,
+            DWORD& devn, int& unit, unsigned& path_flags);
   BOOL case_check (const char *path, char *orig_path);
 };
 
@@ -178,6 +177,123 @@ pathmatch (const char *path1, const char *path2)
                                      : strcasematch (path1, path2);
 }
 
+/* Normalize a POSIX path.
+   \'s are converted to /'s in the process.
+   All duplicate /'s, except for 2 leading /'s, are deleted.
+   The result is 0 for success, or an errno error value.  */
+
+#define isslash(c) ((c) == '/')
+
+static int
+normalize_posix_path (const char *src, char *dst)
+{
+  const char *src_start = src;
+  char *dst_start = dst;
+
+  syscall_printf ("src %s", src);
+  if (isdrive (src) || strpbrk (src, "\\:"))
+    {
+      cygwin_conv_to_full_posix_path (src, dst);
+      return 0;
+    }
+  if (!isslash (src[0]))
+    {
+      if (!cygheap->cwd.get (dst))
+       return get_errno ();
+      dst = strchr (dst, '\0');
+      if (*src == '.')
+       {
+         if (dst == dst_start + 1 && *dst_start == '/')
+            --dst;
+         goto sawdot;
+       }
+      if (dst > dst_start && !isslash (dst[-1]))
+       *dst++ = '/';
+    }
+  /* Two leading /'s?  If so, preserve them.  */
+  else if (isslash (src[1]))
+    {
+      if (cygheap->root.length ())
+       {
+         debug_printf ("ENOENT = normalize_posix_path (%s)", src);
+         return ENOENT;
+       }
+      *dst++ = '/';
+      *dst++ = '/';
+      src += 2;
+      if (isslash (*src))
+       { /* Starts with three or more slashes - reset. */
+         dst = dst_start;
+         *dst++ = '/';
+         src = src_start + 1;
+       }
+    }
+  /* Exactly one leading slash. Absolute path. Check for chroot. */
+  else if (cygheap->root.length ())
+    {
+      strcpy (dst, cygheap->root.path ());
+      dst += cygheap->root.length ();
+    }
+  else
+    *dst = '\0';
+
+  while (*src)
+    {
+      /* Strip runs of /'s.  */
+      if (!isslash (*src))
+       *dst++ = *src++;
+      else
+       {
+         while (*++src)
+           {
+             if (isslash (*src))
+               continue;
+
+             if (*src != '.')
+               break;
+
+           sawdot:
+             if (src[1] != '.')
+               {
+                 if (!src[1])
+                   {
+                     if (dst == dst_start)
+                       *dst++ = '/';
+                     goto done;
+                   }
+                 if (!isslash (src[1]))
+                   break;
+               }
+             else if (src[2] && !isslash (src[2]))
+               break;
+             else
+               {
+                 if (!ischrootpath (dst_start) ||
+                     dst - dst_start != (int) cygheap->root.length ())
+                   while (dst > dst_start && !isslash (*--dst))
+                     continue;
+                 src++;
+               }
+           }
+
+         *dst++ = '/';
+       }
+       if ((dst - dst_start) >= MAX_PATH)
+         {
+           debug_printf ("ENAMETOOLONG = normalize_posix_path (%s)", src);
+           return ENAMETOOLONG;
+         }
+    }
+
+done:
+  *dst = '\0';
+  if (--dst > dst_start && isslash (*dst))
+    *dst = '\0';
+
+  debug_printf ("%s = normalize_posix_path (%s)", dst_start, src_start);
+  return 0;
+}
+
 inline void
 path_conv::add_ext_from_sym (symlink_info &sym)
 {
@@ -209,9 +325,8 @@ path_conv::check (const char *src, unsigned opt,
   /* This array is used when expanding symlinks.  It is MAX_PATH * 2
      in length so that we can hold the expanded symlink plus a
      trailer.  */
-  char path_buf[MAX_PATH];
-  char path_copy[MAX_PATH];
-  char tmp_buf[MAX_PATH];
+  char path_copy[MAX_PATH + 3];
+  char tmp_buf[2 * MAX_PATH + 3];
   symlink_info sym;
   bool need_directory = 0;
   bool saw_symlinks = 0;
@@ -227,8 +342,6 @@ path_conv::check (const char *src, unsigned opt,
     }
 #endif
 
-  char *rel_path, *full_path;
-
   int loop = 0;
   path_flags = 0;
   known_suffix = NULL;
@@ -241,11 +354,6 @@ path_conv::check (const char *src, unsigned opt,
   else if ((error = check_null_empty_path (src)))
     return;
 
-  if (opt & PC_FULL)
-    rel_path = path_buf, full_path = this->path;
-  else
-    rel_path = this->path, full_path = path_buf;
-
   /* This loop handles symlink expansion.  */
   for (;;)
     {
@@ -260,39 +368,14 @@ path_conv::check (const char *src, unsigned opt,
       else if ((p = strrchr (src, '\\')) &&
               (p[1] == '\0' || strcmp (p, "\\.") == 0))
        need_directory = 1;
-      /* Must look up path in mount table, etc.  */
-      error = mount_table->conv_to_win32_path (src, rel_path, full_path, devn,
-                                              unit, &path_flags);
-      MALLOC_CHECK;
+
+      error = normalize_posix_path (src, path_copy);
       if (error)
        return;
-      if (devn != FH_BAD)
-       {
-         fileattr = 0;
-         return;
-       }
 
-      /* Eat trailing slashes */
-      char *tail = strchr (full_path, '\0');
-      /* If path is only a drivename, Windows interprets it as
-        the current working directory on this drive instead of
-        the root dir which is what we want. So we need
-        the trailing backslash in this case. */
-      while (tail > full_path + 3 && (*--tail == '\\'))
-       *tail = '\0';
-      if (full_path[0] && full_path[1] == ':' && full_path[2] == '\0')
-       strcat (full_path, "\\");
-
-      if ((opt & PC_SYM_IGNORE) && pcheck_case == PCHECK_RELAXED)
-       {
-         fileattr = GetFileAttributesA (path);
-         goto out;
-       }
-
-      /* Make a copy of the path that we can munge up */
-      strcpy (path_copy, full_path);
-
-      tail = path_copy + 1 + (tail - full_path);   // Point to end of copy
+      char *tail = strchr (path_copy, '\0');   // Point to end of copy
+      char *path_end = tail;
+      tail[1] = '\0';
 
       /* Scan path_copy from right to left looking either for a symlink
         or an actual existing file.  If an existing file is found, just
@@ -306,6 +389,8 @@ path_conv::check (const char *src, unsigned opt,
       for (;;)
        {
          const suffix_info *suff;
+         char pathbuf[MAX_PATH];
+         char *full_path;
 
          /* Don't allow symlink.check to set anything in the path_conv
             class if we're working on an inner component of the path */
@@ -313,14 +398,17 @@ path_conv::check (const char *src, unsigned opt,
            {
              suff = NULL;
              sym.pflags = 0;
+             full_path = pathbuf;
            }
          else
            {
              suff = suffixes;
              sym.pflags = path_flags;
+             full_path = this->path;
            }
 
-         int len = sym.check (path_copy, suff, full_path, opt & PC_SYM_IGNORE);
+         int len = sym.check (path_copy, suff, full_path, opt,
+                              devn, unit, path_flags);
 
          if (sym.case_clash)
            {
@@ -391,10 +479,15 @@ path_conv::check (const char *src, unsigned opt,
 
            }
 
-         if (!(tail = strrchr (path_copy, '\\')) ||
-             (tail > path_copy && tail[-1] == ':'))
+         char *newtail = strrchr (path_copy, '/');
+         if (tail != path_end)
+           *tail = '/';
+
+         if (!newtail)
            goto out;   // all done
 
+         tail = newtail;
+
          /* Haven't found an existing pathname component yet.
             Pinch off the tail and try again. */
          *tail = '\0';
@@ -407,10 +500,10 @@ path_conv::check (const char *src, unsigned opt,
          error = ELOOP;   // Eep.
          return;
        }
+
       MALLOC_CHECK;
 
-      tail = full_path + (tail - path_copy);
-      int taillen = strlen (tail);
+      int taillen = strlen (tail + 1);
       int buflen = strlen (sym.contents);
       if (buflen + taillen > MAX_PATH)
          {
@@ -419,31 +512,33 @@ path_conv::check (const char *src, unsigned opt,
            return;
          }
 
-      /* Copy tail of full_path to discovered symlink. */
-      for (p = sym.contents + buflen; *tail; tail++)
-       *p++ = *tail == '\\' ? '/' : *tail;
+      if ((p = strrchr (path_copy, '/')) == NULL)
+       p = path_copy;
       *p = '\0';
 
-      /* If symlink referred to an absolute path, then we
-        just use sym.contents and loop.  Otherwise tack the head of
-        path_copy before sym.contents and translate it back from a
-        Win32-style path to a POSIX-style one. */
+      char *headptr;
       if (isabspath (sym.contents))
-       src = sym.contents;
-      else if (!(tail = strrchr (path_copy, '\\')))
-       system_printf ("problem parsing %s - '%s'", src, full_path);
+       headptr = tmp_buf;
       else
        {
-         int headlen = 1 + tail - path_copy;
-         p = sym.contents - headlen;
-         memcpy (p, path_copy, headlen);
-         MALLOC_CHECK;
-         error = mount_table->conv_to_posix_path (p, tmp_buf, 1);
-         MALLOC_CHECK;
-         if (error)
-           return;
-         src = tmp_buf;
+         strcpy (tmp_buf, path_copy);
+         headptr = strchr (tmp_buf, '\0');
        }
+
+      if (headptr > tmp_buf && headptr[-1] != '/')
+       *headptr++ = '/';
+      
+      for (p = sym.contents; *p; p++)
+       *headptr++ = *p == '\\' ? '/' : *p;
+      if (tail == path_end)
+       *headptr = '\0';
+      else
+       {
+         *headptr++ = '/';
+         strcpy (headptr, tail);
+       }
+
+      src = tmp_buf;
     }
 
 /*fillin:*/
@@ -467,21 +562,21 @@ out:
   DWORD serial, volflags;
   char fs_name[16];
 
-  strcpy (tmp_buf, full_path);
+  strcpy (tmp_buf, this->path);
   if (!rootdir (tmp_buf) ||
       !GetVolumeInformation (tmp_buf, NULL, 0, &serial, NULL,
                             &volflags, fs_name, 16))
     {
-      debug_printf ("GetVolumeInformation(%s) = ERR, full_path(%s), set_has_acls(FALSE)",
-                   tmp_buf, full_path, GetLastError ());
+      debug_printf ("GetVolumeInformation(%s) = ERR, this->path(%s), set_has_acls(FALSE)",
+                   tmp_buf, this->path, GetLastError ());
       set_has_acls (FALSE);
       set_has_buggy_open (FALSE);
     }
   else
     {
       set_isdisk ();
-      debug_printf ("GetVolumeInformation(%s) = OK, full_path(%s), set_has_acls(%d)",
-                   tmp_buf, full_path, volflags & FS_PERSISTENT_ACLS);
+      debug_printf ("GetVolumeInformation(%s) = OK, this->path(%s), set_has_acls(%d)",
+                   tmp_buf, this->path, volflags & FS_PERSISTENT_ACLS);
       if (!allow_smbntsec
           && ((tmp_buf[0] == '\\' && tmp_buf[1] == '\\')
               || GetDriveType (tmp_buf) == DRIVE_REMOTE))
@@ -594,7 +689,7 @@ get_device_number (const char *name, int &unit, BOOL from_conv)
       name += 5;
       if (deveq ("tty"))
        {
-         if (tty_attached (myself))
+         if (real_tty_attached (myself))
            {
              unit = myself->ctty;
              devn = FH_TTYS;
@@ -683,123 +778,6 @@ win32_device_name (const char *src_path, char *win32_path,
   return TRUE;
 }
 
-/* Normalize a POSIX path.
-   \'s are converted to /'s in the process.
-   All duplicate /'s, except for 2 leading /'s, are deleted.
-   The result is 0 for success, or an errno error value.  */
-
-#define isslash(c) ((c) == '/')
-
-static int
-normalize_posix_path (const char *src, char *dst)
-{
-  const char *src_start = src;
-  char *dst_start = dst;
-
-  syscall_printf ("src %s", src);
-  if (isdrive (src) || strpbrk (src, "\\:"))
-    {
-      cygwin_conv_to_full_posix_path (src, dst);
-      return 0;
-    }
-  if (!isslash (src[0]))
-    {
-      if (!cygheap->cwd.get (dst))
-       return get_errno ();
-      dst = strchr (dst, '\0');
-      if (*src == '.')
-       {
-         if (dst == dst_start + 1 && *dst_start == '/')
-            --dst;
-         goto sawdot;
-       }
-      if (dst > dst_start && !isslash (dst[-1]))
-       *dst++ = '/';
-    }
-  /* Two leading /'s?  If so, preserve them.  */
-  else if (isslash (src[1]))
-    {
-      if (cygheap->root.length ())
-       {
-         debug_printf ("ENOENT = normalize_posix_path (%s)", src);
-         return ENOENT;
-       }
-      *dst++ = '/';
-      *dst++ = '/';
-      src += 2;
-      if (isslash (*src))
-       { /* Starts with three or more slashes - reset. */
-         dst = dst_start;
-         *dst++ = '/';
-         src = src_start + 1;
-       }
-    }
-  /* Exactly one leading slash. Absolute path. Check for chroot. */
-  else if (cygheap->root.length ())
-    {
-      strcpy (dst, cygheap->root.path ());
-      dst += cygheap->root.length ();
-    }
-  else
-    *dst = '\0';
-
-  while (*src)
-    {
-      /* Strip runs of /'s.  */
-      if (!isslash (*src))
-       *dst++ = *src++;
-      else
-       {
-         while (*++src)
-           {
-             if (isslash (*src))
-               continue;
-
-             if (*src != '.')
-               break;
-
-           sawdot:
-             if (src[1] != '.')
-               {
-                 if (!src[1])
-                   {
-                     if (dst == dst_start)
-                       *dst++ = '/';
-                     goto done;
-                   }
-                 if (!isslash (src[1]))
-                   break;
-               }
-             else if (src[2] && !isslash (src[2]))
-               break;
-             else
-               {
-                 if (!ischrootpath (dst_start) ||
-                     dst - dst_start != (int) cygheap->root.length ())
-                   while (dst > dst_start && !isslash (*--dst))
-                     continue;
-                 src++;
-               }
-           }
-
-         *dst++ = '/';
-       }
-       if ((dst - dst_start) >= MAX_PATH)
-         {
-           debug_printf ("ENAMETOOLONG = normalize_posix_path (%s)", src);
-           return ENAMETOOLONG;
-         }
-    }
-
-done:
-  *dst = '\0';
-  if (--dst > dst_start && isslash (*dst))
-    *dst = '\0';
-
-  debug_printf ("%s = normalize_posix_path (%s)", dst_start, src_start);
-  return 0;
-}
-
 /* Normalize a Win32 path.
    /'s are converted to \'s in the process.
    All duplicate \'s, except for 2 leading \'s, are deleted.
@@ -2643,15 +2621,45 @@ suffix_scan::next ()
 
 int
 symlink_info::check (const char *path, const suffix_info *suffixes,
-                    char *orig_path, BOOL sym_ignore)
+                    char *full_path, unsigned opt,
+                    DWORD& devn, int& unit, unsigned& path_flags)
 {
   HANDLE h;
   int res = 0;
   suffix_scan suffix;
+  contents[0] = '\0';
+  char *tail;
+
+  error = mount_table->conv_to_win32_path (path, NULL, full_path, devn,
+                                          unit, &path_flags);
+
+  if (devn != FH_BAD)
+    {
+      fileattr = 0;
+      goto out;                /* Found a device.  Stop parsing. */
+    }
+
+  /* Eat trailing slashes */
+  tail = strchr (full_path, '\0');
+
+  /* If path is only a drivename, Windows interprets it as the current working
+     directory on this drive instead of the root dir which is what we want. So
+     we need the trailing backslash in this case. */
+  while (tail > full_path + 3 && (*--tail == '\\'))
+    *tail = '\0';
+
+  if (full_path[0] && full_path[1] == ':' && full_path[2] == '\0')
+    strcat (full_path, "\\");
+
+  if ((opt & PC_SYM_IGNORE) && pcheck_case == PCHECK_RELAXED)
+    {
+      fileattr = GetFileAttributesA (path);
+      goto out;
+    }
 
   is_symlink = TRUE;
-  ext_here = suffix.has (path, suffixes);
-  extn = ext_here - path;
+  ext_here = suffix.has (full_path, suffixes);
+  extn = ext_here - full_path;
 
   ext_tacked_on = !*ext_here;
 
@@ -2671,8 +2679,8 @@ symlink_info::check (const char *path, const suffix_info *suffixes,
          continue;
        }
 
-      if (pcheck_case != PCHECK_RELAXED && !case_check (path, orig_path)
-          || sym_ignore)
+      if (pcheck_case != PCHECK_RELAXED && !case_check (path, full_path)
+          || (opt & PC_SYM_IGNORE))
         goto file_not_symlink;
 
       int sym_check = 0;
@@ -2684,13 +2692,13 @@ symlink_info::check (const char *path, const suffix_info *suffixes,
       if (suffix.lnk_match ())
        sym_check = 1;
 
-      /* The old Cygwin method creating symlinks: */
+      /* This is the old Cygwin method creating symlinks: */
       /* A symlink will have the `system' file attribute. */
       /* Only files can be symlinks (which can be symlinks to directories). */
       if (fileattr & FILE_ATTRIBUTE_SYSTEM)
        sym_check = 2;
 
-      if (!sym_check && !(pflags & PATH_SYMLINK))
+      if (!sym_check)
        goto file_not_symlink;
 
       /* Open the file.  */
index bf2400e..48ffaf9 100644 (file)
@@ -1544,7 +1544,7 @@ ctermid (char *str)
   static NO_COPY char buf[16];
   if (str == NULL)
     str = buf;
-  if (!tty_attached (myself))
+  if (!real_tty_attached (myself))
     strcpy (str, "/dev/conin");
   else
     __small_sprintf (str, "/dev/tty%d", myself->ctty);
index 36ff39c..1e4fd36 100644 (file)
@@ -317,7 +317,7 @@ tty::create_inuse (const char *fmt, BOOL inherit)
 void
 tty::init (void)
 {
-  OutputStopped = 0;
+  output_stopped = 0;
   setsid (0);
   pgid = 0;
   hwnd = NULL;
index 6eb32b3..4b2ad7f 100644 (file)
@@ -14,8 +14,7 @@ details. */
 #define INP_BUFFER_SIZE 256
 #define OUT_BUFFER_SIZE 256
 #define NTTYS          128
-#define TTY_CONSOLE    0x40000000
-#define tty_attached(p)        ((p)->ctty >= 0 && (p)->ctty != TTY_CONSOLE)
+#define real_tty_attached(p)   ((p)->ctty >= 0 && (p)->ctty != TTY_CONSOLE)
 
 /* Input/Output/ioctl events */
 
@@ -52,7 +51,7 @@ class tty_min
 public:
   DWORD status;
   pid_t pgid;
-  int OutputStopped;
+  int output_stopped;
   int ntty;
   DWORD last_ctrl_c;   // tick count of last ctrl-c
 
@@ -62,6 +61,7 @@ public:
   void setpgid (int pid) {pgid = pid;}
   int getsid () {return sid;}
   void setsid (pid_t tsid) {sid = tsid;}
+  void set_ctty (int ttynum, int flags);
   struct termios ti;
   struct winsize winsize;