/* * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved * * 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. */ // libs/cutils/socket_local_server.c #include "sockets.h" #include #include #include #include #include #ifdef HAVE_WINSOCK int socket_local_server(const char *name, int namespaceId, int type) { errno = ENOSYS; return -1; } #else /* !HAVE_WINSOCK */ #include #include #include #include #include #include "socket_local.h" #define LISTEN_BACKLOG 4 /** * Binds a pre-created socket(AF_LOCAL) 's' to 'name' * returns 's' on success, -1 on fail * * Does not call listen() */ int socket_local_server_bind(int s, const char *name, int namespaceId) { struct sockaddr_un addr; socklen_t alen; int n; int err; err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen); if (err < 0) { return -1; } /* basically: if this is a filesystem path, unlink first */ #ifndef HAVE_LINUX_LOCAL_SOCKET_NAMESPACE if (1) { #else if (namespaceId == ANDROID_SOCKET_NAMESPACE_RESERVED || namespaceId == ANDROID_SOCKET_NAMESPACE_FILESYSTEM) { #endif /*ignore ENOENT*/ unlink(addr.sun_path); } n = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) < 0 ) { return -1; } 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 socket_local_server(const char *name, int namespace, int type) { int err; int s; s = socket(AF_LOCAL, type, 0); if (s < 0) return -1; err = socket_local_server_bind(s, name, namespace); if (err < 0) { close(s); return -1; } if (type == SOCK_STREAM) { int ret; ret = listen(s, LISTEN_BACKLOG); if (ret < 0) { close(s); return -1; } } return s; } #endif /* !HAVE_WINSOCK */