From a413f8a20eb6831d0162aab4b94c4d25f203e9be Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 15 Feb 2011 15:25:59 +0000 Subject: [PATCH] * devices.in: Throughout use slashes instead of backslashes in the native path of devices not backed by native NT devices. * devices.cc: Regenerate. * globals.cc (ro_u_pmem): Use correct case. (ro_u_globalroot): New R/O unicode string. * path.cc (path_conv::check): Fix incorrect handling of /proc/sys block devices if they are just visited due to a component check. (symlink_info::posixify): Fix typo in comment. (cygwin_conv_path): Use ro_u_globalroot instead of string constant. (fast_cwd_version): New shared variable to store FAST_CWD version used on the system. (find_fast_cwd_pointer): Rename from find_fast_cwd_pointers. Don't set global fast_cwd_ptr pointer here. Return pointer value instead. (find_fast_cwd): New function to set fast_cwd_ptr and fast_cwd_version. (cwdstuff::override_win32_cwd): Call find_fast_cwd from here. Check for fast_cwd_version to differ between old and new FAST_CWD structure. Check old_cwd for NULL to avoid SEGV. Don't set CWD if we have neitehr a valid fast_cwd_ptr, nor a valid CWD handle in the process parameter block. (cwdstuff::set): Create Win32 path taking /proc/sys paths into account. * spawn.cc (spawn_guts): Recode creating runpath. Also take /proc/sys paths into account. Drop special CWD handling when starting non-Cygwin processes. --- winsup/cygwin/ChangeLog | 26 ++++++ winsup/cygwin/devices.cc | 164 ++++++++++++++++---------------- winsup/cygwin/devices.in | 38 ++++---- winsup/cygwin/globals.cc | 5 +- winsup/cygwin/path.cc | 196 ++++++++++++++++++++++++++------------- winsup/cygwin/spawn.cc | 66 +++++++------ 6 files changed, 299 insertions(+), 196 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 3d0880de2..5141bbdeb 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,29 @@ +2011-02-15 Corinna Vinschen + + * devices.in: Throughout use slashes instead of backslashes in the + native path of devices not backed by native NT devices. + * devices.cc: Regenerate. + * globals.cc (ro_u_pmem): Use correct case. + (ro_u_globalroot): New R/O unicode string. + * path.cc (path_conv::check): Fix incorrect handling of /proc/sys + block devices if they are just visited due to a component check. + (symlink_info::posixify): Fix typo in comment. + (cygwin_conv_path): Use ro_u_globalroot instead of string constant. + (fast_cwd_version): New shared variable to store FAST_CWD version + used on the system. + (find_fast_cwd_pointer): Rename from find_fast_cwd_pointers. Don't + set global fast_cwd_ptr pointer here. Return pointer value instead. + (find_fast_cwd): New function to set fast_cwd_ptr and fast_cwd_version. + (cwdstuff::override_win32_cwd): Call find_fast_cwd from here. + Check for fast_cwd_version to differ between old and new FAST_CWD + structure. Check old_cwd for NULL to avoid SEGV. Don't set CWD if + we have neitehr a valid fast_cwd_ptr, nor a valid CWD handle in the + process parameter block. + (cwdstuff::set): Create Win32 path taking /proc/sys paths into account. + * spawn.cc (spawn_guts): Recode creating runpath. Also take /proc/sys + paths into account. Drop special CWD handling when starting non-Cygwin + processes. + 2011-02-15 Corinna Vinschen * fhandler_procsys.cc (fhandler_procsys::opendir): Avoid SEGV if diff --git a/winsup/cygwin/devices.cc b/winsup/cygwin/devices.cc index 66fe020ff..72c9a04a3 100644 --- a/winsup/cygwin/devices.cc +++ b/winsup/cygwin/devices.cc @@ -63,7 +63,7 @@ const device dev_bad_storage = static const device dev_storage[] = { {"/dev", BRACK(FH_DEV), "/dev"}, - {"/dev/clipboard", BRACK(FH_CLIPBOARD), "\\dev\\clipboard"}, + {"/dev/clipboard", BRACK(FH_CLIPBOARD), "/dev/clipboard"}, {"/dev/com1", BRACK(FHDEV(DEV_SERIAL_MAJOR, 0)), "\\??\\COM1"}, {"/dev/com2", BRACK(FHDEV(DEV_SERIAL_MAJOR, 1)), "\\??\\COM2"}, {"/dev/com3", BRACK(FHDEV(DEV_SERIAL_MAJOR, 2)), "\\??\\COM3"}, @@ -80,10 +80,10 @@ static const device dev_storage[] = {"/dev/com14", BRACK(FHDEV(DEV_SERIAL_MAJOR, 13)), "\\??\\COM14"}, {"/dev/com15", BRACK(FHDEV(DEV_SERIAL_MAJOR, 14)), "\\??\\COM15"}, {"/dev/com16", BRACK(FHDEV(DEV_SERIAL_MAJOR, 15)), "\\??\\COM16"}, - {"/dev/conin", BRACK(FH_CONIN), "conin"}, - {"/dev/conout", BRACK(FH_CONOUT), "conout"}, - {"/dev/console", BRACK(FH_CONSOLE), "\\dev\\console"}, - {"/dev/dsp", BRACK(FH_OSS_DSP), "\\dev\\dsp"}, + {"/dev/conin", BRACK(FH_CONIN), "/dev/conin"}, + {"/dev/conout", BRACK(FH_CONOUT), "/dev/conout"}, + {"/dev/console", BRACK(FH_CONSOLE), "/dev/console"}, + {"/dev/dsp", BRACK(FH_OSS_DSP), "/dev/dsp"}, {"/dev/fd0", BRACK(FHDEV(DEV_FLOPPY_MAJOR, 0)), "\\Device\\Floppy0"}, {"/dev/fd1", BRACK(FHDEV(DEV_FLOPPY_MAJOR, 1)), "\\Device\\Floppy1"}, {"/dev/fd2", BRACK(FHDEV(DEV_FLOPPY_MAJOR, 2)), "\\Device\\Floppy2"}, @@ -100,11 +100,11 @@ static const device dev_storage[] = {"/dev/fd13", BRACK(FHDEV(DEV_FLOPPY_MAJOR, 13)), "\\Device\\Floppy13"}, {"/dev/fd14", BRACK(FHDEV(DEV_FLOPPY_MAJOR, 14)), "\\Device\\Floppy14"}, {"/dev/fd15", BRACK(FHDEV(DEV_FLOPPY_MAJOR, 15)), "\\Device\\Floppy15"}, - {"/dev/fifo", BRACK(FH_FIFO), "\\dev\\fifo"}, - {"/dev/full", BRACK(FH_FULL), "\\dev\\full"}, - {"/dev/kmem", BRACK(FH_KMEM), "\\dev\\mem"}, + {"/dev/fifo", BRACK(FH_FIFO), "/dev/fifo"}, + {"/dev/full", BRACK(FH_FULL), "/dev/full"}, + {"/dev/kmem", BRACK(FH_KMEM), "/dev/mem"}, {"/dev/kmsg", BRACK(FH_KMSG), "\\Device\\MailSlot\\cygwin\\dev\\kmsg"}, - {"/dev/mem", BRACK(FH_MEM), "\\dev\\mem"}, + {"/dev/mem", BRACK(FH_MEM), "/dev/mem"}, {"/dev/nst0", BRACK(FHDEV(DEV_TAPE_MAJOR, 128)), "\\Device\\Tape0"}, {"/dev/nst1", BRACK(FHDEV(DEV_TAPE_MAJOR, 129)), "\\Device\\Tape1"}, {"/dev/nst2", BRACK(FHDEV(DEV_TAPE_MAJOR, 130)), "\\Device\\Tape2"}, @@ -234,10 +234,10 @@ static const device dev_storage[] = {"/dev/nst126", BRACK(FHDEV(DEV_TAPE_MAJOR, 254)), "\\Device\\Tape126"}, {"/dev/nst127", BRACK(FHDEV(DEV_TAPE_MAJOR, 255)), "\\Device\\Tape127"}, {"/dev/null", BRACK(FH_NULL), "\\Device\\Null"}, - {"/dev/pipe", BRACK(FH_PIPE), "\\dev\\pipe"}, - {"/dev/port", BRACK(FH_PORT), "\\dev\\port"}, - {"/dev/ptmx", BRACK(FH_PTYM), "\\dev\\ptmx"}, - {"/dev/random", BRACK(FH_RANDOM), "\\dev\\random"}, + {"/dev/pipe", BRACK(FH_PIPE), "/dev/pipe"}, + {"/dev/port", BRACK(FH_PORT), "/dev/port"}, + {"/dev/ptmx", BRACK(FH_PTYM), "/dev/ptmx"}, + {"/dev/random", BRACK(FH_RANDOM), "/dev/random"}, {"/dev/scd0", BRACK(FHDEV(DEV_CDROM_MAJOR, 0)), "\\Device\\CdRom0"}, {"/dev/scd1", BRACK(FHDEV(DEV_CDROM_MAJOR, 1)), "\\Device\\CdRom1"}, {"/dev/scd2", BRACK(FHDEV(DEV_CDROM_MAJOR, 2)), "\\Device\\CdRom2"}, @@ -2446,71 +2446,71 @@ static const device dev_storage[] = {"/dev/st125", BRACK(FHDEV(DEV_TAPE_MAJOR, 125)), "\\Device\\Tape125"}, {"/dev/st126", BRACK(FHDEV(DEV_TAPE_MAJOR, 126)), "\\Device\\Tape126"}, {"/dev/st127", BRACK(FHDEV(DEV_TAPE_MAJOR, 127)), "\\Device\\Tape127"}, - {"/dev/tty", BRACK(FH_TTY), "\\dev\\tty"}, - {"/dev/tty0", BRACK(FHDEV(DEV_TTYS_MAJOR, 0)), "\\dev\\tty0"}, - {"/dev/tty1", BRACK(FHDEV(DEV_TTYS_MAJOR, 1)), "\\dev\\tty1"}, - {"/dev/tty2", BRACK(FHDEV(DEV_TTYS_MAJOR, 2)), "\\dev\\tty2"}, - {"/dev/tty3", BRACK(FHDEV(DEV_TTYS_MAJOR, 3)), "\\dev\\tty3"}, - {"/dev/tty4", BRACK(FHDEV(DEV_TTYS_MAJOR, 4)), "\\dev\\tty4"}, - {"/dev/tty5", BRACK(FHDEV(DEV_TTYS_MAJOR, 5)), "\\dev\\tty5"}, - {"/dev/tty6", BRACK(FHDEV(DEV_TTYS_MAJOR, 6)), "\\dev\\tty6"}, - {"/dev/tty7", BRACK(FHDEV(DEV_TTYS_MAJOR, 7)), "\\dev\\tty7"}, - {"/dev/tty8", BRACK(FHDEV(DEV_TTYS_MAJOR, 8)), "\\dev\\tty8"}, - {"/dev/tty9", BRACK(FHDEV(DEV_TTYS_MAJOR, 9)), "\\dev\\tty9"}, - {"/dev/tty10", BRACK(FHDEV(DEV_TTYS_MAJOR, 10)), "\\dev\\tty10"}, - {"/dev/tty11", BRACK(FHDEV(DEV_TTYS_MAJOR, 11)), "\\dev\\tty11"}, - {"/dev/tty12", BRACK(FHDEV(DEV_TTYS_MAJOR, 12)), "\\dev\\tty12"}, - {"/dev/tty13", BRACK(FHDEV(DEV_TTYS_MAJOR, 13)), "\\dev\\tty13"}, - {"/dev/tty14", BRACK(FHDEV(DEV_TTYS_MAJOR, 14)), "\\dev\\tty14"}, - {"/dev/tty15", BRACK(FHDEV(DEV_TTYS_MAJOR, 15)), "\\dev\\tty15"}, - {"/dev/tty16", BRACK(FHDEV(DEV_TTYS_MAJOR, 16)), "\\dev\\tty16"}, - {"/dev/tty17", BRACK(FHDEV(DEV_TTYS_MAJOR, 17)), "\\dev\\tty17"}, - {"/dev/tty18", BRACK(FHDEV(DEV_TTYS_MAJOR, 18)), "\\dev\\tty18"}, - {"/dev/tty19", BRACK(FHDEV(DEV_TTYS_MAJOR, 19)), "\\dev\\tty19"}, - {"/dev/tty20", BRACK(FHDEV(DEV_TTYS_MAJOR, 20)), "\\dev\\tty20"}, - {"/dev/tty21", BRACK(FHDEV(DEV_TTYS_MAJOR, 21)), "\\dev\\tty21"}, - {"/dev/tty22", BRACK(FHDEV(DEV_TTYS_MAJOR, 22)), "\\dev\\tty22"}, - {"/dev/tty23", BRACK(FHDEV(DEV_TTYS_MAJOR, 23)), "\\dev\\tty23"}, - {"/dev/tty24", BRACK(FHDEV(DEV_TTYS_MAJOR, 24)), "\\dev\\tty24"}, - {"/dev/tty25", BRACK(FHDEV(DEV_TTYS_MAJOR, 25)), "\\dev\\tty25"}, - {"/dev/tty26", BRACK(FHDEV(DEV_TTYS_MAJOR, 26)), "\\dev\\tty26"}, - {"/dev/tty27", BRACK(FHDEV(DEV_TTYS_MAJOR, 27)), "\\dev\\tty27"}, - {"/dev/tty28", BRACK(FHDEV(DEV_TTYS_MAJOR, 28)), "\\dev\\tty28"}, - {"/dev/tty29", BRACK(FHDEV(DEV_TTYS_MAJOR, 29)), "\\dev\\tty29"}, - {"/dev/tty30", BRACK(FHDEV(DEV_TTYS_MAJOR, 30)), "\\dev\\tty30"}, - {"/dev/tty31", BRACK(FHDEV(DEV_TTYS_MAJOR, 31)), "\\dev\\tty31"}, - {"/dev/tty32", BRACK(FHDEV(DEV_TTYS_MAJOR, 32)), "\\dev\\tty32"}, - {"/dev/tty33", BRACK(FHDEV(DEV_TTYS_MAJOR, 33)), "\\dev\\tty33"}, - {"/dev/tty34", BRACK(FHDEV(DEV_TTYS_MAJOR, 34)), "\\dev\\tty34"}, - {"/dev/tty35", BRACK(FHDEV(DEV_TTYS_MAJOR, 35)), "\\dev\\tty35"}, - {"/dev/tty36", BRACK(FHDEV(DEV_TTYS_MAJOR, 36)), "\\dev\\tty36"}, - {"/dev/tty37", BRACK(FHDEV(DEV_TTYS_MAJOR, 37)), "\\dev\\tty37"}, - {"/dev/tty38", BRACK(FHDEV(DEV_TTYS_MAJOR, 38)), "\\dev\\tty38"}, - {"/dev/tty39", BRACK(FHDEV(DEV_TTYS_MAJOR, 39)), "\\dev\\tty39"}, - {"/dev/tty40", BRACK(FHDEV(DEV_TTYS_MAJOR, 40)), "\\dev\\tty40"}, - {"/dev/tty41", BRACK(FHDEV(DEV_TTYS_MAJOR, 41)), "\\dev\\tty41"}, - {"/dev/tty42", BRACK(FHDEV(DEV_TTYS_MAJOR, 42)), "\\dev\\tty42"}, - {"/dev/tty43", BRACK(FHDEV(DEV_TTYS_MAJOR, 43)), "\\dev\\tty43"}, - {"/dev/tty44", BRACK(FHDEV(DEV_TTYS_MAJOR, 44)), "\\dev\\tty44"}, - {"/dev/tty45", BRACK(FHDEV(DEV_TTYS_MAJOR, 45)), "\\dev\\tty45"}, - {"/dev/tty46", BRACK(FHDEV(DEV_TTYS_MAJOR, 46)), "\\dev\\tty46"}, - {"/dev/tty47", BRACK(FHDEV(DEV_TTYS_MAJOR, 47)), "\\dev\\tty47"}, - {"/dev/tty48", BRACK(FHDEV(DEV_TTYS_MAJOR, 48)), "\\dev\\tty48"}, - {"/dev/tty49", BRACK(FHDEV(DEV_TTYS_MAJOR, 49)), "\\dev\\tty49"}, - {"/dev/tty50", BRACK(FHDEV(DEV_TTYS_MAJOR, 50)), "\\dev\\tty50"}, - {"/dev/tty51", BRACK(FHDEV(DEV_TTYS_MAJOR, 51)), "\\dev\\tty51"}, - {"/dev/tty52", BRACK(FHDEV(DEV_TTYS_MAJOR, 52)), "\\dev\\tty52"}, - {"/dev/tty53", BRACK(FHDEV(DEV_TTYS_MAJOR, 53)), "\\dev\\tty53"}, - {"/dev/tty54", BRACK(FHDEV(DEV_TTYS_MAJOR, 54)), "\\dev\\tty54"}, - {"/dev/tty55", BRACK(FHDEV(DEV_TTYS_MAJOR, 55)), "\\dev\\tty55"}, - {"/dev/tty56", BRACK(FHDEV(DEV_TTYS_MAJOR, 56)), "\\dev\\tty56"}, - {"/dev/tty57", BRACK(FHDEV(DEV_TTYS_MAJOR, 57)), "\\dev\\tty57"}, - {"/dev/tty58", BRACK(FHDEV(DEV_TTYS_MAJOR, 58)), "\\dev\\tty58"}, - {"/dev/tty59", BRACK(FHDEV(DEV_TTYS_MAJOR, 59)), "\\dev\\tty59"}, - {"/dev/tty60", BRACK(FHDEV(DEV_TTYS_MAJOR, 60)), "\\dev\\tty60"}, - {"/dev/tty61", BRACK(FHDEV(DEV_TTYS_MAJOR, 61)), "\\dev\\tty61"}, - {"/dev/tty62", BRACK(FHDEV(DEV_TTYS_MAJOR, 62)), "\\dev\\tty62"}, - {"/dev/tty63", BRACK(FHDEV(DEV_TTYS_MAJOR, 63)), "\\dev\\tty63"}, + {"/dev/tty", BRACK(FH_TTY), "/dev/tty"}, + {"/dev/tty0", BRACK(FHDEV(DEV_TTYS_MAJOR, 0)), "/dev/tty0"}, + {"/dev/tty1", BRACK(FHDEV(DEV_TTYS_MAJOR, 1)), "/dev/tty1"}, + {"/dev/tty2", BRACK(FHDEV(DEV_TTYS_MAJOR, 2)), "/dev/tty2"}, + {"/dev/tty3", BRACK(FHDEV(DEV_TTYS_MAJOR, 3)), "/dev/tty3"}, + {"/dev/tty4", BRACK(FHDEV(DEV_TTYS_MAJOR, 4)), "/dev/tty4"}, + {"/dev/tty5", BRACK(FHDEV(DEV_TTYS_MAJOR, 5)), "/dev/tty5"}, + {"/dev/tty6", BRACK(FHDEV(DEV_TTYS_MAJOR, 6)), "/dev/tty6"}, + {"/dev/tty7", BRACK(FHDEV(DEV_TTYS_MAJOR, 7)), "/dev/tty7"}, + {"/dev/tty8", BRACK(FHDEV(DEV_TTYS_MAJOR, 8)), "/dev/tty8"}, + {"/dev/tty9", BRACK(FHDEV(DEV_TTYS_MAJOR, 9)), "/dev/tty9"}, + {"/dev/tty10", BRACK(FHDEV(DEV_TTYS_MAJOR, 10)), "/dev/tty10"}, + {"/dev/tty11", BRACK(FHDEV(DEV_TTYS_MAJOR, 11)), "/dev/tty11"}, + {"/dev/tty12", BRACK(FHDEV(DEV_TTYS_MAJOR, 12)), "/dev/tty12"}, + {"/dev/tty13", BRACK(FHDEV(DEV_TTYS_MAJOR, 13)), "/dev/tty13"}, + {"/dev/tty14", BRACK(FHDEV(DEV_TTYS_MAJOR, 14)), "/dev/tty14"}, + {"/dev/tty15", BRACK(FHDEV(DEV_TTYS_MAJOR, 15)), "/dev/tty15"}, + {"/dev/tty16", BRACK(FHDEV(DEV_TTYS_MAJOR, 16)), "/dev/tty16"}, + {"/dev/tty17", BRACK(FHDEV(DEV_TTYS_MAJOR, 17)), "/dev/tty17"}, + {"/dev/tty18", BRACK(FHDEV(DEV_TTYS_MAJOR, 18)), "/dev/tty18"}, + {"/dev/tty19", BRACK(FHDEV(DEV_TTYS_MAJOR, 19)), "/dev/tty19"}, + {"/dev/tty20", BRACK(FHDEV(DEV_TTYS_MAJOR, 20)), "/dev/tty20"}, + {"/dev/tty21", BRACK(FHDEV(DEV_TTYS_MAJOR, 21)), "/dev/tty21"}, + {"/dev/tty22", BRACK(FHDEV(DEV_TTYS_MAJOR, 22)), "/dev/tty22"}, + {"/dev/tty23", BRACK(FHDEV(DEV_TTYS_MAJOR, 23)), "/dev/tty23"}, + {"/dev/tty24", BRACK(FHDEV(DEV_TTYS_MAJOR, 24)), "/dev/tty24"}, + {"/dev/tty25", BRACK(FHDEV(DEV_TTYS_MAJOR, 25)), "/dev/tty25"}, + {"/dev/tty26", BRACK(FHDEV(DEV_TTYS_MAJOR, 26)), "/dev/tty26"}, + {"/dev/tty27", BRACK(FHDEV(DEV_TTYS_MAJOR, 27)), "/dev/tty27"}, + {"/dev/tty28", BRACK(FHDEV(DEV_TTYS_MAJOR, 28)), "/dev/tty28"}, + {"/dev/tty29", BRACK(FHDEV(DEV_TTYS_MAJOR, 29)), "/dev/tty29"}, + {"/dev/tty30", BRACK(FHDEV(DEV_TTYS_MAJOR, 30)), "/dev/tty30"}, + {"/dev/tty31", BRACK(FHDEV(DEV_TTYS_MAJOR, 31)), "/dev/tty31"}, + {"/dev/tty32", BRACK(FHDEV(DEV_TTYS_MAJOR, 32)), "/dev/tty32"}, + {"/dev/tty33", BRACK(FHDEV(DEV_TTYS_MAJOR, 33)), "/dev/tty33"}, + {"/dev/tty34", BRACK(FHDEV(DEV_TTYS_MAJOR, 34)), "/dev/tty34"}, + {"/dev/tty35", BRACK(FHDEV(DEV_TTYS_MAJOR, 35)), "/dev/tty35"}, + {"/dev/tty36", BRACK(FHDEV(DEV_TTYS_MAJOR, 36)), "/dev/tty36"}, + {"/dev/tty37", BRACK(FHDEV(DEV_TTYS_MAJOR, 37)), "/dev/tty37"}, + {"/dev/tty38", BRACK(FHDEV(DEV_TTYS_MAJOR, 38)), "/dev/tty38"}, + {"/dev/tty39", BRACK(FHDEV(DEV_TTYS_MAJOR, 39)), "/dev/tty39"}, + {"/dev/tty40", BRACK(FHDEV(DEV_TTYS_MAJOR, 40)), "/dev/tty40"}, + {"/dev/tty41", BRACK(FHDEV(DEV_TTYS_MAJOR, 41)), "/dev/tty41"}, + {"/dev/tty42", BRACK(FHDEV(DEV_TTYS_MAJOR, 42)), "/dev/tty42"}, + {"/dev/tty43", BRACK(FHDEV(DEV_TTYS_MAJOR, 43)), "/dev/tty43"}, + {"/dev/tty44", BRACK(FHDEV(DEV_TTYS_MAJOR, 44)), "/dev/tty44"}, + {"/dev/tty45", BRACK(FHDEV(DEV_TTYS_MAJOR, 45)), "/dev/tty45"}, + {"/dev/tty46", BRACK(FHDEV(DEV_TTYS_MAJOR, 46)), "/dev/tty46"}, + {"/dev/tty47", BRACK(FHDEV(DEV_TTYS_MAJOR, 47)), "/dev/tty47"}, + {"/dev/tty48", BRACK(FHDEV(DEV_TTYS_MAJOR, 48)), "/dev/tty48"}, + {"/dev/tty49", BRACK(FHDEV(DEV_TTYS_MAJOR, 49)), "/dev/tty49"}, + {"/dev/tty50", BRACK(FHDEV(DEV_TTYS_MAJOR, 50)), "/dev/tty50"}, + {"/dev/tty51", BRACK(FHDEV(DEV_TTYS_MAJOR, 51)), "/dev/tty51"}, + {"/dev/tty52", BRACK(FHDEV(DEV_TTYS_MAJOR, 52)), "/dev/tty52"}, + {"/dev/tty53", BRACK(FHDEV(DEV_TTYS_MAJOR, 53)), "/dev/tty53"}, + {"/dev/tty54", BRACK(FHDEV(DEV_TTYS_MAJOR, 54)), "/dev/tty54"}, + {"/dev/tty55", BRACK(FHDEV(DEV_TTYS_MAJOR, 55)), "/dev/tty55"}, + {"/dev/tty56", BRACK(FHDEV(DEV_TTYS_MAJOR, 56)), "/dev/tty56"}, + {"/dev/tty57", BRACK(FHDEV(DEV_TTYS_MAJOR, 57)), "/dev/tty57"}, + {"/dev/tty58", BRACK(FHDEV(DEV_TTYS_MAJOR, 58)), "/dev/tty58"}, + {"/dev/tty59", BRACK(FHDEV(DEV_TTYS_MAJOR, 59)), "/dev/tty59"}, + {"/dev/tty60", BRACK(FHDEV(DEV_TTYS_MAJOR, 60)), "/dev/tty60"}, + {"/dev/tty61", BRACK(FHDEV(DEV_TTYS_MAJOR, 61)), "/dev/tty61"}, + {"/dev/tty62", BRACK(FHDEV(DEV_TTYS_MAJOR, 62)), "/dev/tty62"}, + {"/dev/tty63", BRACK(FHDEV(DEV_TTYS_MAJOR, 63)), "/dev/tty63"}, {"/dev/ttyS0", BRACK(FHDEV(DEV_SERIAL_MAJOR, 0)), "\\??\\COM1"}, {"/dev/ttyS1", BRACK(FHDEV(DEV_SERIAL_MAJOR, 1)), "\\??\\COM2"}, {"/dev/ttyS2", BRACK(FHDEV(DEV_SERIAL_MAJOR, 2)), "\\??\\COM3"}, @@ -2575,10 +2575,10 @@ static const device dev_storage[] = {"/dev/ttyS61", BRACK(FHDEV(DEV_SERIAL_MAJOR, 61)), "\\??\\COM62"}, {"/dev/ttyS62", BRACK(FHDEV(DEV_SERIAL_MAJOR, 62)), "\\??\\COM63"}, {"/dev/ttyS63", BRACK(FHDEV(DEV_SERIAL_MAJOR, 63)), "\\??\\COM64"}, - {"/dev/ttym", BRACK(FH_TTYM), "\\dev\\ttym"}, - {"/dev/urandom", BRACK(FH_URANDOM), "\\dev\\urandom"}, - {"/dev/windows", BRACK(FH_WINDOWS), "\\dev\\windows"}, - {"/dev/zero", BRACK(FH_ZERO), "\\dev\\zero"} + {"/dev/ttym", BRACK(FH_TTYM), "/dev/ttym"}, + {"/dev/urandom", BRACK(FH_URANDOM), "/dev/urandom"}, + {"/dev/windows", BRACK(FH_WINDOWS), "/dev/windows"}, + {"/dev/zero", BRACK(FH_ZERO), "/dev/zero"} }; const device *console_dev = dev_storage + 20; diff --git a/winsup/cygwin/devices.in b/winsup/cygwin/devices.in index 591225e20..058e1617f 100644 --- a/winsup/cygwin/devices.in +++ b/winsup/cygwin/devices.in @@ -59,28 +59,28 @@ const device dev_bad_storage = %storage_here } %% -"/dev/tty", BRACK(FH_TTY), "\\dev\\tty" -"/dev/tty%(0-63)d", BRACK(FHDEV(DEV_TTYS_MAJOR, {$1})), "\\dev\\tty{$1}", ttys_dev -"/dev/console", BRACK(FH_CONSOLE), "\\dev\\console", console_dev -"/dev/ttym", BRACK(FH_TTYM), "\\dev\\ttym", ttym_dev -"/dev/ptmx", BRACK(FH_PTYM), "\\dev\\ptmx" -"/dev/windows", BRACK(FH_WINDOWS), "\\dev\\windows" -"/dev/dsp", BRACK(FH_OSS_DSP), "\\dev\\dsp" -"/dev/conin", BRACK(FH_CONIN), "conin" -"/dev/conout", BRACK(FH_CONOUT), "conout" +"/dev/tty", BRACK(FH_TTY), "/dev/tty" +"/dev/tty%(0-63)d", BRACK(FHDEV(DEV_TTYS_MAJOR, {$1})), "/dev/tty{$1}", ttys_dev +"/dev/console", BRACK(FH_CONSOLE), "/dev/console", console_dev +"/dev/ttym", BRACK(FH_TTYM), "/dev/ttym", ttym_dev +"/dev/ptmx", BRACK(FH_PTYM), "/dev/ptmx" +"/dev/windows", BRACK(FH_WINDOWS), "/dev/windows" +"/dev/dsp", BRACK(FH_OSS_DSP), "/dev/dsp" +"/dev/conin", BRACK(FH_CONIN), "/dev/conin" +"/dev/conout", BRACK(FH_CONOUT), "/dev/conout" "/dev/null", BRACK(FH_NULL), "\\Device\\Null" -"/dev/zero", BRACK(FH_ZERO), "\\dev\\zero" -"/dev/full", BRACK(FH_FULL), "\\dev\\full" -"/dev/random", BRACK(FH_RANDOM), "\\dev\\random" -"/dev/urandom", BRACK(FH_URANDOM), "\\dev\\urandom", urandom_dev -"/dev/mem", BRACK(FH_MEM), "\\dev\\mem" -"/dev/kmem", BRACK(FH_KMEM), "\\dev\\mem" -"/dev/clipboard", BRACK(FH_CLIPBOARD), "\\dev\\clipboard" -"/dev/port", BRACK(FH_PORT), "\\dev\\port" +"/dev/zero", BRACK(FH_ZERO), "/dev/zero" +"/dev/full", BRACK(FH_FULL), "/dev/full" +"/dev/random", BRACK(FH_RANDOM), "/dev/random" +"/dev/urandom", BRACK(FH_URANDOM), "/dev/urandom", urandom_dev +"/dev/mem", BRACK(FH_MEM), "/dev/mem" +"/dev/kmem", BRACK(FH_KMEM), "/dev/mem" +"/dev/clipboard", BRACK(FH_CLIPBOARD), "/dev/clipboard" +"/dev/port", BRACK(FH_PORT), "/dev/port" "/dev/com%(1-16)d", BRACK(FHDEV(DEV_SERIAL_MAJOR, {$1 - 1})), "\\??\\COM{$1}" "/dev/ttyS%(0-63)d", BRACK(FHDEV(DEV_SERIAL_MAJOR, {$1})), "\\??\\COM{$1 + 1}" -"/dev/pipe", BRACK(FH_PIPE), "\\dev\\pipe" -"/dev/fifo", BRACK(FH_FIFO), "\\dev\\fifo" +"/dev/pipe", BRACK(FH_PIPE), "/dev/pipe" +"/dev/fifo", BRACK(FH_FIFO), "/dev/fifo" "/dev/st%(0-127)d", BRACK(FHDEV(DEV_TAPE_MAJOR, {$1})), "\\Device\\Tape{$1}" "/dev/nst%(0-127)d", BRACK(FHDEV(DEV_TAPE_MAJOR, {$1 + 128})), "\\Device\\Tape{$1}" "/dev/fd%(0-15)d", BRACK(FHDEV(DEV_FLOPPY_MAJOR, {$1})), "\\Device\\Floppy{$1}" diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc index f04c8e3ea..94823d7cf 100644 --- a/winsup/cygwin/globals.cc +++ b/winsup/cygwin/globals.cc @@ -1,7 +1,7 @@ /* globals.cc - Define global variables here. Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007, 2008, 2009, 2010 Red Hat, Inc. + 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc. This file is part of Cygwin. @@ -99,7 +99,7 @@ UNICODE_STRING _RDATA ro_u_com = _ROU (L".com"); UNICODE_STRING _RDATA ro_u_scr = _ROU (L".scr"); UNICODE_STRING _RDATA ro_u_sys = _ROU (L".sys"); UNICODE_STRING _RDATA ro_u_proc = _ROU (L"proc"); -UNICODE_STRING _RDATA ro_u_pmem = _ROU (L"\\device\\physicalmemory"); +UNICODE_STRING _RDATA ro_u_pmem = _ROU (L"\\Device\\PhysicalMemory"); UNICODE_STRING _RDATA ro_u_natp = _ROU (L"\\??\\"); UNICODE_STRING _RDATA ro_u_uncp = _ROU (L"\\??\\UNC\\"); UNICODE_STRING _RDATA ro_u_mtx = _ROU (L"mtx"); @@ -114,6 +114,7 @@ UNICODE_STRING _RDATA ro_u_unixfs = _ROU (L"UNIXFS"); UNICODE_STRING _RDATA ro_u_nwfs = _ROU (L"NWFS"); UNICODE_STRING _RDATA ro_u_volume = _ROU (L"\\??\\Volume{"); UNICODE_STRING _RDATA ro_u_pipedir = _ROU (L"\\\\?\\PIPE\\"); +UNICODE_STRING _RDATA ro_u_globalroot = _ROU (L"\\\\.\\GLOBALROOT"); #undef _ROU /* Cygwin properties are meant to be readonly data placed in the DLL, but diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index e1371d308..f6704fb8a 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -786,17 +786,12 @@ path_conv::check (const char *src, unsigned opt, requested, the target is the root directory of the filesystem on this block device. So we convert this to a real file and attach the backslash. */ - if (component || need_directory) + if (component == 0 && need_directory) { dev.parse (FH_FS); - if (component == 0) - { - strcat (full_path, "\\"); - fileattr = FILE_ATTRIBUTE_DIRECTORY - | FILE_ATTRIBUTE_DEVICE; - } - else - fileattr = 0; + strcat (full_path, "\\"); + fileattr = FILE_ATTRIBUTE_DIRECTORY + | FILE_ATTRIBUTE_DEVICE; goto out; } /*FALLTHRU*/ @@ -1996,7 +1991,7 @@ symlink_info::posixify (char *srcbuf) A path starting with two slashes(!) or backslashes is converted into an NT UNC path. Unfortunately, in contrast to POSIX rules, paths starting with three or more (back)slashes are also converted into UNC paths, - just incorrectly sticking to one redundant leading backslashe. We go + just incorrectly sticking to one redundant leading backslash. We go along with this behaviour to avoid scenarios in which native tools access other files than Cygwin. The above rules are used exactly the same way on Cygwin specific symlinks @@ -2940,7 +2935,10 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to, { /* Device name points to somewhere else in the NT namespace. Use GLOBALROOT prefix to convert to Win32 path. */ - char *p = stpcpy (buf, "\\\\.\\GLOBALROOT"); + char *p = buf + sys_wcstombs (buf, NT_MAX_PATH, + ro_u_globalroot.Buffer, + ro_u_globalroot.Length + / sizeof (WCHAR)); sys_wcstombs (p, NT_MAX_PATH - (p - buf), up->Buffer, up->Length / sizeof (WCHAR)); } @@ -3001,8 +2999,8 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to, { /* Device name points to somewhere else in the NT namespace. Use GLOBALROOT prefix to convert to Win32 path. */ - to = (void *) wcpcpy ((wchar_t *) to, L"\\\\.\\GLOBALROOT"); - lsiz += sizeof ("\\\\.\\GLOBALROOT") - 1; + to = (void *) wcpcpy ((wchar_t *) to, ro_u_globalroot.Buffer); + lsiz += ro_u_globalroot.Length / sizeof (WCHAR); } /* TODO: Same ".\\" band-aid as in CCP_POSIX_TO_WIN_A case. */ if (relative && !strcmp ((const char *) from, ".") @@ -3378,7 +3376,7 @@ cygwin_split_path (const char *path, char *dir, char *file) /*****************************************************************************/ -/* The find_fast_cwd_pointers function and parts of the +/* The find_fast_cwd_pointer function and parts of the cwdstuff::override_win32_cwd method are based on code using the following license: @@ -3444,11 +3442,16 @@ typedef struct _FAST_CWD_OLD { to the FAST_CWD structure which constitutes the CWD. We put the pointer into the common shared DLL segment. This allows to - restrict the call to find_fast_cwd_pointers() to once per Cygwin session + restrict the call to find_fast_cwd_pointer() to once per Cygwin session per user session. This works, because ASLR randomizes the load address of DLLs only once at boot time. */ static PFAST_CWD *fast_cwd_ptr __attribute__((section (".cygwin_dll_common"), shared)) = (PFAST_CWD *) -1; +/* Type of FAST_CWD used on this system. Keeping this information available + in shared memory avoids to test for the version every time around. + Default to new version. */ +static int fast_cwd_version + __attribute__((section (".cygwin_dll_common"), shared)) = 1; /* This is the mapping of the KUSER_SHARED_DATA structure into the 32 bit user address space. We need it here to access the current DismountCount. */ @@ -3465,25 +3468,23 @@ static KUSER_SHARED_DATA &SharedUserData This code has been tested on Vista 32/64 bit, Server 2008 32/64 bit, Windows 7 32/64 bit, and Server 2008 R2 (which is only 64 bit anyway). There's some hope that this will still work for Windows 8... */ -static void -find_fast_cwd_pointers () +static PFAST_CWD * +find_fast_cwd_pointer () { - /* Note that we have been called. */ - fast_cwd_ptr = NULL; /* Fetch entry points of relevant functions in ntdll.dll. */ HMODULE ntdll = GetModuleHandle ("ntdll.dll"); if (!ntdll) - return; + return NULL; const uint8_t *get_dir = (const uint8_t *) GetProcAddress (ntdll, "RtlGetCurrentDirectory_U"); const uint8_t *ent_crit = (const uint8_t *) GetProcAddress (ntdll, "RtlEnterCriticalSection"); if (!get_dir || !ent_crit) - return; + return NULL; /* Search first relative call instruction in RtlGetCurrentDirectory_U. */ const uint8_t *rcall = (const uint8_t *) memchr (get_dir, 0xe8, 32); if (!rcall) - return; + return NULL; /* Fetch offset from instruction and compute address of called function. This function actually fetches the current FAST_CWD instance and performs some other actions, not important to us. */ @@ -3495,27 +3496,27 @@ find_fast_cwd_pointers () "push edi". */ const uint8_t *movedi = pushedi + 1; if (movedi[0] != 0xbf || movedi[5] != 0x57) - return; + return NULL; /* Compare the address used for the critical section with the known PEB lock as stored in the PEB. */ if ((PRTL_CRITICAL_SECTION) peek32 (movedi + 1) != NtCurrentTeb ()->Peb->FastPebLock) - return; + return NULL; /* To check we are seeing the right code, we check our expectation that the next instruction is a relative call into RtlEnterCriticalSection. */ rcall = movedi + 6; if (rcall[0] != 0xe8) - return; + return NULL; /* Check that this is a relative call to RtlEnterCriticalSection. */ offset = (ptrdiff_t) peek32 (rcall + 1); if (rcall + 5 + offset != ent_crit) - return; + return NULL; /* After locking the critical section, the code should read the global PFAST_CWD * pointer that is guarded by that critical section. */ const uint8_t *movesi = rcall + 5; if (movesi[0] != 0x8b) - return; - fast_cwd_ptr = (PFAST_CWD *) peek32 (movesi + 2); + return NULL; + return (PFAST_CWD *) peek32 (movesi + 2); } static inline void @@ -3529,10 +3530,66 @@ copy_cwd_str (PUNICODE_STRING tgt, PUNICODE_STRING src) } } +static PFAST_CWD * +find_fast_cwd () +{ + /* Fetch the pointer but don't set the global fast_cwd_ptr yet. First + we have to make sure we know the version of the FAST_CWD structure + used on the system. */ + PFAST_CWD *f_cwd_ptr = find_fast_cwd_pointer (); + if (!f_cwd_ptr) + system_printf ("WARNING: Couldn't compute FAST_CWD pointer. " + "Please report this problem to\nthe public mailing " + "list cygwin@cygwin.com"); + if (f_cwd_ptr && *f_cwd_ptr) + { + /* Fortunately it's simple to check for the new structure. + Path.MaximumLength takes the same space as the high word of + the old ReferenceCount. We know that MaximumLength is always + MAX_PATH. For the ref count this would account for a + pratically impossible value between 34078720 and 34079240. */ + fast_cwd_version = ((*f_cwd_ptr)->Path.MaximumLength + == MAX_PATH * sizeof (WCHAR)) ? 1 : 0; + } + else + { + /* If we couldn't fetch fast_cwd_ptr, or if fast_cwd_ptr is + NULL(*) we have to figure out the version from the Buffer + pointer in the ProcessParameters. We must make sure not + to access memory outside of the structure. Therefore we + check the Path.Buffer pointer, + which would be the ReferenceCount in the old structure. + + (*) This is very unlikely to happen when starting the first + Cygwin process, since it only happens when starting the + process in a directory which can't be used as CWD by Win32, or + if the directory doesn't exist. But *if* it happens, we have + no valid FAST_CWD structure, even though upp_cwd_str.Buffer is + not NULL in that case. So we let the OS create a valid + FAST_CWD structure temporarily to have something to work with. + We know the pipe FS works. */ + PEB &peb = *NtCurrentTeb ()->Peb; + + if (f_cwd_ptr /* so *f_cwd_ptr == NULL */ + && !NT_SUCCESS (RtlSetCurrentDirectory_U (&ro_u_pipedir))) + api_fatal ("Couldn't set directory to %S temporarily.\n" + "Cannot continue.", &ro_u_pipedir); + RtlEnterCriticalSection (peb.FastPebLock); + PFAST_CWD f_cwd = (PFAST_CWD) + ((PBYTE) peb.ProcessParameters->CurrentDirectoryName.Buffer + - __builtin_offsetof (struct _FAST_CWD, Buffer)); + fast_cwd_version = (f_cwd->Path.Buffer == f_cwd->Buffer) ? 1 : 0; + RtlLeaveCriticalSection (peb.FastPebLock); + } + /* Eventually, after we set the version as well, set fast_cwd_ptr. */ + return f_cwd_ptr; +} + void cwdstuff::override_win32_cwd (bool init, ULONG old_dismount_count) { NTSTATUS status; + IO_STATUS_BLOCK io; HANDLE h = NULL; PEB &peb = *NtCurrentTeb ()->Peb; @@ -3542,13 +3599,7 @@ cwdstuff::override_win32_cwd (bool init, ULONG old_dismount_count) if (wincap.has_fast_cwd ()) { if (fast_cwd_ptr == (PFAST_CWD *) -1) - { - find_fast_cwd_pointers (); - if (!fast_cwd_ptr) - system_printf ("WARNING: Couldn't compute FAST_CWD pointer. " - "Please report this problem to\nthe public mailing " - "list cygwin@cygwin.com"); - } + fast_cwd_ptr = find_fast_cwd (); if (fast_cwd_ptr) { /* Default method starting with Vista. If we got a valid value for @@ -3566,15 +3617,10 @@ cwdstuff::override_win32_cwd (bool init, ULONG old_dismount_count) debug_printf ("RtlAllocateHeap failed"); return; } - /* Fill in the values. Fortunately it's simple to check for the - new structure. Path.MaximumLength takes the same space as the - high word of the old ReferenceCount. We know that MaximumLength - is always MAX_PATH. For the ref count this would account for a - pratically impossible value between 34078720 and 34079240. */ - if ((*fast_cwd_ptr)->Path.MaximumLength == MAX_PATH * sizeof (WCHAR)) + /* Fill in the values. */ + if (fast_cwd_version) { /* New FAST_CWD structure. */ - IO_STATUS_BLOCK io; FILE_FS_DEVICE_INFORMATION ffdi; RtlInitEmptyUnicodeString (&f_cwd->Path, f_cwd->Buffer, @@ -3608,7 +3654,8 @@ cwdstuff::override_win32_cwd (bool init, ULONG old_dismount_count) RtlLeaveCriticalSection (peb.FastPebLock); /* Decrement the reference count. If it's down to 0, free structure from heap. */ - if (InterlockedDecrement (&old_cwd->ReferenceCount) == 0) + if (old_cwd + && InterlockedDecrement (&old_cwd->ReferenceCount) == 0) { /* In contrast to pre-Vista, the handle on init is always a fresh one and not the handle inherited from the parent @@ -3621,8 +3668,8 @@ cwdstuff::override_win32_cwd (bool init, ULONG old_dismount_count) } else { - /* Old FAST_CWD structure. Otherwise same procedure as above, - except for the non-existant FSCharacteristics member. */ + /* Old FAST_CWD structure. Same procedure as above, except for + the non-existant FSCharacteristics member. */ PFAST_CWD_OLD f_cwd_old = (PFAST_CWD_OLD) f_cwd; f_cwd_old->ReferenceCount = 1; f_cwd_old->DirectoryHandle = dir; @@ -3636,7 +3683,8 @@ cwdstuff::override_win32_cwd (bool init, ULONG old_dismount_count) upp_cwd_str = f_cwd_old->Path; upp_cwd_hdl = dir; RtlLeaveCriticalSection (peb.FastPebLock); - if (InterlockedDecrement (&old_cwd->ReferenceCount) == 0) + if (old_cwd + && InterlockedDecrement (&old_cwd->ReferenceCount) == 0) { if (old_cwd->DirectoryHandle) NtClose (old_cwd->DirectoryHandle); @@ -3681,14 +3729,23 @@ cwdstuff::override_win32_cwd (bool init, ULONG old_dismount_count) return; } } + else if (upp_cwd_hdl == NULL) + return; RtlEnterCriticalSection (peb.FastPebLock); - PFAST_CWD f_cwd = (PFAST_CWD) - ((PBYTE) upp_cwd_str.Buffer - - __builtin_offsetof (struct _FAST_CWD, Buffer)); - if (f_cwd->Path.MaximumLength == MAX_PATH * sizeof (WCHAR)) - f_cwd->DirectoryHandle = dir; + if (fast_cwd_version) + { + PFAST_CWD f_cwd = (PFAST_CWD) + ((PBYTE) upp_cwd_str.Buffer + - __builtin_offsetof (struct _FAST_CWD, Buffer)); + f_cwd->DirectoryHandle = dir; + } else - ((PFAST_CWD_OLD) f_cwd)->DirectoryHandle = dir; + { + PFAST_CWD_OLD f_cwd_old = (PFAST_CWD_OLD) + ((PBYTE) upp_cwd_str.Buffer + - __builtin_offsetof (struct _FAST_CWD_OLD, Buffer)); + f_cwd_old->DirectoryHandle = dir; + } h = upp_cwd_hdl; upp_cwd_hdl = dir; RtlLeaveCriticalSection (peb.FastPebLock); @@ -3878,21 +3935,32 @@ cwdstuff::set (path_conv *nat_cwd, const char *posix_cwd) } else { - if (virtual_path) /* don't mangle virtual path. */ - ; - else + if (!virtual_path) /* don't mangle virtual path. */ { - /* Compute length on Win32 path. */ - size_t len = upath.Length / sizeof (WCHAR) - 4; - if (RtlEqualUnicodePathPrefix (&upath, &ro_u_uncp, TRUE)) + /* Convert into Win32 path and compute length. */ + if (upath.Buffer[1] == L'?') { - len -= 2; - unc_path = true; + upath.Buffer += 4; + upath.Length -= 4 * sizeof (WCHAR); + if (upath.Buffer[1] != L':') + { + /* UNC path */ + upath.Buffer += 2; + upath.Length -= 2 * sizeof (WCHAR); + unc_path = true; + } + } + else + { + /* Path via native NT namespace. Prepend GLOBALROOT prefix + to create a valid Win32 path. */ + PWCHAR buf = (PWCHAR) alloca (upath.Length + + ro_u_globalroot.Length + + sizeof (WCHAR)); + wcpcpy (wcpcpy (buf, ro_u_globalroot.Buffer), upath.Buffer); + upath.Buffer = buf; + upath.Length += ro_u_globalroot.Length; } - /* Convert to a Win32 path. */ - upath.Buffer += upath.Length / sizeof (WCHAR) - len; - upath.Length = len * sizeof (WCHAR); - PWSTR eoBuffer = upath.Buffer + (upath.Length / sizeof (WCHAR)); /* Remove trailing slash if one exists. */ if ((eoBuffer - upath.Buffer) > 3 && eoBuffer[-1] == L'\\') diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 1b268e4a7..68e5572a3 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -490,26 +490,43 @@ spawn_guts (const char *prog_arg, const char *const *argv, system_printf ("duplicate to pid_handle failed, %E"); } - runpath = null_app_name ? NULL : real_path.get_wide_win32_path (runpath); - if (runpath) - { /* If the executable path length is < MAX_PATH, make sure the long path - win32 prefix is removed from the path to make subsequent native Win32 - child processes happy which are not long path aware. */ - USHORT len = real_path.get_nt_native_path ()->Length; - if (len < (MAX_PATH + 4) * sizeof (WCHAR) - || (runpath[5] != L':' /* UNC path */ - && len < (MAX_PATH + 6) * sizeof (WCHAR))) + if (null_app_name) + runpath = NULL; + else + { + USHORT len = real_path.get_nt_native_path ()->Length / sizeof (WCHAR); + if (RtlEqualUnicodePathPrefix (real_path.get_nt_native_path (), + &ro_u_natp, FALSE)) { - PWCHAR r = runpath + 4; - if (r[1] != L':') /* UNC path */ - *(r += 2) = L'\\'; - if (!RtlIsDosDeviceName_U (r)) - runpath = r; - else if (*r == L'\\') - *r = L'C'; + runpath = real_path.get_wide_win32_path (runpath); + /* If the executable path length is < MAX_PATH, make sure the long + path win32 prefix is removed from the path to make subsequent + not long path aware native Win32 child processes happy. */ + if (len < MAX_PATH + 4) + { + if (runpath[5] == ':') + runpath += 4; + else if (len < MAX_PATH + 6) + *(runpath += 6) = L'\\'; + } + } + else if (len < NT_MAX_PATH - ro_u_globalroot.Length / sizeof (WCHAR)) + { + UNICODE_STRING rpath; + + RtlInitEmptyUnicodeString (&rpath, runpath, + (NT_MAX_PATH - 1) * sizeof (WCHAR)); + RtlCopyUnicodeString (&rpath, &ro_u_globalroot); + RtlAppendUnicodeStringToString (&rpath, + real_path.get_nt_native_path ()); + } + else + { + set_errno (ENAMETOOLONG); + res = -1; + goto out; } } - syscall_printf ("null_app_name %d (%W, %.9500W)", null_app_name, runpath, wone_line); @@ -551,14 +568,8 @@ spawn_guts (const char *prog_arg, const char *const *argv, loop: cygheap->user.deimpersonate (); - PWCHAR cwd; - cwd = NULL; if (!real_path.iscygexec ()) - { - myself->process_state |= PID_NOTCYGWIN; - cygheap->cwd.cwd_lock.acquire (); - cwd = cygheap->cwd.win32.Buffer; - } + myself->process_state |= PID_NOTCYGWIN; if (!cygheap->user.issetuid () || (cygheap->user.saved_uid == cygheap->user.real_uid @@ -573,7 +584,7 @@ loop: TRUE, /* inherit handles from parent */ c_flags, envblock, /* environment */ - cwd, + NULL, &si, &pi); } @@ -636,7 +647,7 @@ loop: TRUE, /* inherit handles from parent */ c_flags, envblock, /* environment */ - cwd, + NULL, &si, &pi); if (hwst) @@ -651,9 +662,6 @@ loop: } } - if (!real_path.iscygexec()) - cygheap->cwd.cwd_lock.release (); - /* Restore impersonation. In case of _P_OVERLAY this isn't allowed since it would overwrite child data. */ if (mode != _P_OVERLAY || !rc)