This source file includes following definitions.
- create_socketpair
1
2
3
4
5
6
7
8
9
10
11 #include "opal_config.h"
12
13 #include "opal/win32/opal_socket.h"
14 #include "opal/util/output.h"
15
16 int
17 create_socketpair(int family, int type, int protocol, int fd[2])
18 {
19
20
21
22
23
24
25
26 #ifdef WIN32
27 #define ERR(e) WSA##e
28 #else
29 #define ERR(e) e
30 #endif
31 int listener = -1;
32 int connector = -1;
33 int acceptor = -1;
34 struct sockaddr_in listen_addr;
35 struct sockaddr_in connect_addr;
36 int size;
37 int saved_errno = -1;
38
39 if (protocol
40 || (family != AF_INET
41 #ifdef AF_UNIX
42 && family != AF_UNIX
43 #endif
44 )) {
45 opal_output(0, "Protocol not support: %d", (ERR(EAFNOSUPPORT)));
46 return -1;
47 }
48 if (!fd) {
49 opal_output(0, "Invalid socked: %d", (ERR(EINVAL)));
50 return -1;
51 }
52
53 listener = socket(AF_INET, type, 0);
54 if (listener < 0)
55 return -1;
56 memset(&listen_addr, 0, sizeof(listen_addr));
57 listen_addr.sin_family = AF_INET;
58 listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
59 listen_addr.sin_port = 0;
60 if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
61 == -1)
62 goto tidy_up_and_fail;
63 if (listen(listener, 1) == -1)
64 goto tidy_up_and_fail;
65
66 connector = socket(AF_INET, type, 0);
67 if (connector < 0)
68 goto tidy_up_and_fail;
69
70 size = sizeof(connect_addr);
71 if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
72 goto tidy_up_and_fail;
73 if (size != sizeof (connect_addr))
74 goto abort_tidy_up_and_fail;
75 if (connect(connector, (struct sockaddr *) &connect_addr,
76 sizeof(connect_addr)) == -1)
77 goto tidy_up_and_fail;
78
79 size = sizeof(listen_addr);
80 acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
81 if (acceptor < 0)
82 goto tidy_up_and_fail;
83 if (size != sizeof(listen_addr))
84 goto abort_tidy_up_and_fail;
85 closesocket(listener);
86
87
88 if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
89 goto tidy_up_and_fail;
90 if (size != sizeof (connect_addr)
91 || listen_addr.sin_family != connect_addr.sin_family
92 || listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
93 || listen_addr.sin_port != connect_addr.sin_port)
94 goto abort_tidy_up_and_fail;
95 fd[0] = connector;
96 fd[1] = acceptor;
97
98 return 0;
99
100 abort_tidy_up_and_fail:
101 saved_errno = ERR(ECONNABORTED);
102 tidy_up_and_fail:
103 if (saved_errno < 0)
104 saved_errno = WSAGetLastError();
105 if (listener != -1)
106 closesocket(listener);
107 if (connector != -1)
108 closesocket(connector);
109 if (acceptor != -1)
110 closesocket(acceptor);
111
112 WSASetLastError(saved_errno);
113 return -1;
114 #undef ERR
115 }