File: hpux.c

package info (click to toggle)
links2 2.29-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 27,852 kB
  • sloc: ansic: 181,859; sh: 2,585; cpp: 1,450; makefile: 84; awk: 49; perl: 34
file content (124 lines) | stat: -rw-r--r-- 2,611 bytes parent folder | download | duplicates (6)
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