aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada')
-rw-r--r--gcc/ada/ChangeLog17
-rw-r--r--gcc/ada/a-calend.adb30
-rw-r--r--gcc/ada/g-socket.adb17
-rw-r--r--gcc/ada/g-socket.ads4
-rw-r--r--gcc/ada/s-oscons-tmplt.c5
-rw-r--r--gcc/ada/sysdep.c99
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