blob: 4971b1b1cc516c9b96ad83a45a31256c8cbc70fe [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
46
47/**
48 * Binds a pre-created socket(AF_LOCAL) 's' to 'name'
49 * returns 's' on success, -1 on fail
50 *
51 * Does not call listen()
52 */
53int socket_local_server_bind(int s, const char *name, int namespaceId)
54{
55 struct sockaddr_un addr;
56 socklen_t alen;
57 int n;
58 int err;
59
60 err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen);
61
62 if (err < 0) {
63 return -1;
64 }
65
66 /* basically: if this is a filesystem path, unlink first */
67#ifndef HAVE_LINUX_LOCAL_SOCKET_NAMESPACE
68 if (1) {
69#else
70 if (namespaceId == ANDROID_SOCKET_NAMESPACE_RESERVED
71 || namespaceId == ANDROID_SOCKET_NAMESPACE_FILESYSTEM) {
72#endif
73 /*ignore ENOENT*/
74 unlink(addr.sun_path);
75 }
76
77 n = 1;
78 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
79
80 if(bind(s, (struct sockaddr *) &addr, alen) < 0) {
81 return -1;
82 }
83
84 return s;
85
86}
87
88
89/** Open a server-side UNIX domain datagram socket in the Linux non-filesystem
90 * namespace
91 *
92 * Returns fd on success, -1 on fail
93 */
94
95int socket_local_server(const char *name, int namespace, int type)
96{
97 int err;
98 int s;
99
100 s = socket(AF_LOCAL, type, 0);
101 if (s < 0) return -1;
102
103 err = socket_local_server_bind(s, name, namespace);
104
105 if (err < 0) {
106 close(s);
107 return -1;
108 }
109
110 if (type == SOCK_STREAM) {
111 int ret;
112
113 ret = listen(s, LISTEN_BACKLOG);
114
115 if (ret < 0) {
116 close(s);
117 return -1;
118 }
119 }
120
121 return s;
122}
123
124#endif /* !HAVE_WINSOCK */