changeset 5541:2f99966971b0 v7.4.119

updated for version 7.4.119 Problem: Vim doesn't work well on OpenVMS. Solution: Fix various problems. (Samuel Ferencik)
author Bram Moolenaar <bram@vim.org>
date Wed, 11 Dec 2013 17:12:37 +0100
parents b82c264281a8
children 574142165dc8
files src/os_unix.c src/os_unix.h src/os_vms.c src/version.c
diffstat 4 files changed, 112 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -168,7 +168,7 @@ typedef int waitstatus;
 static pid_t wait4pid __ARGS((pid_t, waitstatus *));
 
 static int  WaitForChar __ARGS((long));
-#if defined(__BEOS__)
+#if defined(__BEOS__) || defined(VMS)
 int  RealWaitForChar __ARGS((int, long, int *));
 #else
 static int  RealWaitForChar __ARGS((int, long, int *));
@@ -435,7 +435,6 @@ mch_inchar(buf, maxlen, wtime, tb_change
 	/* Process the queued netbeans messages. */
 	netbeans_parse_messages();
 #endif
-#ifndef VMS  /* VMS: must try reading, WaitForChar() does nothing. */
 	/*
 	 * We want to be interrupted by the winch signal
 	 * or by an event on the monitored file descriptors.
@@ -446,7 +445,6 @@ mch_inchar(buf, maxlen, wtime, tb_change
 		handle_resize();
 	    return 0;
 	}
-#endif
 
 	/* If input was put directly in typeahead buffer bail out here. */
 	if (typebuf_changed(tb_change_cnt))
@@ -5039,6 +5037,7 @@ WaitForChar(msec)
     return avail;
 }
 
+#ifndef VMS
 /*
  * Wait "msec" msec until a character is available from file descriptor "fd".
  * "msec" == 0 will check for characters once.
@@ -5338,13 +5337,7 @@ select_eintr:
 	}
 # endif
 
-# ifdef OLD_VMS
-	/* Old VMS as v6.2 and older have broken select(). It waits more than
-	 * required. Should not be used */
-	ret = 0;
-# else
 	ret = select(maxfd + 1, &rfds, NULL, &efds, tvp);
-# endif
 # ifdef EINTR
 	if (ret == -1 && errno == EINTR)
 	{
@@ -5466,8 +5459,6 @@ select_eintr:
     return (ret > 0);
 }
 
-#ifndef VMS
-
 #ifndef NO_EXPANDPATH
 /*
  * Expand a path into all matching files and/or directories.  Handles "*",
--- a/src/os_unix.h
+++ b/src/os_unix.h
@@ -225,6 +225,8 @@
 # include <starlet.h>
 # include <socket.h>
 # include <lib$routines.h>
+# include <libdef.h>
+# include <libdtdef.h>
 
 # ifdef FEAT_GUI_GTK
 #  include "gui_gtk_vms.h"
--- a/src/os_vms.c
+++ b/src/os_vms.c
@@ -11,6 +11,23 @@
 
 #include	"vim.h"
 
+/* define _generic_64 for use in time functions */
+#ifndef VAX
+#   include <gen64def.h>
+#else
+/* based on Alpha's gen64def.h; the file is absent on VAX */
+typedef struct _generic_64 {
+#   pragma __nomember_alignment
+    __union  {                          /* You can treat me as...  */
+	/* long long is not available on VAXen */
+	/* unsigned __int64 gen64$q_quadword; ...a single 64-bit value, or */
+
+	unsigned int gen64$l_longword [2]; /* ...two 32-bit values, or */
+	unsigned short int gen64$w_word [4]; /* ...four 16-bit values */
+    } gen64$r_quad_overlay;
+} GENERIC_64;
+#endif
+
 typedef struct
 {
     char	class;
@@ -669,3 +686,92 @@ vms_remove_version(void * fname)
     }
     return ;
 }
+
+struct typeahead_st {
+    unsigned short numchars;
+    unsigned char  firstchar;
+    unsigned char  reserved0;
+    unsigned long  reserved1;
+} typeahead;
+
+/*
+ * Wait "msec" msec until a character is available from file descriptor "fd".
+ * "msec" == 0 will check for characters once.
+ * "msec" == -1 will block until a character is available.
+ */
+    int
+RealWaitForChar(fd, msec, check_for_gpm)
+    int		fd UNUSED; /* always read from iochan */
+    long	msec;
+    int		*check_for_gpm UNUSED;
+{
+    int status;
+    struct _generic_64 time_curr;
+    struct _generic_64 time_diff;
+    struct _generic_64 time_out;
+    unsigned int convert_operation = LIB$K_DELTA_SECONDS_F;
+    float sec = (float) msec / 1000;
+
+    /* make sure the iochan is set */
+    if (!iochan)
+	get_tty();
+
+    if (msec > 0) {
+        /* time-out specified; convert it to absolute time */
+
+        /* get current time (number of 100ns ticks since the VMS Epoch) */
+        status = sys$gettim(&time_curr);
+        if (status != SS$_NORMAL)
+            return 0; /* error */
+
+        /* construct the delta time */
+        status = lib$cvtf_to_internal_time(
+                &convert_operation, &sec, &time_diff);
+        if (status != LIB$_NORMAL)
+            return 0; /* error */
+
+        /* add them up */
+        status = lib$add_times(
+                &time_curr,
+                &time_diff,
+                &time_out);
+        if (status != LIB$_NORMAL)
+            return 0; /* error */
+    }
+
+    while (TRUE) {
+        /* select() */
+        status = sys$qiow(0, iochan, IO$_SENSEMODE | IO$M_TYPEAHDCNT, iosb,
+                0, 0, &typeahead, 8, 0, 0, 0, 0);
+	if (status != SS$_NORMAL || (iosb[0] & 0xFFFF) != SS$_NORMAL)
+            return 0; /* error */
+
+        if (typeahead.numchars)
+            return 1; /* ready to read */
+
+        /* there's nothing to read; what now? */
+        if (msec == 0) {
+            /* immediate time-out; return impatiently */
+            return 0;
+        }
+        else if (msec < 0) {
+            /* no time-out; wait on indefinitely */
+            continue;
+        }
+        else {
+            /* time-out needs to be checked */
+            status = sys$gettim(&time_curr);
+            if (status != SS$_NORMAL)
+                return 0; /* error */
+
+            status = lib$sub_times(
+                    &time_out,
+                    &time_curr,
+                    &time_diff);
+            if (status != LIB$_NORMAL)
+                return 0; /* error, incl. time_diff < 0 (i.e. time-out) */
+
+            /* otherwise wait some more */
+        }
+    }
+}
--- a/src/version.c
+++ b/src/version.c
@@ -739,6 +739,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    119,
+/**/
     118,
 /**/
     117,