From fbae2bf8641db16778ddd4348b6cb7a1115d5cca Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sun, 5 Feb 2006 18:18:02 +0000 Subject: * environ.cc (struct parse_thing): Add transparent_exe option. * fhandler_disk_file.cc (fhandler_disk_file::link): Accomodate transparent_exe option. Add .exe suffix for links to executable files, if transparent_exe is set. * fhandler_process.cc (fhandler_process::fill_filebuf): Remove .exe suffix if transparent_exe option is set. * path.cc (symlink_worker): Accomodate transparent_exe option. (realpath): Don't tack on .exe suffix if transparent_exe is set. * syscalls.cc (transparent_exe): New global variable. (unlink): Accomodate transparent_exe option. (open): Ditto. (link): Ditto. (rename): Ditto. Maybe add .exe suffix when renaming executable files. (pathconf): Accomodate transparent_exe option. * winsup.h: Declare transparent_exe. --- winsup/cygwin/ChangeLog | 18 +++++++++++++ winsup/cygwin/environ.cc | 1 + winsup/cygwin/fhandler_disk_file.cc | 36 +++++++++++++++++++------ winsup/cygwin/fhandler_process.cc | 21 +++++++-------- winsup/cygwin/path.cc | 16 ++++++++---- winsup/cygwin/syscalls.cc | 52 +++++++++++++++++++++++++++---------- winsup/cygwin/winsup.h | 1 + 7 files changed, 108 insertions(+), 37 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index bef06e2..5bf6c4e 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,21 @@ +2006-02-05 Corinna Vinschen + + * environ.cc (struct parse_thing): Add transparent_exe option. + * fhandler_disk_file.cc (fhandler_disk_file::link): Accomodate + transparent_exe option. Add .exe suffix for links to executable files, + if transparent_exe is set. + * fhandler_process.cc (fhandler_process::fill_filebuf): Remove .exe + suffix if transparent_exe option is set. + * path.cc (symlink_worker): Accomodate transparent_exe option. + (realpath): Don't tack on .exe suffix if transparent_exe is set. + * syscalls.cc (transparent_exe): New global variable. + (unlink): Accomodate transparent_exe option. + (open): Ditto. + (link): Ditto. + (rename): Ditto. Maybe add .exe suffix when renaming executable files. + (pathconf): Accomodate transparent_exe option. + * winsup.h: Declare transparent_exe. + 2006-02-05 Christopher Faylor Corinna Vinschen diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index 8c5e79d..eb99d2b 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -586,6 +586,7 @@ static struct parse_thing {"title", {&display_title}, justset, NULL, {{false}, {true}}}, {"tty", {NULL}, set_process_state, NULL, {{0}, {PID_USETTY}}}, {"winsymlinks", {&allow_winsymlinks}, justset, NULL, {{false}, {true}}}, + {"transparent_exe", {&transparent_exe}, justset, NULL, {{false}, {true}}}, {NULL, {0}, justset, 0, {{0}, {0}}} }; diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 048574c..b187de5 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -734,9 +734,11 @@ fhandler_disk_file::ftruncate (_off64_t length) int fhandler_disk_file::link (const char *newpath) { - path_conv newpc (newpath, PC_SYM_NOFOLLOW | PC_POSIX); extern bool allow_winsymlinks; + extern suffix_info stat_suffixes[]; + path_conv newpc (newpath, PC_SYM_NOFOLLOW | PC_POSIX, + transparent_exe ? stat_suffixes : NULL); if (newpc.error) { set_errno (newpc.case_clash ? ECASECLASH : newpc.error); @@ -757,14 +759,32 @@ fhandler_disk_file::link (const char *newpath) return -1; } - /* Shortcut hack. */ - char new_lnk_buf[CYG_MAX_PATH + 5]; - if (allow_winsymlinks && pc.is_lnk_special () && !newpc.case_clash) + char new_buf[CYG_MAX_PATH + 5]; + if (!newpc.error && !newpc.case_clash) { - strcpy (new_lnk_buf, newpath); - strcat (new_lnk_buf, ".lnk"); - newpath = new_lnk_buf; - newpc.check (newpath, PC_SYM_NOFOLLOW); + DWORD bintype; + int len; + + if (allow_winsymlinks && pc.is_lnk_special ()) + { + /* Shortcut hack. */ + strcpy (new_buf, newpath); + strcat (new_buf, ".lnk"); + newpath = new_buf; + newpc.check (newpath, PC_SYM_NOFOLLOW); + } + else if (transparent_exe + && !pc.isdir () + && GetBinaryType (pc, &bintype) + && (len = strlen (newpc)) > 4 + && !strcasematch ((const char *) newpc + len - 4, ".exe")) + { + /* Executable hack. */ + strcpy (new_buf, newpath); + strcat (new_buf, ".exe"); + newpath = new_buf; + newpc.check (newpath, PC_SYM_NOFOLLOW); + } } query_open (query_write_attributes); diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index cb0b805..28fd28c 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -451,19 +451,18 @@ fhandler_process::fill_filebuf () else { mount_table->conv_to_posix_path (p->progname, filebuf, 1); -#if 0 - /* Temporarily disabled. The link will have a suffix so that - an open(2) call will succeed on /proc/$PID/exe now. This - might become unnecessary if open(2) handles the .exe suffix - at one point. */ - int len = strlen (filebuf); - if (len > 4) + /* If transparent_exe isn't set, the link keeps its suffix so that + an open(2) call will succeed on /proc/$PID/exe. */ + if (transparent_exe) { - char *s = filebuf + len - 4; - if (strcasematch (s, ".exe")) - *s = 0; + int len = strlen (filebuf); + if (len > 4) + { + char *s = filebuf + len - 4; + if (strcasematch (s, ".exe")) + *s = 0; + } } -#endif } filesize = strlen (filebuf); break; diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 45dc579..4029ec5 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -2675,6 +2675,8 @@ int symlink_worker (const char *oldpath, const char *newpath, bool use_winsym, bool isdevice) { + extern suffix_info stat_suffixes[]; + HANDLE h; int res = -1; path_conv win32_path, win32_oldpath; @@ -2704,7 +2706,8 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym, goto done; } - win32_path.check (newpath, PC_SYM_NOFOLLOW); + win32_path.check (newpath, PC_SYM_NOFOLLOW, + transparent_exe ? stat_suffixes : NULL); if (use_winsym && !win32_path.exists ()) { strcpy (from, newpath); @@ -2753,7 +2756,8 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym, ITEMIDLIST field. */ if (GetFileAttributes (reloldpath) == INVALID_FILE_ATTRIBUTES) { - win32_oldpath.check (oldpath, PC_SYM_NOFOLLOW); + win32_oldpath.check (oldpath, PC_SYM_NOFOLLOW, + transparent_exe ? stat_suffixes : NULL); if (win32_oldpath.error != ENOENT) strcpy (use_winsym ? reloldpath : w32oldpath, win32_oldpath); } @@ -2761,7 +2765,8 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym, strcpy (w32oldpath, reloldpath); if (use_winsym) { - win32_oldpath.check (oldpath, PC_SYM_NOFOLLOW); + win32_oldpath.check (oldpath, PC_SYM_NOFOLLOW, + transparent_exe ? stat_suffixes : NULL); strcpy (w32oldpath, win32_oldpath); } if (cp) @@ -2772,7 +2777,8 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym, } else { - win32_oldpath.check (oldpath, PC_SYM_NOFOLLOW); + win32_oldpath.check (oldpath, PC_SYM_NOFOLLOW, + transparent_exe ? stat_suffixes : NULL); strcpy (w32oldpath, win32_oldpath); } create_how = CREATE_NEW; @@ -3723,7 +3729,7 @@ realpath (const char *path, char *resolved) { /* Check for the suffix being tacked on. */ int tack_on = 0; - if (real_path.known_suffix) + if (!transparent_exe && real_path.known_suffix) { char *c = strrchr (real_path.normalized_path, '.'); if (!c || !strcasematch (c, real_path.known_suffix)) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 62ebf63..66c5e38 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -84,6 +84,8 @@ suffix_info stat_suffixes[] = suffix_info (NULL) }; +bool transparent_exe = false; + SYSTEM_INFO system_info; static int __stdcall mknod_worker (const char *, mode_t, mode_t, _major_t, @@ -139,7 +141,8 @@ unlink (const char *ourname) int res = -1; DWORD devn; - path_conv win32_name (ourname, PC_SYM_NOFOLLOW); + path_conv win32_name (ourname, PC_SYM_NOFOLLOW, + transparent_exe ? stat_suffixes : NULL); if (win32_name.error) { @@ -598,7 +601,8 @@ open (const char *unix_path, int flags, ...) if (fd >= 0) { if (!(fh = build_fh_name (unix_path, NULL, (flags & O_NOFOLLOW) ? - PC_SYM_NOFOLLOW : PC_SYM_FOLLOW))) + PC_SYM_NOFOLLOW : PC_SYM_FOLLOW, + transparent_exe ? stat_suffixes : NULL))) res = -1; // errno already set else if ((flags & O_NOFOLLOW) && fh->issymlink ()) { @@ -722,7 +726,8 @@ link (const char *oldpath, const char *newpath) int res = -1; fhandler_base *fh; - if (!(fh = build_fh_name (oldpath, NULL, PC_SYM_NOFOLLOW))) + if (!(fh = build_fh_name (oldpath, NULL, PC_SYM_NOFOLLOW, + transparent_exe ? stat_suffixes : NULL))) goto error; if (fh->error ()) @@ -1171,7 +1176,8 @@ rename (const char *oldpath, const char *newpath) int res = 0; char *lnk_suffix = NULL; - path_conv real_old (oldpath, PC_SYM_NOFOLLOW); + path_conv real_old (oldpath, PC_SYM_NOFOLLOW, + transparent_exe ? stat_suffixes : NULL); if (real_old.error) { @@ -1180,16 +1186,35 @@ rename (const char *oldpath, const char *newpath) return -1; } - path_conv real_new (newpath, PC_SYM_NOFOLLOW); + path_conv real_new (newpath, PC_SYM_NOFOLLOW, + transparent_exe ? stat_suffixes : NULL); - /* Shortcut hack. */ - char new_lnk_buf[CYG_MAX_PATH + 5]; - if (real_old.is_lnk_special () && !real_new.error && !real_new.case_clash) + char new_buf[CYG_MAX_PATH + 5]; + if (!real_new.error && !real_new.case_clash) { - strcpy (new_lnk_buf, newpath); - strcat (new_lnk_buf, ".lnk"); - newpath = new_lnk_buf; - real_new.check (newpath, PC_SYM_NOFOLLOW); + DWORD bintype; + int len; + + if (real_old.is_lnk_special ()) + { + /* Shortcut hack. */ + strcpy (new_buf, newpath); + strcat (new_buf, ".lnk"); + newpath = new_buf; + real_new.check (newpath, PC_SYM_NOFOLLOW); + } + else if (transparent_exe + && !real_old.isdir () + && GetBinaryType (real_old, &bintype) + && (len = strlen (real_new)) > 4 + && !strcasematch ((const char *) real_new + len - 4, ".exe")) + { + /* Executable hack. */ + strcpy (new_buf, newpath); + strcat (new_buf, ".exe"); + newpath = new_buf; + real_new.check (newpath, PC_SYM_NOFOLLOW); + } } if (real_new.error || real_new.case_clash) @@ -1510,7 +1535,8 @@ pathconf (const char *file, int v) case _PC_POSIX_PERMISSIONS: case _PC_POSIX_SECURITY: { - path_conv full_path (file, PC_SYM_FOLLOW); + path_conv full_path (file, PC_SYM_FOLLOW, + transparent_exe ? stat_suffixes : NULL); if (full_path.error) { set_errno (full_path.error); diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index c0059ed..3fd669f 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -347,6 +347,7 @@ extern SYSTEM_INFO system_info; extern char *old_title; extern bool display_title; extern bool in_forkee; +extern bool transparent_exe; extern HANDLE hMainThread; extern HANDLE hMainProc; -- cgit v1.1