/*************************************************************************** * Copyright (C) 2006 by Valentine Sinitsyn * * e_val@inbox.ru * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "cpufreqdconnection.h" #include #include #include #include #include #include #include #include /* Excerpt from cpufreqd_remote.h (cpufreqd-2.0.0) * * Copyright (C) 2005 Mattia Dongili * Hrvoje Zeba * * Format: * it is an uint32_t used as bitmask * * 31-16 15-0 * * * The response may be longer than a single line and is * terminated by the RESPONSE_END (see defines). */ #define CMD_SHIFT 16 #define ARG_MASK 0x0000ffff #define REMOTE_CMD(c) (c >> CMD_SHIFT) #define REMOTE_ARG(c) (c & ARG_MASK) #define MAKE_COMMAND(cmd, arg) ((cmd << CMD_SHIFT) | arg) #define INVALID_CMD 0xffffffff /** * This class encapsulates cpufreqd connection performed via Unix sockets *@author: Valentine Sinitsyn (Valentine.Sinitsyn@usu.ru) */ CPUFreqdConnection::CPUFreqdConnection(): m_fd(-1) { lookup(); } CPUFreqdConnection::~CPUFreqdConnection() { } bool CPUFreqdConnection::open() { struct sockaddr_un sck; // socket name is too long - it can't be copied to to sun_path if (m_socket.isEmpty() || m_socket.length() >= 108) return false; if (m_fd > 0) close(); if ((m_fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) return false; sck.sun_family = AF_UNIX; //It is guaranted that socket.ascii() is shorter than 108 bytes, but we want to be sure strncpy(sck.sun_path, m_socket.ascii(), 108); if (::connect(m_fd, (struct sockaddr *)&sck, sizeof(sck)) == -1) return false; return true; } ssize_t CPUFreqdConnection::read(void *buf, size_t size) { return ::read(m_fd, buf, size); } bool CPUFreqdConnection::write(uint32_t cmd, uint32_t arg) { uint32_t command; command = MAKE_COMMAND(cmd, arg); return (::write(m_fd, &command, sizeof(command)) == (int)sizeof(command)); } void CPUFreqdConnection::close() { ::close(m_fd); m_fd = -1; } bool CPUFreqdConnection::available() const { return !m_socket.isEmpty(); } bool CPUFreqdConnection::lookup() { QString candidate; QDir tmp("/tmp", "cpufreqd-*", QDir::Time, QDir::Dirs); if (tmp.count()) candidate = "/tmp/" + tmp[0] + "/cpufreqd"; if (candidate != m_socket) { m_socket = candidate; return true; } return false; }