bug-bash
[Top][All Lists]
Advanced

[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

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]