/* * Copyright 2006, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include #include #include "osi/include/socket_utils/socket_local.h" #include "osi/include/socket_utils/sockets.h" #define LISTEN_BACKLOG 4 /* Only the bottom bits are really the socket type; there are flags too. */ #define SOCK_TYPE_MASK 0xf /** * Binds a pre-created socket(AF_LOCAL) 's' to 'name' * returns 's' on success, -1 on fail * * Does not call listen() */ int osi_socket_local_server_bind(int s, const char* name, int namespaceId) { struct sockaddr_un addr; socklen_t alen; int n; int err; err = osi_socket_make_sockaddr_un(name, namespaceId, &addr, &alen); if (err < 0) { return -1; } /* basically: if this is a filesystem path, unlink first */ #if !defined(__linux__) if (1) { #else if (namespaceId == ANDROID_SOCKET_NAMESPACE_RESERVED || namespaceId == ANDROID_SOCKET_NAMESPACE_FILESYSTEM) { #endif /*ignore ENOENT*/ unlink(addr.sun_path); } n = 1; setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)); if (bind(s, (struct sockaddr*)&addr, alen) < 0) { return -1; } return s; } /** Open a server-side UNIX domain datagram socket in the Linux non-filesystem * namespace * * Returns fd on success, -1 on fail */ int osi_socket_local_server(const char* name, int namespaceId, int type) { int err; int s; s = socket(AF_LOCAL, type, 0); if (s < 0) return -1; err = osi_socket_local_server_bind(s, name, namespaceId); if (err < 0) { close(s); return -1; } if ((type & SOCK_TYPE_MASK) == SOCK_STREAM) { int ret; ret = listen(s, LISTEN_BACKLOG); if (ret < 0) { close(s); return -1; } } return s; }