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 28 int 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 */ 53 int 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 95 int 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