To: vim-dev@vim.org Subject: Patch 6.1.369 (extra) Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.1.369 (extra) Problem: VMS: Vim hangs when attempting to edit a read-only file in the terminal. Problem with VMS filenames for quickfix. Solution: Rewrite low level input. Remove version number from file name in a couple more places. Fix crash after patch 6.1.362. Correct return code for system(). (Zoltan Arpadffy, Tomas Stehlik) Files: src/misc1.c, src/os_unix.c, src/os_vms.c, src/proto/os_vms.pro, src/os_vms_conf.h, src/quickfix.c, src/ui.c *** ../vim61.368/src/misc1.c Sat Mar 8 20:33:32 2003 --- src/misc1.c Fri Mar 7 22:30:02 2003 *************** *** 6451,6456 **** --- 6451,6459 ---- ffname = FullName_save((*file)[i], FALSE); if (ffname == NULL) /* out of memory */ break; + # ifdef VMS + vms_remove_version(ffname); + # endif if (match_file_list(p_wig, (*file)[i], ffname)) { /* remove this matching file from the list */ *************** *** 7082,7088 **** --- 7085,7097 ---- /* * read the names from the file into memory */ + # ifdef VMS + /* created temporary file is not allways readable as binary */ + fd = mch_fopen((char *)tempname, "r"); + # else fd = mch_fopen((char *)tempname, READBIN); + # endif + if (fd == NULL) { EMSG2(_(e_notopen), tempname); *************** *** 7100,7105 **** --- 7109,7117 ---- mch_remove(tempname); if (buffer == NULL) goto done; + #ifdef VMS + len = i; /* why is this? */ + #endif if (i != len) { EMSG2(_(e_notread), tempname); *** ../vim61.368/src/os_unix.c Mon Feb 24 11:29:15 2003 --- src/os_unix.c Fri Mar 7 22:50:28 2003 *************** *** 123,129 **** static void may_core_dump __ARGS((void)); static int WaitForChar __ARGS((long)); ! #if defined(__BEOS__) || defined(VMS) int RealWaitForChar __ARGS((int, long, int *)); #else static int RealWaitForChar __ARGS((int, long, int *)); --- 123,129 ---- static void may_core_dump __ARGS((void)); static int WaitForChar __ARGS((long)); ! #if defined(__BEOS__) int RealWaitForChar __ARGS((int, long, int *)); #else static int RealWaitForChar __ARGS((int, long, int *)); *************** *** 280,287 **** RealWaitForChar(read_cmd_fd, p_wd, NULL); } - #ifndef VMS - /* * mch_inchar(): low level input funcion. * Get a characters from the keyboard. --- 280,285 ---- *************** *** 390,397 **** } } - #endif /* VMS */ - static void handle_resize() { --- 388,393 ---- *************** *** 3109,3121 **** x = system((char *)newcmd); vim_free(newcmd); } ! # endif } if (emsg_silent) ; else if (x == 127) MSG_PUTS(_("\nCannot execute shell sh\n")); ! #endif /* __EMX__ */ else if (x && !(options & SHELL_SILENT)) { MSG_PUTS(_("\nshell returned ")); --- 3114,3129 ---- x = system((char *)newcmd); vim_free(newcmd); } ! # endif } + # ifdef VMS + x = vms_sys_status(x); + # endif if (emsg_silent) ; else if (x == 127) MSG_PUTS(_("\nCannot execute shell sh\n")); ! # endif /* __EMX__ */ else if (x && !(options & SHELL_SILENT)) { MSG_PUTS(_("\nshell returned ")); *************** *** 3862,3868 **** * Or when a Linux GPM mouse event is waiting. */ /* ARGSUSED */ ! #if defined(__BEOS__) || defined(VMS) int #else static int --- 3870,3876 ---- * Or when a Linux GPM mouse event is waiting. */ /* ARGSUSED */ ! #if defined(__BEOS__) int #else static int *************** *** 4040,4046 **** --- 4048,4060 ---- } # 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, (msec >= 0) ? &tv : NULL); + # endif # ifdef FEAT_SNIFF if (ret < 0 ) *** ../vim61.368/src/os_vms.c Wed Jan 29 22:08:43 2003 --- src/os_vms.c Fri Mar 7 22:56:25 2003 *************** *** 11,22 **** #include "vim.h" - #define EFN 0 /* Event flag */ - #define NOTIM 0 - #define TIM_0 1 - #define TIM_1 2 - #define EXPL_ALLOC_INC 16 - typedef struct { char class; --- 11,16 ---- *************** *** 55,61 **** int nul; } ITMLST2; - char ibuf[1]; /* Input buffer */ static TT_MODE orgmode; static short iochan; /* TTY I/O channel */ static short iosb[4]; /* IO status block */ --- 49,54 ---- *************** *** 66,146 **** char_u **vms_fmatch = NULL; static char *Fspec_Rms; /* rms file spec, passed implicitly between routines */ static TT_MODE get_tty __ARGS((void)); static void set_tty __ARGS((int row, int col)); ! static int vms_wait __ARGS((unsigned int fun)); #define EQN(S1,S2,LN) (strncmp(S1,S2,LN) == 0) #define SKIP_FOLLOWING_SLASHES(Str) while (Str[1] == '/') ++Str - /* - * low level input funcion. - * - * Get a characters from the keyboard. - * Return the number of characters that are available. - * If wtime == 0 do not wait for characters. - * If wtime == n wait a short time for characters. - * If wtime == -1 wait forever for characters. - */ - int - mch_inchar(char_u *buf, int maxlen, long wtime) - { - int c, res; - - #ifdef FEAT_GUI - if (gui.in_use) - { - if (!gui_wait_for_chars(wtime)) - return 0; - return read_from_input_buf(buf, (long)maxlen); - } - #endif - /* first check to see if any characters read by - * mch_breakcheck(), mch_delay() or mch_char_avail() - */ - if (!vim_is_input_buf_empty()) - return read_from_input_buf(buf, (long)maxlen); - - out_flush(); - if (wtime == -1) - res = vms_wait(NOTIM); /* without timeout */ - else - res = vms_wait(wtime ? TIM_1 : TIM_0); /* with timeout */ - if (res != SS$_NORMAL) - return(0); - out_flush(); - c = (ibuf[0] & 0xFF); /* Allow multinational */ - *buf = c; - return(1); - } - - static int - vms_wait(unsigned int fun) - { - int ret, term[2] = { 0, 0 }; - - switch(fun) - { - case NOTIM: /* wait forever for characters */ - ret = sys$qiow(EFN, iochan, IO$_READLBLK, iosb, 0, 0, - ibuf, 1, 0, term, 0, 0); - break; - case TIM_1: /* wait a short time for characters */ - ret = sys$qiow(EFN, iochan, IO$_READLBLK | IO$M_TIMED, iosb, 0, 0, - ibuf, 1, 1, term, 0, 0); - break; - default: /* do not wait for characters */ - ret = sys$qiow(EFN, iochan, IO$_READLBLK | IO$M_TIMED, iosb, 0, 0, - ibuf, 1, 0, term, 0, 0); - break; - } - if (ret != SS$_NORMAL) - return(ret); - if ((fun && (iosb[0] != SS$_TIMEOUT) && (iosb[0] != SS$_NORMAL)) || - (!fun && (iosb[0] != SS$_NORMAL))) - return(iosb[0]); - return(iosb[1] + iosb[3]); - } /* * vul_desc vult een descriptor met een string en de lengte --- 59,74 ---- char_u **vms_fmatch = NULL; static char *Fspec_Rms; /* rms file spec, passed implicitly between routines */ + + static TT_MODE get_tty __ARGS((void)); static void set_tty __ARGS((int row, int col)); ! ! #define EXPL_ALLOC_INC 64 #define EQN(S1,S2,LN) (strncmp(S1,S2,LN) == 0) #define SKIP_FOLLOWING_SLASHES(Str) while (Str[1] == '/') ++Str /* * vul_desc vult een descriptor met een string en de lengte *************** *** 170,176 **** void mch_settmode(int tmode) { ! long mystatus; if ( tmode == TMODE_RAW ) set_tty(0, 0); --- 98,104 ---- void mch_settmode(int tmode) { ! int status; if ( tmode == TMODE_RAW ) set_tty(0, 0); *************** *** 182,190 **** default: break; } out_flush(); ! mystatus = sys$qiow(0, iochan, IO$_SETMODE, iosb, 0, 0, &orgmode, sizeof(TT_MODE), 0,0,0,0); ! if (mystatus!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) return; (void)sys$dassgn(iochan); iochan = 0; --- 110,118 ---- default: break; } out_flush(); ! status = sys$qiow(0, iochan, IO$_SETMODE, iosb, 0, 0, &orgmode, sizeof(TT_MODE), 0,0,0,0); ! if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) return; (void)sys$dassgn(iochan); iochan = 0; *************** *** 194,202 **** static void set_tty(int row, int col) { ! long mystatus; TT_MODE newmode; /* New TTY mode bits */ ! static short first_time = TRUE; if (first_time) { --- 122,130 ---- static void set_tty(int row, int col) { ! int status; TT_MODE newmode; /* New TTY mode bits */ ! static short first_time = TRUE; if (first_time) { *************** *** 211,240 **** newmode.x.basic |= (TT$M_NOECHO | TT$M_HOSTSYNC); newmode.x.basic &= ~TT$M_TTSYNC; newmode.extended |= TT2$M_PASTHRU; ! mystatus = sys$qiow(0, iochan, IO$_SETMODE, iosb, 0, 0, &newmode, sizeof(newmode), 0, 0, 0, 0); ! if (mystatus!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) return; } ! static TT_MODE get_tty(void) { ! long mystatus; TT_MODE tt_mode; - DESC odsc; - char *cp1, *cp2 = "TT"; if (!iochan) ! { ! while (cp1 = (char *)mch_getenv((char_u *)cp2)) ! cp2 = cp1; ! vul_desc(&odsc, cp2); ! (void)sys$assign(&odsc, &iochan, 0, 0); ! } ! mystatus = sys$qiow(0, iochan, IO$_SENSEMODE, iosb, 0, 0, &tt_mode, sizeof(tt_mode), 0, 0, 0, 0); ! if (mystatus != SS$_NORMAL || (iosb[0] & 0xFFFF) != SS$_NORMAL) { tt_mode.width = 0; tt_mode.type = 0; --- 139,165 ---- newmode.x.basic |= (TT$M_NOECHO | TT$M_HOSTSYNC); newmode.x.basic &= ~TT$M_TTSYNC; newmode.extended |= TT2$M_PASTHRU; ! status = sys$qiow(0, iochan, IO$_SETMODE, iosb, 0, 0, &newmode, sizeof(newmode), 0, 0, 0, 0); ! if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) return; } ! static TT_MODE get_tty(void) { ! ! static $DESCRIPTOR(odsc,"SYS$OUTPUT"); /* output descriptor */ ! ! int status; TT_MODE tt_mode; if (!iochan) ! status = sys$assign(&odsc,&iochan,0,0); ! ! status = sys$qiow(0, iochan, IO$_SENSEMODE, iosb, 0, 0, &tt_mode, sizeof(tt_mode), 0, 0, 0, 0); ! if (status != SS$_NORMAL || (iosb[0] & 0xFFFF) != SS$_NORMAL) { tt_mode.width = 0; tt_mode.type = 0; *************** *** 321,327 **** { int res, dum; long attrib = 0L; ! char acmode = PSL$C_SUPER; /* SYSNAM privilege nodig */ DESC tabnam, lognam; ITMLST1 itmlst; --- 246,252 ---- { int res, dum; long attrib = 0L; ! char acmode = PSL$C_SUPER; /* needs SYSNAM privilege */ DESC tabnam, lognam; ITMLST1 itmlst; *************** *** 338,344 **** vms_sys(char *cmd, char *out, char *inp) { DESC cdsc, odsc, idsc; ! long status, substatus; if (cmd) vul_desc(&cdsc, cmd); --- 263,269 ---- vms_sys(char *cmd, char *out, char *inp) { DESC cdsc, odsc, idsc; ! long status; if (cmd) vul_desc(&cdsc, cmd); *************** *** 347,362 **** if (inp) vul_desc(&idsc, inp); ! status = lib$spawn( ! cmd ? &cdsc : NULL, /* command string */ ! inp ? &idsc : NULL, /* input file */ ! out ? &odsc : NULL, /* output file */ ! 0, 0, 0, &substatus, 0, 0, 0, 0, 0, 0); ! if (status != SS$_NORMAL) ! substatus = status; ! if ((substatus&STS$M_SUCCESS) == 0) /* Command failed. */ ! return(FALSE); ! return(TRUE); } /* --- 272,339 ---- if (inp) vul_desc(&idsc, inp); ! lib$spawn(cmd ? &cdsc : NULL, /* command string */ ! inp ? &idsc : NULL, /* input file */ ! out ? &odsc : NULL, /* output file */ ! 0, 0, 0, &status, 0, 0, 0, 0, 0, 0); ! return status; ! } ! ! /* ! * Convert VMS system() or lib$spawn() return code to Unix-like exit value. ! */ ! int ! vms_sys_status(int status) ! { ! if (status != SS$_NORMAL && (status & STS$M_SUCCESS) == 0) ! return status; /* Command failed. */ ! return 0; ! } ! ! /* ! * vms_read() ! * function for low level char input ! * ! * Returns: input length ! */ ! ! int ! vms_read(char *inbuf, size_t nbytes) ! { ! ! static unsigned short add_esc, was_esc = 0; ! ! char ibuf[nbytes]; ! int status, function, len; ! TT_MODE tt_mode; ! ! /* whatever happened earlier we need an iochan here */ ! if (!iochan) ! tt_mode=get_tty(); ! ! function = ( IO$_READLBLK | IO$M_NOECHO | IO$M_TIMED ) ; ! len=0; ! add_esc=0; ! ! while(1) { ! memset(ibuf,0,sizeof(ibuf)); ! status = sys$qiow(0,iochan,function,&iosb,0,0,&ibuf,nbytes-1,0,0,0,0); ! len=strlen( ibuf ); ! if ( was_esc ) { /* ESC interrupts the BLOCK QIO */ ! add_esc=1; /* therefore we need to handle */ ! was_esc=0; /* it on special way in order to */ ! inbuf[0]=27; /* read ESC sequences */ ! } ! if ( len>0 ){ ! if ( ibuf[len-1]==27 ){ ! was_esc=1; ! len=len-1; ! } ! mch_memmove(inbuf+add_esc, ibuf, len); ! } ! if ((add_esc+len) > 0) break; ! } ! return add_esc+len; } /* *************** *** 365,371 **** * * Returns: 1 - continue finding matches * 0 - stop trying to find any further mathces - * */ static int vms_wproc(char *name, int val) --- 342,347 ---- *************** *** 668,674 **** * we need it in some special cases as: * creating swap file name and writing new file */ ! void * vms_remove_version(void * fname) { char_u *cp; --- 644,650 ---- * we need it in some special cases as: * creating swap file name and writing new file */ ! void vms_remove_version(void * fname) { char_u *cp; *************** *** 686,691 **** if ( *fp++ == '.' ) *cp = '\0'; } ! ! return fname; } --- 662,666 ---- if ( *fp++ == '.' ) *cp = '\0'; } ! return ; } *** ../vim61.368/src/proto/os_vms.pro Fri Mar 22 21:41:33 2002 --- src/proto/os_vms.pro Thu Mar 6 21:26:59 2003 *************** *** 1,13 **** /* os_vms.c */ - int mch_inchar __ARGS((char_u *buf, int maxlen, long wtime)); void mch_settmode __ARGS((int tmode)); int mch_get_shellsize __ARGS((void)); void mch_set_shellsize __ARGS((void)); char_u *mch_getenv __ARGS((char_u *lognam)); int mch_setenv __ARGS((char *var, char *value, int x)); int vms_sys __ARGS((char *cmd, char *out, char *inp)); int mch_expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file, int flags)); int mch_expandpath __ARGS((garray_T *gap, char_u *path, int flags)); void *vms_fixfilename __ARGS((void *instring)); ! void *vms_remove_version __ARGS((void *fname)); /* vim: set ft=c : */ --- 1,13 ---- /* os_vms.c */ void mch_settmode __ARGS((int tmode)); int mch_get_shellsize __ARGS((void)); void mch_set_shellsize __ARGS((void)); char_u *mch_getenv __ARGS((char_u *lognam)); int mch_setenv __ARGS((char *var, char *value, int x)); int vms_sys __ARGS((char *cmd, char *out, char *inp)); + int vms_read __ARGS((char *inbuf, size_t nbytes)); int mch_expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file, int flags)); int mch_expandpath __ARGS((garray_T *gap, char_u *path, int flags)); void *vms_fixfilename __ARGS((void *instring)); ! void vms_remove_version __ARGS((void *fname)); /* vim: set ft=c : */ *** ../vim61.368/src/os_vms_conf.h Sun Feb 24 19:36:04 2002 --- src/os_vms_conf.h Mon Mar 3 18:55:11 2003 *************** *** 7,24 **** #define USE_GETCWD #define USE_SYSTEM - /* Define when termcap library found */ - /* #undef HAVE_LIBTERMCAP */ - - /* Define when termlib library found */ - /* #undef HAVE_LIBTERMLIB */ - - /* Define when ncurses library found */ - #undef HAVE_LIBNCURSES - - /* Define when curses library found */ - /* #undef HAVE_LIBCURSES */ - /* Define when terminfo support found */ #undef TERMINFO --- 7,12 ---- *************** *** 104,109 **** --- 92,98 ---- /* Define if you have the sigset() function. */ /* #undef HAVE_SIGSET */ + #define TGETENT_ZERO_ERR #define HAVE_GETCWD #define HAVE_STRCSPN #define HAVE_STRTOL *** ../vim61.368/src/quickfix.c Mon Feb 24 11:29:15 2003 --- src/quickfix.c Wed Feb 19 19:54:19 2003 *************** *** 702,707 **** --- 702,710 ---- char_u *ptr; int fnum; + # ifdef VMS + vms_remove_version(fname); + # endif if (directory != NULL && !vim_isAbsName(fname) && (ptr = concat_fnames(directory, fname, TRUE)) != NULL) { *** ../vim61.368/src/ui.c Sat Mar 8 20:33:33 2003 --- src/ui.c Sat Mar 8 17:44:27 2003 *************** *** 58,64 **** #endif } ! #if (defined(FEAT_GUI) && defined(UNIX)) || defined(MACOS_X_UNIX) || defined(PROTO) /* * When executing an external program, there may be some typed characters that * are not consumed by it. Give them back to ui_inchar() and they are stored --- 58,65 ---- #endif } ! #if (defined(FEAT_GUI) && (defined(UNIX) || defined(VMS))) \ ! || defined(MACOS_X_UNIX) || defined(PROTO) /* * When executing an external program, there may be some typed characters that * are not consumed by it. Give them back to ui_inchar() and they are stored *************** *** 113,119 **** { int retval = 0; ! #if defined(FEAT_GUI) && defined(UNIX) /* * Use the typeahead if there is any. */ --- 114,120 ---- { int retval = 0; ! #if defined(FEAT_GUI) && (defined(UNIX) || defined(VMS)) /* * Use the typeahead if there is any. */ *************** *** 141,151 **** { static int count = 0; ! #ifndef NO_CONSOLE retval = mch_inchar(buf, maxlen, 10L); if (retval > 0) return retval; ! #endif if (wtime == -1 && ++count == 1000) read_error_exit(); buf[0] = CR; --- 142,152 ---- { static int count = 0; ! # ifndef NO_CONSOLE retval = mch_inchar(buf, maxlen, 10L); if (retval > 0) return retval; ! # endif if (wtime == -1 && ++count == 1000) read_error_exit(); buf[0] = CR; *************** *** 1656,1664 **** int try; static int did_read_something = FALSE; #endif - #ifdef VMS - extern char ibuf[]; - #endif #ifdef FEAT_GUI if (gui.in_use) --- 1657,1662 ---- *************** *** 1696,1721 **** return; } # endif - # ifdef VMS_OLD_STUFF - while (!vim_is_input_buf_full() && RealWaitForChar(0, 0L)) - { - add_to_input_buf((char_u *)ibuf, 1); - } - if (inbufcount < 1 && !exit_on_error) - return; - len = inbufcount; - inbufcount = 0; - # else len = 0; /* to avoid gcc warning */ for (try = 0; try < 100; ++try) { ! len = read(read_cmd_fd, (char *)inbuf + inbufcount, ! (size_t)((INBUFLEN - inbufcount) # ifdef FEAT_MBYTE / input_conv.vc_factor # endif )); if (len > 0 || got_int) break; /* --- 1694,1716 ---- return; } # endif len = 0; /* to avoid gcc warning */ for (try = 0; try < 100; ++try) { ! # ifdef VMS ! len = vms_read( ! # else ! len = read(read_cmd_fd, ! # endif ! (char *)inbuf + inbufcount, (size_t)((INBUFLEN - inbufcount) # ifdef FEAT_MBYTE / input_conv.vc_factor # endif )); + # if 0 + ) /* avoid syntax highlight error */ + # endif if (len > 0 || got_int) break; /* *************** *** 1742,1748 **** if (!exit_on_error) return; } - # endif /* VMS */ # endif if (len <= 0 && !got_int) read_error_exit(); --- 1737,1742 ---- *** ../vim61.368/src/version.c Sun Mar 9 14:01:01 2003 --- src/version.c Sun Mar 9 14:03:53 2003 *************** *** 613,614 **** --- 613,616 ---- { /* Add new patch number below this line */ + /**/ + 369, /**/ -- I think that you'll agree that engineers are very effective in their social interactions. It's the "normal" people who are nuts. (Scott Adams - The Dilbert principle) /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// Creator of Vim - Vi IMproved -- http://www.Vim.org \\\ \\\ Project leader for A-A-P -- http://www.A-A-P.org /// \\\ Help AIDS victims, buy at Amazon -- http://ICCF.nl/click1.html ///