summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog30
-rw-r--r--arscan.c26
-rw-r--r--config.h-vms.template5
-rw-r--r--dir.c23
-rw-r--r--job.h1
-rw-r--r--main.c13
-rw-r--r--readme.vms95
-rw-r--r--vmsfunctions.c5
-rw-r--r--vmsify.c22
-rw-r--r--vmsjobs.c123
10 files changed, 271 insertions, 72 deletions
diff --git a/ChangeLog b/ChangeLog
index e8c89d1..b5f32f2 100644
--- a/ChangeLog
+++ b/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
diff --git a/arscan.c b/arscan.c
index 782786c..771e394 100644
--- a/arscan.c
+++ b/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);
diff --git a/config.h-vms.template b/config.h-vms.template
index 9811d6c..68af4ec 100644
--- a/config.h-vms.template
+++ b/config.h-vms.template
@@ -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 */
diff --git a/dir.c b/dir.c
index 9c92fa0..e127fc1 100644
--- a/dir.c
+++ b/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);
}
diff --git a/job.h b/job.h
index 8947251..4664e75 100644
--- a/job.h
+++ b/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. */
diff --git a/main.c b/main.c
index babf21d..f45f608 100644
--- a/main.c
+++ b/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
diff --git a/readme.vms b/readme.vms
index be11778..5a84374 100644
--- a/readme.vms
+++ b/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.
diff --git a/vmsfunctions.c b/vmsfunctions.c
index 9ff543f..e100826 100644
--- a/vmsfunctions.c
+++ b/vmsfunctions.c
@@ -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)
diff --git a/vmsify.c b/vmsify.c
index 628ac6d..178fc51 100644
--- a/vmsify.c
+++ b/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++;
diff --git a/vmsjobs.c b/vmsjobs.c
index 71492a8..3cba00b 100644
--- a/vmsjobs.c
+++ b/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);
}