| 1262 | } |
| 1263 | |
| 1264 | bool cmdInterfaceCreateUnixSocket(const std::string& local_path) |
| 1265 | { |
| 1266 | if (local_path.empty()) |
| 1267 | { |
| 1268 | errlog("WZCMD FAILURE: Requested socket path is empty - cancelling\n"); |
| 1269 | return false; |
| 1270 | } |
| 1271 | int socket_type = SOCK_STREAM; |
| 1272 | #if defined(SOCK_CLOEXEC) |
| 1273 | socket_type |= SOCK_CLOEXEC; |
| 1274 | #endif |
| 1275 | int cmdSockFd = socket(AF_UNIX, socket_type, 0); |
| 1276 | if (cmdSockFd == -1) |
| 1277 | { |
| 1278 | int errno_cpy = errno; |
| 1279 | errlog("WZCMD FAILURE: socket() call failed with errno: %d\n", errno_cpy); |
| 1280 | return false; |
| 1281 | } |
| 1282 | sockBlockSIGPIPE(cmdSockFd, true); |
| 1283 | |
| 1284 | sockaddr_un addr; |
| 1285 | socklen_t sockLen = sizeof(addr); |
| 1286 | memset(&addr, 0, sizeof(struct sockaddr_un)); |
| 1287 | addr.sun_family = AF_UNIX; |
| 1288 | snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", local_path.c_str()); |
| 1289 | if (strlen(addr.sun_path) != local_path.length()) |
| 1290 | { |
| 1291 | errlog("WZCMD FAILURE: Requested socket path %s would be truncated to %s - cancelling\n", local_path.c_str(), addr.sun_path); |
| 1292 | return false; |
| 1293 | } |
| 1294 | #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__NetBSD__) |
| 1295 | addr.sun_len = SUN_LEN(&addr); |
| 1296 | sockLen = addr.sun_len; |
| 1297 | #endif |
| 1298 | |
| 1299 | unlink(addr.sun_path); |
| 1300 | |
| 1301 | if (bind(cmdSockFd, reinterpret_cast<sockaddr*>(&addr), sockLen) != 0) |
| 1302 | { |
| 1303 | int errno_cpy = errno; |
| 1304 | errlog("WZCMD FAILURE: bind() failed with errno: %d\n", errno_cpy); |
| 1305 | return false; |
| 1306 | } |
| 1307 | auto listenResult = listen(cmdSockFd, 1); |
| 1308 | if (listenResult != 0) |
| 1309 | { |
| 1310 | int errno_cpy = errno; |
| 1311 | errlog("WZCMD FAILURE: listen() failed with errno: %d\n", errno_cpy); |
| 1312 | return false; |
| 1313 | } |
| 1314 | struct sockaddr_storage ss; |
| 1315 | socklen_t slen = sizeof(ss); |
| 1316 | int cmdPeerFd = -1; |
| 1317 | do { |
| 1318 | #if defined(SOCK_CLOEXEC) |
| 1319 | cmdPeerFd = accept4(cmdSockFd, (struct sockaddr*)&ss, &slen, SOCK_CLOEXEC); |
| 1320 | #else |
| 1321 | cmdPeerFd = accept(cmdSockFd, (struct sockaddr*)&ss, &slen); |
no test coverage detected