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; }
bool NetlinkListener::onDataAvailable(SocketClient *cli) { int socket = cli->getSocket(); ssize_t count; uid_t uid = -1; count = TEMP_FAILURE_RETRY(uevent_kernel_multicast_uid_recv( socket, mBuffer, sizeof(mBuffer), &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)) { SLOGE("Error decoding NetlinkEvent"); } else { onEvent(evt); } delete evt; return true; }
virtual void Notify(const NetlinkEvent &aEvent) { // this will run on IO thread NetlinkEvent *event = const_cast<NetlinkEvent*>(&aEvent); const char *subsystem = event->getSubsystem(); // e.g. DEVPATH=/devices/platform/sec-battery/power_supply/battery const char *devpath = event->findParam("DEVPATH"); if (strcmp(subsystem, "power_supply") == 0 && strstr(devpath, "battery")) { // aEvent will be valid only in this method. NS_DispatchToMainThread(mUpdater); } }
bool NetlinkListener::onDataAvailable(SocketClient *cli) { int socket = cli->getSocket(); ssize_t count; char cred_msg[CMSG_SPACE(sizeof(struct ucred))]; struct sockaddr_nl snl; struct iovec iov = {mBuffer, sizeof(mBuffer)}; struct msghdr hdr = {&snl, sizeof(snl), &iov, 1, cred_msg, sizeof(cred_msg), 0}; if ((count = recvmsg(socket, &hdr, 0)) < 0) { SLOGE("recvmsg failed (%s)", strerror(errno)); return false; } if ((snl.nl_groups != 1) || (snl.nl_pid != 0)) { SLOGE("ignoring non-kernel netlink multicast message"); return false; } struct cmsghdr * cmsg = CMSG_FIRSTHDR(&hdr); if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { SLOGE("ignoring message with no sender credentials"); return false; } struct ucred * cred = (struct ucred *)CMSG_DATA(cmsg); if (cred->uid != 0) { SLOGE("ignoring message from non-root UID %d", cred->uid); return false; } NetlinkEvent *evt = new NetlinkEvent(); if (!evt->decode(mBuffer, count)) { SLOGE("Error decoding NetlinkEvent"); goto out; } onEvent(evt); out: delete evt; return true; }
bool NetlinkListener::onDataAvailable(SocketClient *cli) { int socket = cli->getSocket(); int count; if ((count = recv(socket, mBuffer, sizeof(mBuffer), 0)) < 0) { SLOGE("recv failed (%s)", strerror(errno)); return false; } NetlinkEvent *evt = new NetlinkEvent(); if (!evt->decode(mBuffer, count)) { SLOGE("Error decoding NetlinkEvent"); goto out; } onEvent(evt); out: delete evt; return true; }
void NetlinkPoller::OnFileCanReadWithoutBlocking(int fd) { MOZ_ASSERT(fd == mSocket.get()); while (true) { int ret = read(fd, mBuffer, kBuffsize); if (ret == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { return; } if (errno == EINTR) { continue; } } if (ret <= 0) { // fatal error on netlink socket which should not happen _exit(1); } NetlinkEvent netlinkEvent; netlinkEvent.decode(reinterpret_cast<char*>(mBuffer), ret); mUeventObserverList.Broadcast(netlinkEvent); } }