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