55261c00af38d954ce2e9ea017d676b24ac90515
[iec.git] / src / type3_AndroidCloud / anbox-master / src / anbox / network / socket_helper.cpp
1 /*
2  * Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
3  *
4  * This program is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 3, as published
6  * by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranties of
10  * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11  * PURPOSE.  See the GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program.  If not, see <http://www.gnu.org/licenses/>.
15  *
16  */
17
18 #include "anbox/network/socket_helper.h"
19
20 #include <sys/stat.h>
21
22 #include <cstdio>
23 #include <fstream>
24 #include <iostream>
25
26 #include <boost/exception/errinfo_errno.hpp>
27
28 namespace anbox {
29 namespace network {
30 bool socket_file_exists(std::string const& filename) {
31   struct stat statbuf;
32   bool exists = (0 == stat(filename.c_str(), &statbuf));
33   /* Avoid removing non-socket files */
34   bool is_socket_type = (statbuf.st_mode & S_IFMT) == S_IFSOCK;
35   return exists && is_socket_type;
36 }
37
38 bool socket_exists(std::string const& socket_name) {
39   try {
40     std::string socket_path{socket_name};
41
42     /* In case an abstract socket name exists with the same name*/
43     socket_path.insert(std::begin(socket_path), ' ');
44
45     /* If the name is contained in this table, it signifies
46      * a process is truly using that socket connection
47      */
48     std::ifstream socket_names_file("/proc/net/unix");
49     std::string line;
50     while (std::getline(socket_names_file, line)) {
51       auto index = line.find(socket_path);
52       /* check for complete match */
53       if (index != std::string::npos &&
54           (index + socket_path.length()) == line.length()) {
55         return true;
56       }
57     }
58   } catch (...) {
59     /* Assume the socket exists */
60     return true;
61   }
62   return false;
63 }
64
65 std::string remove_socket_if_stale(std::string const& socket_name) {
66   if (socket_file_exists(socket_name) && !socket_exists(socket_name)) {
67     if (std::remove(socket_name.c_str()) != 0) {
68       BOOST_THROW_EXCEPTION(boost::enable_error_info(std::runtime_error(
69                                 "Failed removing stale socket file"))
70                             << boost::errinfo_errno(errno));
71     }
72   }
73   return socket_name;
74 }
75 }  // namespace network
76 }  // namespace anbox