--- lib/tempname.c_orig 2011-01-03 15:04:38 -0600 +++ lib/tempname.c 2012-09-29 00:47:34 -0500 @@ -172,7 +172,12 @@ return -1; } +#ifdef __VMS + /* No "/" required (or desired) on VMS. */ + sprintf (tmpl, "%.*s%.*sXXXXXX", (int) dlen, dir, (int) plen, pfx); +#else /* def __VMS */ sprintf (tmpl, "%.*s/%.*sXXXXXX", (int) dlen, dir, (int) plen, pfx); +#endif /* def __VMS [else] */ return 0; } #endif /* _LIBC */ --- src/cmp.c_orig 2011-06-13 02:16:59 -0500 +++ src/cmp.c 2012-09-29 00:51:59 -0500 @@ -43,6 +43,12 @@ proper_name_utf8 ("Torbjorn Granlund", "Torbj\303\266rn Granlund"), \ proper_name ("David MacKenzie") +#ifdef __VMS +# define OPEN_ARG , "ctx = stm" +#else /* def __VMS */ +# define OPEN_ARG +#endif /* def __VMS [else] */ + #if defined LC_MESSAGES && ENABLE_NLS # define hard_locale_LC_MESSAGES hard_locale (LC_MESSAGES) #else @@ -296,7 +302,7 @@ xfreopen (NULL, "rb", stdin); } else - file_desc[f1] = open (file[f1], O_RDONLY | O_BINARY, 0); + file_desc[f1] = open (file[f1], O_RDONLY | O_BINARY, 0 OPEN_ARG); if (file_desc[f1] < 0 || fstat (file_desc[f1], stat_buf + f1) != 0) { --- src/diff.c_orig 2011-08-15 00:24:38 -0500 +++ src/diff.c 2012-09-29 00:53:26 -0500 @@ -286,6 +286,14 @@ re_set_syntax (RE_SYNTAX_GREP | RE_NO_POSIX_BACKTRACKING); excluded = new_exclude (); +#ifdef __VMS + /* Set the default ignore_file_name_case value according to the + * current SET PROCESS /CASE_LOOKUP setting. Override this default + * with an explicit --[no-]ignore-file-name-case option. + */ + ignore_file_name_case = vms_case_blind(); +#endif /* def __VMS */ + /* Decode the options. */ while ((c = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) --- src/diff3.c_orig 2011-07-03 15:42:54 -0500 +++ src/diff3.c 2012-09-29 01:00:52 -0500 @@ -1184,10 +1184,23 @@ if (pipe (fds) != 0) perror_with_exit ("pipe"); +# ifdef __VMS + if (decc$set_child_standard_streams( fds[ 0], fds[ 1], -1) < 0) + perror_with_exit ("decc$set_child_standard_streams"); +# endif /* def __VMS */ + pid = fork (); if (pid == 0) { /* Child */ +# ifdef __VMS + if (execv (diff_program, (char **) argv) < 0) + { + char msg[ 8+ 2048] = "execv"; + strcpy( msg, diff_program); + perror_with_exit (msg); + } +# else /* def __VMS */ close (fds[0]); if (fds[1] != STDOUT_FILENO) { @@ -1200,15 +1213,19 @@ execvp (diff_program, (char **) argv); _exit (errno == ENOENT ? 127 : 126); +# endif /* def __VMS [else] */ } if (pid == -1) perror_with_exit ("fork"); +# ifndef __VMS close (fds[1]); /* Prevent erroneous lack of EOF */ +# endif /* ndef __VMS */ + fd = fds[0]; -#else +#else /* HAVE_WORKING_FORK */ FILE *fpipe; char const args[] = " --horizon-lines=100 -- "; @@ -1243,7 +1260,7 @@ free (command); fd = fileno (fpipe); -#endif +#endif /* HAVE_WORKING_FORK [else] */ if (fstat (fd, &pipestat) != 0) perror_with_exit ("fstat"); @@ -1279,14 +1296,19 @@ if (wstatus == -1) werrno = errno; -#else +#else /* ! HAVE_WORKING_FORK */ if (close (fd) != 0) perror_with_exit ("close"); if (waitpid (pid, &wstatus, 0) < 0) perror_with_exit ("waitpid"); -#endif +# ifdef __VMS + if (close (fds[ 1]) != 0) /* Not closed above. */ + perror_with_exit ("close"); +# endif /* def __VMS */ + +#endif /* ! HAVE_WORKING_FORK [else] */ status = ! werrno && WIFEXITED (wstatus) ? WEXITSTATUS (wstatus) : INT_MAX; --- src/ifdef.c_orig 2011-06-12 04:13:28 -0500 +++ src/ifdef.c 2012-09-28 20:05:07 -0500 @@ -152,7 +152,7 @@ else { value[i] = groups_letter_value (groups, *f); - if (value[i] == -1) + if (value[i] == (uintmax_t)-1) goto bad_format; f++; } --- src/sdiff.c_orig 2011-08-15 00:24:38 -0500 +++ src/sdiff.c 2012-10-08 17:30:29 -0500 @@ -85,6 +85,9 @@ #endif #ifdef SIGPIPE SIGPIPE, +# ifdef __VMS +# define handler_index_of_SIGPIPE (NUM_SIGS - 2) +# endif /* def __VMS */ #endif SIGINT #define handler_index_of_SIGINT (NUM_SIGS - 1) @@ -299,7 +302,15 @@ static size_t ck_fread (char *buf, size_t size, FILE *f) { - size_t r = fread (buf, sizeof (char), size, f); + size_t r; + +#ifdef __VMS + /* Not classy, but it seems to do better than nothing. */ + if (feof( f)) + return 0; +#endif /* def __VMS */ + + r = fread (buf, sizeof (char), size, f); if (r == 0 && ferror (f)) perror_fatal (_("read failed")); return r; @@ -588,6 +599,8 @@ bool leftdir = diraccess (argv[optind]); bool rightdir = diraccess (argv[optind + 1]); + int diff_fds[2]; + if (leftdir & rightdir) fatal ("both files to be compared are directories"); @@ -628,11 +641,28 @@ } #else { - int diff_fds[2]; - +# ifdef __VMS /* Was: #if HAVE_WORKING_VFORK */ + sigset_t procmask; + sigset_t blocked; +# endif /* def __VMS Was: #if HAVE_WORKING_VFORK */ + if (pipe (diff_fds) != 0) perror_fatal ("pipe"); +# ifdef __VMS /* Was: #if HAVE_WORKING_VFORK */ + /* Block SIGINT and SIGPIPE. */ + sigemptyset (&blocked); + sigaddset (&blocked, SIGINT); + sigaddset (&blocked, SIGPIPE); + sigprocmask (SIG_BLOCK, &blocked, &procmask); +# endif /* def __VMS Was: #if HAVE_WORKING_VFORK */ + +# ifdef __VMS + if (decc$set_child_standard_streams( + diff_fds[ 0], diff_fds[ 1], -1) < 0) + perror_fatal ("decc$set_child_standard_streams"); +# endif /* def __VMS */ + diffpid = fork (); if (diffpid < 0) perror_fatal ("fork"); @@ -645,6 +675,21 @@ if (initial_handler (handler_index_of_SIGINT) != SIG_IGN) signal_handler (SIGINT, SIG_IGN); signal_handler (SIGPIPE, SIG_DFL); +# ifdef __VMS /* Was: #if HAVE_WORKING_VFORK */ + /* Stop blocking SIGINT and SIGPIPE in the child. */ + sigprocmask (SIG_SETMASK, &procmask, 0); +# endif /* def __VMS Was: #if HAVE_WORKING_VFORK */ +# ifdef __VMS + /* Use a logical name in the definition of the "diff" + * command to locate the executable, and execv() to run it. + */ + if (execv (diffargv[0], (char **) diffargv) < 0) + { + char msg[ 8+ 2048] = "execv"; + strcpy( msg, diffargv[0]); + perror_fatal (msg); + } +# else /* def __VMS */ close (diff_fds[0]); if (diff_fds[1] != STDOUT_FILENO) { @@ -654,9 +699,25 @@ execvp (diffargv[0], (char **) diffargv); _exit (errno == ENOENT ? 127 : 126); +# endif /* def __VMS [else] */ } - close (diff_fds[1]); +# ifdef __VMS /* Was: #if HAVE_WORKING_VFORK */ + /* Restore the parent's SIGINT and SIGPIPE behavior. */ + if (initial_handler (handler_index_of_SIGINT) != SIG_IGN) + signal_handler (SIGINT, catchsig); + if (initial_handler (handler_index_of_SIGPIPE) != SIG_IGN) + signal_handler (SIGPIPE, catchsig); + else + signal_handler (SIGPIPE, SIG_IGN); + + /* Stop blocking SIGINT and SIGPIPE in the parent. */ + sigprocmask (SIG_SETMASK, &procmask, 0); +# endif /* def __VMS Was: #if HAVE_WORKING_VFORK */ + +# ifndef __VMS + close (diff_fds[1]); /* Closed later on VMS. */ +# endif /* ndef __VMS */ diffout = fdopen (diff_fds[0], "r"); if (! diffout) perror_fatal ("fdopen"); @@ -691,6 +752,11 @@ diffpid = 0; #endif +# ifdef __VMS + if (close (diff_fds[ 1]) != 0) /* Not closed above on VMS. */ + perror_fatal ("close"); +# endif /* def __VMS */ + if (tmpname) { unlink (tmpname); @@ -824,7 +890,14 @@ static void give_help (void) { - fprintf (stderr, "%s", _("\ + fprintf (stderr, +#ifdef __VMS + /* Carriage control differs on VMS. */ + "%s\n", +#else /* def __VMS */ + "%s", +#endif /* def __VMS [else] */ + _("\ ed:\tEdit then use both versions, each decorated with a header.\n\ eb:\tEdit then use both versions.\n\ el or e1:\tEdit then use the left version.\n\ @@ -960,7 +1033,20 @@ int fd; if (tmpname) - tmp = fopen (tmpname, "w"); + { +#ifdef __VMS + /* 2012-10-08 SMS. + * On VMS, fopen() with "w" will create a new version of + * an existing file, and the overwrite mode ("r+") + * allows old data to corrupt the new, so it's easiest + * simply to delete any old file before opening a new + * one. Note that unlink() will be replaced by + * vms_unlink() to deal with any multiple versions. + */ + unlink (tmpname); +#endif /* def __VMS */ + tmp = fopen (tmpname, "w"); + } else { if ((fd = temporary_file ()) < 0) @@ -1024,7 +1110,29 @@ checksigs (); { -#if ! HAVE_WORKING_FORK +#if defined( __VMS) + /* Use system() to execute the "editor_program" with + * "tmpname" as the (only) argument. + */ + char *command = + xmalloc (strlen( editor_program) + 1 + strlen (tmpname) + 1); + sprintf (command, "%s %s", editor_program, tmpname); + + wstatus = system (command); + if ((wstatus & STS$M_SEVERITY) == STS$K_SUCCESS) + { + /* Translate VMS success to UNIX success. */ + wstatus = 0; + } + else + { + /* Stow the real VMS status away. */ + vaxc$errno = wstatus; + /* Suggest use of the real VMS status. */ + werrno = EVMSERR; + } + free (command); +#elif ! HAVE_WORKING_FORK char *command = xmalloc (shell_quote_length (editor_program) + 1 + strlen (tmpname) + 1); @@ -1181,7 +1289,12 @@ int e; sigset_t procmask; sigset_t blocked; +#ifdef __VMS + /* No "/" required (or desired) on VMS. */ + sprintf (buf, "%ssdiffXXXXXX", dir); +#else /* def __VMS */ sprintf (buf, "%s/sdiffXXXXXX", dir); +#endif /* def __VMS [else] */ sigemptyset (&blocked); sigaddset (&blocked, SIGINT); sigprocmask (SIG_BLOCK, &blocked, &procmask);