Bash has a very convenient feature that is called process substitution (e.g. `diff -u <(seq 0 10) <(seq 1 11)`). To make this work, Bash requires the `/dev/fd` symlink to exist, and Cygwin therefore creates this symlink (together with the `stdin`, `stdout` and `stderr` ones) upon start-up.
This strategy is incompatible with the idea of providing a subset of Cygwin in a `.zip` file (because there is no standard way to represent symlinks in `.zip` files, and besides, older Windows versions would potentially lack support for them anyway). That type of `.zip` file is what Git for Windows wants to use, though, bundling a minimal subset for third-party applications in MinGit (see https://github.com/git-for-windows/git/wiki/MinGit for details). Let's side-step this problem completely by creating those symlinks implicitly, similar to the way `/dev/` is populated with special devices. Signed-off-by: Johannes Schindelin <johannes.schinde...@gmx.de> --- winsup/cygwin/Makefile.am | 1 + winsup/cygwin/devices.h | 3 +- winsup/cygwin/devices.in | 4 +++ winsup/cygwin/dtable.cc | 3 ++ winsup/cygwin/fhandler.h | 28 +++++++++++++++++ winsup/cygwin/fhandler_dev_fd.cc | 53 ++++++++++++++++++++++++++++++++ 6 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 winsup/cygwin/fhandler_dev_fd.cc diff --git a/winsup/cygwin/Makefile.am b/winsup/cygwin/Makefile.am index 2b8e87fcd0..c8936354b8 100644 --- a/winsup/cygwin/Makefile.am +++ b/winsup/cygwin/Makefile.am @@ -230,6 +230,7 @@ DLL_FILES= \ fhandler_console.cc \ fhandler_cygdrive.cc \ fhandler_dev.cc \ + fhandler_dev_fd.cc \ fhandler_disk_file.cc \ fhandler_dsp.cc \ fhandler_fifo.cc \ diff --git a/winsup/cygwin/devices.h b/winsup/cygwin/devices.h index 4310f435fe..fbbde6ab9c 100644 --- a/winsup/cygwin/devices.h +++ b/winsup/cygwin/devices.h @@ -70,6 +70,7 @@ enum fh_devices FH_NETDRIVE= FHDEV (DEV_VIRTFS_MAJOR, 194), FH_DEV = FHDEV (DEV_VIRTFS_MAJOR, 193), FH_CYGDRIVE= FHDEV (DEV_VIRTFS_MAJOR, 192), + FH_DEV_FD = FHDEV (DEV_VIRTFS_MAJOR, 191), FH_SIGNALFD= FHDEV (DEV_VIRTFS_MAJOR, 13), FH_TIMERFD = FHDEV (DEV_VIRTFS_MAJOR, 14), @@ -436,7 +437,7 @@ extern const _device dev_fs_storage; #define isprocsys_dev(devn) (devn == FH_PROCSYS) #define isvirtual_dev(devn) \ - (isproc_dev (devn) || devn == FH_CYGDRIVE || devn == FH_NETDRIVE) + (isproc_dev (devn) || devn == FH_CYGDRIVE || devn == FH_NETDRIVE || devn == FH_DEV_FD) #define iscons_dev(n) \ ((device::major ((dev_t) (n)) == DEV_CONS_MAJOR) \ diff --git a/winsup/cygwin/devices.in b/winsup/cygwin/devices.in index f33510eb7e..7506dfe9cb 100644 --- a/winsup/cygwin/devices.in +++ b/winsup/cygwin/devices.in @@ -175,6 +175,10 @@ const _device dev_error_storage = "/dev/fd%(0-15)d", BRACK(FHDEV(DEV_FLOPPY_MAJOR, {$1})), "\\Device\\Floppy{$1}", exists_ntdev, S_IFBLK "/dev/scd%(0-15)d", BRACK(FHDEV(DEV_CDROM_MAJOR, {$1})), "\\Device\\CdRom{$1}", exists_ntdev, S_IFBLK "/dev/sr%(0-15)d", BRACK(FHDEV(DEV_CDROM_MAJOR, {$1})), "\\Device\\CdRom{$1}", exists_ntdev, S_IFBLK +"/dev/fd", BRACK(FH_DEV_FD), "/proc/self/fd", exists, S_IFLNK +"/dev/stdin", BRACK(FH_DEV_FD), "/proc/self/fd/0", exists, S_IFLNK +"/dev/stdout", BRACK(FH_DEV_FD), "/proc/self/fd/1", exists, S_IFLNK +"/dev/stderr", BRACK(FH_DEV_FD), "/proc/self/fd/2", exists, S_IFLNK %other {return NULL;} %% #undef BRACK diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index ce5f6411b3..28d7697259 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -579,6 +579,9 @@ fh_alloc (path_conv& pc) case FH_DEV: fh = cnew (fhandler_dev); break; + case FH_DEV_FD: + fh = cnew (fhandler_dev_fd); + break; case FH_CYGDRIVE: fh = cnew (fhandler_cygdrive); break; diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index f764eccd33..6c1b2a8025 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -3009,6 +3009,33 @@ class fhandler_procnet: public fhandler_proc } }; +class fhandler_dev_fd: public fhandler_virtual +{ + public: + fhandler_dev_fd (); + virtual_ftype_t exists(); + + int __reg2 fstat (struct stat *buf); + bool fill_filebuf (); + + fhandler_dev_fd (void *) {} + + virtual void copy_from (fhandler_base *x) + { + pc.free_strings (); + *this = *reinterpret_cast<fhandler_dev_fd *> (x); + _copy_from_reset_helper (); + } + + virtual fhandler_dev_fd *clone (cygheap_types malloc_type = HEAP_FHANDLER) + { + void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_dev_fd)); + fhandler_dev_fd *fh = new (ptr) fhandler_dev_fd (ptr); + fh->copy_from (this); + return fh; + } +}; + class fhandler_signalfd : public fhandler_base { sigset_t sigset; @@ -3208,6 +3235,7 @@ typedef union char __dev_raw[sizeof (fhandler_dev_raw)]; char __dev_tape[sizeof (fhandler_dev_tape)]; char __dev_zero[sizeof (fhandler_dev_zero)]; + char __dev_fd[sizeof (fhandler_dev_fd)]; char __disk_file[sizeof (fhandler_disk_file)]; char __fifo[sizeof (fhandler_fifo)]; char __netdrive[sizeof (fhandler_netdrive)]; diff --git a/winsup/cygwin/fhandler_dev_fd.cc b/winsup/cygwin/fhandler_dev_fd.cc new file mode 100644 index 0000000000..6462838317 --- /dev/null +++ b/winsup/cygwin/fhandler_dev_fd.cc @@ -0,0 +1,53 @@ +/* fhandler_process_fd.cc: fhandler for the /dev/{fd,std{in,out,err}} symlinks + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#include "winsup.h" +#include "path.h" +#include "fhandler.h" + +fhandler_dev_fd::fhandler_dev_fd (): + fhandler_virtual () +{ +} + +virtual_ftype_t +fhandler_dev_fd::exists () +{ + return virt_symlink; +} + +int __reg2 +fhandler_dev_fd::fstat (struct stat *buf) +{ + const char *path = get_name (); + debug_printf ("fstat (%s)", path); + + fhandler_base::fstat (buf); + + buf->st_mode = S_IFLNK | STD_RBITS | S_IWUSR | S_IWGRP | S_IWOTH | STD_XBITS; + buf->st_ino = get_ino (); + + return 0; +} + +bool +fhandler_dev_fd::fill_filebuf () +{ + const char *path = get_name (); + debug_printf ("fill_filebuf (%s)", path); + + const char *native = get_native_name (); + if (!native) + { + return false; + } + + free(filebuf); + filebuf = cstrdup (native); + return true; +} -- 2.35.1