in watchman/listener.cpp [73:164]
static FileDescriptor get_listener_unix_domain_socket(const char* path) {
#ifndef _WIN32
mode_t perms = cfg_get_perms(
"sock_access", true /* write bits */, false /* execute bits */);
#endif
FileDescriptor listener_fd;
#ifdef __APPLE__
listener_fd = w_get_listener_socket_from_launchd();
if (listener_fd) {
logf(ERR, "Using socket from launchd as listening socket\n");
return listener_fd;
}
#endif
struct sockaddr_un un {};
if (strlen(path) >= sizeof(un.sun_path) - 1) {
logf(ERR, "{}: path is too long\n", path);
return FileDescriptor();
}
listener_fd = FileDescriptor(
::socket(PF_LOCAL, SOCK_STREAM, 0),
"socket",
FileDescriptor::FDType::Socket);
un.sun_family = PF_LOCAL;
memcpy(un.sun_path, path, strlen(path) + 1);
(void)unlink(path);
if (::bind(listener_fd.system_handle(), (struct sockaddr*)&un, sizeof(un)) !=
0) {
logf(ERR, "bind({}): {}\n", path, folly::errnoStr(errno));
return FileDescriptor();
}
#ifndef _WIN32
// The permissions in the containing directory should be correct, so this
// should be correct as well. But set the permissions in any case.
if (chmod(path, perms) == -1) {
logf(ERR, "chmod({}, {:o}): {}", path, perms, folly::errnoStr(errno));
return FileDescriptor();
}
// Double-check that the socket has the right permissions. This can happen
// when the containing directory was created in a previous run, with a group
// the user is no longer in.
struct stat st;
if (lstat(path, &st) == -1) {
watchman::log(
watchman::ERR, "lstat(", path, "): ", folly::errnoStr(errno), "\n");
return FileDescriptor();
}
// This is for testing only
// (test_sock_perms.py:test_user_previously_in_sock_group). Do not document.
const char* sock_group_name = cfg_get_string("__sock_file_group", nullptr);
if (!sock_group_name) {
sock_group_name = cfg_get_string("sock_group", nullptr);
}
if (sock_group_name) {
const struct group* sock_group = w_get_group(sock_group_name);
if (!sock_group) {
return FileDescriptor();
}
if (st.st_gid != sock_group->gr_gid) {
watchman::log(
watchman::ERR,
"for socket '",
path,
"', gid ",
st.st_gid,
" doesn't match expected gid ",
sock_group->gr_gid,
" (group name ",
sock_group_name,
"). Ensure that you are still a member of group ",
sock_group_name,
".\n");
return FileDescriptor();
}
}
#endif
if (::listen(listener_fd.system_handle(), 200) != 0) {
logf(ERR, "listen({}): {}\n", path, folly::errnoStr(errno));
return FileDescriptor();
}
return listener_fd;
}