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