diff options
author | Gaius Mulley <gaiusmod2@gmail.com> | 2023-08-09 09:35:13 +0100 |
---|---|---|
committer | Gaius Mulley <gaiusmod2@gmail.com> | 2023-08-09 09:35:13 +0100 |
commit | e3476ed2233911e6a578488899179bd91e818947 (patch) | |
tree | ef67c0a577509902889645f64aecc0914791a803 /libgm2 | |
parent | 6ef7956e9df910fa49bd5106139a7d26c9d51fdf (diff) | |
download | gcc-e3476ed2233911e6a578488899179bd91e818947.zip gcc-e3476ed2233911e6a578488899179bd91e818947.tar.gz gcc-e3476ed2233911e6a578488899179bd91e818947.tar.bz2 |
PR modula2/110779: libgm2 fix solaris bootstrap check for tm_gmtoff
This patch defensively checks for every C function and every struct
used in wrapclock.cc. It adds return values to GetTimespec and
SetTimespec to allow the module to return a code representing
unavailable.
gcc/m2/ChangeLog:
PR modula2/110779
* gm2-libs-iso/SysClock.mod (GetClock): Test GetTimespec
return value.
(SetClock): Test SetTimespec return value.
* gm2-libs-iso/wrapclock.def (GetTimespec): Add integer
return type.
(SetTimespec): Add integer return type.
libgm2/ChangeLog:
PR modula2/110779
* config.h.in: Regenerate.
* configure: Regenerate.
* configure.ac (AC_CACHE_CHECK): Check for tm_gmtoff field in
struct tm.
(GM2_CHECK_LIB): Check for daylight, timezone and tzname.
* libm2iso/wrapclock.cc (timezone): Guard against absence of
struct tm and tm_gmtoff.
(daylight): Check for daylight.
(timezone): Check for timezone.
(isdst): Check for isdst.
(tzname): Check for tzname.
(GetTimeRealtime): Check for struct timespec.
(SetTimeRealtime): Check for struct timespec.
(InitTimespec): Check for struct timespec.
(KillTimespec): Check for struct timespec.
(SetTimespec): Check for struct timespec.
(GetTimespec): Check for struct timespec.
Signed-off-by: Gaius Mulley <gaiusmod2@gmail.com>
Diffstat (limited to 'libgm2')
-rw-r--r-- | libgm2/config.h.in | 15 | ||||
-rwxr-xr-x | libgm2/configure | 258 | ||||
-rw-r--r-- | libgm2/configure.ac | 23 | ||||
-rw-r--r-- | libgm2/libm2iso/wrapclock.cc | 96 |
4 files changed, 388 insertions, 4 deletions
diff --git a/libgm2/config.h.in b/libgm2/config.h.in index 8372055..f91f5a4 100644 --- a/libgm2/config.h.in +++ b/libgm2/config.h.in @@ -24,6 +24,9 @@ /* function ctime exists */ #undef HAVE_CTIME +/* function daylight exists */ +#undef HAVE_DAYLIGHT + /* Define to 1 if you have the <direct.h> header file. */ #undef HAVE_DIRECT_H @@ -195,6 +198,9 @@ /* Define to 1 if the system has the type `struct timezone'. */ #undef HAVE_STRUCT_TIMEZONE +/* Define to 1 if the system has the type `struct tm'. */ +#undef HAVE_STRUCT_TM + /* Define to 1 if you have the <sys/errno.h> header file. */ #undef HAVE_SYS_ERRNO_H @@ -240,9 +246,18 @@ /* function times exists */ #undef HAVE_TIMES +/* function timezone exists */ +#undef HAVE_TIMEZONE + /* Define to 1 if you have the <time.h> header file. */ #undef HAVE_TIME_H +/* Define if struct tm has a tm_gmtoff field. */ +#undef HAVE_TM_TM_GMTOFF + +/* function tzname exists */ +#undef HAVE_TZNAME + /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H diff --git a/libgm2/configure b/libgm2/configure index ee5d86e..74f93ac 100755 --- a/libgm2/configure +++ b/libgm2/configure @@ -16130,7 +16130,58 @@ _ACEOF fi +ac_fn_c_check_type "$LINENO" "struct tm" "ac_cv_type_struct_tm" "$ac_includes_default" +if test "x$ac_cv_type_struct_tm" = xyes; then : +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_TM 1 +_ACEOF + + +fi + + +# Check if struct tm contains the tm_gmtoff field. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tm_gmtoff in struct tm" >&5 +$as_echo_n "checking for tm_gmtoff in struct tm... " >&6; } +if ${ac_cv_struct_tm_gmtoff+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <time.h> + +int +main () +{ + + struct tm tm; + tm.tm_gmtoff = 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_struct_tm_gmtoff=yes +else + ac_cv_struct_tm_gmtoff=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm_gmtoff" >&5 +$as_echo "$ac_cv_struct_tm_gmtoff" >&6; } + +if (test "$ac_cv_struct_tm_gmtoff" = "yes"); then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking m2 front end detects struct tm with the tm_gmtoff field." >&5 +$as_echo_n "checking m2 front end detects struct tm with the tm_gmtoff field.... " >&6; } + +$as_echo "#define HAVE_TM_TM_GMTOFF 1" >>confdefs.h + +fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -17305,6 +17356,75 @@ $as_echo "#define HAVE_CREAT 1" >>confdefs.h fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking m2 front end checking c library for daylight" >&5 +$as_echo_n "checking m2 front end checking c library for daylight... " >&6; } + if test x$gcc_no_link != xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for daylight in -lc" >&5 +$as_echo_n "checking for daylight in -lc... " >&6; } +if ${ac_cv_lib_c_daylight+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $LIBS" +if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char daylight (); +int +main () +{ +return daylight (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_c_daylight=yes +else + ac_cv_lib_c_daylight=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_daylight" >&5 +$as_echo "$ac_cv_lib_c_daylight" >&6; } +if test "x$ac_cv_lib_c_daylight" = xyes; then : + +$as_echo "#define HAVE_DAYLIGHT 1" >>confdefs.h + +else + + $as_echo "#undef HAVE_DAYLIGHT" >>confdefs.h + +fi + + else + if test "x$ac_cv_lib_c_daylight" = xyes; then + +$as_echo "#define HAVE_DAYLIGHT 1" >>confdefs.h + + elif test "x$ac_cv_func_daylight" = xyes; then + +$as_echo "#define HAVE_DAYLIGHT 1" >>confdefs.h + + else + + $as_echo "#undef HAVE_DAYLIGHT" >>confdefs.h + + fi + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking m2 front end checking c library for dup" >&5 $as_echo_n "checking m2 front end checking c library for dup... " >&6; } if test x$gcc_no_link != xyes; then @@ -19237,6 +19357,144 @@ $as_echo "#define HAVE_TIMES 1" >>confdefs.h fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking m2 front end checking c library for timezone" >&5 +$as_echo_n "checking m2 front end checking c library for timezone... " >&6; } + if test x$gcc_no_link != xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for timezone in -lc" >&5 +$as_echo_n "checking for timezone in -lc... " >&6; } +if ${ac_cv_lib_c_timezone+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $LIBS" +if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char timezone (); +int +main () +{ +return timezone (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_c_timezone=yes +else + ac_cv_lib_c_timezone=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_timezone" >&5 +$as_echo "$ac_cv_lib_c_timezone" >&6; } +if test "x$ac_cv_lib_c_timezone" = xyes; then : + +$as_echo "#define HAVE_TIMEZONE 1" >>confdefs.h + +else + + $as_echo "#undef HAVE_TIMEZONE" >>confdefs.h + +fi + + else + if test "x$ac_cv_lib_c_timezone" = xyes; then + +$as_echo "#define HAVE_TIMEZONE 1" >>confdefs.h + + elif test "x$ac_cv_func_timezone" = xyes; then + +$as_echo "#define HAVE_TIMEZONE 1" >>confdefs.h + + else + + $as_echo "#undef HAVE_TIMEZONE" >>confdefs.h + + fi + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking m2 front end checking c library for tzname" >&5 +$as_echo_n "checking m2 front end checking c library for tzname... " >&6; } + if test x$gcc_no_link != xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tzname in -lc" >&5 +$as_echo_n "checking for tzname in -lc... " >&6; } +if ${ac_cv_lib_c_tzname+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $LIBS" +if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tzname (); +int +main () +{ +return tzname (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_c_tzname=yes +else + ac_cv_lib_c_tzname=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_tzname" >&5 +$as_echo "$ac_cv_lib_c_tzname" >&6; } +if test "x$ac_cv_lib_c_tzname" = xyes; then : + +$as_echo "#define HAVE_TZNAME 1" >>confdefs.h + +else + + $as_echo "#undef HAVE_TZNAME" >>confdefs.h + +fi + + else + if test "x$ac_cv_lib_c_tzname" = xyes; then + +$as_echo "#define HAVE_TZNAME 1" >>confdefs.h + + elif test "x$ac_cv_func_tzname" = xyes; then + +$as_echo "#define HAVE_TZNAME 1" >>confdefs.h + + else + + $as_echo "#undef HAVE_TZNAME" >>confdefs.h + + fi + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking m2 front end checking c library for unlink" >&5 $as_echo_n "checking m2 front end checking c library for unlink... " >&6; } if test x$gcc_no_link != xyes; then diff --git a/libgm2/configure.ac b/libgm2/configure.ac index d64a8ee..75ca603 100644 --- a/libgm2/configure.ac +++ b/libgm2/configure.ac @@ -187,7 +187,25 @@ else multilib_arg= fi -AC_CHECK_TYPES([struct timezone, struct stat, struct timespec, struct timeval]) +AC_CHECK_TYPES([struct timezone, struct stat, struct timespec, struct timeval, struct tm]) + +# Check if struct tm contains the tm_gmtoff field. +AC_CACHE_CHECK(for tm_gmtoff in struct tm, ac_cv_struct_tm_gmtoff, + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ + #include <time.h> + ], [ + struct tm tm; + tm.tm_gmtoff = 1; + ])], + [ac_cv_struct_tm_gmtoff=yes], + [ac_cv_struct_tm_gmtoff=no] + ) +) + +if (test "$ac_cv_struct_tm_gmtoff" = "yes"); then + AC_MSG_CHECKING([m2 front end detects struct tm with the tm_gmtoff field.]) + AC_DEFINE(HAVE_TM_TM_GMTOFF, 1, [Define if struct tm has a tm_gmtoff field.]) +fi AC_LANG_C # Check the compiler. @@ -230,6 +248,7 @@ GM2_CHECK_LIB([c],[clock_settime],[CLOCK_SETTIME]) GM2_CHECK_LIB([c],[close],[CLOSE]) GM2_CHECK_LIB([c],[ctime],[CTIME]) GM2_CHECK_LIB([c],[creat],[CREAT]) +GM2_CHECK_LIB([c],[daylight],[DAYLIGHT]) GM2_CHECK_LIB([c],[dup],[DUP]) GM2_CHECK_LIB([c],[execve],[EXECVE]) GM2_CHECK_LIB([c],[exit],[EXIT]) @@ -258,6 +277,8 @@ GM2_CHECK_LIB([c],[strsignal],[STRSIGNAL]) GM2_CHECK_LIB([c],[strtod],[STRTOD]) GM2_CHECK_LIB([c],[strtold],[STRTOLD]) GM2_CHECK_LIB([c],[times],[TIMES]) +GM2_CHECK_LIB([c],[timezone],[TIMEZONE]) +GM2_CHECK_LIB([c],[tzname],[TZNAME]) GM2_CHECK_LIB([c],[unlink],[UNLINK]) GM2_CHECK_LIB([c],[wait],[WAIT]) GM2_CHECK_LIB([c],[write],[WRITE]) diff --git a/libgm2/libm2iso/wrapclock.cc b/libgm2/libm2iso/wrapclock.cc index 7ee1f25..91ac96f 100644 --- a/libgm2/libm2iso/wrapclock.cc +++ b/libgm2/libm2iso/wrapclock.cc @@ -67,9 +67,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see extern "C" long int EXPORT(timezone) (void) { +#if defined(HAVE_STRUCT_TM) && defined(HAVE_STRUCT_TIMESPEC) struct tm result; struct timespec ts; +#if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_TM_TM_GMTOFF) if (clock_gettime (CLOCK_REALTIME, &ts) == 0) { time_t time = ts.tv_sec; @@ -77,6 +79,8 @@ EXPORT(timezone) (void) return result.tm_gmtoff; } else +#endif +#endif return timezone; } @@ -84,7 +88,11 @@ EXPORT(timezone) (void) extern "C" int EXPORT(daylight) (void) { +#if defined(HAVE_DAYLIGHT) return daylight; +#else + return 0; +#endif } @@ -94,9 +102,11 @@ EXPORT(daylight) (void) extern "C" int EXPORT(isdst) (void) { +#if defined(HAVE_STRUCT_TM) && defined(HAVE_STRUCT_TIMESPEC) struct tm result; struct timespec ts; +#if defined(HAVE_CLOCK_SETTIME) if (clock_gettime (CLOCK_REALTIME, &ts) == 0) { time_t time = ts.tv_sec; @@ -104,6 +114,8 @@ EXPORT(isdst) (void) return result.tm_isdst; } else +#endif +#endif return 0; } @@ -111,12 +123,17 @@ EXPORT(isdst) (void) /* tzname returns the string associated with the local timezone. The daylight value is 0 or 1. The value 0 returns the non daylight saving timezone string and the value of 1 returns the - daylight saving timezone string. */ + daylight saving timezone string. It returns NULL if tzname is + unavailable. */ extern "C" char * EXPORT(tzname) (int daylight) { +#if defined(HAVE_TZNAME) return tzname[daylight]; +#else + return NULL; +#endif } @@ -124,6 +141,7 @@ EXPORT(tzname) (int daylight) gettime returns 0 on success and -1 on failure. If the underlying system does not have gettime then GetTimeRealtime returns 1. */ +#if defined(HAVE_STRUCT_TIMESPEC) extern "C" int EXPORT(GetTimeRealtime) (struct timespec *ts) { @@ -134,11 +152,21 @@ EXPORT(GetTimeRealtime) (struct timespec *ts) #endif } +#else + +extern "C" int +EXPORT(GetTimeRealtime) (void *ts) +{ + return 1; +} +#endif + /* SetTimeRealtime performs return settime (CLOCK_REALTIME, ts). gettime returns 0 on success and -1 on failure. If the underlying system does not have gettime then GetTimeRealtime returns 1. */ +#if defined(HAVE_STRUCT_TIMESPEC) extern "C" int EXPORT(SetTimeRealtime) (struct timespec *ts) { @@ -149,18 +177,42 @@ EXPORT(SetTimeRealtime) (struct timespec *ts) #endif } +#else + +extern "C" int +EXPORT(SetTimeRealtime) (void *ts) +{ + return 1; +} +#endif + /* InitTimespec returns a newly created opaque type. */ +#if defined(HAVE_STRUCT_TIMESPEC) extern "C" struct timespec * EXPORT(InitTimespec) (void) { +#if defined(HAVE_STRUCT_TIMESPEC) && defined(HAVE_MALLOC_H) return (struct timespec *)malloc (sizeof (struct timespec)); +#else + return NULL; +#endif } +#else + +extern "C" void * +EXPORT(InitTimespec) (void) +{ + return NULL; +} +#endif + /* KillTimeval deallocates the memory associated with an opaque type. */ +#if defined(HAVE_STRUCT_TIMESPEC) extern "C" struct timespec * EXPORT(KillTimespec) (void *ts) { @@ -170,26 +222,64 @@ EXPORT(KillTimespec) (void *ts) return NULL; } +#else + +extern "C" void * +EXPORT(KillTimespec) (void *ts) +{ + return NULL; +} +#endif + /* GetTimespec retrieves the number of seconds and nanoseconds from the timespec. */ -extern "C" void +#if defined(HAVE_STRUCT_TIMESPEC) +extern "C" int EXPORT(GetTimespec) (timespec *ts, unsigned long *sec, unsigned long *nano) { +#if defined(HAVE_STRUCT_TIMESPEC) *sec = ts->tv_sec; *nano = ts->tv_nsec; + return 1; +#else + return 0; +#endif } +#else +extern "C" int +EXPORT(GetTimespec) (void *ts, unsigned long *sec, unsigned long *nano) +{ + return 0; +} +#endif + /* SetTimespec sets the number of seconds and nanoseconds into timespec. */ -extern "C" void +#if defined(HAVE_STRUCT_TIMESPEC) +extern "C" int EXPORT(SetTimespec) (timespec *ts, unsigned long sec, unsigned long nano) { +#if defined(HAVE_STRUCT_TIMESPEC) ts->tv_sec = sec; ts->tv_nsec = nano; + return 1; +#else + return 0; +#endif +} + +#else + +extern "C" int +EXPORT(SetTimespec) (void *ts, unsigned long sec, unsigned long nano) +{ + return 0; } +#endif /* init - init/finish functions for the module */ |