bool NetlinkListener::onDataAvailable(SocketClient *cli) { int socket = cli->getSocket(); ssize_t count; uid_t uid = -1; bool require_group = true; if (mFormat == NETLINK_FORMAT_BINARY_UNICAST) { require_group = false; } count = TEMP_FAILURE_RETRY(uevent_kernel_recv(socket, mBuffer, sizeof(mBuffer), require_group, &uid)); if (count < 0) { if (uid > 0) LOG_EVENT_INT(65537, uid); SLOGE("recvmsg failed (%s)", strerror(errno)); return false; } NetlinkEvent *evt = new NetlinkEvent(); if (evt->decode(mBuffer, count, mFormat)) { onEvent(evt); } else if (mFormat != NETLINK_FORMAT_BINARY) { // Don't complain if parseBinaryNetlinkMessage returns false. That can // just mean that the buffer contained no messages we're interested in. SLOGE("Error decoding NetlinkEvent"); } delete evt; return true; }
/** * Like the above, but passes a uid_t in by pointer. In the event that this * fails due to a bad uid check, the uid_t will be set to the uid of the * socket's peer. * * If this method rejects a netlink message from outside the kernel, it * returns -1, sets errno to EIO, and sets "user" to the UID associated with the * message. If the peer UID cannot be determined, "user" is set to -1." */ ssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer, size_t length, uid_t *uid) { return uevent_kernel_recv(socket, buffer, length, true, uid); }