diff options
-rw-r--r-- | erts/aclocal.m4 | 2 | ||||
-rw-r--r-- | erts/configure.in | 12 | ||||
-rw-r--r-- | erts/emulator/beam/sys.h | 3 | ||||
-rw-r--r-- | erts/emulator/beam/utils.c | 2 | ||||
-rw-r--r-- | erts/emulator/nifs/common/socket_nif.c | 130 | ||||
-rw-r--r-- | erts/emulator/sys/unix/erl_child_setup.c | 4 | ||||
-rw-r--r-- | erts/emulator/sys/unix/sys.c | 7 | ||||
-rw-r--r-- | erts/etc/unix/run_erl.c | 12 | ||||
-rw-r--r-- | lib/erl_interface/include/ei.h | 13 | ||||
-rw-r--r-- | lib/erl_interface/src/connect/ei_resolve.c | 12 | ||||
-rw-r--r-- | lib/erl_interface/src/misc/ei_portio.c | 2 |
11 files changed, 130 insertions, 69 deletions
diff --git a/erts/aclocal.m4 b/erts/aclocal.m4 index 0ca2755802..e2b7e1eada 100644 --- a/erts/aclocal.m4 +++ b/erts/aclocal.m4 @@ -2988,7 +2988,7 @@ case $host_os in DED_LDFLAGS="-64 $DED_LDFLAGS" fi ;; - aix4*) + aix*|os400*) DED_LDFLAGS="-G -bnoentry -bexpall" ;; freebsd2*) diff --git a/erts/configure.in b/erts/configure.in index 3a043c940d..e8923d0dcf 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -447,6 +447,12 @@ dnl --------------------------------------------------------------------- dnl NOTE: CPPFLAGS will be included in CFLAGS at the end case $host_os in linux*) CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE";; + aix*|os400*) + # * _ALL_SOURCE: Required to get the winsize structure for TIOCSWINSZ. + # * _LINUX_SOURCE_COMPAT: Not required, but makes some libc functions + # behave closer to glibc assumptions. + CPPFLAGS="$CPPFLAGS -D_ALL_SOURCE -D_LINUX_SOURCE_COMPAT" + ;; win32) # The ethread library requires _WIN32_WINNT of at least 0x0403. # -D_WIN32_WINNT=* from CPPFLAGS is saved in ETHR_DEFS. @@ -966,7 +972,7 @@ AC_SUBST(ERLANG_OSTYPE) AC_MSG_CHECKING(for extra flags needed to export symbols) DEXPORT="" case $host_os in - aix4*) + aix*|os400*) DEXPORT=-Wl,-bexpall,-brtl ;; bsdi*) @@ -1427,7 +1433,7 @@ if test "$have_gethostbyname_r" = yes; then AC_DEFINE(HAVE_GETHOSTBYNAME_R, GHBN_R_SOLARIS, [Define to flavour of gethostbyname_r]) ;; - aix4*) + aix*|os400*) # AIX version also needs "struct hostent_data" defn AC_TRY_COMPILE([#include <netdb.h>], [struct hostent_data hd;], @@ -2036,7 +2042,7 @@ AC_CHECK_FUNCS([ieee_handler fpsetmask finite isnan isinf res_gethostbyname dlop gethrtime localtime_r gmtime_r inet_pton mprotect \ mmap mremap memcpy mallopt sbrk _sbrk __sbrk brk _brk __brk \ flockfile fstat strlcpy strlcat setsid posix2time time2posix \ - setlocale nl_langinfo poll mlockall ppoll]) + setlocale nl_langinfo poll mlockall ppoll vsyslog]) AC_MSG_CHECKING([for isfinite]) AC_TRY_LINK([#include <math.h>], diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h index acc321aa51..db07512cf7 100644 --- a/erts/emulator/beam/sys.h +++ b/erts/emulator/beam/sys.h @@ -178,7 +178,8 @@ typedef ERTS_SYS_FD_TYPE ErtsSysFdType; # define ERTS_UNLIKELY(BOOL) (BOOL) #endif -#if ERTS_AT_LEAST_GCC_VSN__(2, 96, 0) +/* AIX doesn't like this and claims section conflicts */ +#if ERTS_AT_LEAST_GCC_VSN__(2, 96, 0) && !defined(_AIX) #if (defined(__APPLE__) && defined(__MACH__)) || defined(__DARWIN__) # define ERTS_WRITE_UNLIKELY(X) X __attribute__ ((section ("__DATA,ERTS_LOW_WRITE") )) #else diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c index ad71828d72..fb06d60768 100644 --- a/erts/emulator/beam/utils.c +++ b/erts/emulator/beam/utils.c @@ -66,7 +66,7 @@ #undef M_MMAP_THRESHOLD #undef M_MMAP_MAX -#if defined(__GLIBC__) && defined(HAVE_MALLOC_H) +#if (defined(__GLIBC__) || defined(_AIX)) && defined(HAVE_MALLOC_H) #include <malloc.h> #endif diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c index adecbb3b6e..73158ae019 100644 --- a/erts/emulator/nifs/common/socket_nif.c +++ b/erts/emulator/nifs/common/socket_nif.c @@ -1034,10 +1034,10 @@ static ERL_NIF_TERM nconnect(ErlNifEnv* env, static ERL_NIF_TERM nlisten(ErlNifEnv* env, ESockDescriptor* descP, int backlog); -static ERL_NIF_TERM naccept(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM ref); +static ERL_NIF_TERM naccept_erts(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM ref); static ERL_NIF_TERM naccept_listening(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM sockRef, @@ -1101,31 +1101,31 @@ static ERL_NIF_TERM nsendto(ErlNifEnv* env, int flags, ESockAddress* toAddrP, unsigned int toAddrLen); -static ERL_NIF_TERM nsendmsg(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM sendRef, - ERL_NIF_TERM eMsgHdr, - int flags); +static ERL_NIF_TERM nsendmsg_erts(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM sendRef, + ERL_NIF_TERM eMsgHdr, + int flags); static ERL_NIF_TERM nrecv(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM sendRef, ERL_NIF_TERM recvRef, int len, int flags); -static ERL_NIF_TERM nrecvfrom(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM recvRef, - Uint16 bufSz, - int flags); -static ERL_NIF_TERM nrecvmsg(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM recvRef, - Uint16 bufLen, - Uint16 ctrlLen, - int flags); +static ERL_NIF_TERM nrecvfrom_erts(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM recvRef, + Uint16 bufSz, + int flags); +static ERL_NIF_TERM nrecvmsg_erts(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM recvRef, + Uint16 bufLen, + Uint16 ctrlLen, + int flags); static ERL_NIF_TERM nclose(ErlNifEnv* env, ESockDescriptor* descP); static BOOLEAN_T nclose_check(ErlNifEnv* env, @@ -5313,7 +5313,7 @@ ERL_NIF_TERM nif_accept(ErlNifEnv* env, descP->currentAcceptor.env, descP->currentAcceptor.ref) ); - res = naccept(env, descP, sockRef, ref); + res = naccept_erts(env, descP, sockRef, ref); MUNLOCK(descP->accMtx); @@ -5325,10 +5325,10 @@ ERL_NIF_TERM nif_accept(ErlNifEnv* env, #if !defined(__WIN32__) static -ERL_NIF_TERM naccept(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM ref) +ERL_NIF_TERM naccept_erts(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM ref) { ERL_NIF_TERM res; @@ -6123,7 +6123,7 @@ ERL_NIF_TERM nif_sendmsg(ErlNifEnv* env, MLOCK(descP->writeMtx); - res = nsendmsg(env, descP, sockRef, sendRef, eMsgHdr, flags); + res = nsendmsg_erts(env, descP, sockRef, sendRef, eMsgHdr, flags); MUNLOCK(descP->writeMtx); @@ -6140,12 +6140,12 @@ ERL_NIF_TERM nif_sendmsg(ErlNifEnv* env, #if !defined(__WIN32__) static -ERL_NIF_TERM nsendmsg(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM sendRef, - ERL_NIF_TERM eMsgHdr, - int flags) +ERL_NIF_TERM nsendmsg_erts(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM sendRef, + ERL_NIF_TERM eMsgHdr, + int flags) { ERL_NIF_TERM res, eAddr, eIOV, eCtrl; ESockAddress addr; @@ -6174,7 +6174,7 @@ ERL_NIF_TERM nsendmsg(ErlNifEnv* env, /* We don't need the address */ - SSDBG( descP, ("SOCKET", "nsendmsg -> connected: no address\r\n") ); + SSDBG( descP, ("SOCKET", "nsendmsg_erts -> connected: no address\r\n") ); msgHdr.msg_name = NULL; msgHdr.msg_namelen = 0; @@ -6189,7 +6189,7 @@ ERL_NIF_TERM nsendmsg(ErlNifEnv* env, if (!GET_MAP_VAL(env, eMsgHdr, esock_atom_addr, &eAddr)) return esock_make_error(env, esock_atom_einval); - SSDBG( descP, ("SOCKET", "nsendmsg -> not connected: " + SSDBG( descP, ("SOCKET", "nsendmsg_erts -> not connected: " "\r\n address: %T" "\r\n", eAddr) ); @@ -6209,7 +6209,7 @@ ERL_NIF_TERM nsendmsg(ErlNifEnv* env, if (!GET_LIST_LEN(env, eIOV, &iovLen) && (iovLen > 0)) return esock_make_error(env, esock_atom_einval); - SSDBG( descP, ("SOCKET", "nsendmsg -> iov length: %d\r\n", iovLen) ); + SSDBG( descP, ("SOCKET", "nsendmsg_erts -> iov length: %d\r\n", iovLen) ); iovBins = MALLOC(iovLen * sizeof(ErlNifBinary)); ESOCK_ASSERT( (iovBins != NULL) ); @@ -6227,7 +6227,7 @@ ERL_NIF_TERM nsendmsg(ErlNifEnv* env, ctrlBufLen = 0; ctrlBuf = NULL; } - SSDBG( descP, ("SOCKET", "nsendmsg -> optional ctrl: " + SSDBG( descP, ("SOCKET", "nsendmsg_erts -> optional ctrl: " "\r\n ctrlBuf: 0x%lX" "\r\n ctrlBufLen: %d" "\r\n eCtrl: %T\r\n", ctrlBuf, ctrlBufLen, eCtrl) ); @@ -6245,7 +6245,7 @@ ERL_NIF_TERM nsendmsg(ErlNifEnv* env, SSDBG( descP, ("SOCKET", - "nsendmsg -> total (iov) data size: %d\r\n", dataSize) ); + "nsendmsg_erts -> total (iov) data size: %d\r\n", dataSize) ); /* Decode the ctrl and initiate that part of the msghdr. @@ -6586,7 +6586,7 @@ ERL_NIF_TERM nif_recvfrom(ErlNifEnv* env, * </KOLLA> */ - res = nrecvfrom(env, descP, sockRef, recvRef, bufSz, flags); + res = nrecvfrom_erts(env, descP, sockRef, recvRef, bufSz, flags); MUNLOCK(descP->readMtx); @@ -6602,12 +6602,12 @@ ERL_NIF_TERM nif_recvfrom(ErlNifEnv* env, */ #if !defined(__WIN32__) static -ERL_NIF_TERM nrecvfrom(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM recvRef, - Uint16 len, - int flags) +ERL_NIF_TERM nrecvfrom_erts(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM recvRef, + Uint16 len, + int flags) { ESockAddress fromAddr; unsigned int addrLen; @@ -6617,7 +6617,7 @@ ERL_NIF_TERM nrecvfrom(ErlNifEnv* env, ERL_NIF_TERM readerCheck; int bufSz = (len ? len : descP->rBufSz); - SSDBG( descP, ("SOCKET", "nrecvfrom -> entry with" + SSDBG( descP, ("SOCKET", "nrecvfrom_erts -> entry with" "\r\n len: %d (%d)" "\r\n flags: %d" "\r\n", len, bufSz, flags) ); @@ -6758,7 +6758,7 @@ ERL_NIF_TERM nif_recvmsg(ErlNifEnv* env, * </KOLLA> */ - res = nrecvmsg(env, descP, sockRef, recvRef, bufSz, ctrlSz, flags); + res = nrecvmsg_erts(env, descP, sockRef, recvRef, bufSz, ctrlSz, flags); MUNLOCK(descP->readMtx); @@ -6774,13 +6774,13 @@ ERL_NIF_TERM nif_recvmsg(ErlNifEnv* env, */ #if !defined(__WIN32__) static -ERL_NIF_TERM nrecvmsg(ErlNifEnv* env, - ESockDescriptor* descP, - ERL_NIF_TERM sockRef, - ERL_NIF_TERM recvRef, - Uint16 bufLen, - Uint16 ctrlLen, - int flags) +ERL_NIF_TERM nrecvmsg_erts(ErlNifEnv* env, + ESockDescriptor* descP, + ERL_NIF_TERM sockRef, + ERL_NIF_TERM recvRef, + Uint16 bufLen, + Uint16 ctrlLen, + int flags) { unsigned int addrLen; ssize_t read; @@ -6794,7 +6794,7 @@ ERL_NIF_TERM nrecvmsg(ErlNifEnv* env, ERL_NIF_TERM readerCheck; ESockAddress addr; - SSDBG( descP, ("SOCKET", "nrecvmsg -> entry with" + SSDBG( descP, ("SOCKET", "nrecvmsg_erts -> entry with" "\r\n bufSz: %d (%d)" "\r\n ctrlSz: %d (%d)" "\r\n flags: %d" @@ -9328,8 +9328,12 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_addrform(ErlNifEnv* env, domain) ); res = socket_setopt(descP->sock, - SOL_IPV6, IPV6_ADDRFORM, - &domain, sizeof(domain)); +#if defined(SOL_IPV6) + SOL_IPV6, +#else + IPPROTO_IPV6, +#endif + IPV6_ADDRFORM, &domain, sizeof(domain)); if (res != 0) result = esock_make_error_errno(env, sock_errno()); @@ -9359,7 +9363,13 @@ ERL_NIF_TERM nsetopt_lvl_ipv6_authhdr(ErlNifEnv* env, ESockDescriptor* descP, ERL_NIF_TERM eVal) { - return nsetopt_bool_opt(env, descP, SOL_IPV6, IPV6_AUTHHDR, eVal); + return nsetopt_bool_opt(env, descP, +#if defined(SOL_IPV6) + SOL_IPV6, +#else + IPPROTO_IPV6, +#endif + IPV6_AUTHHDR, eVal); } #endif diff --git a/erts/emulator/sys/unix/erl_child_setup.c b/erts/emulator/sys/unix/erl_child_setup.c index 129861ebd5..9241660069 100644 --- a/erts/emulator/sys/unix/erl_child_setup.c +++ b/erts/emulator/sys/unix/erl_child_setup.c @@ -75,6 +75,10 @@ #define SHELL "/bin/sh" #endif /* __ANDROID__ */ +#if !defined(MSG_DONTWAIT) && defined(MSG_NONBLOCK) +#define MSG_DONTWAIT MSG_NONBLOCK +#endif + //#define HARD_DEBUG #ifdef HARD_DEBUG #define DEBUG_PRINT(fmt, ...) fprintf(stderr, "%d:" fmt "\r\n", getpid(), ##__VA_ARGS__) diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c index 4823e549ea..78866b356c 100644 --- a/erts/emulator/sys/unix/sys.c +++ b/erts/emulator/sys/unix/sys.c @@ -740,10 +740,17 @@ void os_version(int *pMajor, int *pMinor, int *pBuild) { * X.Y or X.Y.Z. */ (void) uname(&uts); +#ifdef _AIX + /* AIX stores the major in version and minor in release */ + *pMajor = atoi(uts.version); + *pMinor = atoi(uts.release); + *pBuild = 0; /* XXX: get oslevel for AIX or TR on i */ +#else release = uts.release; *pMajor = get_number(&release); /* Pointer to major version. */ *pMinor = get_number(&release); /* Pointer to minor version. */ *pBuild = get_number(&release); /* Pointer to build number. */ +#endif } void erts_do_break_handling(void) diff --git a/erts/etc/unix/run_erl.c b/erts/etc/unix/run_erl.c index bfb3e1bd2c..e974630695 100644 --- a/erts/etc/unix/run_erl.c +++ b/erts/etc/unix/run_erl.c @@ -1201,7 +1201,19 @@ static void error_logf(int priority, int line, const char *format, ...) #ifdef HAVE_SYSLOG_H if (run_daemon) { +#ifdef HAVE_VSYSLOG vsyslog(priority,format,args); +#else + /* Some OSes like AIX lack vsyslog. */ + va_list ap; + char message[900]; /* AIX man page says truncation past this */ + + va_start (ap, format); + vsnprintf(message, 900, format, ap); + va_end(ap); + + syslog(priority, message); +#endif } else #endif diff --git a/lib/erl_interface/include/ei.h b/lib/erl_interface/include/ei.h index b138118f04..7d39043bb2 100644 --- a/lib/erl_interface/include/ei.h +++ b/lib/erl_interface/include/ei.h @@ -323,13 +323,24 @@ typedef struct { #define EI_SCLBK_FLG_FULL_IMPL (1 << 0) +/* + * HACK: AIX defines many socket functions like accept to be naccept, which + * pollutes the global namespace. Set up an ugly ifdef for consumers of this + * API here so they get a mangled name for AIX and the sane name elsewhere. + */ +#ifdef _AIX +#define EI_ACCEPT_NAME accept_ei +#else +#define EI_ACCEPT_NAME accept +#endif + typedef struct { int flags; int (*socket)(void **ctx, void *setup_ctx); int (*close)(void *ctx); int (*listen)(void *ctx, void *addr, int *len, int backlog); - int (*accept)(void **ctx, void *addr, int *len, unsigned tmo); + int (*EI_ACCEPT_NAME)(void **ctx, void *addr, int *len, unsigned tmo); int (*connect)(void *ctx, void *addr, int len, unsigned tmo); int (*writev)(void *ctx, const void *iov, int iovcnt, ssize_t *len, unsigned tmo); int (*write)(void *ctx, const char *buf, ssize_t *len, unsigned tmo); diff --git a/lib/erl_interface/src/connect/ei_resolve.c b/lib/erl_interface/src/connect/ei_resolve.c index 225fddc784..5a8ca0c567 100644 --- a/lib/erl_interface/src/connect/ei_resolve.c +++ b/lib/erl_interface/src/connect/ei_resolve.c @@ -55,6 +55,16 @@ #include "ei_resolve.h" #include "ei_locking.h" +/* AIX has a totally different signature (allegedly shared with some other + * Unices) that isn't compatible. It turns out that the _r version isn't + * thread-safe according to curl - but bizarrely, since AIX 4.3, libc + * is thread-safe in a manner that makes the normal gethostbyname OK + * for re-entrant use. + */ +#ifdef _AIX +#undef HAVE_GETHOSTBYNAME_R +#endif + #ifdef HAVE_GETHOSTBYNAME_R int ei_init_resolve(void) @@ -75,7 +85,7 @@ int ei_init_resolve(void) static ei_mutex_t *ei_gethost_sem = NULL; #endif /* _REENTRANT */ static int ei_resolve_initialized = 0; -#ifndef __WIN32__ +#if !defined(__WIN32__) && !defined(_AIX) int h_errno; #endif diff --git a/lib/erl_interface/src/misc/ei_portio.c b/lib/erl_interface/src/misc/ei_portio.c index bccc86c1b1..bfe67a732c 100644 --- a/lib/erl_interface/src/misc/ei_portio.c +++ b/lib/erl_interface/src/misc/ei_portio.c @@ -622,7 +622,7 @@ int ei_accept_ctx_t__(ei_socket_callbacks *cbs, void **ctx, } while (error == EINTR); } do { - error = cbs->accept(ctx, addr, len, ms); + error = cbs->EI_ACCEPT_NAME(ctx, addr, len, ms); } while (error == EINTR); return error; } |