Commit 3f25c54d by Arnaud Charlet

[multiple changes]

2009-04-20  Hristian Kirtchev  <kirtchev@adacore.com>

	* a-calend.adb: Remove types char_Pointer, int, tm and tm_Pointer.
	(localtime_tzoff): This routine no longer accepts an actual of type
	tm_Pointer.
	(UTC_Time_Offset): Remove local variable Secs_TM.

	* sysdep.c (__gnat_localtime_tzoff): This routine no longer accepts an
	actual of type struct tm*. Add local variable of type struct tm for all
	targets that provide localtime_r and need to invoke it.

2009-04-20  Thomas Quinot  <quinot@adacore.com>

	* s-oscons-tmplt.c, g-socket.adb, g-socket.ads
	(GNAT.Sockets.Resolve_Error): Add case of EPIPE
	Add case of EAGAIN for platforms where it is not equal to EWOULDBLOCK

From-SVN: r146369
parent 8dbf3473
2009-04-20 Hristian Kirtchev <kirtchev@adacore.com>
* a-calend.adb: Remove types char_Pointer, int, tm and tm_Pointer.
(localtime_tzoff): This routine no longer accepts an actual of type
tm_Pointer.
(UTC_Time_Offset): Remove local variable Secs_TM.
* sysdep.c (__gnat_localtime_tzoff): This routine no longer accepts an
actual of type struct tm*. Add local variable of type struct tm for all
targets that provide localtime_r and need to invoke it.
2009-04-20 Thomas Quinot <quinot@adacore.com>
* s-oscons-tmplt.c, g-socket.adb, g-socket.ads
(GNAT.Sockets.Resolve_Error): Add case of EPIPE
Add case of EAGAIN for platforms where it is not equal to EWOULDBLOCK
2009-04-20 Robert Dewar <dewar@adacore.com>
* sem_ch3.adb: Minor reformatting
......@@ -1474,39 +1474,15 @@ package body Ada.Calendar is
Nanos_In_56_Years : constant := (14 * 366 + 42 * 365) * Nanos_In_Day;
-- Base C types. There is no point dragging in Interfaces.C just for
-- these four types.
type char_Pointer is access Character;
subtype int is Integer;
subtype long is Long_Integer;
type long_Pointer is access all long;
-- The Ada equivalent of struct tm and type time_t
type tm is record
tm_sec : int; -- seconds after the minute (0 .. 60)
tm_min : int; -- minutes after the hour (0 .. 59)
tm_hour : int; -- hours since midnight (0 .. 24)
tm_mday : int; -- day of the month (1 .. 31)
tm_mon : int; -- months since January (0 .. 11)
tm_year : int; -- years since 1900
tm_wday : int; -- days since Sunday (0 .. 6)
tm_yday : int; -- days since January 1 (0 .. 365)
tm_isdst : int; -- Daylight Savings Time flag (-1 .. 1)
tm_gmtoff : long; -- offset from UTC in seconds
tm_zone : char_Pointer; -- timezone abbreviation
end record;
type tm_Pointer is access all tm;
subtype time_t is long;
type time_t_Pointer is access all time_t;
procedure localtime_tzoff
(C : time_t_Pointer;
res : tm_Pointer;
off : long_Pointer);
(timer : time_t_Pointer;
off : long_Pointer);
pragma Import (C, localtime_tzoff, "__gnat_localtime_tzoff");
-- This is a lightweight wrapper around the system library function
-- localtime_r. Parameter 'off' captures the UTC offset which is either
......@@ -1522,7 +1498,6 @@ package body Ada.Calendar is
Date_N : Time_Rep;
Offset : aliased long;
Secs_T : aliased time_t;
Secs_TM : aliased tm;
begin
Date_N := Time_Rep (Date);
......@@ -1568,7 +1543,6 @@ package body Ada.Calendar is
localtime_tzoff
(Secs_T'Unchecked_Access,
Secs_TM'Unchecked_Access,
Offset'Unchecked_Access);
return Offset;
......
......@@ -1681,6 +1681,17 @@ package body GNAT.Sockets is
end case;
end if;
-- Special case: EAGAIN may be the same value as EWOULDBLOCK, so we
-- can't include it in the case statement below.
pragma Warnings (Off);
-- Condition "EAGAIN /= EWOULDBLOCK" is known at compile time
if EAGAIN /= EWOULDBLOCK and then Error_Value = EAGAIN then
return Resource_Temporarily_Unavailable;
end if;
pragma Warnings (On);
case Error_Value is
when ENOERROR => return Success;
when EACCES => return Permission_Denied;
......@@ -1716,6 +1727,7 @@ package body GNAT.Sockets is
when ENOTSOCK => return Socket_Operation_On_Non_Socket;
when EOPNOTSUPP => return Operation_Not_Supported;
when EPFNOSUPPORT => return Protocol_Family_Not_Supported;
when EPIPE => return Broken_Pipe;
when EPROTONOSUPPORT => return Protocol_Not_Supported;
when EPROTOTYPE => return Protocol_Wrong_Type_For_Socket;
when ESHUTDOWN => return
......@@ -1724,10 +1736,9 @@ package body GNAT.Sockets is
when ETIMEDOUT => return Connection_Timed_Out;
when ETOOMANYREFS => return Too_Many_References;
when EWOULDBLOCK => return Resource_Temporarily_Unavailable;
when others => null;
end case;
return Cannot_Resolve_Error;
when others => return Cannot_Resolve_Error;
end case;
end Resolve_Error;
-----------------------
......
......@@ -603,6 +603,9 @@ package GNAT.Sockets is
-- brackets and a string describing the error code.
-- The name of the enumeration constant documents the error condition
-- Note that on some platforms, a single error value is used for both
-- EWOULDBLOCK and EAGAIN. Both errors are therefore always reported as
-- Resource_Temporarily_Unavailable.
type Error_Type is
(Success,
......@@ -644,6 +647,7 @@ package GNAT.Sockets is
Connection_Timed_Out,
Too_Many_References,
Resource_Temporarily_Unavailable,
Broken_Pipe,
Unknown_Host,
Host_Name_Lookup_Failure,
Non_Recoverable_Error,
......
......@@ -451,6 +451,11 @@ CND(ENOTSOCK, "Operation on non socket")
#endif
CND(EOPNOTSUPP, "Operation not supported")
#ifndef EPIPE
# define EPIPE -1
#endif
CND(EPIPE, "Broken pipe")
#ifndef EPFNOSUPPORT
# define EPFNOSUPPORT -1
#endif
......
......@@ -743,26 +743,53 @@ extern void (*Unlock_Task) (void);
/* Reentrant localtime for Windows and OS/2. */
extern struct tm *
__gnat_localtime_tzoff (const time_t *, struct tm *, long *);
extern void
__gnat_localtime_tzoff (const time_t *, long *);
struct tm *
__gnat_localtime_tzoff (const time_t *timer, struct tm *tp, long *off)
static const unsigned long long w32_epoch_offset = 11644473600ULL;
void
__gnat_localtime_tzoff (const time_t *timer, long *off)
{
DWORD dwRet;
struct tm *tmp;
union
{
FILETIME ft_time;
unsigned long long ull_time;
} utc_time, local_time;
SYSTEMTIME utc_sys_time, local_sys_time;
TIME_ZONE_INFORMATION tzi;
BOOL status = 1;
DWORD tzi_status;
(*Lock_Task) ();
tmp = localtime (timer);
memcpy (tp, tmp, sizeof (struct tm));
dwRet = GetTimeZoneInformation (&tzi);
*off = tzi.Bias;
if (tp->tm_isdst > 0)
*off = *off + tzi.DaylightBias;
*off = *off * -60;
/* First convert unix time_t structure to windows FILETIME format. */
utc_time.ull_time = ((unsigned long long) *timer + w32_epoch_offset)
* 10000000ULL;
tzi_status = GetTimeZoneInformation (&tzi);
/* If GetTimeZoneInformation does not return a value between 0 and 2 then
it means that we were not able to retrieve timezone informations.
Note that we cannot use here FileTimeToLocalFileTime as Windows will use
in always in this case the current timezone setting. As suggested on
MSDN we use the following three system calls to get the right information.
Note also that starting with Windows Vista new functions are provided to
get timezone settings that depend on the year. We cannot use them as we
still support Windows XP and Windows 2003. */
status = (tzi_status >= 0 && tzi_status <= 2)
&& FileTimeToSystemTime (&utc_time.ft_time, &utc_sys_time)
&& SystemTimeToTzSpecificLocalTime (&tzi, &utc_sys_time, &local_sys_time)
&& SystemTimeToFileTime (&local_sys_time, &local_time.ft_time);
if (!status)
/* An error occurs so return invalid_tzoff. */
*off = __gnat_invalid_tzoff;
else
*off = (long) ((local_time.ull_time - utc_time.ull_time) / 10000000ULL);
(*Unlock_Task) ();
return tp;
}
#else
......@@ -774,16 +801,14 @@ __gnat_localtime_tzoff (const time_t *timer, struct tm *tp, long *off)
spec is required. Only use when ___THREADS_POSIX4ad4__ is defined,
the Lynx convention when building against the legacy API. */
extern struct tm *
__gnat_localtime_tzoff (const time_t *, struct tm *, long *);
extern void
__gnat_localtime_tzoff (const time_t *, long *);
struct tm *
__gnat_localtime_tzoff (const time_t *timer, struct tm *tp, long *off)
void
__gnat_localtime_tzoff (const time_t *timer, long *off)
{
/* Treat all time values in GMT */
localtime_r (tp, timer);
*off = 0;
return NULL;
}
#else
......@@ -795,28 +820,21 @@ __gnat_localtime_tzoff (const time_t *timer, struct tm *tp, long *off)
/* All other targets provide a standard localtime_r */
extern struct tm *
__gnat_localtime_tzoff (const time_t *, struct tm *, long *);
extern void
__gnat_localtime_tzoff (const time_t *, long *);
struct tm *
__gnat_localtime_tzoff (const time_t *timer, struct tm *tp, long *off)
void
__gnat_localtime_tzoff (const time_t *timer, long *off)
{
localtime_r (timer, tp);
struct tm tp;
localtime_r (timer, &tp);
/* AIX, HPUX, SGI Irix, Sun Solaris */
#if defined (_AIX) || defined (__hpux__) || defined (sgi) || defined (sun)
/* The contents of external variable "timezone" may not always be
initialized. Instead of returning an incorrect offset, treat the local
time zone as 0 (UTC). The value of 28 hours is the maximum valid offset
allowed by Ada.Calendar.Time_Zones. */
if ((timezone < -28 * 3600) || (timezone > 28 * 3600))
*off = 0;
else
{
*off = (long) -timezone;
if (tp->tm_isdst > 0)
*off = *off + 3600;
}
*off = (long) -timezone;
if (tp.tm_isdst > 0)
*off = *off + 3600;
/* Lynx - Treat all time values in GMT */
#elif defined (__Lynx__)
*off = 0;
......@@ -850,17 +868,16 @@ __gnat_localtime_tzoff (const time_t *timer, struct tm *tp, long *off)
}
}
/* Darwin, Free BSD, Linux, Tru64, where there exists a component tm_gmtoff
in struct tm */
/* Darwin, Free BSD, Linux, Tru64, where component tm_gmtoff is present in
struct tm */
#elif defined (__APPLE__) || defined (__FreeBSD__) || defined (linux) ||\
(defined (__alpha__) && defined (__osf__)) || defined (__GLIBC__)
*off = tp->tm_gmtoff;
*off = tp.tm_gmtoff;
/* All other platforms: Treat all time values in GMT */
#else
*off = 0;
#endif
return NULL;
}
#endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment