summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'libcutils/socket_local_server_unix.cpp')
-rw-r--r--libcutils/socket_local_server_unix.cpp126
1 files changed, 126 insertions, 0 deletions
diff --git a/libcutils/socket_local_server_unix.cpp b/libcutils/socket_local_server_unix.cpp
new file mode 100644
index 000000000..855e5da4e
--- /dev/null
+++ b/libcutils/socket_local_server_unix.cpp
@@ -0,0 +1,126 @@
1/* libs/cutils/socket_local_server.c
2**
3** Copyright 2006, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#include <cutils/sockets.h>
19
20#include <stdlib.h>
21#include <string.h>
22#include <unistd.h>
23#include <errno.h>
24#include <stddef.h>
25
26#if defined(_WIN32)
27
28int socket_local_server(const char *name, int namespaceId, int type)
29{
30 errno = ENOSYS;
31 return -1;
32}
33
34#else /* !_WIN32 */
35
36#include <sys/socket.h>
37#include <sys/un.h>
38#include <sys/select.h>
39#include <sys/types.h>
40#include <netinet/in.h>
41
42#include "socket_local_unix.h"
43
44#define LISTEN_BACKLOG 4
45
46/* Only the bottom bits are really the socket type; there are flags too. */
47#define SOCK_TYPE_MASK 0xf
48
49/**
50 * Binds a pre-created socket(AF_LOCAL) 's' to 'name'
51 * returns 's' on success, -1 on fail
52 *
53 * Does not call listen()
54 */
55int socket_local_server_bind(int s, const char *name, int namespaceId)
56{
57 struct sockaddr_un addr;
58 socklen_t alen;
59 int n;
60 int err;
61
62 err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen);
63
64 if (err < 0) {
65 return -1;
66 }
67
68 /* basically: if this is a filesystem path, unlink first */
69#if !defined(__linux__)
70 if (1) {
71#else
72 if (namespaceId == ANDROID_SOCKET_NAMESPACE_RESERVED
73 || namespaceId == ANDROID_SOCKET_NAMESPACE_FILESYSTEM) {
74#endif
75 /*ignore ENOENT*/
76 unlink(addr.sun_path);
77 }
78
79 n = 1;
80 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
81
82 if(bind(s, (struct sockaddr *) &addr, alen) < 0) {
83 return -1;
84 }
85
86 return s;
87
88}
89
90
91/** Open a server-side UNIX domain datagram socket in the Linux non-filesystem
92 * namespace
93 *
94 * Returns fd on success, -1 on fail
95 */
96
97int socket_local_server(const char *name, int namespaceId, int type)
98{
99 int err;
100 int s;
101
102 s = socket(AF_LOCAL, type, 0);
103 if (s < 0) return -1;
104
105 err = socket_local_server_bind(s, name, namespaceId);
106
107 if (err < 0) {
108 close(s);
109 return -1;
110 }
111
112 if ((type & SOCK_TYPE_MASK) == SOCK_STREAM) {
113 int ret;
114
115 ret = listen(s, LISTEN_BACKLOG);
116
117 if (ret < 0) {
118 close(s);
119 return -1;
120 }
121 }
122
123 return s;
124}
125
126#endif /* !_WIN32 */