tonyrog / afunix

Unix domain sockets (again)
28 stars 12 forks source link

Build problem on OS X 10.7.5 #3

Closed mmzeeman closed 10 years ago

mmzeeman commented 10 years ago

afunix fails to build on OS X 10.7.5.

For details see: https://github.com/zotonic/zotonic/issues/797

tonyrog commented 10 years ago

Thanks for reporting. What is the content of /usr/include/sys/un.h ? At least on OS X 10.8 - 10.9 that include LOCAL_PEERCRED and LOCAL_PEERPID (I am currently using 10.9 my ) There is a function called getpeereid that could possibly be used on mac os x, could you please do a man getpeereid on your 10.7.5 machine? have not found a getpeerpid yet.

mworrell commented 10 years ago

@tonyrog Thanks for coming back that fast!

 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
(…)
 * Copyright (c) 1982, 1986, 1993
 *  The Regents of the University of California.  All rights reserved.
(…)
 *  @(#)un.h    8.3 (Berkeley) 2/19/95
 */

#ifndef _SYS_UN_H_
#define _SYS_UN_H_

#include <sys/appleapiopts.h>
#include <sys/cdefs.h>
#include <sys/_types.h>

/* [XSI] The sa_family_t type shall be defined as described in <sys/socket.h> */
#ifndef _SA_FAMILY_T
#define _SA_FAMILY_T
typedef __uint8_t       sa_family_t;
#endif

/*
 * [XSI] Definitions for UNIX IPC domain.
 */
struct  sockaddr_un {
    unsigned char   sun_len;    /* sockaddr len including null */
    sa_family_t sun_family; /* [XSI] AF_UNIX */
    char        sun_path[104];  /* [XSI] path name (gag) */
};

#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)

/* Level number of get/setsockopt for local domain sockets */
#define SOL_LOCAL       0

/* Socket options. */
#define LOCAL_PEERCRED          0x001           /* retrieve peer credentails */

#endif  /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */

#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
/* actual length of an initialized sockaddr_un */
#define SUN_LEN(su) \
    (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
#endif  /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */

#endif /* !_SYS_UN_H_ */
mworrell commented 10 years ago

And man getpeerid returns:

GETPEEREID(3)            BSD Library Functions Manual            GETPEEREID(3)

NAME
     getpeereid -- get the effective credentials of a UNIX-domain peer

LIBRARY
     Standard C Library (libc, -lc)

SYNOPSIS
     #include <sys/types.h>
     #include <unistd.h>

     int
     getpeereid(int s, uid_t *euid, gid_t *egid);

DESCRIPTION
     The getpeereid() function returns the effective user and group IDs of
     the peer connected to a UNIX-domain socket.  The argument s must be a
     UNIX-domain socket (unix(4)) of type SOCK_STREAM on which either
     connect(2) or listen(2) have been called.  The effective used ID is
     placed in euid, and the effective group ID in egid.

     The credentials returned to the listen(2) caller are those of its peer
     at the time it called connect(2); the credentials returned to the
     connect(2) caller are those of its peer at the time it called
     listen(2).  This mechanism is reliable; there is no way for either side
     to influence the credentials returned to its peer except by calling the
     appropriate system call (i.e., either connect(2) or listen(2)) under
     different effective credentials.

     One common use of this routine is for a UNIX-domain server to verify
     the credentials of its client.  Likewise, the client can verify the
     credentials of the server.

IMPLEMENTATION NOTES
     On FreeBSD, getpeereid() is implemented in terms of the LOCAL_PEERCRED
     unix(4) socket option.

RETURN VALUES
     The getpeereid() function returns the value 0 if successful; otherwise
     the value -1 is returned and the global variable errno is set to indi-
     cate the error.

ERRORS
     The getpeereid() function fails if:

     [EBADF]            The argument s is not a valid descriptor.

     [ENOTSOCK]         The argument s is a file, not a socket.

     [ENOTCONN]         The argument s does not refer to a socket on which
                        connect(2) or listen(2) have been called.

     [EINVAL]           The argument s does not refer to a socket of type
                        SOCK_STREAM, or the kernel returned invalid data.

SEE ALSO
     connect(2), getpeername(2), getsockname(2), getsockopt(2), listen(2),
     unix(4)

HISTORY
     The getpeereid() function appeared in FreeBSD 4.6.

BSD                              July 15, 2001                             BSD
tonyrog commented 10 years ago

Ok, you can try a pull. Please send any warning output from the compiler. I do not think exometer is using any of the cred and pid stuff so it is really just an macro defs / compiler issue in this case. I did however check that the driver compiles when LOCAL_PEERCRED and/or LOCAL_PEERPID where undefined. And also checked for SO_PEERCRED.

mworrell commented 10 years ago

Great.

I tried a recompile with the master. Only some warnings where left:

The first one looks a bit more serious.

Compiling c_src/afunix_drv.c
c_src/afunix_drv.c:3108:2: warning: #warning "no method of accessing socket peerpid found" [-W#warnings]
#warning "no method of accessing socket peerpid found"
 ^
c_src/afunix_drv.c:3894:45: warning: incompatible integer to pointer conversion passing 'long' to parameter of type 'ErlDrvPort' (aka 'struct _erl_drv_port *'); 
    port =  (ErlDrvPort) driver_create_port(CREATE_CAST port, owner, "tcp_inet", (ErlDrvData) ((long)copy_desc));
                                            ^~~~~~~~~~~~~~~~
c_src/afunix_drv.c:3849:21: note: expanded from macro 'CREATE_CAST'
#define CREATE_CAST (long)
                    ^~~~~~
/usr/local/lib/erlang/erts-5.9.3.1/include/erl_driver.h:598:49: note: passing argument to parameter 'creator_port' here
EXTERN ErlDrvPort driver_create_port(ErlDrvPort creator_port, 
                                                ^
2 warnings generated.
tonyrog commented 10 years ago

Thanks. Perfect. The warning is supposed to be there, since there is no method of accessing the peerpid on mac os x 10.7 ;-) The second warning I will fix. Thanks again.