This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[vms/committed]: Add functions to get vms time
- From: Tristan Gingold <gingold at adacore dot com>
- To: binutils <binutils at sourceware dot org>
- Date: Thu, 27 May 2010 15:43:28 +0200
- Subject: [vms/committed]: Add functions to get vms time
Hi,
this patch adds a few function to get current time in VMS format and to convert a time from UNIX to VMS.
This will be used by vms-lib.c
Tristan.
bfd/
2010-05-27 Tristan Gingold <gingold@adacore.com>
* vms-misc.c: Define __NEW_STARLET. Remove trailing spaces.
(VMS_TIME_FACTOR, VMS_TIME_OFFSET): New macros.
(vms_time_to_time_t): Use them instead of local const.
(vms_time_t_to_vms_time): New function.
(vms_get_time): Likewise.
(vms_raw_get_time): Likewise.
* vms.h (vms_time_t_to_vms_time): New declaration.
(vms_get_time): Likewise.
(vms_raw_get_time): Likewise.
Index: vms-misc.c
===================================================================
RCS file: /cvs/src/src/bfd/vms-misc.c,v
retrieving revision 1.34
diff -c -r1.34 vms-misc.c
*** vms-misc.c 25 May 2010 10:14:15 -0000 1.34
--- vms-misc.c 27 May 2010 13:33:35 -0000
***************
*** 33,43 ****
#include "safe-ctype.h"
#ifdef VMS
! #if defined(__GNUC__) && !defined(globalref)
! #define globalref extern
! #endif
#include <rms.h>
#include <unixlib.h>
#include <starlet.h>
#define RME$C_SETRFM 0x00000001
#include <unistd.h>
--- 33,42 ----
#include "safe-ctype.h"
#ifdef VMS
! #define __NEW_STARLET
#include <rms.h>
#include <unixlib.h>
+ #include <gen64def.h>
#include <starlet.h>
#define RME$C_SETRFM 0x00000001
#include <unistd.h>
***************
*** 497,515 ****
fout++;
else
fout = filename;
!
/* Strip UNIX path. */
fptr = strrchr (fout, '/');
if (fptr != NULL)
fout = fptr + 1;
!
fname = strdup (fout);
/* Strip suffix. */
fptr = strrchr (fname, '.');
if (fptr != 0)
*fptr = 0;
!
/* Convert to upper case and truncate at 31 characters.
(VMS object file format restricts module name length to 31). */
fptr = fname;
--- 496,514 ----
fout++;
else
fout = filename;
!
/* Strip UNIX path. */
fptr = strrchr (fout, '/');
if (fptr != NULL)
fout = fptr + 1;
!
fname = strdup (fout);
/* Strip suffix. */
fptr = strrchr (fname, '.');
if (fptr != 0)
*fptr = 0;
!
/* Convert to upper case and truncate at 31 characters.
(VMS object file format restricts module name length to 31). */
fptr = fname;
***************
*** 526,561 ****
return fname;
}
! /* Convert a raw VMS time to a unix time. */
time_t
vms_time_to_time_t (unsigned int hi, unsigned int lo)
{
- const unsigned int off = 3506716800U;
- const unsigned int factor = 10000000;
unsigned int tmp;
unsigned int rlo;
int i;
/* First convert to seconds. */
! tmp = hi % factor;
! hi = hi / factor;
rlo = 0;
for (i = 0; i < 4; i++)
{
tmp = (tmp << 8) | (lo >> 24);
lo <<= 8;
! rlo = (rlo << 8) | (tmp / factor);
! tmp %= factor;
}
lo = rlo;
/* Return 0 in case of overflow. */
! if (lo > off && hi > 1)
return 0;
! return lo - off;
}
/* Convert a raw (stored in a buffer) VMS time to a unix time. */
--- 525,633 ----
return fname;
}
! /* Compared to usual UNIX time_t, VMS time has less limits:
! - 64 bit (63 bits in fact as the MSB must be 0)
! - 100ns granularity
! - epoch is Nov 17, 1858.
! Here has the constants and the routines used to convert VMS from/to UNIX time.
! The conversion routines don't assume 64 bits arithmetic. */
!
! /* UNIX time granularity for VMS, ie 1s / 100ns. */
! #define VMS_TIME_FACTOR 10000000
!
! /* Number of seconds since VMS epoch of the UNIX epoch. */
! #define VMS_TIME_OFFSET 3506716800U
!
! /* Convert a VMS time to a unix time. */
time_t
vms_time_to_time_t (unsigned int hi, unsigned int lo)
{
unsigned int tmp;
unsigned int rlo;
int i;
/* First convert to seconds. */
! tmp = hi % VMS_TIME_FACTOR;
! hi = hi / VMS_TIME_FACTOR;
rlo = 0;
for (i = 0; i < 4; i++)
{
tmp = (tmp << 8) | (lo >> 24);
lo <<= 8;
! rlo = (rlo << 8) | (tmp / VMS_TIME_FACTOR);
! tmp %= VMS_TIME_FACTOR;
}
lo = rlo;
/* Return 0 in case of overflow. */
! if (lo > VMS_TIME_OFFSET && hi > 1)
! return 0;
!
! /* Return 0 in case of underflow. */
! if (lo < VMS_TIME_OFFSET)
return 0;
! return lo - VMS_TIME_OFFSET;
! }
!
! /* Convert a time_t to a VMS time. */
!
! void
! vms_time_t_to_vms_time (time_t ut, unsigned int *hi, unsigned int *lo)
! {
! unsigned short val[4];
! unsigned short tmp[4];
! unsigned int carry;
! int i;
!
! /* Put into val. */
! val[0] = ut & 0xffff;
! val[1] = (ut >> 16) & 0xffff;
! if (sizeof (ut) > 4)
! {
! val[2] = (ut >> 32) & 0xffff;
! val[3] = (ut >> 48) & 0xffff;
! }
! else
! {
! val[2] = 0;
! val[3] = 0;
! }
!
! /* Add offset. */
! tmp[0] = VMS_TIME_OFFSET & 0xffff;
! tmp[1] = VMS_TIME_OFFSET >> 16;
! tmp[2] = 0;
! tmp[3] = 0;
! carry = 0;
! for (i = 0; i < 4; i++)
! {
! carry += tmp[i] + val[i];
! val[i] = carry & 0xffff;
! carry = carry >> 16;
! }
!
! /* Multiply by factor, well first by 10000 and then by 1000. */
! carry = 0;
! for (i = 0; i < 4; i++)
! {
! carry += val[i] * 10000;
! val[i] = carry & 0xffff;
! carry = carry >> 16;
! }
! carry = 0;
! for (i = 0; i < 4; i++)
! {
! carry += val[i] * 1000;
! val[i] = carry & 0xffff;
! carry = carry >> 16;
! }
!
! /* Write the result. */
! *lo = val[0] | (val[1] << 16);
! *hi = val[2] | (val[3] << 16);
}
/* Convert a raw (stored in a buffer) VMS time to a unix time. */
***************
*** 568,570 ****
--- 640,671 ----
return vms_time_to_time_t (hi, lo);
}
+
+ void
+ vms_get_time (unsigned int *hi, unsigned int *lo)
+ {
+ #ifdef VMS
+ struct _generic_64 t;
+
+ sys$gettim (&t);
+ *lo = t.gen64$q_quadword;
+ *hi = t.gen64$q_quadword >> 32;
+ #else
+ time_t t;
+
+ time (&t);
+ vms_time_t_to_vms_time (t, hi, lo);
+ #endif
+ }
+
+ /* Get the current time into a raw buffer BUF. */
+
+ void
+ vms_raw_get_time (unsigned char *buf)
+ {
+ unsigned int hi, lo;
+
+ vms_get_time (&hi, &lo);
+ bfd_putl32 (lo, buf + 0);
+ bfd_putl32 (hi, buf + 4);
+ }
Index: vms.h
===================================================================
RCS file: /cvs/src/src/bfd/vms.h,v
retrieving revision 1.20
diff -c -r1.20 vms.h
*** vms.h 25 May 2010 10:14:15 -0000 1.20
--- vms.h 27 May 2010 13:33:35 -0000
***************
*** 115,120 ****
--- 115,123 ----
extern unsigned char *get_vms_time_string (void);
extern time_t vms_time_to_time_t (unsigned int hi, unsigned int lo);
extern time_t vms_rawtime_to_time_t (unsigned char *);
+ extern void vms_time_t_to_vms_time (time_t ut, unsigned int *hi, unsigned int *lo);
+ extern void vms_get_time (unsigned int *hi, unsigned int *lo);
+ extern void vms_raw_get_time (unsigned char *buf);
extern char * _bfd_vms_save_sized_string (unsigned char *, int);
extern char * _bfd_vms_save_counted_string (unsigned char *);