Operating System - OpenVMS
1752810 Members
6095 Online
108789 Solutions
New Discussion юеВ

Re: FORTRAN interface to CRTL functions

 
SOLVED
Go to solution
Michael Menge
Frequent Advisor

Re: FORTRAN interface to CRTL functions

I have made a call to HP:
decc$gmtime_r returns null, decc$localtime_r returns MGT-time. From C, gmtimes works fine (local time is MEZ = UTC + 1).

Here the answer from engineering:

We have following update:
We are able to reproduce the problem. During analysis, we noticed that when we invoke CRTL routines gmtime_r and localtime_r from FORTRAN program, the functions related to local time based model is being considered. On observing the function definition for gmtime_r within local time based model, we noticed that the function gmtime_r just returns NULL. Hence the output of gmtime_r was inappropriate.
However when these functions are invoked in a C Program, they are considering UTC based time model and hence are generating appropriate output.
As a workaround, we could get the gmtime & localtime by invoking decc$__utctz_gmtime_r and decc$__utctz_localtime_r routines instead of decc$gmtime_r/decc$localtime_r routines respectively.
Meanwhile we will check with CRTL team and get back to you on this.

Joseph Huber_1
Honored Contributor

Re: FORTRAN interface to CRTL functions

I think that the gmtime_r returning NULL is a real bug and should be corrected.

But for the rest of local/UTC based time handling, I vote strongly against CRTL changing its behaviour:
the default implementation calls the correct decc$utc... entry points, while the decc$gmtime,decc$localtime etc. entries are called if explicitly the "old" behaviour is wanted.
From the CRTL help for gmtime,localtime and other time related functions:

Compiling with the _DECC_V4_SOURCE and _VMS_V6_SOURCE feature-
test macros defined enables a local-time-based entry point to
this function that is equivalent to the behavior before OpenVMS
Version 7.0.

So changing the decc$ entries would break existing software.

As I have told in earlier replies, user programs simply should not call directly the time related DECC$ entry points, but rather write a C wrapper!

Calling decc$localtime(_r) or decc$gmtime(_r) is equivalent to
#define _VMS_V6_SOURCE
and the using localtime/gmtime.

See as an example
http://www.mpp.mpg.de/~huber/util/localtime_f.C

Compile it with /define=(TEST)
and /define=(TEST,_VMS_V6_SOURCE)
to see the difference.


http://www.mpp.mpg.de/~huber
Ian Miller.
Honored Contributor

Re: FORTRAN interface to CRTL functions

Just to muddy the waters further there is also the DTS routines

http://h71000.www7.hp.com/doc/84final/4493/4493pro_016.html#port_api

____________________
Purely Personal Opinion
Joseph Huber_1
Honored Contributor

Re: FORTRAN interface to CRTL functions

The DTS routines have their own internal binary time (128 bit UTC).
But converting between all of VMS quad/time_t/struct tm/utc_t requires use of a consistent set of C time calls, which is not guaranteed by using direct decc$* calls.

I have put together all my time related routines on my web-page:

http://www.mpp.mpg.de/~huber/util/time.html

I tested them to be sure that all conversions reproduce the same result in both directions.
http://www.mpp.mpg.de/~huber
WW304289
Frequent Advisor

Re: FORTRAN interface to CRTL functions

Joseph Huber wrote:
> I think that the gmtime_r returning NULL is a real bug and should be corrected.

I disagree. The gmtime[_r] functions returning NULL are called by programs compiled with _VMS_V6_SOURCE macro defined (or when called explicitly as decc$gmtime[_r]). This macro indicates, among other things, that the system does not support UTC, so, it is only logical (at least to me) that functions like gmtime[_r] fail. What can be considered a bug is that the functions fail without setting errno. In this case ENOTSUP would be appropriate, I believe.

What's definitely a bug is that UTC-based gmtime succeeds, but sets errno. The following was obtained on OpenVMS IA64 V8.3:

$ pipe cc x.c ; link x.obj ; run x.exe
gmtime: no such file or directory
54BD8
$

x.c
---
#include
#include
#include

int main() {
time_t t = time(0);
struct tm *tms;

errno = 0;
tms = gmtime(&t);
perror("gmtime");
printf("%p\n", tms);
}
$
Joseph Huber_1
Honored Contributor

Re: FORTRAN interface to CRTL functions

Well, the C standard says about errno:

