# Define the common source files for all the libc instances
# =========================================================
libc_common_src_files := \
- bionic/bindresvport.c \
bionic/ether_aton.c \
bionic/ether_ntoa.c \
bionic/fts.c \
bionic/mremap.cpp \
bionic/NetdClientDispatch.cpp \
bionic/net_if.cpp \
+ bionic/netinet_in.cpp \
bionic/open.cpp \
bionic/pathconf.cpp \
bionic/pause.cpp \
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+
+#include <netinet/in.h>
+
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
-#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
-#define START_PORT 600
-#define END_PORT IPPORT_RESERVED
-#define NUM_PORTS (END_PORT - START_PORT)
+constexpr int START_PORT = 600;
+constexpr int END_PORT = IPPORT_RESERVED;
+constexpr int NUM_PORTS = (END_PORT - START_PORT);
-int bindresvport(int sd, struct sockaddr_in *sin)
-{
- static short port;
- struct sockaddr_in sin0;
- int nn, ret;
+int bindresvport(int sd, struct sockaddr_in* sin) {
+ sockaddr_in sin0;
+ if (sin == nullptr) {
+ memset(&sin0, 0, sizeof(sin0));
+ sin = &sin0;
+ sin->sin_family = AF_INET;
+ }
- if (sin == NULL) {
- sin = &sin0;
- memset( sin, 0, sizeof *sin );
- sin->sin_family = AF_INET;
- } else if (sin->sin_family != AF_INET) {
- errno = EPFNOSUPPORT;
- return -1;
- }
+ if (sin->sin_family != AF_INET) {
+ errno = EPFNOSUPPORT;
+ return -1;
+ }
- if (port == 0) {
- port = START_PORT + (getpid() % NUM_PORTS);
- }
+ // TODO: thread safety!
+ static short port;
+ if (port == 0) {
+ port = START_PORT + (getpid() % NUM_PORTS);
+ }
- for (nn = NUM_PORTS; nn > 0; nn--, port++)
- {
- if (port == END_PORT)
- port = START_PORT;
-
- sin->sin_port = htons(port);
- do {
- ret = bind(sd, (struct sockaddr*)sin, sizeof(*sin));
- } while (ret < 0 && errno == EINTR);
-
- if (!ret)
- break;
- }
- return ret;
+ for (size_t i = NUM_PORTS; i > 0; i--, port++) {
+ if (port == END_PORT) port = START_PORT;
+ sin->sin_port = htons(port);
+ int rc = TEMP_FAILURE_RETRY(bind(sd, reinterpret_cast<sockaddr*>(sin), sizeof(*sin)));
+ if (rc >= 0) return rc;
+ }
+ return -1;
}
+
+const in6_addr in6addr_any = IN6ADDR_ANY_INIT;
+const in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
typedef uint16_t in_port_t;
typedef uint32_t in_addr_t;
-extern int bindresvport (int sd, struct sockaddr_in *sin);
+int bindresvport(int, struct sockaddr_in*);
-static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
-static const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
+extern const struct in6_addr in6addr_any;
+extern const struct in6_addr in6addr_loopback;
__END_DECLS
getifaddrs;
if_freenameindex;
if_nameindex;
+ in6addr_any;
+ in6addr_loopback;
lockf;
lockf64;
preadv;
getifaddrs;
if_freenameindex;
if_nameindex;
+ in6addr_any;
+ in6addr_loopback;
lockf;
lockf64;
preadv;
getifaddrs;
if_freenameindex;
if_nameindex;
+ in6addr_any;
+ in6addr_loopback;
lockf;
lockf64;
preadv;
getifaddrs;
if_freenameindex;
if_nameindex;
+ in6addr_any;
+ in6addr_loopback;
lockf;
lockf64;
preadv;
getifaddrs;
if_freenameindex;
if_nameindex;
+ in6addr_any;
+ in6addr_loopback;
lockf;
lockf64;
preadv;
getifaddrs;
if_freenameindex;
if_nameindex;
+ in6addr_any;
+ in6addr_loopback;
lockf;
lockf64;
preadv;
getifaddrs;
if_freenameindex;
if_nameindex;
+ in6addr_any;
+ in6addr_loopback;
lockf;
lockf64;
preadv;
getifaddrs;
if_freenameindex;
if_nameindex;
+ in6addr_any;
+ in6addr_loopback;
lockf;
lockf64;
preadv;
getifaddrs;
if_freenameindex;
if_nameindex;
+ in6addr_any;
+ in6addr_loopback;
lockf;
lockf64;
preadv;
getifaddrs;
if_freenameindex;
if_nameindex;
+ in6addr_any;
+ in6addr_loopback;
lockf;
lockf64;
preadv;
malloc_test.cpp \
math_test.cpp \
mntent_test.cpp \
- net_if_test.cpp \
netdb_test.cpp \
+ net_if_test.cpp \
+ netinet_in_test.cpp \
netinet_udp_test.cpp \
pthread_test.cpp \
pty_test.cpp \
--- /dev/null
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <netinet/in.h>
+
+#include <errno.h>
+
+#include <gtest/gtest.h>
+
+TEST(netinet_in, bindresvport) {
+ // This isn't something we can usually test, so just check the symbol's there.
+ ASSERT_EQ(-1, bindresvport(-1, nullptr));
+}
+
+TEST(netinet_in, in6addr_any) {
+ in6_addr any = IN6ADDR_ANY_INIT;
+ ASSERT_EQ(0, memcmp(&any, &in6addr_any, sizeof(in6addr_any)));
+}
+
+TEST(netinet_in, in6addr_loopback) {
+ in6_addr loopback = IN6ADDR_LOOPBACK_INIT;
+ ASSERT_EQ(0, memcmp(&loopback, &in6addr_loopback, sizeof(in6addr_loopback)));
+}