mirror of
https://git.savannah.gnu.org/git/make.git
synced 2024-11-25 04:35:44 +00:00
Add VMS enhancements from Hartmut Becker.
This commit is contained in:
parent
fe43fa9de3
commit
b6f45ddc53
10 changed files with 271 additions and 72 deletions
30
ChangeLog
30
ChangeLog
|
@ -1,3 +1,33 @@
|
|||
2009-11-15 Paul Smith <psmith@gnu.org>
|
||||
|
||||
Patches for VMS provided by Hartmut Becker <Hartmut.Becker@hp.com>
|
||||
|
||||
* vmsjobs.c (ctrlYPressed) [VMS]: Deal with CTRL-Y.
|
||||
(vmsHandleChildTerm) [VMS]: Ditto.
|
||||
(astYHandler) [VMS]: Ditto.
|
||||
(tryToSetupYAst) [VMS]: Ditto.
|
||||
(child_execute_job) [VMS]: Ditto.
|
||||
|
||||
* vmsify.c (trnlog) [VMS]: Fix const errors.
|
||||
(vmsify) [VMS]: Ditto.
|
||||
|
||||
* readme.vms [VMS]: Update with notes for 3.82.
|
||||
|
||||
* job.h (comname) [VMS]: Remember the temporary command filename
|
||||
|
||||
* dir.c (vmsify) [VMS]: Fix const errors.
|
||||
(vms_hash) [VMS]: Ditto.
|
||||
(vmsstat_dir) [VMS]: Ditto.
|
||||
(find_directory) [VMS]: Fix case-insensitive option for VMS
|
||||
(dir_contents_file_exists_p) [VMS]: Ditto.
|
||||
(file_impossible) [VMS]: Ditto.
|
||||
|
||||
* config.h-vms.template (HAVE_FDOPEN) [VMS]: Have it.
|
||||
(HAVE_STRCASECMP) [VMS]: Ditto.
|
||||
|
||||
* arscan.c (VMS_get_member_info) [VMS]: Fix timezone computation.
|
||||
(ar_scan) [VMS]: Fix const error.
|
||||
|
||||
2009-11-12 Boris Kolpackov <boris@codesynthesis.com>
|
||||
|
||||
* vpath.c (vpath_search, selective_vpath_search): Add index arguments
|
||||
|
|
26
arscan.c
26
arscan.c
|
@ -81,7 +81,28 @@ VMS_get_member_info (struct dsc$descriptor_s *module, unsigned long *rfa)
|
|||
* but that decc$fix_time() isn't documented to work this way. Let me
|
||||
* know if this causes problems in other VMS environments.
|
||||
*/
|
||||
val = decc$fix_time (&mhd->mhd$l_datim) + timezone - daylight*3600;
|
||||
{
|
||||
/* Modified by M. Gehre at 11-JAN-2008 because old formula is wrong:
|
||||
* val = decc$fix_time (&mhd->mhd$l_datim) + timezone - daylight*3600;
|
||||
* a) daylight specifies, if the timezone has daylight saving enabled, not
|
||||
* if it is active
|
||||
* b) what we need is the information, if daylight saving was active, if
|
||||
* the library module was replaced. This information we get using the
|
||||
* localtime function
|
||||
*/
|
||||
|
||||
struct tm *tmp;
|
||||
|
||||
/* Conversion from VMS time to C time */
|
||||
val = decc$fix_time (&mhd->mhd$l_datim);
|
||||
|
||||
/*
|
||||
* Conversion from local time (stored in library) to GMT (needed for gmake)
|
||||
* Note: The tm_gmtoff element is a VMS extension to the ANSI standard.
|
||||
*/
|
||||
tmp = localtime (&val);
|
||||
val -= tmp->tm_gmtoff;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < module->dsc$w_length; i++)
|
||||
|
@ -155,7 +176,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
|||
return -2;
|
||||
}
|
||||
|
||||
libdesc.dsc$a_pointer = archive;
|
||||
/* there is no such descriptor with "const char *dsc$a_pointer" */
|
||||
libdesc.dsc$a_pointer = (char *)archive;
|
||||
libdesc.dsc$w_length = strlen (archive);
|
||||
|
||||
status = lbr$open (&VMS_lib_idx, &libdesc, 0, 0, 0, 0, 0);
|
||||
|
|
|
@ -76,6 +76,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
|||
/* Define to 1 if you don't have vprintf but do have _doprnt. */
|
||||
/* #undef HAVE_DOPRNT */
|
||||
|
||||
/* Define to 1 if you have the fdopen function. */
|
||||
#define HAVE_FDOPEN 1
|
||||
|
||||
/* Define to 1 if your system has a working fnmatch function. */
|
||||
/* #undef HAVE_FNMATCH */
|
||||
|
||||
|
@ -289,7 +292,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
|||
/* #undef HAVE_SOCKET */
|
||||
|
||||
/* Define to 1 if you have the strcasecmp function. */
|
||||
/* #undef HAVE_STRCASECMP */
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the strcmpi function. */
|
||||
/* #undef HAVE_STRCMPI */
|
||||
|
|
23
dir.c
23
dir.c
|
@ -23,7 +23,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
|||
# include <dirent.h>
|
||||
# define NAMLEN(dirent) strlen((dirent)->d_name)
|
||||
# ifdef VMS
|
||||
char *vmsify (char *name, int type);
|
||||
/* its prototype is in vmsdir.h, which is not needed for HAVE_DIRENT_H */
|
||||
const char *vmsify (const char *name, int type);
|
||||
# endif
|
||||
#else
|
||||
# define dirent direct
|
||||
|
@ -145,7 +146,7 @@ downcase (const char *filename)
|
|||
#ifdef VMS
|
||||
|
||||
static int
|
||||
vms_hash (char *name)
|
||||
vms_hash (const char *name)
|
||||
{
|
||||
int h = 0;
|
||||
int g;
|
||||
|
@ -171,7 +172,7 @@ vms_hash (char *name)
|
|||
|
||||
/* fake stat entry for a directory */
|
||||
static int
|
||||
vmsstat_dir (char *name, struct stat *st)
|
||||
vmsstat_dir (const char *name, struct stat *st)
|
||||
{
|
||||
char *s;
|
||||
int h;
|
||||
|
@ -184,6 +185,7 @@ vmsstat_dir (char *name, struct stat *st)
|
|||
s = strchr (name, ':'); /* find device */
|
||||
if (s)
|
||||
{
|
||||
/* to keep the compiler happy we said "const char *name", now we cheat */
|
||||
*s++ = 0;
|
||||
st->st_dev = (char *)vms_hash (name);
|
||||
h = vms_hash (s);
|
||||
|
@ -192,8 +194,7 @@ vmsstat_dir (char *name, struct stat *st)
|
|||
else
|
||||
{
|
||||
st->st_dev = 0;
|
||||
s = name;
|
||||
h = vms_hash (s);
|
||||
h = vms_hash (name);
|
||||
}
|
||||
|
||||
st->st_ino[0] = h & 0xff;
|
||||
|
@ -449,7 +450,11 @@ find_directory (const char *name)
|
|||
|
||||
p = name + strlen (name);
|
||||
dir = xmalloc (sizeof (struct directory));
|
||||
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
|
||||
dir->name = strcache_add_len (downcase(name), p - name);
|
||||
#else
|
||||
dir->name = strcache_add_len (name, p - name);
|
||||
#endif
|
||||
hash_insert_at (&directories, dir, dir_slot);
|
||||
/* The directory is not in the name hash table.
|
||||
Find its device and inode numbers, and look it up by them. */
|
||||
|
@ -706,7 +711,11 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
|||
#endif
|
||||
{
|
||||
df = xmalloc (sizeof (struct dirfile));
|
||||
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
|
||||
df->name = strcache_add_len (downcase(d->d_name), len);
|
||||
#else
|
||||
df->name = strcache_add_len (d->d_name, len);
|
||||
#endif
|
||||
df->length = len;
|
||||
df->impossible = 0;
|
||||
hash_insert_at (&dir->dirfiles, df, dirfile_slot);
|
||||
|
@ -880,7 +889,11 @@ file_impossible (const char *filename)
|
|||
|
||||
new = xmalloc (sizeof (struct dirfile));
|
||||
new->length = strlen (filename);
|
||||
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
|
||||
new->name = strcache_add_len (downcase(filename), new->length);
|
||||
#else
|
||||
new->name = strcache_add_len (filename, new->length);
|
||||
#endif
|
||||
new->impossible = 1;
|
||||
hash_insert (&dir->contents->dirfiles, new);
|
||||
}
|
||||
|
|
1
job.h
1
job.h
|
@ -53,6 +53,7 @@ struct child
|
|||
#ifdef VMS
|
||||
int efn; /* Completion event flag number */
|
||||
int cstatus; /* Completion status */
|
||||
char *comname; /* Temporary command file name */
|
||||
#endif
|
||||
char *sh_batch_file; /* Script file for shell commands */
|
||||
unsigned int remote:1; /* Nonzero if executing remotely. */
|
||||
|
|
13
main.c
13
main.c
|
@ -1127,20 +1127,17 @@ main (int argc, char **argv, char **envp)
|
|||
/* Set up .FEATURES */
|
||||
define_variable_cname (".FEATURES",
|
||||
"target-specific order-only second-expansion else-if"
|
||||
"shortest-stem undefine",
|
||||
o_default, 0);
|
||||
"shortest-stem undefine"
|
||||
#ifndef NO_ARCHIVES
|
||||
do_variable_definition (NILF, ".FEATURES", "archives",
|
||||
o_default, f_append, 0);
|
||||
"archives"
|
||||
#endif
|
||||
#ifdef MAKE_JOBSERVER
|
||||
do_variable_definition (NILF, ".FEATURES", "jobserver",
|
||||
o_default, f_append, 0);
|
||||
"jobserver"
|
||||
#endif
|
||||
#ifdef MAKE_SYMLINKS
|
||||
do_variable_definition (NILF, ".FEATURES", "check-symlink",
|
||||
o_default, f_append, 0);
|
||||
"check-symlink"
|
||||
#endif
|
||||
, o_default, 0);
|
||||
|
||||
/* Read in variables from the environment. It is important that this be
|
||||
done before $(MAKE) is figured out so its definitions will not be
|
||||
|
|
95
readme.vms
95
readme.vms
|
@ -1,16 +1,13 @@
|
|||
This is the VMS version of GNU Make, updated by Hartmut Becker
|
||||
|
||||
Changes are based on GNU make 3.80. Latest changes are for OpenVMS/I64
|
||||
and new VMS CRTLs.
|
||||
Changes are based on GNU make 3.82.
|
||||
|
||||
This version was tested on OpenVMS/I64 V8.2 (field test) with hp C
|
||||
X7.1-024 OpenVMS/Alpha V7.3-2 with Compaq C V6.5-001 and OpenVMS/VAX 7.1
|
||||
with Compaq C V6.2-003 There are still some warning and informational
|
||||
message issued by the compilers.
|
||||
This version was built and tested on OpenVMS V7.3 (VAX), V7.3-2 (Alpha) and
|
||||
V8.3-1H1 (I64).
|
||||
|
||||
Build instructions
|
||||
Make a 1st version
|
||||
$ @makefile.com
|
||||
$ @makefile.com ! ignore any compiler and/or linker warning
|
||||
$ rena make.exe 1st-make.exe
|
||||
Use the 1st version to generate a 2nd version
|
||||
$ mc sys$disk:[]1st-make clean
|
||||
|
@ -20,7 +17,89 @@ Verify your 2nd version
|
|||
$ mc sys$disk:[]2nd-make clean
|
||||
$ mc sys$disk:[]2nd-make
|
||||
|
||||
Changes:
|
||||
Changes (3.81.90)
|
||||
|
||||
Michael Gehre (at VISTEC-SEMI dot COM) supplied a fix for a problem with
|
||||
timestamps of object modules in OLBs. The timestamps were not correctly
|
||||
adjusted to GMT based time, if the local VMS time was using a daylight saving
|
||||
algorithm and if daylight saving was switched off.
|
||||
|
||||
John Eisenbraun (at HP dot COM) supplied fixes and and an enhancement to append
|
||||
output redirection in action lines.
|
||||
|
||||
Rework of ctrl+c and ctrl+y handling.
|
||||
|
||||
Fix a problem with cached strings, which showed on case-insensitive file
|
||||
systems.
|
||||
|
||||
Build fixes for const-ified code in VMS specific sources.
|
||||
|
||||
Build notes:
|
||||
- Try to avoid HP C V7.2-001, which has an incompatible change
|
||||
how __STDC__ is defined. This results at least in compile time warnings.
|
||||
|
||||
- On V8.3-1H1, if you press Ctrl+C you may see a traceback, starting with
|
||||
%SYSTEM-F-CONTROLC, operation completed under CTRL/C
|
||||
%TRACE-F-TRACEBACK, symbolic stack dump follows
|
||||
image module routine line rel PC abs PC
|
||||
|
||||
DECC$SHR C$SIGNAL gsignal 27991 0000000000001180
|
||||
FFFFFFFF84AB2DA0
|
||||
DECC$SHR C$SIGNAL raise 28048 0000000000001280
|
||||
FFFFFFFF84AB2EA0
|
||||
DECC$SHR C$SIGPENDING decc$$deliver_signals
|
||||
12475 0000000000000890
|
||||
FFFFFFFF84C13690
|
||||
...
|
||||
This looks like an incompatibility to the Alpha and VAX behavior, so it looks
|
||||
like a problem in I64 VMS version(s).
|
||||
|
||||
- There is no clean build on VAX. In the environment I tested, I had to use GNU
|
||||
make's alloca which produced a couple of compile time warnings. It seems too
|
||||
much effort to work on a clean build on VAX.
|
||||
|
||||
A note on appending the redirected output. With this change, a simple mechanism
|
||||
is implemented to make ">>" work in action lines. In VMS there is no simple
|
||||
feature like ">>" to have DCL command or program output redirected and appended
|
||||
to a file. GNU make for VMS already implements the redirection of output. If
|
||||
such a redirection is detected, an ">" on the action line, GNU make creates a
|
||||
DCL command procedure to execute the action and to redirect its output. Based
|
||||
on that, now ">>" is also recognized and a similar but different command
|
||||
procedure is created to implement the append. The main idea here is to create a
|
||||
temporary file which collects the output and which is appended to the wanted
|
||||
output file. Then the temporary file is deleted. This is all done in the
|
||||
command procedure to keep changes in make small and simple. This obviously has
|
||||
some limitations but it seems good enough compared with the current ">"
|
||||
implementation. (And in my opinion, redirection is not really what GNU make has
|
||||
to do.) With this approach, it may happen that the temporary file is not yet
|
||||
appended and is left in SYS$SCRATCH. The temporary file names look like
|
||||
"CMDxxxxx.". Any time the created command procedure can not complete, this
|
||||
happens. Pressing Ctrl+Y to abort make is one case. In case of Ctrl+Y the
|
||||
associated command procedure is left in SYS$SCRATCH as well. Its name is
|
||||
CMDxxxxx.COM.
|
||||
|
||||
Change in the Ctrl+Y handling
|
||||
|
||||
Ctrl+Y was: The CtrlY handler called $forcex for the current child.
|
||||
|
||||
Ctrl+Y changed: The CtrlY handler uses $delprc to delete all children. This way
|
||||
also actions with DCL commands will be stopped. As before Ctrl+Y then sends
|
||||
SIGQUIT to itself, which is handled in common code.
|
||||
|
||||
Change in deleteing temporary command files
|
||||
|
||||
Temporary command files were deleted in the main line, after returning from the
|
||||
vms child termination handler. If Ctrl+C was pressed, the handler is called but
|
||||
did not return to main line.
|
||||
|
||||
Now, temporary command files are deleted in the vms child termination
|
||||
handler. That deletes the them even if a Ctrl+C was pressed.
|
||||
|
||||
The behavior of pressing Ctrl+C is not changed. It still has only an effect,
|
||||
after the current action is terminated. If that doesn't happen or takes too
|
||||
long, Ctrl+Y should be used instead.
|
||||
|
||||
Changes (3.80)
|
||||
|
||||
. In default.c define variable ARCH as IA64 for VMS on Itanium systems.
|
||||
|
||||
|
|
|
@ -139,6 +139,10 @@ getwd (char *cwd)
|
|||
return (getcwd (buf, 512));
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Is this used? I don't see any reference, so I suggest to remove it.
|
||||
*/
|
||||
int
|
||||
vms_stat (char *name, struct stat *buf)
|
||||
{
|
||||
|
@ -235,6 +239,7 @@ vms_stat (char *name, struct stat *buf)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
char *
|
||||
cvt_time (unsigned long tval)
|
||||
|
|
22
vmsify.c
22
vmsify.c
|
@ -120,7 +120,11 @@ trnlog (const char *name)
|
|||
struct dsc$descriptor_s name_dsc;
|
||||
char *s;
|
||||
|
||||
INIT_DSC_CSTRING (name_dsc, name);
|
||||
/*
|
||||
* the string isn't changed, but there is no string descriptor with
|
||||
* "const char *dsc$a_pointer"
|
||||
*/
|
||||
INIT_DSC_CSTRING (name_dsc, (char *)name);
|
||||
|
||||
stat = lib$sys_trnlog (&name_dsc, &resltlen, &reslt_dsc);
|
||||
|
||||
|
@ -227,6 +231,9 @@ vmsify (const char *name, int type)
|
|||
char *vptr;
|
||||
int as_dir;
|
||||
int count;
|
||||
const char *s;
|
||||
const char *s1;
|
||||
const char *s2;
|
||||
|
||||
if (name == 0)
|
||||
return 0;
|
||||
|
@ -239,8 +246,8 @@ vmsify (const char *name, int type)
|
|||
|
||||
if (t != 0)
|
||||
{
|
||||
const char *s1;
|
||||
const char *s2;
|
||||
// const char *s1;
|
||||
// const char *s2;
|
||||
|
||||
if (type == 1)
|
||||
{
|
||||
|
@ -272,8 +279,9 @@ vmsify (const char *name, int type)
|
|||
|
||||
if (t != 0)
|
||||
{
|
||||
const char *s;
|
||||
const char *s1 = strchr (t+1, '[');
|
||||
// const char *s;
|
||||
// const char *s1 = strchr (t+1, '[');
|
||||
s1 = strchr (t+1, '[');
|
||||
if (s1 == 0)
|
||||
{
|
||||
strcpy (vmsname, name);
|
||||
|
@ -388,8 +396,8 @@ vmsify (const char *name, int type)
|
|||
|
||||
case 3: /* '//' at start */
|
||||
{
|
||||
const char *s;
|
||||
const char *s1;
|
||||
// const char *s;
|
||||
// const char *s1;
|
||||
char *vp;
|
||||
while (*fptr == '/') /* collapse all '/' */
|
||||
fptr++;
|
||||
|
|
123
vmsjobs.c
123
vmsjobs.c
|
@ -110,8 +110,11 @@ vms_handle_apos (char *p)
|
|||
return p;
|
||||
}
|
||||
|
||||
/* This is called as an AST when a child process dies (it won't get
|
||||
interrupted by anything except a higher level AST).
|
||||
static int ctrlYPressed= 0;
|
||||
/* This is called at main or AST level. It is at AST level for DONTWAITFORCHILD
|
||||
and at main level otherwise. In any case it is called when a child process
|
||||
terminated. At AST level it won't get interrupted by anything except a
|
||||
inner mode level AST.
|
||||
*/
|
||||
int
|
||||
vmsHandleChildTerm(struct child *child)
|
||||
|
@ -123,6 +126,12 @@ vmsHandleChildTerm(struct child *child)
|
|||
vms_jobsefnmask &= ~(1 << (child->efn - 32));
|
||||
|
||||
lib$free_ef(&child->efn);
|
||||
if (child->comname)
|
||||
{
|
||||
if (!ISDB (DB_JOBS)&&!ctrlYPressed)
|
||||
unlink (child->comname);
|
||||
free (child->comname);
|
||||
}
|
||||
|
||||
(void) sigblock (fatal_signal_mask);
|
||||
|
||||
|
@ -219,8 +228,7 @@ vmsHandleChildTerm(struct child *child)
|
|||
static int ctrlMask= LIB$M_CLI_CTRLY;
|
||||
static int oldCtrlMask;
|
||||
static int setupYAstTried= 0;
|
||||
static int pidToAbort= 0;
|
||||
static int chan= 0;
|
||||
static unsigned short int chan= 0;
|
||||
|
||||
static void
|
||||
reEnableAst(void)
|
||||
|
@ -228,14 +236,15 @@ reEnableAst(void)
|
|||
lib$enable_ctrl (&oldCtrlMask,0);
|
||||
}
|
||||
|
||||
static void
|
||||
astHandler (void)
|
||||
static int
|
||||
astYHandler (void)
|
||||
{
|
||||
if (pidToAbort) {
|
||||
sys$forcex (&pidToAbort, 0, SS$_ABORT);
|
||||
pidToAbort= 0;
|
||||
}
|
||||
struct child *c;
|
||||
for (c = children; c != 0; c = c->next)
|
||||
sys$delprc (&c->pid, 0, 0);
|
||||
ctrlYPressed= 1;
|
||||
kill (getpid(),SIGQUIT);
|
||||
return SS$_NORMAL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -247,32 +256,28 @@ tryToSetupYAst(void)
|
|||
short int status, count;
|
||||
int dvi;
|
||||
} iosb;
|
||||
unsigned short int loc_chan;
|
||||
|
||||
setupYAstTried++;
|
||||
|
||||
if (!chan) {
|
||||
status= sys$assign(&inputDsc,&chan,0,0);
|
||||
if (chan)
|
||||
loc_chan= chan;
|
||||
else {
|
||||
status= sys$assign(&inputDsc,&loc_chan,0,0);
|
||||
if (!(status&SS$_NORMAL)) {
|
||||
lib$signal(status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
status= sys$qiow (0, chan, IO$_SETMODE|IO$M_CTRLYAST,&iosb,0,0,
|
||||
astHandler,0,0,0,0,0);
|
||||
if (status==SS$_NORMAL)
|
||||
status= iosb.status;
|
||||
if (status==SS$_ILLIOFUNC || status==SS$_NOPRIV) {
|
||||
sys$dassgn(chan);
|
||||
#ifdef CTRLY_ENABLED_ANYWAY
|
||||
fprintf (stderr,
|
||||
_("-warning, CTRL-Y will leave sub-process(es) around.\n"));
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
else if (!(status&SS$_NORMAL)) {
|
||||
sys$dassgn(chan);
|
||||
lib$signal(status);
|
||||
status= sys$qiow (0, loc_chan, IO$_SETMODE|IO$M_CTRLYAST,&iosb,0,0,
|
||||
astYHandler,0,0,0,0,0);
|
||||
if (status==SS$_NORMAL)
|
||||
status= iosb.status;
|
||||
if (status!=SS$_NORMAL) {
|
||||
if (!chan)
|
||||
sys$dassgn(loc_chan);
|
||||
if (status!=SS$_ILLIOFUNC && status!=SS$_NOPRIV)
|
||||
lib$signal(status);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -287,6 +292,8 @@ tryToSetupYAst(void)
|
|||
lib$signal(status);
|
||||
return;
|
||||
}
|
||||
if (!chan)
|
||||
chan = loc_chan;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -299,13 +306,14 @@ child_execute_job (char *argv, struct child *child)
|
|||
static struct dsc$descriptor_s ofiledsc;
|
||||
static struct dsc$descriptor_s efiledsc;
|
||||
int have_redirection = 0;
|
||||
int have_append = 0;
|
||||
int have_newline = 0;
|
||||
|
||||
int spflags = CLI$M_NOWAIT;
|
||||
int status;
|
||||
char *cmd = alloca (strlen (argv) + 512), *p, *q;
|
||||
char ifile[256], ofile[256], efile[256];
|
||||
char *comname = 0;
|
||||
int comnamelen;
|
||||
char procname[100];
|
||||
int in_string;
|
||||
|
||||
|
@ -314,6 +322,7 @@ child_execute_job (char *argv, struct child *child)
|
|||
ifile[0] = 0;
|
||||
ofile[0] = 0;
|
||||
efile[0] = 0;
|
||||
child->comname = NULL;
|
||||
|
||||
DB (DB_JOBS, ("child_execute_job (%s)\n", argv));
|
||||
|
||||
|
@ -383,6 +392,11 @@ child_execute_job (char *argv, struct child *child)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (*(p+1) == '>')
|
||||
{
|
||||
have_append = 1;
|
||||
p += 1;
|
||||
}
|
||||
p = vms_redirect (&ofiledsc, ofile, p);
|
||||
}
|
||||
*q = ' ';
|
||||
|
@ -481,9 +495,10 @@ child_execute_job (char *argv, struct child *child)
|
|||
return 0;
|
||||
}
|
||||
|
||||
outfile = open_tmpfile (&comname, "sys$scratch:CMDXXXXXX.COM");
|
||||
outfile = open_tmpfile (&child->comname, "sys$scratch:CMDXXXXXX.COM");
|
||||
if (outfile == 0)
|
||||
pfatal_with_name (_("fopen (temporary file)"));
|
||||
comnamelen = strlen (child->comname);
|
||||
|
||||
if (ifile[0])
|
||||
{
|
||||
|
@ -501,9 +516,19 @@ child_execute_job (char *argv, struct child *child)
|
|||
|
||||
if (ofile[0])
|
||||
{
|
||||
fprintf (outfile, "$ define sys$output %s\n", ofile);
|
||||
DB (DB_JOBS, (_("Redirected output to %s\n"), ofile));
|
||||
ofiledsc.dsc$w_length = 0;
|
||||
if (have_append)
|
||||
{
|
||||
fprintf (outfile, "$ set noon\n");
|
||||
fprintf (outfile, "$ define sys$output %.*s\n", comnamelen-3, child->comname);
|
||||
DB (DB_JOBS, (_("Append output to %s\n"), ofile));
|
||||
ofiledsc.dsc$w_length = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (outfile, "$ define sys$output %s\n", ofile);
|
||||
DB (DB_JOBS, (_("Redirected output to %s\n"), ofile));
|
||||
ofiledsc.dsc$w_length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
p = sep = q = cmd;
|
||||
|
@ -558,12 +583,25 @@ child_execute_job (char *argv, struct child *child)
|
|||
}
|
||||
}
|
||||
|
||||
fwrite (p, 1, q - p, outfile);
|
||||
if (*p)
|
||||
{
|
||||
fwrite (p, 1, --q - p, outfile);
|
||||
fputc ('\n', outfile);
|
||||
}
|
||||
|
||||
if (have_append)
|
||||
{
|
||||
fprintf (outfile, "$ deassign sys$output ! 'f$verify(0)\n");
|
||||
fprintf (outfile, "$ append:=append\n");
|
||||
fprintf (outfile, "$ delete:=delete\n");
|
||||
fprintf (outfile, "$ append/new %.*s %s\n", comnamelen-3, child->comname, ofile);
|
||||
fprintf (outfile, "$ delete %.*s;*\n", comnamelen-3, child->comname);
|
||||
DB (DB_JOBS, (_("Append %.*s and cleanup\n"), comnamelen-3, child->comname));
|
||||
}
|
||||
|
||||
fclose (outfile);
|
||||
|
||||
sprintf (cmd, "$ @%s", comname);
|
||||
sprintf (cmd, "$ @%s", child->comname);
|
||||
|
||||
DB (DB_JOBS, (_("Executing %s instead\n"), cmd));
|
||||
}
|
||||
|
@ -578,7 +616,15 @@ child_execute_job (char *argv, struct child *child)
|
|||
{
|
||||
status = lib$get_ef ((unsigned long *)&child->efn);
|
||||
if (!(status & 1))
|
||||
return 0;
|
||||
{
|
||||
if (child->comname)
|
||||
{
|
||||
if (!ISDB (DB_JOBS))
|
||||
unlink (child->comname);
|
||||
free (child->comname);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
sys$clref (child->efn);
|
||||
|
@ -647,9 +693,7 @@ child_execute_job (char *argv, struct child *child)
|
|||
0, 0, 0);
|
||||
if (status & 1)
|
||||
{
|
||||
pidToAbort= child->pid;
|
||||
status= sys$waitfr (child->efn);
|
||||
pidToAbort= 0;
|
||||
vmsHandleChildTerm(child);
|
||||
}
|
||||
#else
|
||||
|
@ -677,8 +721,5 @@ child_execute_job (char *argv, struct child *child)
|
|||
}
|
||||
}
|
||||
|
||||
if (comname && !ISDB (DB_JOBS))
|
||||
unlink (comname);
|
||||
|
||||
return (status & 1);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue