Fwd: Re: ports/52016: New port: lang/harbour - AClipper-compatible compiler

Bruce Evans bde at zeta.org.au
Fri Jan 9 07:04:09 PST 2004

On Thu, 8 Jan 2004, Mark Linimon wrote:

> Hello.  I'm a ports committer trying to help a submitter get a port ready
> for inclusion in the tree.  This problem is clearly outside my league, so
> any suggestions on how I can help him would be appreciated.

> ----------  Forwarded Message  ----------
> [mcl's cited compile error:]
>  > ../../../../source/rtl/bsd/gcc/librtl.a(filesys.o): In function
>  > `hb_fsCommit':
>  > /usr/ports/lang/harbour/work/harbour/source/rtl/bsd/gcc/../../filesys.c:14
>  >92: undefined reference to `fdatasync'
> [the submitter replied:]
>  The hb_fsCommit function in filesys.c only attempts to use fdatasync if
>  _POSIX_SYNCHRONIZED_IO is defined, so this error appears to be due to a bug
>  in the POSIX library implementation in GCC on -current. The fdatasync
>  function is a POSIX function that appears to me to be mandated to be
>  present, even if unimplemented, if _POSIX_SYNCHRONIZED_IO is defined in
>  unistd.h.

_POSIX_SYNCRONIZED_IO is defined as -1, which means that this optional
feature is not supported at all.  From <sys/unistd.h>:

% /*
%  * POSIX options and option groups we unconditionally do or don't
%  * implement.  Those options which are implemented (or not) entirely
%  * in user mode are defined in <unistd.h>.  Please keep this list in
%  * alphabetical order.
%  *
%  * Anything which is defined as zero below **must** have an
%  * implementation for the corresponding sysconf() which is able to
%  * determine conclusively whether or not the feature is supported.
%  * Anything which is defined as other than -1 below **must** have
%  * complete headers, types, and function declarations as specified by
%  * the POSIX standard; however, if the relevant sysconf() function
%  * returns -1, the functions may be stubbed out.
%  */

I vaguely remember that fdatasync() is a subset of _POSIX_SYNCHRONIZED_IO.
fdatasync() is certainly not supported in FreeBSD, and the feature test
macro is correctly defined to indicate this.

The application's test of _POSIX_SYNCHRONIZED_IO is apparently broken.
It must do something like testing for (_POSIX_SYNCHRONIZED_IO + 0) !=
-1 at compile time (not just "#ifdef _POSIX_SYNCHRONIZED_IO"), and
according to the above, must also use sysconf() at runtime to see if
the feature actually works.  I don't remember the latter requirement
in the standard, except in the following form:
- if a feature test macro has value 0, then the feature might not be
  available and sysconf() must be used, as above.
- at least old standards seem to permit feature test macros to have no
  value (they may be empty, or perhaps more bizarre).  The "+ 0" in the
  above is to handle this case, so that feature test with an empty value
  work the same as ones with value 0.
- if a feature test macro has value > 0, then the feature is fully present
  and need not be checked using sysconf().

POSIX feature tests macros are hard to use in their full generality (it
takes about a page of code per macro just to ifdef all the cases).
Practical applications would probably avoid most of these complications
by only supporting fully dynamic or fully static configuration.  E.g.:

/* Fully static: */
/* Might "cache" the macro values in HAVE_FDATASYNC, etc. */
#elif _POSIX_FSYNC + 0 > 0
	err(1, "system might not support fdatsync() or fsync()");

/* Fully dynamic: */
	/* Might cache the sysconf() values in have_fdatasync, etc. */
	if (sysconf(_SC_SYNCHRONIZED_IO) > 0)
	else if (sysconf(_SC_FSYNC) > 0)
	err(1, "system does not support fdatsync() or fsync()");


More information about the freebsd-standards mailing list