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