diff options
Diffstat (limited to 'gcc/ada')
-rw-r--r-- | gcc/ada/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/ada/a-calend.adb | 30 | ||||
-rw-r--r-- | gcc/ada/g-socket.adb | 17 | ||||
-rw-r--r-- | gcc/ada/g-socket.ads | 4 | ||||
-rw-r--r-- | gcc/ada/s-oscons-tmplt.c | 5 | ||||
-rw-r--r-- | gcc/ada/sysdep.c | 99 |
6 files changed, 100 insertions, 72 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 1ef52e0..b9463f6 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,20 @@ +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 diff --git a/gcc/ada/a-calend.adb b/gcc/ada/a-calend.adb index 7e78511..9aa8852 100644 --- a/gcc/ada/a-calend.adb +++ b/gcc/ada/a-calend.adb @@ -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; diff --git a/gcc/ada/g-socket.adb b/gcc/ada/g-socket.adb index 1250607..784d062 100644 --- a/gcc/ada/g-socket.adb +++ b/gcc/ada/g-socket.adb @@ -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; ----------------------- diff --git a/gcc/ada/g-socket.ads b/gcc/ada/g-socket.ads index 439655f..f8dd6bf 100644 --- a/gcc/ada/g-socket.ads +++ b/gcc/ada/g-socket.ads @@ -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, diff --git a/gcc/ada/s-oscons-tmplt.c b/gcc/ada/s-oscons-tmplt.c index 958b11e..e6e1849 100644 --- a/gcc/ada/s-oscons-tmplt.c +++ b/gcc/ada/s-oscons-tmplt.c @@ -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 diff --git a/gcc/ada/sysdep.c b/gcc/ada/sysdep.c index 56f3ebd..8a227b4 100644 --- a/gcc/ada/sysdep.c +++ b/gcc/ada/sysdep.c @@ -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 |