From d7c29a7b61edb553bc8d7e5af9706ccaffbddf76 Mon Sep 17 00:00:00 2001 From: cgf Date: Sat, 28 Apr 2001 23:48:27 +0000 Subject: [PATCH] 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 ) * 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. --- winsup/cygwin/ChangeLog | 32 +++ winsup/cygwin/dcrt0.cc | 2 +- winsup/cygwin/dtable.cc | 5 + winsup/cygwin/exceptions.cc | 4 +- winsup/cygwin/external.cc | 2 +- winsup/cygwin/fhandler.h | 1 - winsup/cygwin/fhandler_console.cc | 16 +- winsup/cygwin/fhandler_termios.cc | 26 +-- winsup/cygwin/fhandler_tty.cc | 4 +- winsup/cygwin/include/sys/cygwin.h | 4 +- winsup/cygwin/path.cc | 404 +++++++++++++++++++------------------ winsup/cygwin/syscalls.cc | 2 +- winsup/cygwin/tty.cc | 2 +- winsup/cygwin/tty.h | 6 +- 14 files changed, 281 insertions(+), 229 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 81ae2a8628..ce9b2d03b6 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,35 @@ +Sat Apr 28 19:36:13 2001 Christopher Faylor + + 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 ) + * 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 * thread.cc (thread_init_wrapper): Use _REENT_INIT to initialize the diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index a56f6281cd..e25c311440 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 88c3adced4..19a589b3c3 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 8cd60a8d53..6e80b6bf90 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 ffcf915ae0..9f46835838 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 ac000bac7b..73aadd607b 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 7a340fe0dd..01d90fe229 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 6d4e4e9a82..058410d9da 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 acb10a93db..1a6ffb4a2f 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 bca09f7b8f..6b0dc91b7b 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 +#define TTY_CONSOLE 0x40000000 + struct external_pinfo { pid_t pid; diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index c218a1606e..a0e8640a1f 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 bf2400edd9..48ffaf9eca 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 36ff39cd88..1e4fd36857 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 6eb32b3879..4b2ad7f4b1 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; -- 2.11.0