Skip to content

Commit 709ccc6

Browse files
authored
Merge pull request #122 from dscho/fix-stdio-with-app-exec-aliases-msys2
Fix stdio with app execution aliases (Microsoft Store applications)
2 parents 1f9f2cb + 1113cd7 commit 709ccc6

File tree

5 files changed

+36
-12
lines changed

5 files changed

+36
-12
lines changed

winsup/cygwin/fhandler/termios.cc

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -702,24 +702,43 @@ fhandler_termios::fstat (struct stat *buf)
702702
}
703703

704704
static bool
705-
is_console_app (const WCHAR *filename)
705+
is_console_app (path_conv &pc)
706706
{
707+
tmp_pathbuf tp;
708+
WCHAR *native_path = tp.w_get ();
709+
pc.get_wide_win32_path (native_path);
710+
711+
wchar_t *e = wcsrchr (native_path, L'.');
712+
if (e && (wcscasecmp (e, L".bat") == 0 || wcscasecmp (e, L".cmd") == 0))
713+
return true;
714+
715+
if (pc.is_app_execution_alias ())
716+
{
717+
UNICODE_STRING upath;
718+
RtlInitUnicodeString (&upath, native_path);
719+
path_conv target (&upath, PC_SYM_FOLLOW);
720+
target.get_wide_win32_path (native_path);
721+
}
722+
707723
HANDLE h;
708-
h = CreateFileW (filename, GENERIC_READ, FILE_SHARE_READ,
724+
h = CreateFileW (native_path, GENERIC_READ, FILE_SHARE_READ,
709725
NULL, OPEN_EXISTING, 0, NULL);
726+
if (h == INVALID_HANDLE_VALUE)
727+
return true;
710728
char buf[1024];
711729
DWORD n;
712-
ReadFile (h, buf, sizeof (buf), &n, 0);
730+
BOOL res = ReadFile (h, buf, sizeof (buf), &n, 0);
713731
CloseHandle (h);
732+
if (!res)
733+
return true;
714734
/* The offset of Subsystem is the same for both IMAGE_NT_HEADERS32 and
715735
IMAGE_NT_HEADERS64, so only IMAGE_NT_HEADERS32 is used here. */
716736
IMAGE_NT_HEADERS32 *p = (IMAGE_NT_HEADERS32 *) memmem (buf, n, "PE\0\0", 4);
717737
if (p && (char *) &p->OptionalHeader.DllCharacteristics <= buf + n)
718738
return p->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI;
719-
wchar_t *e = wcsrchr (filename, L'.');
720-
if (e && (wcscasecmp (e, L".bat") == 0 || wcscasecmp (e, L".cmd") == 0))
721-
return true;
722-
return false;
739+
/* Return true for unknown to avoid standard handles from being unset.
740+
Setting-up standard handles for GUI apps is pointless, but not unsafe. */
741+
return true;
723742
}
724743

725744
int
@@ -755,7 +774,7 @@ fhandler_termios::ioctl (unsigned int cmd, void *varg)
755774

756775
void
757776
fhandler_termios::spawn_worker::setup (bool iscygwin, HANDLE h_stdin,
758-
const WCHAR *runpath, bool nopcon,
777+
path_conv &pc, bool nopcon,
759778
bool reset_sendsig,
760779
const WCHAR *envblock)
761780
{
@@ -794,7 +813,7 @@ fhandler_termios::spawn_worker::setup (bool iscygwin, HANDLE h_stdin,
794813
ptys->setup_locale ();
795814
}
796815
}
797-
if (!iscygwin && ptys_primary && is_console_app (runpath))
816+
if (!iscygwin && ptys_primary && is_console_app (pc))
798817
{
799818
if (h_stdin == ptys_primary->get_handle_nat ())
800819
stdin_is_ptys = true;

winsup/cygwin/local_includes/fhandler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2035,7 +2035,7 @@ class fhandler_termios: public fhandler_base
20352035
spawn_worker () :
20362036
ptys_need_cleanup (false), cons_need_cleanup (false),
20372037
stdin_is_ptys (false), ptys_ttyp (NULL) {}
2038-
void setup (bool iscygwin, HANDLE h_stdin, const WCHAR *runpath,
2038+
void setup (bool iscygwin, HANDLE h_stdin, path_conv &pc,
20392039
bool nopcon, bool reset_sendsig, const WCHAR *envblock);
20402040
bool need_cleanup () { return ptys_need_cleanup || cons_need_cleanup; }
20412041
void cleanup ();

winsup/cygwin/local_includes/path.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ enum path_types
7979
PATH_SOCKET = _BIT ( 5), /* AF_UNIX socket file */
8080
PATH_RESOLVE_PROCFD = _BIT ( 6), /* fd symlink via /proc */
8181
PATH_REP_NOAPI = _BIT ( 7), /* rep. point unknown to WinAPI */
82+
PATH_APPEXECLINK = _BIT ( 8), /* rep. point app execution alias */
8283
PATH_DONT_USE = _BIT (31) /* conversion to signed happens. */
8384
};
8485

@@ -214,6 +215,10 @@ class path_conv
214215
{
215216
return (path_flags & (PATH_REP | PATH_REP_NOAPI)) == PATH_REP;
216217
}
218+
int is_app_execution_alias () const
219+
{
220+
return path_flags & PATH_APPEXECLINK;
221+
}
217222

218223
int isfifo () const {return dev.is_device (FH_FIFO);}
219224
int iscygdrive () const {return dev.is_device (FH_CYGDRIVE);}

winsup/cygwin/path.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2946,7 +2946,7 @@ check_reparse_point_target (HANDLE h, bool remote, PREPARSE_DATA_BUFFER rp,
29462946
if (i == 2 && n > 0 && n < size)
29472947
{
29482948
RtlInitCountedUnicodeString (psymbuf, buf, n * sizeof (WCHAR));
2949-
return PATH_SYMLINK | PATH_REP;
2949+
return PATH_SYMLINK | PATH_REP | PATH_APPEXECLINK;
29502950
}
29512951
if (i == 2)
29522952
break;

winsup/cygwin/spawn.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
609609

610610
bool no_pcon = mode != _P_OVERLAY && mode != _P_WAIT;
611611
term_spawn_worker.setup (iscygwin (), handle (fileno_stdin, false),
612-
runpath, no_pcon, reset_sendsig, envblock);
612+
real_path, no_pcon, reset_sendsig, envblock);
613613

614614
/* Set up needed handles for stdio */
615615
si.dwFlags = STARTF_USESTDHANDLES;

0 commit comments

Comments
 (0)