Repository: hyprwm/Hyprland
File: src/config/ConfigWatcher.cpp (C++)

Code before:
        const auto      CANONICAL  = std::filesystem::canonical(path, ec);
        const auto      IS_SYMLINK = std::filesystem::is_symlink(path, ec2);
        if (!ec && !ec2 && IS_SYMLINK) {
            m_watches.emplace_back(SInotifyWatch{
                .wd   = inotify_add_watch(m_inotifyFd.get(), CANONICAL.c_str(), IN_MODIFY),
                .file = path,
            });
        }
    }
}

void CConfigWatcher::setOnChange(const std::function<void(const SConfigWatchEvent&)>& fn) {
    m_watchCallback = fn;
}

void CConfigWatcher::onInotifyEvent() {
    constexpr size_t BUFFER_SIZE = sizeof(inotify_event) + NAME_MAX + 1;
    alignas(inotify_event) std::array<char, BUFFER_SIZE> buffer{};

    const ssize_t bytesRead = read(m_inotifyFd.get(), buffer.data(), buffer.size());
    if (bytesRead <= 0) {
        return;
    }

    for (size_t offset = 0; offset < static_cast<size_t>(bytesRead);) {
        const auto* ev = reinterpret_cast<const inotify_event*>(buffer.data() + offset);

        if (offset + sizeof(inotify_event) > static_cast<size_t>(bytesRead)) {
            Debug::log(ERR, "CConfigWatcher: malformed inotify event, truncated header");
            break;
        }

        if (offset + sizeof(inotify_event) + ev->len > static_cast<size_t>(bytesRead)) {
            Debug::log(ERR, "CConfigWatcher: malformed inotify event, truncated name field");
            break;
        }

        const auto WD = std::ranges::find_if(m_watches, [wd = ev->wd](const auto& e) { return e.wd == wd; });

        if (WD == m_watches.end()) {
            Debug::log(ERR, "CConfigWatcher: got an event for wd {} which we don't have?!", ev->wd);
        } else {
            m_watchCallback(SConfigWatchEvent{
                .file = WD->file,
            });
        }

        offset += sizeof(inotify_event) + ev->len;
    }
}


Review comment (suggestion):
we generally prefer C-style casts, `(inotify_event*)(buffer.data() ...)`

Code after:
        const auto      CANONICAL  = std::filesystem::canonical(path, ec);
        const auto      IS_SYMLINK = std::filesystem::is_symlink(path, ec2);
        if (!ec && !ec2 && IS_SYMLINK) {
            m_watches.emplace_back(SInotifyWatch{
                .wd   = inotify_add_watch(m_inotifyFd.get(), CANONICAL.c_str(), IN_MODIFY),
                .file = path,
            });
        }
    }
}

void CConfigWatcher::setOnChange(const std::function<void(const SConfigWatchEvent&)>& fn) {
    m_watchCallback = fn;
}

void CConfigWatcher::onInotifyEvent() {
    constexpr size_t                                     BUFFER_SIZE = sizeof(inotify_event) + NAME_MAX + 1;
    alignas(inotify_event) std::array<char, BUFFER_SIZE> buffer      = {};
    const ssize_t                                        bytesRead   = read(m_inotifyFd.get(), buffer.data(), buffer.size());
    if (bytesRead <= 0)
        return;

    for (size_t offset = 0; offset < (size_t)bytesRead;) {
        const auto* ev = (const inotify_event*)(buffer.data() + offset);

        if (offset + sizeof(inotify_event) > (size_t)bytesRead) {
            Debug::log(ERR, "CConfigWatcher: malformed inotify event, truncated header");
            break;
        }

        if (offset + sizeof(inotify_event) + ev->len > (size_t)(bytesRead)) {
            Debug::log(ERR, "CConfigWatcher: malformed inotify event, truncated name field");
            break;
        }

        const auto WD = std::ranges::find_if(m_watches, [wd = ev->wd](const auto& e) { return e.wd == wd; });

        if (WD == m_watches.end())
            Debug::log(ERR, "CConfigWatcher: got an event for wd {} which we don't have?!", ev->wd);
        else
            m_watchCallback(SConfigWatchEvent{
                .file = WD->file,
            });

        offset += sizeof(inotify_event) + ev->len;
    }
}