From 818722451465c21dcb6a637a4e4241b898a22a33 Mon Sep 17 00:00:00 2001 From: "Philip.Hazel" Date: Sat, 24 Nov 2018 16:31:10 +0000 Subject: [PATCH] Add VMS support for pcre2grep callout of an external program. --- ChangeLog | 3 +++ doc/pcre2grep.1 | 16 ++++++++++------ src/pcre2grep.c | 41 ++++++++++++++++++++++++++++++++++------- 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8549ea8..21c1be9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -80,6 +80,9 @@ that do not support fork(). 19. Fix two instances of <= 0 being applied to unsigned integers (the VMS compiler complains). +20. Added "fork" support for VMS to pcre2grep, for running an external program +via a string callout. + Version 10.32 10-September-2018 ------------------------------- diff --git a/doc/pcre2grep.1 b/doc/pcre2grep.1 index 6f8c440..9a8b0db 100644 --- a/doc/pcre2grep.1 +++ b/doc/pcre2grep.1 @@ -1,4 +1,4 @@ -.TH PCRE2GREP 1 "17 November 2018" "PCRE2 10.33" +.TH PCRE2GREP 1 "24 November 2018" "PCRE2 10.33" .SH NAME pcre2grep - a grep with Perl-compatible regular expressions. .SH SYNOPSIS @@ -778,9 +778,13 @@ only callouts with string arguments are useful. .SS "Calling external programs or scripts" .rs .sp -This facility can be independently disabled when \fBpcre2grep\fP is built. If -the callout string does not start with a pipe (vertical bar) character, it is -parsed into a list of substrings separated by pipe characters. The first +This facility can be independently disabled when \fBpcre2grep\fP is built. It +is supported for Windows, where a call to \fB_spawnvp()\fP is used, for VMS, +where \fBlib$spawn()\fP is used, and for any other Unix-like environment where +\fBfork()\fP and \fBexecv()\fP are available. +.P +If the callout string does not start with a pipe (vertical bar) character, it +is parsed into a list of substrings separated by pipe characters. The first substring must be an executable name, with the following substrings specifying arguments: .sp @@ -806,7 +810,7 @@ a single dollar and $| is replaced by a pipe character. Here is an example: Arg1: [1] [234] [4] Arg2: |1| () 12345 .sp -The parameters for the \fBexecv()\fP system call that is used to run the +The parameters for the system call that is used to run the program or script are zero-terminated strings. This means that binary zero characters in the callout argument will cause premature termination of their substrings, and therefore should not be present. Any syntax errors in the @@ -880,6 +884,6 @@ Cambridge, England. .rs .sp .nf -Last updated: 17 November 2018 +Last updated: 24 November 2018 Copyright (c) 1997-2018 University of Cambridge. .fi diff --git a/src/pcre2grep.c b/src/pcre2grep.c index 477e867..a3cc3ec 100644 --- a/src/pcre2grep.c +++ b/src/pcre2grep.c @@ -68,6 +68,12 @@ POSSIBILITY OF SUCH DAMAGE. #undef WIN32 #endif +#ifdef __VMS +#include clidef +#include descrip +#include lib$routines +#endif + #ifdef WIN32 #include /* For _setmode() */ #include /* For _O_BINARY */ @@ -573,8 +579,6 @@ status of 1, which is not helpful. To help with this problem, define a symbol therein. */ #ifdef __VMS -#include descrip -#include lib$routines char val_buf[4]; $DESCRIPTOR(sym_nam, "PCRE2GREP_RC"); $DESCRIPTOR(sym_val, val_buf); @@ -2041,7 +2045,7 @@ follows: dollar or $| replaced by a pipe character. Alternatively, if string starts with pipe, the remainder is taken as an output -string, same as --output. This is the only form that is supported if +string, same as --output. This is the only form that is supported if SUPPORT_PCRE2GREP_FORK is not defined. In this case, --om-separator is used to separate each callout, defaulting to newline. @@ -2100,7 +2104,7 @@ if (*string == '|') (void)display_output_text(string, TRUE, subject, ovector, capture_top); return 0; } - + #ifndef SUPPORT_PCRE2GREP_CALLOUT_FORK return 0; #else @@ -2285,11 +2289,34 @@ while (length > 0) *argsptr++ = '\0'; *argsvectorptr = NULL; +/* Running an external command is system-dependent. Handle Windows and VMS as +necessary, otherwise assume fork(). */ + #ifdef WIN32 result = _spawnvp(_P_WAIT, argsvector[0], (const char * const *)argsvector); -#else -pid = fork(); +#elif defined __VMS + { + char cmdbuf[500]; + short i = 0; + int flags = CLI$M_NOCLISYM|CLI$M_NOLOGNAM|CLI$M_NOKEYPAD, status, retstat; + $DESCRIPTOR(cmd, cmdbuf); + + cmdbuf[0] = 0; + while (argsvector[i]) + { + strcat(cmdbuf, argsvector[i]); + strcat(cmdbuf, " "); + i++; + } + cmd.dsc$w_length = strlen(cmdbuf) - 1; + status = lib$spawn(&cmd, 0,0, &flags, 0,0, &retstat); + if (!(status & 1)) result = 0; + else result = retstat & 1 ? 0 : 1; + } + +#else /* Neither Windows nor VMS */ +pid = fork(); if (pid == 0) { (void)execv(argsvector[0], argsvector); @@ -2298,7 +2325,7 @@ if (pid == 0) } else if (pid > 0) (void)waitpid(pid, &result, 0); -#endif +#endif /* End Windows/VMS/other handling */ free(args); free(argsvector);