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