/* * OProfile User Interface * * Copyright (C) 2007 Nokia Corporation. All rights reserved. * * Author: Robert Bradford * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * * 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 St, Fifth Floor, Boston, MA * 02110-1301 USA * */ #include #include #include #include "util.h" int util_read_in_full (int fd, char *buf, size_t count) { size_t pos = 0; while (count-pos > 0) { int res = read (fd, &buf[pos], count-pos); if (res < 0) { return res; } if (res == 0) return 0; pos += res; } return pos; } int util_write_in_full (int fd, char *buf, size_t count) { size_t pos = 0; while (count - pos > 0) { int res = write (fd, &buf[pos], count-pos); if (res < 0) { return res; } if (res == 0) return 0; pos += res; } return pos; } int util_sendfile_in_full (int src_fd, int dest_fd, size_t count) { off_t offset = 0; while (count - offset > 0) { int res = sendfile (src_fd, dest_fd, &offset, count-offset); if (res < 0) { return res; } if (res == 0) return 0; } return count; } void util_resp_header_to_host (OpuiResponse *resp) { resp->length = ntohl (resp->length); } void util_resp_body_to_host (OpuiResponse *resp) { switch (resp->opcode) { case RESPONSE_OP_STATUS: { OpuiResponseStatus *status = (OpuiResponseStatus *)resp->payload; status->proto_version = ntohl (status->proto_version); status->profiling = ntohl (status->profiling); status->configured = ntohl (status->configured); } break; case RESPONSE_OP_FILESTAT: { OpuiResponseFileStat *stat = (OpuiResponseFileStat *)resp->payload; stat->mtime_h = ntohl (stat->mtime_h); stat->mtime_l = ntohl (stat->mtime_l); stat->size_h = ntohl (stat->size_h); stat->size_l = ntohl (stat->size_l); stat->mode_h = ntohl (stat->mode_h); stat->mode_l = ntohl (stat->mode_l); } break; default: break; } } void util_cmd_header_to_net (OpuiCommand *cmd) { cmd->length = htonl (cmd->length); } void util_cmd_header_to_host (OpuiCommand *cmd) { cmd->length = ntohl (cmd->length); } int util_cmd_header_read_in_full (int fd, OpuiCommand *cmd) { int res = util_read_in_full (fd, (char *)cmd, sizeof(OpuiCommand)); if (res > 0) cmd->length = ntohl (cmd->length); return res; } int util_resp_header_write_in_full (int fd, OpuiResponse *resp) { int ret; uint32_t value; size_t total; static uint32_t res_count = 0; /* write opcode & reserved[3] */ total = ret = util_write_in_full (fd, &resp->opcode, 4); if (ret > 0) { /* write length */ value = htonl (resp->length); ret = util_write_in_full (fd, (char *)&value, sizeof(uint32_t)); total += ret; } return (ret > 0) ? total : ret; } static int util_resp_body_write_in_full (int fd, OpuiResponse *resp) { int ret = 0; uint32_t value[6]; size_t total = 0; switch (resp->opcode) { case RESPONSE_OP_STATUS: { OpuiResponseStatus *status = (OpuiResponseStatus *)resp->payload; value[0] = htonl (status->proto_version); value[1] = htonl (status->profiling); value[2] = htonl (status->configured); total = ret = util_write_in_full (fd, (char *)value, 3*sizeof(uint32_t)); } break; case RESPONSE_OP_FILESTAT: { OpuiResponseFileStat *stat = (OpuiResponseFileStat *)resp->payload; value[0] = htonl (stat->mtime_h); value[1] = htonl (stat->mtime_l); value[2] = htonl (stat->size_h); value[3] = htonl (stat->size_l); value[4] = htonl (stat->mode_h); value[5] = htonl (stat->mode_l); total = ret = util_write_in_full (fd, (char *)value, 6*sizeof(uint32_t)); } break; default: ret = 1; total = 0; break; } if (ret > 0 && resp->length - total > 0) { ret = util_write_in_full (fd, &resp->payload[total], resp->length - total); total += ret; } return (ret > 0) ? total : ret; } int util_resp_write_in_full (int fd, OpuiResponse *resp) { int ret; size_t total; total = ret = util_resp_header_write_in_full (fd, resp); if (ret > 0 && resp->length > 0) { ret = util_resp_body_write_in_full (fd, resp); total += ret; } return (ret > 0) ? total : ret; }