The value of errno is zero at program startup, but is never set to zero by any library
function.
The value of errno may be set to nonzero by a library function call
whether or not there is an error, provided the use of errno is not documented in the
description of the function in this International Standard.

VMS CRTL (and other C systems like GNU C) do not say anything about errno, so errno should not be used unless the function return value is NULL.
http://www.mpp.mpg.de/~huber
WW304289
Frequent Advisor

Re: FORTRAN interface to CRTL functions

"
The value of errno is zero at program startup, but is never set to zero by any library
function.
The value of errno may be set to nonzero by a library function call
whether or not there is an error, provided the use of errno is not documented in the
description of the function in this International Standard.
"

The use of errno by gmtime() is not documented in "this International Standard" so one can argue that setting errno by gmtime is not a violation of the C standard.

However, the use of errno by gmtime() is documented in X/Open specs. So, this is a violation of X/Open which C RTL on VMS claims to support.

Now consider the gmtime_r() function which only defined in X/Open and POSIX: it exhibits the same behavior that gmtime().

I'm pretty sure that errno is set to ENOENT when CRTL is trying to load a timezone file.

The people supporting C RTL can give us definitive answer w.r.t. standard compliance and, perhaps, comment on whether setting errno by gmtime[_r] is intentional or an oversight. Btw, the functions set errno only on first invocation which does not look like a consistent behavior of the C RTL.

-Boris
Craig A Berry
Honored Contributor

Re: FORTRAN interface to CRTL functions

It's probably more a question of whether gmtime() should save and restore errno than whether it should avoid setting it on success. It probably doesn't directly set it but uses other functions that do. There are things that can go wrong with almost any way of handling it, which is why new POSIX functions are supposed to avoid errno and use specific return values for specific error conditions. Too bad no one thought of that decades ago -- oh, wait....
Hoff
Honored Contributor

Re: FORTRAN interface to CRTL functions

Non-native calls directly into the C RTL have not been considered supported, at least classically.

The CRTL classically required initialization before use, there's a CRTL_INIT call in the library when the main routine was not a C main. I don't know if that's been relaxed, but the CRTL initialization call is still documented.

http://h71000.www7.hp.com/doc/83final/5763/5763pro_028.html#decc_crtl_init_routine

I don't know off-hand if that call effects the timekeeping initialization.

An alternative library that will likely remain (at least somewhat) more stable than the CRTL interfaces is the DTSS library; that's documented in the utility routines, and provides all manner of time-related calls. (I'd post a link to the Utility Routines manual, but parts of the HP web site have been glacially slow this week.)

And in general, a direct CRTL call and the rest of the baggage saves all of a few lines of C code for a local jacket, and for an approach that would not necessarily be one that will be maintained going forward. The C RTL folks have been free to shuffle their entry points behind that forest of preprocessor calls, and sometimes have. (Well, a few lines of a C jacket here, plus the CRTL initialize call somewhere earlier in the Fortran application.)

And a caveat: By calling the gmtime and friends, you're now sensitive to the C TZ and TDF logical names in your Fortran application, and the complete morass that is daylight saving time on VMS. Put another way, you can end up with values off by an hour if your UTC/TZ/TDF isn't right.

HP OpenVMS Engineering would seem better served here by adding a GMTIME call into the Fortran RTL, rather than sorting out a direct C call from Fortran. As mentioned in another reply, this Fortran call exists in other Fortran compilers, so it's not inventing a wholly new Fortran API. (Well, if it isn't now open season on direct C RTL calls...)
Joseph Huber_1
Honored Contributor

Re: FORTRAN interface to CRTL functions

I can't resisty to answer to the question errno setting by gmtime_r(), I just read what the posix standard (1003.1) is saying:

=============================================
The value of errno shall be defined only after a call to a function for which it is explicitly stated to be set and until it is changed by the next function call or if the application assigns it a value. The value of errno should only be examined when it is indicated to be valid by a function's return value.
No function in this volume of IEEE Std 1003.1-2001 shall set errno to 0. The setting of errno after a successful call to a function is unspecified unless the description of that function specifies that errno shall not be modified.
=============================================

So Posix is even more clear in stating that errno should not be used in success case unless the function description says so.
And the Posix description of gmtime_r says nothing different from the C standard: in case of error errno shall be set, it says nothing about errno in success (non-NULL) case.

The rule for library functions to never set errno to 0 even forbids the VMS implementation to reset errno if it was set by some other internal calls.

So a programmer shall not use errno after a successfull return of gmtime(_r) !
http://www.mpp.mpg.de/~huber