[Top][All Lists]

[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

"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:

#  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'

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:

#  define Setjmp(x) sigsetjmp((x), 1)
#  define Setjmp(x) setjmp(x)

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]