Discussion:
getcwd() issues on VMS / canonicalize-lgpl.c
John Malmberg
2017-06-06 13:43:24 UTC
Permalink
Summary:

1. The VMS CRTL getcwd() will not pass configure tests and will be
marked for replacement from gnulib.

2. The replacement from gnulib causes canonicalize-lgpl.c to fail
because the replacement only has 2 parameters, not three.

3. The replacement from gnulib also does not fix all the known ills in
VMS getcwd().

I do not have fixes here for all of these issues, however this VMS
specific code in canonicalize-lgpl.c probably should just be removed.

--- /src_root/gnulib/lib/canonicalize-lgpl.c 2017-06-01 07:48:41 -0500
+++ /vms_root/gnulib/lib/canonicalize-lgpl.c 2017-06-06 08:01:11 -0500
@@ -59,12 +59,7 @@
*/
# undef getcwd
# endif
-# ifdef VMS
- /* We want the directory in Unix syntax, not in VMS syntax. */
-# define __getcwd(buf, max) getcwd (buf, max, 0)
-# else
-# define __getcwd getcwd
-# endif
+# define __getcwd getcwd
# else
# define __getcwd(buf, max) getwd (buf)
# endif

This code is not needed anymore on VMS.

TL:DR:

At VMS 5.5-2, VMS switched from VAXC/VAXCRTL to DECC/DECCRTL. GCC/VAX
can also use the DECCRTL non-prefixed shared library.

For the DECCRTL having the routines like getcwd() to return results in
Unix syntax instead of VMS syntax was a run time setting that the
program could do. Unfortunately there are two APIs for setting this
based on the version of VMS, which can be hidden with a macro.

Because some of these settings must be made before main() is called,
they are typically placed in a "lib$initialize" object module that
linked with the program. Typically this lib$initialize module is common
to a lot of programs, so application source code does not need to be
modified.

The DECCRTL getcwd() has two known bugs.
1. If buffer is NULL and size is 0, it access violates,
so a wrapper must detect this and allocate 4097 bytes on non-VAX
and 256 bytes on VAX.
2. If the directory is too long to fit into 4097 bytes, it must
be returned in VMS format, and then translated to Unix syntax.

Because of that, VMS is not currently using the GNULIB replacement getcwd.

At this time, I have not worked out what would be needed for GNULIB to
support replacing the DECCRTL getcwd, or providing a suitable
"lib$initialize" source module.

Regards,
-John
Bruno Haible
2017-06-06 16:01:58 UTC
Permalink
Hi,
Post by John Malmberg
1. The VMS CRTL getcwd() will not pass configure tests and will be
marked for replacement from gnulib.
2. The replacement from gnulib causes canonicalize-lgpl.c to fail
because the replacement only has 2 parameters, not three.
3. The replacement from gnulib also does not fix all the known ills in
VMS getcwd().
I do not have fixes here for all of these issues, however this VMS
specific code in canonicalize-lgpl.c probably should just be removed.
But when IN_RELOCWRAPPER is defined (i.e. when this code is used through the
'relocatable-prog-wrapper' module) we '#undef getcwd', so in this case
the lines
/* We want the directory in Unix syntax, not in VMS syntax. */
# define __getcwd(buf, max) getcwd (buf, max, 0)
are appropriate, right?

Bruno
John E. Malmberg
2017-06-06 23:01:11 UTC
Permalink
Post by Bruno Haible
Hi,
Post by John Malmberg
1. The VMS CRTL getcwd() will not pass configure tests and will be
marked for replacement from gnulib.
2. The replacement from gnulib causes canonicalize-lgpl.c to fail
because the replacement only has 2 parameters, not three.
3. The replacement from gnulib also does not fix all the known ills in
VMS getcwd().
I do not have fixes here for all of these issues, however this VMS
specific code in canonicalize-lgpl.c probably should just be removed.
But when IN_RELOCWRAPPER is defined (i.e. when this code is used through the
'relocatable-prog-wrapper' module) we '#undef getcwd', so in this case
the lines
/* We want the directory in Unix syntax, not in VMS syntax. */
# define __getcwd(buf, max) getcwd (buf, max, 0)
are appropriate, right?
I have not encountered the relocatable-prog-wrapper on a VMS project
yet, so I do not know what it is.

It still does not need the vms specific variant as a production program
would set the DECCRTL mode to have getcwd() return a Unix format path,
usually in a "lib$initialize" object.

For a test program, the same could be done, or the script running the
test can define the logical name DECC$FILENAME_UNIX_REPORT "ENABLE"
before starting the test.

Regards,
-John
Bruno Haible
2017-06-07 13:33:45 UTC
Permalink
Hi John,
Post by John E. Malmberg
Post by John Malmberg
1. The VMS CRTL getcwd() will not pass configure tests and will be
marked for replacement from gnulib.
2. The replacement from gnulib causes canonicalize-lgpl.c to fail
because the replacement only has 2 parameters, not three.
...
I have not encountered the relocatable-prog-wrapper on a VMS project
yet, so I do not know what it is.
In the relocatable-prog-wrapper situation, like in all other uses of
gnulib without the 'getcwd' module, getcwd is not #defined. Therefore,
as I understand, it takes 3 arguments.
Post by John E. Malmberg
It still does not need the vms specific variant as a production program
would set the DECCRTL mode to have getcwd() return a Unix format path,
usually in a "lib$initialize" object.
gnulib does not make use of per-program initializers. Rather, its overrides
must work in programs as well as in libraries, without additional object
files (other than the ones provided by gnulib).
Post by John E. Malmberg
For a test program, the same could be done, or the script running the
test can define the logical name DECC$FILENAME_UNIX_REPORT "ENABLE"
before starting the test.
Programs that use gnulib do not make assumptions about how they are
invoked, or what environments are set when they are run. They must work
out-of-the-box.

To fix the issue you reported, I'm applying this:

2017-06-07 Bruno Haible <***@clisp.org>

canonicalize-lgpl: Avoid conflict with gnulib 'getcwd' module on VMS.
Reported by John E. Malmberg <***@gmail.com> in
<https://lists.gnu.org/archive/html/bug-gnulib/2017-06/msg00029.html>.
* lib/canonicalize-lgpl.c (__getcwd): On VMS, when using gnulib's getcwd
override, pass 2 arguments to getcwd, not 3.

diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c
index a32da91..34b3711 100644
--- a/lib/canonicalize-lgpl.c
+++ b/lib/canonicalize-lgpl.c
@@ -59,8 +59,10 @@
*/
# undef getcwd
# endif
-# ifdef VMS
- /* We want the directory in Unix syntax, not in VMS syntax. */
+# if defined VMS && !defined getcwd
+ /* We want the directory in Unix syntax, not in VMS syntax.
+ The gnulib override of 'getcwd' takes 2 arguments; the original VMS
+ 'getcwd' takes 3 arguments. */
# define __getcwd(buf, max) getcwd (buf, max, 0)
# else
# define __getcwd getcwd
Post by John E. Malmberg
Post by John Malmberg
3. The replacement from gnulib also does not fix all the known ills in
VMS getcwd().
This is something that sounds worthy to look at. As I understand it, the
configure test already marks the getcwd function as to be overridden (because
the incompatible prototype); therefore the fixes should be limited to modifications
of lib/getcwd.d and lib/getcwd-lgpl.c.

Bruno

Loading...