[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
readline 6.3 violates POSIX by doing #undef setjmp
From: |
Eric Blake |
Subject: |
readline 6.3 violates POSIX by doing #undef setjmp |
Date: |
Fri, 23 Jan 2015 14:58:36 -0700 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.4.0 |
http://pubs.opengroup.org/onlinepubs/9699919799/functions/setjmp.html is
clear:
"It is unspecified whether setjmp() is a macro or a function. If a macro
definition is suppressed in order to access an actual function, or a
program defines an external identifier with the name setjmp, the
behavior is undefined."
But in readline's posixjmp.h wrapper file, you do:
#if defined (HAVE_POSIX_SIGSETJMP)
# define procenv_t sigjmp_buf
# if !defined (__OPENNT)
# undef setjmp
# define setjmp(x) sigsetjmp((x), 1)
which breaks on Cygwin. There, <setjmp.h> declares setjmp() as a
function, and sigsetjmp() as a macro in terms of setjmp(). Observe:
$ printf '#include <setjmp.h>
sigsetjmp(a,0)\n' | gcc -E - | tail -n1
__extension__ ({ sigjump_buf *_sjbuf = &(a); ((*_sjbuf)[(13 * 4)] = 0,
pthread_sigmask (0, 0, (sigset_t *)((*_sjbuf) + ((13 * 4)+1))), setjmp
(*_sjbuf)); })
which, when combined with your wrapper, produces garbage:
$ printf '#include "config.h"
#include <setjmp.h>
#include "posixjmp.h"
sigsetjmp(a,0)\n' | gcc -E - | tail -n1
__extension__ ({ sigjump_buf *_sjbuf = &(a); ((*_sjbuf)[(13 * 4)] = 0,
pthread_sigmask (0, 0, (sigset_t *)((*_sjbuf) + ((13 * 4)+1))),
sigsetjmp (*_sjbuf)); })
Basically, because your wrapper means there are now two macros defined
in terms of each other, the expansion of sigsetjmp is trying to invoke a
function named sigsetjmp, but no such function exists on Cygwin, leading
to this compilation failure:
readline.c: In function 'readline_internal_char':
readline.c:541:7: error: implicit declaration of function 'sigsetjmp'
[-Werror=implicit-function-declaration]
It looks like "posixjmp.h" exists to rewrite 'setjmp' into 'sigsetjmp' -
but that is not possible to portably do via macro expansion. You'll
need to break down and actually do the replacement by hand. You could
get away with something like:
#if defined (HAVE_POSIX_SIGSETJMP)
# define Setjmp(x) sigsetjmp((x), 1)
#else
# define Setjmp(x) setjmp(x)
#endif
and using Setjmp instead of setjmp throughout any file that includes
"posixjmp.h". I'll leave it up to you to decide on the best solution
for your coding style. [Meanwhile, I'll file a bug with the Cygwin
folks to see if we can use some namespace tricks in <setjmp.h> to avoid
problems for code like readline, to be tolerant of your redefine attempt
the way Linux is, even if it is above and beyond what POSIX requires]
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature
- readline 6.3 violates POSIX by doing #undef setjmp,
Eric Blake <=