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
path: root/winsup
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2001-04-29 03:48:28 +0400
committerChristopher Faylor <me@cgf.cx>2001-04-29 03:48:28 +0400
commitb98ebf5470da68c0ab4a3877c453ac82c12974ae (patch)
treeb53116bef4a3e4ff86a02d59c3aad37ca7a2cd2c /winsup
parent0ca66974933232188d8d347b225abacf77d241cf (diff)
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.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog32
-rw-r--r--winsup/cygwin/dcrt0.cc2
-rw-r--r--winsup/cygwin/dtable.cc5
-rw-r--r--winsup/cygwin/exceptions.cc4
-rw-r--r--winsup/cygwin/external.cc2
-rw-r--r--winsup/cygwin/fhandler.h1
-rw-r--r--winsup/cygwin/fhandler_console.cc16
-rw-r--r--winsup/cygwin/fhandler_termios.cc26
-rw-r--r--winsup/cygwin/fhandler_tty.cc4
-rw-r--r--winsup/cygwin/include/sys/cygwin.h4
-rw-r--r--winsup/cygwin/path.cc404
-rw-r--r--winsup/cygwin/syscalls.cc2
-rw-r--r--winsup/cygwin/tty.cc2
-rw-r--r--winsup/cygwin/tty.h6
14 files changed, 281 insertions, 229 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 81ae2a862..ce9b2d03b 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index a56f6281c..e25c31144 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -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",
diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
index 88c3adced..19a589b3c 100644
--- a/winsup/cygwin/dtable.cc
+++ b/winsup/cygwin/dtable.cc
@@ -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 ();
}
}
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 8cd60a8d5..6e80b6bf9 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -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
diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc
index ffcf915ae..9f4683583 100644
--- a/winsup/cygwin/external.cc
+++ b/winsup/cygwin/external.cc
@@ -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;
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index ac000bac7..73aadd607 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -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) {}
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index 7a340fe0d..01d90fe22 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -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 ());
diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc
index 6d4e4e9a8..058410d9d 100644
--- a/winsup/cygwin/fhandler_termios.cc
+++ b/winsup/cygwin/fhandler_termios.cc
@@ -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])
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index acb10a93d..1a6ffb4a2 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -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 */
diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h
index bca09f7b8..6b0dc91b7 100644
--- a/winsup/cygwin/include/sys/cygwin.h
+++ b/winsup/cygwin/include/sys/cygwin.h
@@ -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;
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index c218a1606..a0e8640a1 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -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. */
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index bf2400edd..48ffaf9ec 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -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);
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index 36ff39cd8..1e4fd3685 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -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;
diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h
index 6eb32b387..4b2ad7f4b 100644
--- a/winsup/cygwin/tty.h
+++ b/winsup/cygwin/tty.h
@@ -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;