1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <cutils/sockets.h> 18 19 #include <errno.h> 20 #include <stddef.h> 21 #include <stdlib.h> 22 #include <string.h> 23 #include <unistd.h> 24 25 #if defined(_WIN32) 26 27 int socket_local_client(const char *name, int namespaceId, int type) 28 { 29 errno = ENOSYS; 30 return -1; 31 } 32 33 #else /* !_WIN32 */ 34 35 #include <sys/socket.h> 36 #include <sys/un.h> 37 #include <sys/select.h> 38 #include <sys/types.h> 39 40 #include "socket_local_unix.h" 41 42 #define LISTEN_BACKLOG 4 43 44 /* Documented in header file. */ 45 int socket_make_sockaddr_un(const char *name, int namespaceId, 46 struct sockaddr_un *p_addr, socklen_t *alen) 47 { 48 memset (p_addr, 0, sizeof (*p_addr)); 49 size_t namelen; 50 51 switch (namespaceId) { 52 case ANDROID_SOCKET_NAMESPACE_ABSTRACT: 53 #if defined(__linux__) 54 namelen = strlen(name); 55 56 // Test with length +1 for the *initial* '\0'. 57 if ((namelen + 1) > sizeof(p_addr->sun_path)) { 58 goto error; 59 } 60 61 /* 62 * Note: The path in this case is *not* supposed to be 63 * '\0'-terminated. ("man 7 unix" for the gory details.) 64 */ 65 66 p_addr->sun_path[0] = 0; 67 memcpy(p_addr->sun_path + 1, name, namelen); 68 #else 69 /* this OS doesn't have the Linux abstract namespace */ 70 71 namelen = strlen(name) + strlen(FILESYSTEM_SOCKET_PREFIX); 72 /* unix_path_max appears to be missing on linux */ 73 if (namelen > sizeof(*p_addr) 74 - offsetof(struct sockaddr_un, sun_path) - 1) { 75 goto error; 76 } 77 78 strcpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX); 79 strcat(p_addr->sun_path, name); 80 #endif 81 break; 82 83 case ANDROID_SOCKET_NAMESPACE_RESERVED: 84 namelen = strlen(name) + strlen(ANDROID_RESERVED_SOCKET_PREFIX); 85 /* unix_path_max appears to be missing on linux */ 86 if (namelen > sizeof(*p_addr) 87 - offsetof(struct sockaddr_un, sun_path) - 1) { 88 goto error; 89 } 90 91 strcpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX); 92 strcat(p_addr->sun_path, name); 93 break; 94 95 case ANDROID_SOCKET_NAMESPACE_FILESYSTEM: 96 namelen = strlen(name); 97 /* unix_path_max appears to be missing on linux */ 98 if (namelen > sizeof(*p_addr) 99 - offsetof(struct sockaddr_un, sun_path) - 1) { 100 goto error; 101 } 102 103 strcpy(p_addr->sun_path, name); 104 break; 105 default: 106 // invalid namespace id 107 return -1; 108 } 109 110 p_addr->sun_family = AF_LOCAL; 111 *alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1; 112 return 0; 113 error: 114 return -1; 115 } 116 117 /** 118 * connect to peer named "name" on fd 119 * returns same fd or -1 on error. 120 * fd is not closed on error. that's your job. 121 * 122 * Used by AndroidSocketImpl 123 */ 124 int socket_local_client_connect(int fd, const char* name, int namespaceId, int /*type*/) { 125 struct sockaddr_un addr; 126 socklen_t alen; 127 int err; 128 129 err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen); 130 131 if (err < 0) { 132 goto error; 133 } 134 135 if(connect(fd, (struct sockaddr *) &addr, alen) < 0) { 136 goto error; 137 } 138 139 return fd; 140 141 error: 142 return -1; 143 } 144 145 /** 146 * connect to peer named "name" 147 * returns fd or -1 on error 148 */ 149 int socket_local_client(const char *name, int namespaceId, int type) 150 { 151 int s; 152 153 s = socket(AF_LOCAL, type, 0); 154 if(s < 0) return -1; 155 156 if ( 0 > socket_local_client_connect(s, name, namespaceId, type)) { 157 close(s); 158 return -1; 159 } 160 161 return s; 162 } 163 164 #endif /* !_WIN32 */ 165