diff --git a/ChangeLog b/ChangeLog index 60f1e0ed9..b375fa68f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2012-08-26 Niels Grewe + + * configure.ac: Check for QNX slog facilities. + * Headers/GNUstepBase/config.h.in + * configure: + Regenerate + * Source/NSLog.m: Implement logging to the QNX slog. + + Add support for logging to the QNX slog via NSLog(). + 2012-08-25 Niels Grewe * configure.ac: Allow a cross-compilation configuration to be diff --git a/Headers/GNUstepBase/config.h.in b/Headers/GNUstepBase/config.h.in index 250bf75cc..e4293d6f1 100644 --- a/Headers/GNUstepBase/config.h.in +++ b/Headers/GNUstepBase/config.h.in @@ -484,6 +484,9 @@ /* Define to 1 if you have the `Sleep' function. */ #undef HAVE_SLEEP +/* Define to 1 if you have the `slogf' function. */ +#undef HAVE_SLOGF + /* Define to 1 if you have the `snprintf' function. */ #undef HAVE_SNPRINTF @@ -564,6 +567,12 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SIGNAL_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SLOGCODES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SLOG_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H diff --git a/Source/NSLog.m b/Source/NSLog.m index 68e04039d..64e8462f9 100644 --- a/Source/NSLog.m +++ b/Source/NSLog.m @@ -39,6 +39,16 @@ #ifdef HAVE_SYSLOG_H #include +#elif HAVE_SYS_SLOG_H + // we are on a QNX-ish system, which has a syslog symbol somewhere, but it isn't + // our syslog function (we use slogf().) +# ifdef HAVE_SYSLOG +# undef HAVE_SYSLOG +# endif +# include +# ifdef HAVE_SYS_SLOGCODES_H +# include +# endif #endif #define UNISTR(X) \ @@ -106,8 +116,8 @@ _NSLog_standard_printf_handler (NSString* message) #if defined(__MINGW__) LPCWSTR null_terminated_buf; #else -#if defined(HAVE_SYSLOG) - char *null_terminated_buf; +#if defined(HAVE_SYSLOG) || defined(HAVE_SLOGF) + char *null_terminated_buf = NULL; #endif #endif static NSStringEncoding enc = 0; @@ -162,8 +172,8 @@ _NSLog_standard_printf_handler (NSString* message) NULL); // pointer to data } } -#else - +#else + #if defined(HAVE_SYSLOG) if (GSPrivateDefaultsFlag(GSLogSyslog) == YES || write(_NSLogDescriptor, buf, len) != (int)len) @@ -176,6 +186,36 @@ _NSLog_standard_printf_handler (NSString* message) free(null_terminated_buf); } +#elif defined(HAVE_SLOGF) + if (GSPrivateDefaultsFlag(GSLogSyslog) == YES + || write(_NSLogDescriptor, buf, len) != (int)len) + { + // QNX's slog has a size limit per entry. We might need to iterate over + // _SLOG_MAXSIZEd chunks of the buffer + const char *newBuf = buf; + unsigned newLen = len; + + // Allocate at most _SLOG_MAXSIZE bytes + null_terminated_buf = malloc(sizeof(char) * MIN(newLen, _SLOG_MAXSIZE)); + // If it's shorter than that, we never even enter the loop + while (newLen >= _SLOG_MAXSIZE) + { + strncpy (null_terminated_buf, newBuf, (_SLOG_MAXSIZE - 1)); + null_terminated_buf[_SLOG_MAXSIZE] = '\0'; + slogf(_SLOG_SETCODE(_SLOG_SYSLOG, 0), _SLOG_ERROR, "%s", null_terminated_buf); + newBuf+= (_SLOG_MAXSIZE - 1); + newLen-= (_SLOG_MAXSIZE - 1 ); + } + // Write out the rest (which will be at most (_SLOG_MAXSIZE - 1) chars, so + // the terminator still fits. + if (0 != newLen) + { + strncpy(null_terminated_buf, newBuf, newLen); + null_terminated_buf[newLen] = '\0'; + slogf(_SLOG_SETCODE(_SLOG_SYSLOG, 0), _SLOG_ERROR, "%s", null_terminated_buf); + } + free(null_terminated_buf); + } #else write(_NSLogDescriptor, buf, len); #endif diff --git a/configure b/configure index bbf4a4163..e13314b8f 100755 --- a/configure +++ b/configure @@ -18900,7 +18900,9 @@ done # These headers/functions needed by NSLog.m #-------------------------------------------------------------------- -for ac_header in syslog.h + + +for ac_header in syslog.h sys/slog.h sys/slogcodes.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then @@ -19173,7 +19175,123 @@ _ACEOF fi done +if test "$ac_cv_header_sys_slog_h" = "yes"; then + oldLibs="$LIBS"; + LIBS="$LIBS -l:libc.a"; +for ac_func in slogf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* 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 $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + if test "$ac_cv_func_slogf" = "no"; then + LIBS="$oldLibs" + fi +fi #-------------------------------------------------------------------- # These headers/functions needed by NSRunLoop.m #-------------------------------------------------------------------- diff --git a/configure.ac b/configure.ac index 58c21909c..dd5c15633 100644 --- a/configure.ac +++ b/configure.ac @@ -2122,9 +2122,16 @@ AC_CHECK_FUNCS(__builtin_extract_return_address) #-------------------------------------------------------------------- # These headers/functions needed by NSLog.m #-------------------------------------------------------------------- -AC_CHECK_HEADERS(syslog.h) +AC_CHECK_HEADERS(syslog.h sys/slog.h sys/slogcodes.h) AC_CHECK_FUNCS(syslog) - +if test "$ac_cv_header_sys_slog_h" = "yes"; then + oldLibs="$LIBS"; + LIBS="$LIBS -l:libc.a"; + AC_CHECK_FUNCS(slogf) + if test "$ac_cv_func_slogf" = "no"; then + LIBS="$oldLibs" + fi +fi #-------------------------------------------------------------------- # These headers/functions needed by NSRunLoop.m #--------------------------------------------------------------------