From b25e8b65c27642806ba9f6cc6a75373bdc17c337 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sat, 18 Dec 2004 16:37:44 +0000 Subject: [PATCH] * fhandler_proc.cc (proc_listing): Add entry for "self". (proc_fhandlers): Add entry for "self". * fhandler_process.cc (fhandler_process::fstate): Handle "self". (fhandler_process::open): Handle "self". --- winsup/cygwin/ChangeLog | 19 ++- winsup/cygwin/child_info.h | 2 +- winsup/cygwin/fhandler_proc.cc | 2 + winsup/cygwin/fhandler_process.cc | 13 +- winsup/cygwin/path.cc | 192 +++++++++++++++--------------- winsup/cygwin/shared_info.h | 17 ++- 6 files changed, 139 insertions(+), 106 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 8743c0ac1..912a12d3a 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,10 @@ +2004-12-18 Chris January + + * fhandler_proc.cc (proc_listing): Add entry for "self". + (proc_fhandlers): Add entry for "self". + * fhandler_process.cc (fhandler_process::fstate): Handle "self". + (fhandler_process::open): Handle "self". + 2004-12-17 Christopher Faylor * sigproc.cc (proc_subproc): Fix long-standing problem. Only wait for @@ -194,14 +201,14 @@ * registry.h (reg_key::reg_key): Change arguments. * shared_info.h (class mount_info): Remove had_to_create_mount_areas. * registry.cc (reg_key::reg_key): Change constructors to always handle - HKLM and to avoid relying on HKCU. - Do not set mount_table->had_to_create_mount_areas. - * path.cc (mount_info::conv_to_win32_path): Improve update of + HKLM and to avoid relying on HKCU. + Do not set mount_table->had_to_create_mount_areas. + * path.cc (mount_info::conv_to_win32_path): Improve update of sys_mount_table_counter. (mount_info::read_mounts): Use new reg_key constructor. - (mount_info::add_reg_mount): Ditto. + (mount_info::add_reg_mount): Ditto. (mount_info::del_reg_mount): Ditto. - (mount_info::read_cygdrive_info_from_registry): Ditto. + (mount_info::read_cygdrive_info_from_registry): Ditto. (mount_info::write_cygdrive_info_to_registry): Ditto. Update cygwin_shared->sys_mount_table_counter after registry update. (mount_info::get_cygdrive_info): Ditto. @@ -392,7 +399,7 @@ accessing HKLM. (mount_info::read_cygdrive_info_from_registry): Ditto. * cygheap.h: Define NO_IMPERSONATION. - (cygheap_user::issetuid): Replace INVALID_HANDLE_VALUE by + (cygheap_user::issetuid): Replace INVALID_HANDLE_VALUE by NO_IMPERSONATION. (cygheap_user::has_impersonation_tokens): Ditto. (cygheap_user::close_impersonation_tokens): Ditto. diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h index 601fdfd8b..97cf455e2 100644 --- a/winsup/cygwin/child_info.h +++ b/winsup/cygwin/child_info.h @@ -29,7 +29,7 @@ enum child_info_types #define EXEC_MAGIC_SIZE sizeof(child_info) -#define CURR_CHILD_INFO_MAGIC 0x694cd4b8U +#define CURR_CHILD_INFO_MAGIC 0x17ad771aU /* NOTE: Do not make gratuitous changes to the names or organization of the below class. The layout is checksummed to determine compatibility between diff --git a/winsup/cygwin/fhandler_proc.cc b/winsup/cygwin/fhandler_proc.cc index 0443240d2..8e94092df 100644 --- a/winsup/cygwin/fhandler_proc.cc +++ b/winsup/cygwin/fhandler_proc.cc @@ -54,6 +54,7 @@ static const char *proc_listing[] = { "uptime", "cpuinfo", "partitions", + "self", NULL }; @@ -73,6 +74,7 @@ static const DWORD proc_fhandlers[PROC_LINK_COUNT] = { FH_PROC, FH_PROC, FH_PROC, + FH_PROCESS, }; /* name of the /proc filesystem */ diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index e56b85357..004233d3a 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -107,7 +107,10 @@ fhandler_process::fstat (struct __stat64 *buf) int file_type = exists (); (void) fhandler_base::fstat (buf); path += proc_len + 1; - pid = atoi (path); + if (path_prefix_p ("self", path, 4)) + pid = getpid (); + else + pid = atoi (path); pinfo p (pid); if (!p) { @@ -167,7 +170,10 @@ fhandler_process::open (int flags, mode_t mode) const char *path; path = get_name () + proc_len + 1; - pid = atoi (path); + if (path_prefix_p ("self", path, 4)) + pid = getpid (); + else + pid = atoi (path); while (*path != 0 && !isdirsep (*path)) path++; @@ -313,7 +319,8 @@ fhandler_process::fill_filebuf () strcpy (filebuf, ""); else { - mount_table->conv_to_posix_path (p->progname, filebuf, 1); + charplus x (p->progname); + mount_table->conv_to_posix_path (x, filebuf, 1); int len = strlen (filebuf); if (len > 4) { diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 2e4c725c7..63044702f 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -75,7 +75,7 @@ details. */ #include "cygtls.h" #include -static int normalize_win32_path (const char *src, char *dst, char ** tail); +static int normalize_win32_path (const char *, charplus&); static void slashify (const char *src, char *dst, int trailing_slash_p); static void backslashify (const char *src, char *dst, int trailing_slash_p); @@ -190,38 +190,37 @@ pathmatch (const char *path1, const char *path2) The result is 0 for success, or an errno error value. */ static int -normalize_posix_path (const char *src, char *dst, char **tail) +normalize_posix_path (const char *src, charplus& dst) { const char *src_start = src; - char *dst_start = dst; syscall_printf ("src %s", src); const char *in_src = src; - char *in_dst = dst; if (isdrive (src) || *src == '\\') goto win32_path; + dst.tail = dst; if (!isslash (src[0])) { if (!cygheap->cwd.get (dst)) return get_errno (); - dst = strchr (dst, '\0'); + dst.tail = strchr (dst.tail, '\0'); if (*src == '.') { - if (dst == dst_start + 1 && *dst_start == '/') - --dst; + if (dst.tail == dst + 1 && *dst == '/') + dst.tail--; goto sawdot; } - if (dst > dst_start && !isslash (dst[-1])) - *dst++ = '/'; + if (dst.tail > dst && !isslash (dst.tail[-1])) + *dst.tail++ = '/'; } /* Two leading /'s? If so, preserve them. */ else if (isslash (src[1]) && !isslash (src[2])) { - *dst++ = '/'; - *dst++ = '/'; + *dst.tail++ = '/'; + *dst.tail++ = '/'; src += 2; } @@ -231,7 +230,7 @@ normalize_posix_path (const char *src, char *dst, char **tail) goto win32_path; /* Strip runs of /'s. */ if (!isslash (*src)) - *dst++ = *src++; + *dst.tail++ = *src++; else { while (*++src) @@ -247,7 +246,7 @@ normalize_posix_path (const char *src, char *dst, char **tail) { if (!src[1]) { - *dst++ = '/'; + *dst.tail++ = '/'; goto done; } if (!isslash (src[1])) @@ -268,15 +267,15 @@ normalize_posix_path (const char *src, char *dst, char **tail) } else { - while (dst > dst_start && !isslash (*--dst)) + while (dst.tail > dst && !isslash (*--dst.tail)) continue; src++; } } - *dst++ = '/'; + *dst.tail++ = '/'; } - if ((dst - dst_start) >= CYG_MAX_PATH) + if ((dst.tail - dst) >= CYG_MAX_PATH) { debug_printf ("ENAMETOOLONG = normalize_posix_path (%s)", src); return ENAMETOOLONG; @@ -284,16 +283,15 @@ normalize_posix_path (const char *src, char *dst, char **tail) } done: - *dst = '\0'; - *tail = dst; + *dst.tail = '\0'; - debug_printf ("%s = normalize_posix_path (%s)", dst_start, src_start); + debug_printf ("%s = normalize_posix_path (%s)", (char *) dst, src_start); return 0; win32_path: - int err = normalize_win32_path (in_src, in_dst, tail); + int err = normalize_win32_path (in_src, dst); if (!err) - for (char *p = in_dst; (p = strchr (p, '\\')); p++) + for (char *p = dst; (p = strchr (p, '\\')); p++) *p = '/'; return err; } @@ -500,13 +498,13 @@ path_conv::check (const char *src, unsigned opt, /* This array is used when expanding symlinks. It is CYG_MAX_PATH * 2 in length so that we can hold the expanded symlink plus a trailer. */ - char path_copy[CYG_MAX_PATH + 3]; + charplus path_copy; char tmp_buf[2 * CYG_MAX_PATH + 3]; symlink_info sym; bool need_directory = 0; bool saw_symlinks = 0; int is_relpath; - char *tail, *path_end; + char *path_end; #if 0 static path_conv last_path_conv; @@ -537,34 +535,34 @@ path_conv::check (const char *src, unsigned opt, { MALLOC_CHECK; assert (src); - is_relpath = !isabspath (src); - error = normalize_posix_path (src, path_copy, &tail); + error = normalize_posix_path (src, path_copy); if (error) return; /* Detect if the user was looking for a directory. We have to strip the trailing slash initially while trying to add extensions but take it into account during processing */ - if (tail > path_copy + 1) + if (path_copy.tail > path_copy + 1) { - if (isslash (tail[-1])) + if (isslash (path_copy.tail[-1])) { need_directory = 1; - tail--; + *--path_copy.tail = '\0'; } /* Remove trailing dots and spaces which are ignored by Win32 functions but not by native NT functions. */ - while (tail[-1] == '.' || tail[-1] == ' ') - tail--; - if (tail > path_copy + 1 && isslash (tail[-1])) + while (path_copy.tail[-1] == '.' || path_copy.tail[-1] == ' ') + path_copy.tail--; + if (path_copy.tail > path_copy + 1 && isslash (path_copy.tail[-1])) { error = ENOENT; return; } } - path_end = tail; - *tail = '\0'; + path_end = path_copy.tail; + path_copy.tailch = *path_copy.tail; + *path_copy.tail = '\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 @@ -601,6 +599,7 @@ path_conv::check (const char *src, unsigned opt, error = mount_table->conv_to_win32_path (path_copy, full_path, dev, &sym.pflags); + path_copy.tailch = '\0'; if (error) return; @@ -747,17 +746,17 @@ path_conv::check (const char *src, unsigned opt, /* Find the new "tail" of the path, e.g. in '/for/bar/baz', /baz is the tail. */ - if (tail != path_end) - *tail = '/'; - while (--tail > path_copy + 1 && *tail != '/') {} + if (path_copy.tail != path_end) + *path_copy.tail = '/'; + while (--path_copy.tail > path_copy + 1 && *path_copy.tail != '/') {} /* Exit loop if there is no tail or we are at the beginning of a UNC path */ - if (tail <= path_copy + 1) + if (path_copy.tail <= path_copy + 1) goto out; // all done /* Haven't found an existing pathname component yet. Pinch off the tail and try again. */ - *tail = '\0'; + *path_copy.tail = '\0'; component++; } @@ -779,7 +778,7 @@ path_conv::check (const char *src, unsigned opt, else { /* Copy the first part of the path (with ending /) and point to the end. */ - char *prevtail = tail; + char *prevtail = path_copy.tail; while (--prevtail > path_copy && *prevtail != '/') {} int headlen = prevtail - path_copy + 1;; memcpy (tmp_buf, path_copy, headlen); @@ -802,15 +801,15 @@ path_conv::check (const char *src, unsigned opt, *headptr = '\0'; /* Copy any tail component (with the 0) */ - if (tail++ < path_end) + if (path_copy.tail++ < path_end) { /* Add a slash if needed. There is space. */ if (*(headptr - 1) != '/') *headptr++ = '/'; - int taillen = path_end - tail + 1; + int taillen = path_end - path_copy.tail + 1; if (headptr + taillen > tmp_buf + sizeof (tmp_buf)) goto too_long; - memcpy (headptr, tail, taillen); + memcpy (headptr, path_copy.tail, taillen); } /* Evaluate everything all over again. */ @@ -891,8 +890,8 @@ out: normalized_path_size = 0; else { - if (tail < path_end && tail > path_copy + 1) - *tail = '/'; + if (path_copy.tail < path_end && path_copy.tail > path_copy + 1) + *path_copy.tail = '/'; set_normalized_path (path_copy); } @@ -957,34 +956,33 @@ is_unc_share (const char *path) The result is 0 for success, or an errno error value. FIXME: A lot of this should be mergeable with the POSIX critter. */ static int -normalize_win32_path (const char *src, char *dst, char **tail) +normalize_win32_path (const char *src, charplus& dst) { const char *src_start = src; - char *dst_start = dst; - char *dst_root_start = dst; bool beg_src_slash = isdirsep (src[0]); + dst.tail = dst; if (beg_src_slash && isdirsep (src[1])) { - *dst++ = '\\'; + *dst.tail++ = '\\'; src++; if (src[1] == '.' && isdirsep (src[2])) { - *dst++ = '\\'; - *dst++ = '.'; + *dst.tail++ = '\\'; + *dst.tail++ = '.'; src += 2; } } else if (!isdrive(src) && *src != '/') { if (beg_src_slash) - dst += cygheap->cwd.get_drive (dst); + dst.tail += cygheap->cwd.get_drive (dst); else if (!cygheap->cwd.get (dst, 0)) return get_errno (); else { - dst += strlen (dst); - *dst++ = '\\'; + dst.tail = strchr (dst.tail, '\0'); + *dst.tail++ = '\\'; } } @@ -1001,16 +999,16 @@ normalize_win32_path (const char *src, char *dst, char **tail) /* Backup if "..". */ else if (src[0] == '.' && src[1] == '.' /* dst must be greater than dst_start */ - && dst[-1] == '\\') + && dst.tail[-1] == '\\') { if (isdirsep (src[2]) || src[2] == 0) { /* Back up over /, but not if it's the first one. */ - if (dst > dst_root_start + 1) - dst--; + if (dst.tail > dst + 1) + dst.tail--; /* Now back up to the next /. */ - while (dst > dst_root_start + 1 && dst[-1] != '\\' && dst[-2] != ':') - dst--; + while (dst.tail > dst + 1 && dst.tail[-1] != '\\' && dst.tail[-2] != ':') + dst.tail--; src += 2; if (isdirsep (*src)) src++; @@ -1020,26 +1018,25 @@ normalize_win32_path (const char *src, char *dst, char **tail) int n = strspn (src, "."); if (!src[n] || isdirsep (src[n])) /* just dots... */ return ENOENT; - *dst++ = *src++; + *dst.tail++ = *src++; } } /* Otherwise, add char to result. */ else { if (*src == '/') - *dst++ = '\\'; + *dst.tail++ = '\\'; else - *dst++ = *src; - ++src; + *dst.tail++ = *src; + src++; } - if ((dst - dst_start) >= CYG_MAX_PATH) + if ((dst.tail - dst) >= CYG_MAX_PATH) return ENAMETOOLONG; } - if (dst > dst_start + 1 && dst[-1] == '.' && dst[-2] == '\\') - dst--; - *dst = '\0'; - *tail = dst; - debug_printf ("%s = normalize_win32_path (%s)", dst_start, src_start); + if (dst.tail > dst + 1 && dst.tail[-1] == '.' && dst.tail[-2] == '\\') + dst.tail--; + *dst.tail = '\0'; + debug_printf ("%s = normalize_win32_path (%s)", (char *) dst, src_start); return 0; } @@ -1324,7 +1321,7 @@ mount_item::fnmunge (char *dst, const char *src, int& left) } int -mount_item::build_win32 (char *dst, const char *src, unsigned *outflags, unsigned chroot_pathlen) +mount_item::build_win32 (char *dst, const charplus& src, unsigned *outflags, unsigned chroot_pathlen) { int n, err = 0; const char *real_native_path; @@ -1357,6 +1354,16 @@ mount_item::build_win32 (char *dst, const char *src, unsigned *outflags, unsigne } else { + char buf[CYG_MAX_PATH]; + if (src.tailch) + { + strcpy (buf, p); + char *endp = strchr (buf, '\0'); + *endp = src.tailch; + strcpy (endp + 1, src.tail + 1); + p = buf; + } + int left = CYG_MAX_PATH - n; while (*p) { @@ -1392,8 +1399,8 @@ mount_item::build_win32 (char *dst, const char *src, unsigned *outflags, unsigne {,full_}win32_path must have sufficient space (i.e. CYG_MAX_PATH bytes). */ int -mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, - unsigned *flags) +mount_info::conv_to_win32_path (const charplus& src_path, char *dst, + device& dev, unsigned *flags) { bool chroot_ok = !cygheap->root.exists (); while (sys_mount_table_counter < cygwin_shared->sys_mount_table_counter) @@ -1407,7 +1414,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, dev.devn = FH_FS; *flags = 0; - debug_printf ("conv_to_win32_path (%s)", src_path); + debug_printf ("conv_to_win32_path (%s)", (const char *) src_path); int i, rc; mount_item *mi = NULL; /* initialized to avoid compiler warning */ @@ -1525,7 +1532,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, } out_no_chroot_check: - debug_printf ("src_path %s, dst %s, flags %p, rc %d", src_path, dst, *flags, rc); + debug_printf ("src_path %s, dst %s, flags %p, rc %d", (const char *) src_path, dst, *flags, rc); return rc; } @@ -1590,7 +1597,7 @@ mount_info::cygdrive_win32_path (const char *src, char *dst, int& unit) If keep_rel_p is non-zero, relative paths stay that way. */ int -mount_info::conv_to_posix_path (const char *src_path, char *posix_path, +mount_info::conv_to_posix_path (const charplus& src_path, char *posix_path, int keep_rel_p) { int src_path_len = strlen (src_path); @@ -1605,7 +1612,7 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path, trailing_slash_p = isdirsep (*lastchar) && lastchar[-1] != ':'; } - debug_printf ("conv_to_posix_path (%s, %s, %s)", src_path, + debug_printf ("conv_to_posix_path (%s, %s, %s)", (const char *) src_path, keep_rel_p ? "keep-rel" : "no-keep-rel", trailing_slash_p ? "add-slash" : "no-add-slash"); MALLOC_CHECK; @@ -1622,20 +1629,19 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path, if (keep_rel_p && relative_path_p) { slashify (src_path, posix_path, 0); - debug_printf ("%s = conv_to_posix_path (%s)", posix_path, src_path); + debug_printf ("%s = conv_to_posix_path (%s)", posix_path, (const char *) src_path); return 0; } - char pathbuf[CYG_MAX_PATH]; - char * tail; - int rc = normalize_win32_path (src_path, pathbuf, &tail); + charplus pathbuf; + int rc = normalize_win32_path (src_path, pathbuf); if (rc != 0) { - debug_printf ("%d = conv_to_posix_path (%s)", rc, src_path); + debug_printf ("%d = conv_to_posix_path (%s)", rc, (const char *) src_path); return rc; } - int pathbuflen = tail - pathbuf; + int pathbuflen = pathbuf.tail - pathbuf; for (int i = 0; i < nmounts; ++i) { mount_item &mi = mount[native_sorted[i]]; @@ -1713,7 +1719,7 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path, } out: - debug_printf ("%s = conv_to_posix_path (%s)", posix_path, src_path); + debug_printf ("%s = conv_to_posix_path (%s)", posix_path, (const char *) src_path); MALLOC_CHECK; return 0; } @@ -2109,9 +2115,9 @@ mount_info::sort () int mount_info::add_item (const char *native, const char *posix, unsigned mountflags, int reg_p) { - char nativetmp[CYG_MAX_PATH]; - char posixtmp[CYG_MAX_PATH]; - char *nativetail, *posixtail, error[] = "error"; + charplus nativetmp; + charplus posixtmp; + char error[] = "error"; int nativeerr, posixerr; /* Something's wrong if either path is NULL or empty, or if it's @@ -2121,17 +2127,17 @@ mount_info::add_item (const char *native, const char *posix, unsigned mountflags !(is_unc_share (native) || isdrive (native))) nativeerr = EINVAL; else - nativeerr = normalize_win32_path (native, nativetmp, &nativetail); + nativeerr = normalize_win32_path (native, nativetmp); if (posix == NULL || !isabspath (posix) || is_unc_share (posix) || isdrive (posix)) posixerr = EINVAL; else - posixerr = normalize_posix_path (posix, posixtmp, &posixtail); + posixerr = normalize_posix_path (posix, posixtmp); debug_printf ("%s[%s], %s[%s], %p", - native, nativeerr ? error : nativetmp, - posix, posixerr ? error : posixtmp, mountflags); + native, nativeerr ? error : (const char *) nativetmp, + posix, posixerr ? error : (const char *) posixtmp, mountflags); if (nativeerr || posixerr) { @@ -2140,10 +2146,10 @@ mount_info::add_item (const char *native, const char *posix, unsigned mountflags } /* Make sure both paths do not end in /. */ - if (nativetail > nativetmp + 1 && nativetail[-1] == '\\') - nativetail[-1] = '\0'; - if (posixtail > posixtmp + 1 && posixtail[-1] == '/') - posixtail[-1] = '\0'; + if (nativetmp.tail > nativetmp + 1 && nativetmp.tail[-1] == '\\') + nativetmp.tail[-1] = '\0'; + if (posixtmp.tail > posixtmp + 1 && posixtmp.tail[-1] == '/') + posixtmp.tail[-1] = '\0'; /* Write over an existing mount item with the same POSIX path if it exists and is from the same registry area. */ diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h index 7a9b0e096..fe0a30729 100644 --- a/winsup/cygwin/shared_info.h +++ b/winsup/cygwin/shared_info.h @@ -11,6 +11,17 @@ details. */ #include "tty.h" #include "security.h" +struct charplus +{ + char buf[CYG_MAX_PATH]; + char tailch; + char *tail; + operator char * () { return buf; } + operator const char * () const { return buf; } + charplus (const char *s) : tailch (0), tail (0) {strcpy (buf, s);} + charplus () : tailch (0), tail (0) {*buf = '\0';} +}; + /* Mount table entry */ class mount_item @@ -33,7 +44,7 @@ class mount_item struct mntent *getmntent (); int fnmunge (char *, const char *, int&); - int build_win32 (char *, const char *, unsigned *, unsigned); + int build_win32 (char *, const charplus&, unsigned *, unsigned); }; /* Warning: Decreasing this value will cause cygwin.dll to ignore existing @@ -80,9 +91,9 @@ class mount_info int del_reg_mount (const char * posix_path, unsigned mountflags); unsigned set_flags_from_win32_path (const char *path); - int conv_to_win32_path (const char *src_path, char *dst, device&, + int conv_to_win32_path (const charplus& src_path, char *dst, device&, unsigned *flags = NULL); - int conv_to_posix_path (const char *src_path, char *posix_path, + int conv_to_posix_path (const charplus& src_path, char *posix_path, int keep_rel_p); struct mntent *getmntent (int x); -- 2.43.5