1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
#if defined(__hpux)
#include "cfg.h"
#include "com-defs.h"
#ifdef report
#include <stdio.h>
#include <unistd.h>
#endif
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#ifndef HAVE_SOCKLEN_T
#define socklen_t int
#endif
#include "hpux.h"
union len_t {
int intlen;
socklen_t socklen;
};
static int hp_detect_length(int s)
{
static int mode_cache = -1;
union len_t u;
int val;
int r;
if (sizeof(int) == sizeof(socklen_t)) return 0;
if (mode_cache >= 0) return mode_cache;
memset(&u, 1, sizeof u);
r = getsockopt(s, SOL_SOCKET, SO_ERROR, (void *)&val, (void *)&u);
if (r) return -1;
if (u.socklen == sizeof(int)) {
#ifdef report
fprintf(stderr, "detected socklen argument\n");
sleep(1);
#endif
mode_cache = 1;
return 1;
} else if (u.intlen == sizeof(int)) {
#ifdef report
fprintf(stderr, "detected int argument\n");
sleep(1);
#endif
mode_cache = 0;
return 0;
} else {
fatal_exit("Could not detect HP-UX socklen argument type: %lx,%x", (long)u.socklen, u.intlen);
errno = EINVAL;
return -1;
}
}
int hp_accept(int s, struct sockaddr *addr, socklen_t *len)
{
union len_t u;
int mode, r;
if (addr == NULL || len == NULL) return accept(s, NULL, NULL);
if ((mode = hp_detect_length(s)) == -1) return -1;
memset(&u, 0, sizeof u);
if (!mode) u.intlen = *len;
else u.socklen = *len;
r = accept(s, addr, (void *)&u);
if (!mode) *len = u.intlen;
else *len = u.socklen;
return r;
}
int hp_getpeername(int s, struct sockaddr *addr, socklen_t *len)
{
union len_t u;
int mode, r;
if ((mode = hp_detect_length(s)) == -1) return -1;
memset(&u, 0, sizeof u);
if (!mode) u.intlen = *len;
else u.socklen = *len;
r = getpeername(s, addr, (void *)&u);
if (!mode) *len = u.intlen;
else *len = u.socklen;
return r;
}
int hp_getsockname(int s, struct sockaddr *addr, socklen_t *len)
{
union len_t u;
int mode, r;
if ((mode = hp_detect_length(s)) == -1) return -1;
memset(&u, 0, sizeof u);
if (!mode) u.intlen = *len;
else u.socklen = *len;
r = getsockname(s, addr, (void *)&u);
if (!mode) *len = u.intlen;
else *len = u.socklen;
return r;
}
int hp_getsockopt(int s, int level, int opt, void *val, socklen_t *len)
{
union len_t u;
int mode, r;
if (val == NULL || len == NULL) return getsockopt(s, level, opt, NULL, NULL);
if ((mode = hp_detect_length(s)) == -1) return -1;
memset(&u, 0, sizeof u);
if (!mode) u.intlen = *len;
else u.socklen = *len;
r = getsockopt(s, level, opt, val, (void *)&u);
if (!mode) *len = u.intlen;
else *len = u.socklen;
return r;
}
#else
typedef int hpux_c_no_empty_unit;
#endif
|