blob: 60eb86b8320ed0025819d2d793ce9fcf933cde0f [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001/* 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#ifdef HAVE_WINSOCK
27
28int socket_local_server(const char *name, int namespaceId, int type)
29{
30 errno = ENOSYS;
31 return -1;
32}
33
34#else /* !HAVE_WINSOCK */
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.h"
43
44#define LISTEN_BACKLOG 4
45
Paul Kocialkowskia7e2e762014-02-26 13:41:11 +010046/* Only the bottom bits are really the socket type; there are flags too. */
47#define SOCK_TYPE_MASK 0xf
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080048
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 */
Elliott Hughes9768d242014-11-21 22:50:20 -080069#if !defined(__linux__)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080070 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 namespace, 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, namespace);
106
107 if (err < 0) {
108 close(s);
109 return -1;
110 }
111
Paul Kocialkowskia7e2e762014-02-26 13:41:11 +0100112 if ((type & SOCK_TYPE_MASK) == SOCK_STREAM) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800113 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 /* !HAVE_WINSOCK */