Darwin orac.local 8.9.0 Darwin Kernel Version 8.9.0: Thu Feb 22 20:54:07 PST
2007; root:xnu-792.17.14~1/RELEASE_PPC Power Macintosh powerpc (Mac OS X 10.4.9)
GPGME 1.1.4
Apple XTools 2.0 (gcc 4.0)
On 32-bit Darwin systems the symbol ttyname_r resolves by default to the
pre-POSIX version of the function, the one that returns a char* instead of an
int. The POSIX version is called ttyname_r$UNIX2003; ttyname_r becomes an alias
for this if any of _POSIX_C_SOURCE, _APPLE_C_SOURCE, _XOPEN_SOURCE, or LP64
is set.
The configure script detects the presence of ttyname_r but fails to detect the
old-style prototype or cause the POSIX version to be used. As a result the
obsolete ttyname_r() is used and successful calls to it in rungpg.c and
engine-gpgsm.c are treated as failures; the calling functions return some random
value of errno which drives people nuts when they try to figure out the cause of
the "failure".
If the obsolete function is to be used then the test for failure has to be
negated; the function returns (char*)0 on failure, not on success!
Even if the POSIX version is used the code in GPGME is incorrect; the standard
does not require that ttyname_r() set errno before returning. Instead of
if (ttyname_r(...)) {
err = gpg_error_from_errno(errno); ...
}
one should write something like
int status;
if (status = ttyname_r(...)) {
err = gpg_error_from_errno(status); ...
}
The same is true in general for any POSIX function that returns an error code,
e.g., pthread calls; you can't rely on errno even though any reasonable
implementation would set it.
I don't know how to correct the configure script but I'm attaching a patch that
will cause the POSIX function to be called correctly.
References:
Darwin header /usr/include/sys/cdefs.h Darwin header /usr/include/unistd.h POSIX standard for ttyname_r():