about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Doc/Makefile.in2
-rw-r--r--Src/builtin.c10
-rw-r--r--Src/exec.c7
-rw-r--r--Src/main.c56
-rw-r--r--Src/system.h1
-rw-r--r--configure.ac6
7 files changed, 81 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index a96d5da92..d6965c23b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2004-04-06  Peter Stephenson  <pws@csr.com>
 
+	* Peter Castro <doctor@fruitbat.org>: 19735 (minus texinfo hunk):
+	Doc/Makefile.in, Src/builtin.c, Src/exec.c, Src/main.c,
+	Src/system.h, configure.ac: improved use of paths, text/binary
+	and dynamic library usage for Cygwin.
+
 	* 19733 (with improved documentation): Doc/Zsh/contrib.yo,
 	Doc/Zsh/zle.yo, Functions/Misc/zed, Src/Zle/zle_keymap.c,
 	Src/Zle/zle_main.c: vared -M and -m allow you to provide
diff --git a/Doc/Makefile.in b/Doc/Makefile.in
index 1fb2386ff..c817474ba 100644
--- a/Doc/Makefile.in
+++ b/Doc/Makefile.in
@@ -303,7 +303,7 @@ uninstall.info:
 # install HTML manual
 install.html: html
 	${SHELL} $(sdir_top)/mkinstalldirs $(DESTDIR)$(htmldir)
-	for file in zsh*.html; do \
+	for file in ${sdir}/zsh*.html; do \
 	    $(INSTALL_DATA) $$file $(DESTDIR)$(htmldir) || exit 1; \
 	done
 .PHONY: install.html
diff --git a/Src/builtin.c b/Src/builtin.c
index 2ae7e9bbf..8703ecead 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -927,7 +927,9 @@ cd_do_chdir(char *cnam, char *dest, int hard)
      * DOS style names with drives in them
      */
     static char buf[PATH_MAX];
+#ifndef _SYS_CYGWIN_H
     void cygwin_conv_to_posix_path(const char *, char *);
+#endif
 
     cygwin_conv_to_posix_path(dest, buf);
     dest = buf;
