From 0e3f530185d494dbb9db1b47f72f10f3ae598564 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 4 Oct 2011 01:25:26 -0400 Subject: [PATCH] Remove cruft from g_strerror and g_strsignal We can just assume that strerror/strsignal are available nowadays. At the same time, drop use of thread-private storage. Instead, always return interned strings. https://bugzilla.gnome.org/show_bug.cgi?id=660849 --- configure.ac | 33 --- glib/gstrfuncs.c | 627 +++---------------------------------------------------- 2 files changed, 29 insertions(+), 631 deletions(-) diff --git a/configure.ac b/configure.ac index a6f4a6a..e4235e0 100644 --- a/configure.ac +++ b/configure.ac @@ -1234,39 +1234,6 @@ if test "$ac_cv_func_memmove" != "yes"; then fi fi -# Check for sys_errlist -AC_MSG_CHECKING(for sys_errlist) -AC_TRY_LINK(, [ -extern char *sys_errlist[]; -extern int sys_nerr; -sys_errlist[sys_nerr-1][0] = 0; -], glib_ok=yes, glib_ok=no) -AC_MSG_RESULT($glib_ok) -if test "$glib_ok" = "no"; then - AC_DEFINE(NO_SYS_ERRLIST,1,[global 'sys_errlist' not found]) -fi - -# Check for sys_siglist -AC_MSG_CHECKING(for sys_siglist) -AC_TRY_LINK(, [ -extern char *sys_siglist[]; -exit (sys_siglist[0]); -], glib_ok=yes, glib_ok=no) -AC_MSG_RESULT($glib_ok) -if test "$glib_ok" = "no"; then - AC_DEFINE(NO_SYS_SIGLIST,1,[global 'sys_siglist' not found]) -fi - -# Check for sys_siglist decl (see Tue Jan 19 00:44:24 1999 in changelog) -AC_MSG_CHECKING(for sys_siglist declaration) -AC_TRY_COMPILE([#include ], [ -strlen (sys_siglist[0]); -], glib_ok=yes, glib_ok=no) -AC_MSG_RESULT($glib_ok) -if test "$glib_ok" = "no"; then - AC_DEFINE(NO_SYS_SIGLIST_DECL,1,[global 'sys_siglist' not declared]) -fi - # Check if needs to be included for fd_set AC_MSG_CHECKING([for fd_set]) AC_TRY_COMPILE([#include ], diff --git a/glib/gstrfuncs.c b/glib/gstrfuncs.c index 3ae8c7b..260f224 100644 --- a/glib/gstrfuncs.c +++ b/glib/gstrfuncs.c @@ -38,9 +38,6 @@ #include #include #include /* For tolower() */ -#if !defined (HAVE_STRSIGNAL) || !defined(NO_SYS_SIGLIST_DECL) -#include -#endif #ifdef G_OS_WIN32 #include @@ -1209,474 +1206,35 @@ g_ascii_strtoll (const gchar *nptr, * not all platforms support the strerror() function. * * Returns: a UTF-8 string describing the error code. If the error code - * is unknown, it returns "unknown error (<code>)". The string - * can only be used until the next call to g_strerror() + * is unknown, it returns "unknown error (<code>)". */ const gchar * g_strerror (gint errnum) { - static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT; - char *msg; - int saved_errno = errno; + gchar buf[64]; + gchar *msg; + gchar *tofree; + const gchar *ret; + gint saved_errno = errno; -#ifdef HAVE_STRERROR - const char *msg_locale; + msg = tofree = NULL; - msg_locale = strerror (errnum); - if (g_get_charset (NULL)) - { - errno = saved_errno; - return msg_locale; - } - else - { - gchar *msg_utf8 = g_locale_to_utf8 (msg_locale, -1, NULL, NULL, NULL); - if (msg_utf8) - { - /* Stick in the quark table so that we can return a static result - */ - GQuark msg_quark = g_quark_from_string (msg_utf8); - g_free (msg_utf8); - - msg_utf8 = (gchar *) g_quark_to_string (msg_quark); - errno = saved_errno; - return msg_utf8; - } - } -#elif NO_SYS_ERRLIST - switch (errnum) - { -#ifdef E2BIG - case E2BIG: return "argument list too long"; -#endif -#ifdef EACCES - case EACCES: return "permission denied"; -#endif -#ifdef EADDRINUSE - case EADDRINUSE: return "address already in use"; -#endif -#ifdef EADDRNOTAVAIL - case EADDRNOTAVAIL: return "can't assign requested address"; -#endif -#ifdef EADV - case EADV: return "advertise error"; -#endif -#ifdef EAFNOSUPPORT - case EAFNOSUPPORT: return "address family not supported by protocol family"; -#endif -#ifdef EAGAIN - case EAGAIN: return "try again"; -#endif -#ifdef EALIGN - case EALIGN: return "EALIGN"; -#endif -#ifdef EALREADY - case EALREADY: return "operation already in progress"; -#endif -#ifdef EBADE - case EBADE: return "bad exchange descriptor"; -#endif -#ifdef EBADF - case EBADF: return "bad file number"; -#endif -#ifdef EBADFD - case EBADFD: return "file descriptor in bad state"; -#endif -#ifdef EBADMSG - case EBADMSG: return "not a data message"; -#endif -#ifdef EBADR - case EBADR: return "bad request descriptor"; -#endif -#ifdef EBADRPC - case EBADRPC: return "RPC structure is bad"; -#endif -#ifdef EBADRQC - case EBADRQC: return "bad request code"; -#endif -#ifdef EBADSLT - case EBADSLT: return "invalid slot"; -#endif -#ifdef EBFONT - case EBFONT: return "bad font file format"; -#endif -#ifdef EBUSY - case EBUSY: return "mount device busy"; -#endif -#ifdef ECHILD - case ECHILD: return "no children"; -#endif -#ifdef ECHRNG - case ECHRNG: return "channel number out of range"; -#endif -#ifdef ECOMM - case ECOMM: return "communication error on send"; -#endif -#ifdef ECONNABORTED - case ECONNABORTED: return "software caused connection abort"; -#endif -#ifdef ECONNREFUSED - case ECONNREFUSED: return "connection refused"; -#endif -#ifdef ECONNRESET - case ECONNRESET: return "connection reset by peer"; -#endif -#if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK)) - case EDEADLK: return "resource deadlock avoided"; -#endif -#if defined(EDEADLOCK) && (!defined(EDEADLK) || (EDEADLOCK != EDEADLK)) - case EDEADLOCK: return "resource deadlock avoided"; -#endif -#ifdef EDESTADDRREQ - case EDESTADDRREQ: return "destination address required"; -#endif -#ifdef EDIRTY - case EDIRTY: return "mounting a dirty fs w/o force"; -#endif -#ifdef EDOM - case EDOM: return "math argument out of range"; -#endif -#ifdef EDOTDOT - case EDOTDOT: return "cross mount point"; -#endif -#ifdef EDQUOT - case EDQUOT: return "disk quota exceeded"; -#endif -#ifdef EDUPPKG - case EDUPPKG: return "duplicate package name"; -#endif -#ifdef EEXIST - case EEXIST: return "file already exists"; -#endif -#ifdef EFAULT - case EFAULT: return "bad address in system call argument"; -#endif -#ifdef EFBIG - case EFBIG: return "file too large"; -#endif -#ifdef EHOSTDOWN - case EHOSTDOWN: return "host is down"; -#endif -#ifdef EHOSTUNREACH - case EHOSTUNREACH: return "host is unreachable"; -#endif -#ifdef EIDRM - case EIDRM: return "identifier removed"; -#endif -#ifdef EINIT - case EINIT: return "initialization error"; -#endif -#ifdef EINPROGRESS - case EINPROGRESS: return "operation now in progress"; -#endif -#ifdef EINTR - case EINTR: return "interrupted system call"; -#endif -#ifdef EINVAL - case EINVAL: return "invalid argument"; -#endif -#ifdef EIO - case EIO: return "I/O error"; -#endif -#ifdef EISCONN - case EISCONN: return "socket is already connected"; -#endif -#ifdef EISDIR - case EISDIR: return "is a directory"; -#endif -#ifdef EISNAME - case EISNAM: return "is a name file"; -#endif -#ifdef ELBIN - case ELBIN: return "ELBIN"; -#endif -#ifdef EL2HLT - case EL2HLT: return "level 2 halted"; -#endif -#ifdef EL2NSYNC - case EL2NSYNC: return "level 2 not synchronized"; -#endif -#ifdef EL3HLT - case EL3HLT: return "level 3 halted"; -#endif -#ifdef EL3RST - case EL3RST: return "level 3 reset"; -#endif -#ifdef ELIBACC - case ELIBACC: return "can not access a needed shared library"; -#endif -#ifdef ELIBBAD - case ELIBBAD: return "accessing a corrupted shared library"; -#endif -#ifdef ELIBEXEC - case ELIBEXEC: return "can not exec a shared library directly"; -#endif -#ifdef ELIBMAX - case ELIBMAX: return "attempting to link in more shared libraries than system limit"; -#endif -#ifdef ELIBSCN - case ELIBSCN: return ".lib section in a.out corrupted"; -#endif -#ifdef ELNRNG - case ELNRNG: return "link number out of range"; -#endif -#ifdef ELOOP - case ELOOP: return "too many levels of symbolic links"; -#endif -#ifdef EMFILE - case EMFILE: return "too many open files"; -#endif -#ifdef EMLINK - case EMLINK: return "too many links"; -#endif -#ifdef EMSGSIZE - case EMSGSIZE: return "message too long"; -#endif -#ifdef EMULTIHOP - case EMULTIHOP: return "multihop attempted"; -#endif -#ifdef ENAMETOOLONG - case ENAMETOOLONG: return "file name too long"; -#endif -#ifdef ENAVAIL - case ENAVAIL: return "not available"; -#endif -#ifdef ENET - case ENET: return "ENET"; -#endif -#ifdef ENETDOWN - case ENETDOWN: return "network is down"; -#endif -#ifdef ENETRESET - case ENETRESET: return "network dropped connection on reset"; -#endif -#ifdef ENETUNREACH - case ENETUNREACH: return "network is unreachable"; -#endif -#ifdef ENFILE - case ENFILE: return "file table overflow"; -#endif -#ifdef ENOANO - case ENOANO: return "anode table overflow"; -#endif -#if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR)) - case ENOBUFS: return "no buffer space available"; -#endif -#ifdef ENOCSI - case ENOCSI: return "no CSI structure available"; -#endif -#ifdef ENODATA - case ENODATA: return "no data available"; -#endif -#ifdef ENODEV - case ENODEV: return "no such device"; -#endif -#ifdef ENOENT - case ENOENT: return "no such file or directory"; -#endif -#ifdef ENOEXEC - case ENOEXEC: return "exec format error"; -#endif -#ifdef ENOLCK - case ENOLCK: return "no locks available"; -#endif -#ifdef ENOLINK - case ENOLINK: return "link has be severed"; -#endif -#ifdef ENOMEM - case ENOMEM: return "not enough memory"; -#endif -#ifdef ENOMSG - case ENOMSG: return "no message of desired type"; -#endif -#ifdef ENONET - case ENONET: return "machine is not on the network"; -#endif -#ifdef ENOPKG - case ENOPKG: return "package not installed"; -#endif -#ifdef ENOPROTOOPT - case ENOPROTOOPT: return "bad proocol option"; -#endif -#ifdef ENOSPC - case ENOSPC: return "no space left on device"; -#endif -#ifdef ENOSR - case ENOSR: return "out of stream resources"; -#endif -#ifdef ENOSTR - case ENOSTR: return "not a stream device"; -#endif -#ifdef ENOSYM - case ENOSYM: return "unresolved symbol name"; -#endif -#ifdef ENOSYS - case ENOSYS: return "function not implemented"; -#endif -#ifdef ENOTBLK - case ENOTBLK: return "block device required"; -#endif -#ifdef ENOTCONN - case ENOTCONN: return "socket is not connected"; -#endif -#ifdef ENOTDIR - case ENOTDIR: return "not a directory"; -#endif -#ifdef ENOTEMPTY - case ENOTEMPTY: return "directory not empty"; -#endif -#ifdef ENOTNAM - case ENOTNAM: return "not a name file"; -#endif -#ifdef ENOTSOCK - case ENOTSOCK: return "socket operation on non-socket"; -#endif -#ifdef ENOTTY - case ENOTTY: return "inappropriate device for ioctl"; -#endif -#ifdef ENOTUNIQ - case ENOTUNIQ: return "name not unique on network"; -#endif -#ifdef ENXIO - case ENXIO: return "no such device or address"; -#endif -#ifdef EOPNOTSUPP - case EOPNOTSUPP: return "operation not supported on socket"; -#endif -#ifdef EPERM - case EPERM: return "not owner"; -#endif -#ifdef EPFNOSUPPORT - case EPFNOSUPPORT: return "protocol family not supported"; -#endif -#ifdef EPIPE - case EPIPE: return "broken pipe"; -#endif -#ifdef EPROCLIM - case EPROCLIM: return "too many processes"; -#endif -#ifdef EPROCUNAVAIL - case EPROCUNAVAIL: return "bad procedure for program"; -#endif -#ifdef EPROGMISMATCH - case EPROGMISMATCH: return "program version wrong"; -#endif -#ifdef EPROGUNAVAIL - case EPROGUNAVAIL: return "RPC program not available"; -#endif -#ifdef EPROTO - case EPROTO: return "protocol error"; -#endif -#ifdef EPROTONOSUPPORT - case EPROTONOSUPPORT: return "protocol not suppored"; -#endif -#ifdef EPROTOTYPE - case EPROTOTYPE: return "protocol wrong type for socket"; -#endif -#ifdef ERANGE - case ERANGE: return "math result unrepresentable"; -#endif -#if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED)) - case EREFUSED: return "EREFUSED"; -#endif -#ifdef EREMCHG - case EREMCHG: return "remote address changed"; -#endif -#ifdef EREMDEV - case EREMDEV: return "remote device"; -#endif -#ifdef EREMOTE - case EREMOTE: return "pathname hit remote file system"; -#endif -#ifdef EREMOTEIO - case EREMOTEIO: return "remote i/o error"; -#endif -#ifdef EREMOTERELEASE - case EREMOTERELEASE: return "EREMOTERELEASE"; -#endif -#ifdef EROFS - case EROFS: return "read-only file system"; -#endif -#ifdef ERPCMISMATCH - case ERPCMISMATCH: return "RPC version is wrong"; -#endif -#ifdef ERREMOTE - case ERREMOTE: return "object is remote"; -#endif -#ifdef ESHUTDOWN - case ESHUTDOWN: return "can't send afer socket shutdown"; -#endif -#ifdef ESOCKTNOSUPPORT - case ESOCKTNOSUPPORT: return "socket type not supported"; -#endif -#ifdef ESPIPE - case ESPIPE: return "invalid seek"; -#endif -#ifdef ESRCH - case ESRCH: return "no such process"; -#endif -#ifdef ESRMNT - case ESRMNT: return "srmount error"; -#endif -#ifdef ESTALE - case ESTALE: return "stale remote file handle"; -#endif -#ifdef ESUCCESS - case ESUCCESS: return "Error 0"; -#endif -#ifdef ETIME - case ETIME: return "timer expired"; -#endif -#ifdef ETIMEDOUT - case ETIMEDOUT: return "connection timed out"; -#endif -#ifdef ETOOMANYREFS - case ETOOMANYREFS: return "too many references: can't splice"; -#endif -#ifdef ETXTBSY - case ETXTBSY: return "text file or pseudo-device busy"; -#endif -#ifdef EUCLEAN - case EUCLEAN: return "structure needs cleaning"; -#endif -#ifdef EUNATCH - case EUNATCH: return "protocol driver not attached"; -#endif -#ifdef EUSERS - case EUSERS: return "too many users"; -#endif -#ifdef EVERSION - case EVERSION: return "version mismatch"; -#endif -#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) - case EWOULDBLOCK: return "operation would block"; -#endif -#ifdef EXDEV - case EXDEV: return "cross-domain link"; -#endif -#ifdef EXFULL - case EXFULL: return "message tables full"; +#ifdef HAVE_STRERROR + msg = strerror (errnum); + if (!g_get_charset (NULL)) + msg = tofree = g_locale_to_utf8 (msg, -1, NULL, NULL, NULL); #endif - } -#else /* NO_SYS_ERRLIST */ - extern int sys_nerr; - extern char *sys_errlist[]; - if ((errnum > 0) && (errnum <= sys_nerr)) - return sys_errlist [errnum]; -#endif /* NO_SYS_ERRLIST */ - - msg = g_static_private_get (&msg_private); if (!msg) { - msg = g_new (gchar, 64); - g_static_private_set (&msg_private, msg, g_free); + msg = buf; + _g_sprintf (msg, "unknown error (%d)", errnum); } - _g_sprintf (msg, "unknown error (%d)", errnum); - + ret = g_intern_string (msg); + g_free (tofree); errno = saved_errno; - return msg; + return ret; } /** @@ -1690,156 +1248,29 @@ g_strerror (gint errnum) * the strsignal() function. * * Returns: a UTF-8 string describing the signal. If the signal is unknown, - * it returns "unknown signal (<signum>)". The string can only be - * used until the next call to g_strsignal() + * it returns "unknown signal (<signum>)". */ const gchar * g_strsignal (gint signum) { - static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT; - char *msg; - -#ifdef HAVE_STRSIGNAL - const char *msg_locale; + gchar *msg; + gchar *tofree; + const gchar *ret; -#if defined(G_OS_BEOS) || defined(G_WITH_CYGWIN) -extern const char *strsignal(int); -#else - /* this is declared differently (const) in string.h on BeOS */ - extern char *strsignal (int sig); -#endif /* !G_OS_BEOS && !G_WITH_CYGWIN */ - msg_locale = strsignal (signum); - if (g_get_charset (NULL)) - return msg_locale; - else - { - gchar *msg_utf8 = g_locale_to_utf8 (msg_locale, -1, NULL, NULL, NULL); - if (msg_utf8) - { - /* Stick in the quark table so that we can return a static result - */ - GQuark msg_quark = g_quark_from_string (msg_utf8); - g_free (msg_utf8); - - return g_quark_to_string (msg_quark); - } - } -#elif NO_SYS_SIGLIST - switch (signum) - { -#ifdef SIGHUP - case SIGHUP: return "Hangup"; -#endif -#ifdef SIGINT - case SIGINT: return "Interrupt"; -#endif -#ifdef SIGQUIT - case SIGQUIT: return "Quit"; -#endif -#ifdef SIGILL - case SIGILL: return "Illegal instruction"; -#endif -#ifdef SIGTRAP - case SIGTRAP: return "Trace/breakpoint trap"; -#endif -#ifdef SIGABRT - case SIGABRT: return "IOT trap/Abort"; -#endif -#ifdef SIGBUS - case SIGBUS: return "Bus error"; -#endif -#ifdef SIGFPE - case SIGFPE: return "Floating point exception"; -#endif -#ifdef SIGKILL - case SIGKILL: return "Killed"; -#endif -#ifdef SIGUSR1 - case SIGUSR1: return "User defined signal 1"; -#endif -#ifdef SIGSEGV - case SIGSEGV: return "Segmentation fault"; -#endif -#ifdef SIGUSR2 - case SIGUSR2: return "User defined signal 2"; -#endif -#ifdef SIGPIPE - case SIGPIPE: return "Broken pipe"; -#endif -#ifdef SIGALRM - case SIGALRM: return "Alarm clock"; -#endif -#ifdef SIGTERM - case SIGTERM: return "Terminated"; -#endif -#ifdef SIGSTKFLT - case SIGSTKFLT: return "Stack fault"; -#endif -#ifdef SIGCHLD - case SIGCHLD: return "Child exited"; -#endif -#ifdef SIGCONT - case SIGCONT: return "Continued"; -#endif -#ifdef SIGSTOP - case SIGSTOP: return "Stopped (signal)"; -#endif -#ifdef SIGTSTP - case SIGTSTP: return "Stopped"; -#endif -#ifdef SIGTTIN - case SIGTTIN: return "Stopped (tty input)"; -#endif -#ifdef SIGTTOU - case SIGTTOU: return "Stopped (tty output)"; -#endif -#ifdef SIGURG - case SIGURG: return "Urgent condition"; -#endif -#ifdef SIGXCPU - case SIGXCPU: return "CPU time limit exceeded"; -#endif -#ifdef SIGXFSZ - case SIGXFSZ: return "File size limit exceeded"; -#endif -#ifdef SIGVTALRM - case SIGVTALRM: return "Virtual time alarm"; -#endif -#ifdef SIGPROF - case SIGPROF: return "Profile signal"; -#endif -#ifdef SIGWINCH - case SIGWINCH: return "Window size changed"; -#endif -#ifdef SIGIO - case SIGIO: return "Possible I/O"; -#endif -#ifdef SIGPWR - case SIGPWR: return "Power failure"; -#endif -#ifdef SIGUNUSED - case SIGUNUSED: return "Unused signal"; -#endif - } -#else /* NO_SYS_SIGLIST */ + msg = tofree = NULL; -#ifdef NO_SYS_SIGLIST_DECL - extern char *sys_siglist[]; /*(see Tue Jan 19 00:44:24 1999 in changelog)*/ +#ifdef HAVE_STRSIGNAL + msg = strsignal (signum); + if (!g_get_charset (NULL)) + msg = tofree = g_locale_to_utf8 (msg, -1, NULL, NULL, NULL); #endif - return (char*) /* this function should return const --josh */ sys_siglist [signum]; -#endif /* NO_SYS_SIGLIST */ - - msg = g_static_private_get (&msg_private); if (!msg) - { - msg = g_new (gchar, 64); - g_static_private_set (&msg_private, msg, g_free); - } - - _g_sprintf (msg, "unknown signal (%d)", signum); + msg = tofree = g_strdup_printf ("unknown signal (%d)", signum); + ret = g_intern_string (msg); + g_free (tofree); - return msg; + return ret; } /* Functions g_strlcpy and g_strlcat were originally developed by -- 2.7.4