Loading ...
Sorry, an error occurred while loading the content.

[patch] on VMS, prevent freeze when is pressed on E325

Expand Messages
  • Samuel Ferencik
    On the E325 screen (Found a swap file...), the user can choose different keys to press (e.g. [O]pen Read-Only, (E)dit anyway,...). If she presses , vim
    Message 1 of 3 , Sep 28, 2013
    • 0 Attachment
      On the E325 screen (Found a swap file...), the user can choose different keys to
      press (e.g. [O]pen Read-Only, (E)dit anyway,...). If she presses <Esc>, vim
      freezes (and the terminal session has to be killed).

      Reproduce as follows:
      1) in one terminal, $ vim a.txt
      2) in another terminal, $ vim a.txt
      3) vim prompts with E325, warning that there already is a swap file
      4) press <Esc> - vim freezes

      It turns out that vim (on VMS) uses select() to poll on the terminal input.
      Unfortunately, select() has never been ported fully and only works for sockets
      (same as on Windows).

      The full details of how/why this manifests only for <Esc> are probably
      unnecessary here. (If someone is interested, I'm ready to share them, of
      course.)

      The idea of the patch is to replace select() by the native IO-sniffing call,
      sys$qiow(). VMS thus gets its very own RealWaitForChar(), rather than using
      Unix's one. The time-out is implemented manually by looping (just like on
      Windows).

      Thanks,
      Sam




      diff -r 3a32cbcc2449 src/os_unix.c
      --- a/src/os_unix.c Wed Sep 25 23:24:58 2013 +0200
      +++ b/src/os_unix.c Sat Sep 28 23:17:03 2013 +0200
      @@ -168,7 +168,7 @@
      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 @@
      /* 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 @@
      handle_resize();
      return 0;
      }
      -#endif

      /* If input was put directly in typeahead buffer bail out here. */
      if (typebuf_changed(tb_change_cnt))
      @@ -5035,6 +5033,7 @@
      return avail;
      }

      +#ifndef VMS
      /*
      * Wait "msec" msec until a character is available from file descriptor "fd".
      * "msec" == 0 will check for characters once.
      @@ -5334,13 +5333,7 @@
      }
      # 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)
      {
      @@ -5462,8 +5455,6 @@
      return (ret > 0);
      }

      -#ifndef VMS
      -
      #ifndef NO_EXPANDPATH
      /*
      * Expand a path into all matching files and/or directories. Handles "*",
      diff -r 3a32cbcc2449 src/os_unix.h
      --- a/src/os_unix.h Wed Sep 25 23:24:58 2013 +0200
      +++ b/src/os_unix.h Sat Sep 28 23:17:03 2013 +0200
      @@ -225,6 +225,9 @@
      # include <starlet.h>
      # include <socket.h>
      # include <lib$routines.h>
      +# include <gen64def.h>
      +# include <libdef.h>
      +# include <libdtdef.h>

      # ifdef FEAT_GUI_GTK
      # include "gui_gtk_vms.h"
      diff -r 3a32cbcc2449 src/os_vms.c
      --- a/src/os_vms.c Wed Sep 25 23:24:58 2013 +0200
      +++ b/src/os_vms.c Sat Sep 28 23:17:03 2013 +0200
      @@ -669,3 +669,92 @@
      }
      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 */
      + }
      + }
      +}

      --
      --
      You received this message from the "vim_dev" maillist.
      Do not top-post! Type your reply below the text you are replying to.
      For more information, visit http://www.vim.org/maillist.php

      ---
      You received this message because you are subscribed to the Google Groups "vim_dev" group.
      To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
      For more options, visit https://groups.google.com/groups/opt_out.
    • Bram Moolenaar
      ... Thanks for making a solution for this. Obviously I can t test it. Are there any other VMS users who can try this on their system? If I don t hear
      Message 2 of 3 , Sep 29, 2013
      • 0 Attachment
        Samuel Ferencik wrote:

        > On the E325 screen (Found a swap file...), the user can choose
        > different keys to press (e.g. [O]pen Read-Only, (E)dit anyway,...). If
        > she presses <Esc>, vim freezes (and the terminal session has to be
        > killed).
        >
        > Reproduce as follows:
        > 1) in one terminal, $ vim a.txt
        > 2) in another terminal, $ vim a.txt
        > 3) vim prompts with E325, warning that there already is a swap file
        > 4) press <Esc> - vim freezes
        >
        > It turns out that vim (on VMS) uses select() to poll on the terminal input.
        > Unfortunately, select() has never been ported fully and only works for sockets
        > (same as on Windows).
        >
        > The full details of how/why this manifests only for <Esc> are probably
        > unnecessary here. (If someone is interested, I'm ready to share them, of
        > course.)
        >
        > The idea of the patch is to replace select() by the native IO-sniffing call,
        > sys$qiow(). VMS thus gets its very own RealWaitForChar(), rather than using
        > Unix's one. The time-out is implemented manually by looping (just like on
        > Windows).

        Thanks for making a solution for this. Obviously I can't test it. Are
        there any other VMS users who can try this on their system?
        If I don't hear anything I'll include it.


        --
        "My particular problem is with registry entries, which seem to just
        accumulate like plastic coffee cups..." -- Paul Moore

        /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
        /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
        \\\ an exciting new programming language -- http://www.Zimbu.org ///
        \\\ help me help AIDS victims -- http://ICCF-Holland.org ///

        --
        --
        You received this message from the "vim_dev" maillist.
        Do not top-post! Type your reply below the text you are replying to.
        For more information, visit http://www.vim.org/maillist.php

        ---
        You received this message because you are subscribed to the Google Groups "vim_dev" group.
        To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
        For more options, visit https://groups.google.com/groups/opt_out.
      • Samuel Ferencik
        ... Unfortunately, Zoltan (the obvious choice) is busy. Zoli, how do you feel about this? Should we wait for your review, or go ahead? Would you know someone
        Message 3 of 3 , Sep 29, 2013
        • 0 Attachment
          On Sunday, September 29, 2013 2:10:52 PM UTC+2, Bram Moolenaar wrote:
          > Thanks for making a solution for this. Obviously I can't test it. Are
          > there any other VMS users who can try this on their system?
          > If I don't hear anything I'll include it.

          Unfortunately, Zoltan (the obvious choice) is busy.

          Zoli, how do you feel about this? Should we wait for your review, or go ahead?
          Would you know someone else who can review and/or test vim@VMS?

          Thanks,
          Sam

          --
          --
          You received this message from the "vim_dev" maillist.
          Do not top-post! Type your reply below the text you are replying to.
          For more information, visit http://www.vim.org/maillist.php

          ---
          You received this message because you are subscribed to the Google Groups "vim_dev" group.
          To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
          For more options, visit https://groups.google.com/groups/opt_out.
        Your message has been successfully submitted and would be delivered to recipients shortly.