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