1/* 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 */ 125