help with understanding __BSD_VISIBLE

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

help with understanding __BSD_VISIBLE

Allan Streib-2
Probably an elementary question stemming from my lack of C expertise.

I am trying to complile some C code that includes its own "bcrypt"
function. This is conflicting with the declaration in pwd.h.

    error: conflicting types for 'bcrypt'
    int bcrypt(char *, const char *, const char *);
        ^
    /usr/include/pwd.h:112:8: note: previous declaration is here
    char            *bcrypt(const char *, const char *);

In pwd.h I see that the bcrypt declaration is wrapped in a #if block:

    #if __BSD_VISIBLE
    int              setpassent(int);
    int              uid_from_user(const char *, uid_t *);
    const char      *user_from_uid(uid_t, int);
    char            *bcrypt_gensalt(u_int8_t);
    char            *bcrypt(const char *, const char *);
    int             bcrypt_newhash(const char *, int, char *, size_t);
    int             bcrypt_checkpass(const char *, const char *);
    struct passwd   *pw_dup(const struct passwd *);
    #endif

So I'm trying to work out why __BSD_VISIBLE is 1 when I'm compiling.

sys/cdefs.h says:

    /*
     * Finally deal with BSD-specific interfaces that are not covered
     * by any standards.  We expose these when none of the POSIX or XPG
     * macros is defined or if the user explicitly asks for them.
     */
    #if !defined(_BSD_SOURCE) && \
       (defined(_ANSI_SOURCE) || defined(__XPG_VISIBLE) || defined(__POSIX_VISIBLE))
    # define __BSD_VISIBLE          0
    #endif

__POSIX_VISIBLE is defined as 200809, so __BSD_VISIBLE should be 0 and
the pwd.h declaration for bcrypt should be skipped?

Allan






Reply | Threaded
Open this post in threaded view
|

Re: help with understanding __BSD_VISIBLE

Otto Moerbeek
On Fri, Jul 12, 2019 at 03:35:54PM -0400, Allan Streib wrote:

> Probably an elementary question stemming from my lack of C expertise.
>
> I am trying to complile some C code that includes its own "bcrypt"
> function. This is conflicting with the declaration in pwd.h.
>
>     error: conflicting types for 'bcrypt'
>     int bcrypt(char *, const char *, const char *);
>         ^
>     /usr/include/pwd.h:112:8: note: previous declaration is here
>     char            *bcrypt(const char *, const char *);
>
> In pwd.h I see that the bcrypt declaration is wrapped in a #if block:
>
>     #if __BSD_VISIBLE
>     int              setpassent(int);
>     int              uid_from_user(const char *, uid_t *);
>     const char      *user_from_uid(uid_t, int);
>     char            *bcrypt_gensalt(u_int8_t);
>     char            *bcrypt(const char *, const char *);
>     int             bcrypt_newhash(const char *, int, char *, size_t);
>     int             bcrypt_checkpass(const char *, const char *);
>     struct passwd   *pw_dup(const struct passwd *);
>     #endif
>
> So I'm trying to work out why __BSD_VISIBLE is 1 when I'm compiling.
>
> sys/cdefs.h says:
>
>     /*
>      * Finally deal with BSD-specific interfaces that are not covered
>      * by any standards.  We expose these when none of the POSIX or XPG
>      * macros is defined or if the user explicitly asks for them.
>      */
>     #if !defined(_BSD_SOURCE) && \
>        (defined(_ANSI_SOURCE) || defined(__XPG_VISIBLE) || defined(__POSIX_VISIBLE))
>     # define __BSD_VISIBLE          0
>     #endif
>
> __POSIX_VISIBLE is defined as 200809, so __BSD_VISIBLE should be 0 and
> the pwd.h declaration for bcrypt should be skipped?
>
> Allan

Likely __POSIX_VISIBLE isn't defined until after that statements in
the bottom part of cdefs.h

You need to define _POSIX_C_SOURCE yourself before including cdefs.h

        -Otto

Reply | Threaded
Open this post in threaded view
|