@@ -1031,7 +1033,15 @@ cd_try_chdir(char *pfix, char *dest, int hard)
     /* handle directory prefix */
     if (pfix && *pfix) {
 	if (*pfix == '/')
+#ifdef __CYGWIN__
+/* NB: Don't turn "/"+"bin" into "//"+"bin" by mistake!  "//bin" may *
+ * not be what user really wants (probably wants "/bin"), but        *
+ * "//bin" could be valid too (see fixdir())!  This is primarily for *
+ * handling CDPATH correctly.                                        */
+	    buf = tricat(pfix, ( pfix[1] == '\0' ? "" : "/" ), dest);
+#else
 	    buf = tricat(pfix, "/", dest);
+#endif
 	else {
 	    int pfl = strlen(pfix);
 	    dlen = strlen(pwd);
diff --git a/Src/exec.c b/Src/exec.c
index 4bd6503bf..8256910b3 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -3662,6 +3662,7 @@ getfpfunc(char *s, int *ksh)
 {
     char **pp, buf[PATH_MAX];
     off_t len;
+    off_t rlen;
     char *d;
     Eprog r;
     int fd;
@@ -3681,12 +3682,12 @@ getfpfunc(char *s, int *ksh)
 	    if ((len = lseek(fd, 0, 2)) != -1) {
 		d = (char *) zalloc(len + 1);
 		lseek(fd, 0, 0);
-		if (read(fd, d, len) == len) {
+		if ((rlen = read(fd, d, len)) >= 0) {
 		    char *oldscriptname = scriptname;
 
 		    close(fd);
-		    d[len] = '\0';
-		    d = metafy(d, len, META_REALLOC);
+		    d[rlen] = '\0';
+		    d = metafy(d, rlen, META_REALLOC);
 
 		    scriptname = dupstring(s);
 		    r = parse_string(d);
diff --git a/Src/main.c b/Src/main.c
index c9c5fa867..30eef5a25 100644
--- a/Src/main.c
+++ b/Src/main.c
@@ -30,6 +30,62 @@
 #include "zsh.mdh"
 #include "main.pro"
 
+/*
+ * Support for Cygwin binary/text mode filesystems.
+ * Peter A. Castro <doctor@fruitbat.org>
+ *
+ * This deserves some explaination, because it uses Cygwin specific
+ * runtime functions.
+ *
+ * Cygwin supports the notion of binary or text mode access to files
+ * based on the mount attributes of the filesystem.  If a file is on
+ * a binary mounted filesystem, you get exactly what's in the file, CRLF's
+ * and all.  If it's on a text mounted filesystem, Cygwin will strip out
+ * the CRs.  This presents a problem because zsh code doesn't allow for
+ * CRLF's as line terminators.  So, we must force all open files to be
+ * in text mode reguardless of the underlying filesystem attributes.
+ * However, we only want to do this for reading, not writing as we still
+ * want to write files in the mode of the filesystem.  To do this,
+ * we have two options: augment all {f}open() calls to have O_TEXT added to
+ * the list of file mode options, or have the Cygwin runtime do it for us.
+ * I choose the latter. :)
+ *
+ * Cygwin's runtime provides pre-execution hooks which allow you to set
+ * various attributes for the process which effect how the process functions.
+ * One of these attributes controls how files are opened.  I've set
+ * it up so that all files opened RDONLY will have the O_TEXT option set,
+ * thus forcing line termination manipulation.  This seems to solve the
+ * problem (at least the Test suite runs clean :).
+ *
+ * Note: this may not work in later implementations.  This will override
+ * all mode options passed into open().  Cygwin (really Windows) doesn't
+ * support all that much in options, so for now this is OK, but later on
+ * it may not, in which case O_TEXT will have to be added to all opens calls
+ * appropriately.
+ *
+ * This function is actually a hook in the Cygwin runtime which
+ * is called before the main of a program.  Because it's part of the program
+ * pre-startup, it must be located in the program main and not in a DLL.
+ * It must also be made an export so the linker resolves this function to
+ * our code instead of the default Cygwin stub routine.
+ */
+
+/**/
+#ifdef __CYGWIN__
+/**/
+mod_export void
+cygwin_premain0 (int argc, char **argv, void *myself)
+{
+    static struct __cygwin_perfile pf[] =
+    {
+        {"", O_RDONLY | O_TEXT},
+        {NULL, 0}
+    };
+    cygwin_internal (CW_PERFILE, pf);
+}
+/**/
+#endif /* __CYGWIN__ */
+
 /**/
 int
 main(int argc, char **argv)
diff --git a/Src/system.h b/Src/system.h
index 558508d2d..f03d890c4 100644
--- a/Src/system.h
+++ b/Src/system.h
@@ -675,6 +675,7 @@ extern short ospeed;
 #endif
 
 #ifdef __CYGWIN__
+# include <sys/cygwin.h>
 # define IS_DIRSEP(c) ((c) == '/' || (c) == '\\')
 #else
 # define IS_DIRSEP(c) ((c) == '/')
diff --git a/configure.ac b/configure.ac
index f37a97c7f..ba2b99e0c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1935,8 +1935,10 @@ if test "x$aixdynamic" = xyes; then
   zsh_cv_shared_environ="${zsh_cv_shared_environ=yes}"
 elif test "$host_os" = cygwin; then
   DL_EXT="${DL_EXT=dll}"
-  DLLD="${DLLD=dllwrap}"
-  DLLDFLAGS="${DLLDFLAGS=--export-all-symbols}"
+##DLLD="${DLLD=dllwrap}"
+  DLLD="${DLLD=$CC}"
+##DLLDFLAGS="${DLLDFLAGS=--export-all-symbols}"
+  DLLDFLAGS=${DLLDFLAGS=-shared -Wl,--export-all-symbols}
   zsh_cv_func_dlsym_needs_underscore=no
   DLLDFLAGS=${DLLDFLAGS=}
   EXTRA_LDFLAGS=${EXTRA_LDFLAGS=}