Re: help with understanding __BSD_VISIBLE

Philip Guenther-2
In reply to this post by Allan Streib-2
On Fri, Jul 12, 2019 at 10:39 AM Allan Streib <[hidden email]> wrote:

> Probably an elementary question stemming from my lack of C expertise.
>
> I am trying to complile some C code that includes its own "bcrypt"
> function. This is conflicting with the declaration in pwd.h.
>
>     error: conflicting types for 'bcrypt'
>     int bcrypt(char *, const char *, const char *);
>         ^
>     /usr/include/pwd.h:112:8: note: previous declaration is here
>     char            *bcrypt(const char *, const char *);
>
> In pwd.h I see that the bcrypt declaration is wrapped in a #if block:
>
...

> __POSIX_VISIBLE is defined as 200809, so __BSD_VISIBLE should be 0 and
> the pwd.h declaration for bcrypt should be skipped?
>

There are four options here:
1) change the software to not use the name 'bcrypt' for a non-static
function.  OpenBSD has only been using it for 15 years...

2) If you're going to use the name bcrypt, then don't do so in files that
pull in <pwd.h>.  (This would be a last choice in my book, as that's a
fragile setup)

3) *IF* the software was written to only rely on the interfaces of some
version of the POSIX standard, then follow the compilation rules described
in that standard.  You mention POSIX 2008, so perhaps this software would
build when following those rules, passing the compiler
-D_POSIX_C_SOURCE=200809L to only declare the symbols from that standard

Note that application software should *never* define macros matching the
pattern __*_VISIBLE such as __BSD_VISIBLE.  Those are in the reserved
namespace and on OpenBSD they are set by <sys/cdefs.h> based on the macros
specified in the various standards for use by application and build
software.  The ones you should care about are:
  _POSIX_C_SOURCE     -- standardized: specifies a POSIX version
  _XOPEN_SOURCE        -- standardized: specifies a POSIX + XSI version
  _ISOC11_SOURCE        -- adds C2011 interfaces
  _BSD_SOURCE             -- adds all BSD and obsoleted interfaces

Make sense?

Philip Guenther
Reply | Threaded
Open this post in threaded view
|

Re: help with understanding __BSD_VISIBLE

Allan Streib-2
Philip Guenther <[hidden email]> writes:

> There are four options here:
> 1) change the software to not use the name 'bcrypt' for a non-static
> function.  OpenBSD has only been using it for 15 years...

Agree, but for now I'm trying to keep changes to a minimum as I work out
larger issues. This is in an erlang wrapper for bcrypt. It includes its
own copy of bcrypt.c

The change that diverges from the OpenBSD version is in this commit, in
case anyone is interested.

https://github.com/smarkets/erlang-bcrypt/commit/1277ee41bba86d47e039e3f24a47a491efe48d78

> 3) *IF* the software was written to only rely on the interfaces of some
> version of the POSIX standard, then follow the compilation rules
> described in that standard.  You mention POSIX 2008, so perhaps this
> software would build when following those rules, passing the compiler
> -D_POSIX_C_SOURCE=200809L to only declare the symbols from that
> standard

This seems to work, at least I don't get any compile errors. Thank you.

Allan

Reply | Threaded
Open this post in threaded view
|

Re: help with understanding __BSD_VISIBLE

Theo de Raadt-2
In reply to this post by Allan Streib-2
>Philip Guenther <[hidden email]> writes:
>
>> There are four options here:
>> 1) change the software to not use the name 'bcrypt' for a non-static
>> function.  OpenBSD has only been using it for 15 years...
>
>Agree, but for now I'm trying to keep changes to a minimum as I work out
>larger issues. This is in an erlang wrapper for bcrypt. It includes its
>own copy of bcrypt.c
>
>The change that diverges from the OpenBSD version is in this commit, in
>case anyone is interested.
>
>https://github.com/smarkets/erlang-bcrypt/commit/1277ee41bba86d47e039e3f24a47a491efe48d78

Whoever did that should have renamed it.  There really is no excuse.
I look forward to the amusing consequences in the future.