From patchwork Thu Jul 30 10:52:22 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 502063 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id D2ECF140D26 for ; Thu, 30 Jul 2015 20:52:35 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755253AbbG3Kwd (ORCPT ); Thu, 30 Jul 2015 06:52:33 -0400 Received: from foss.arm.com ([217.140.101.70]:40013 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755158AbbG3Kwb (ORCPT ); Thu, 30 Jul 2015 06:52:31 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 3868075; Thu, 30 Jul 2015 03:52:39 -0700 (PDT) Received: from e104803-lin.lan (unknown [10.1.203.153]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 4C3A73F21A; Thu, 30 Jul 2015 03:52:30 -0700 (PDT) From: Andre Przywara To: will.deacon@arm.com, kvm@vger.kernel.org Cc: marc.zyngier@arm.com, kvmarm@lists.cs.columbia.edu, kvm-ppc@vger.kernel.org Subject: [PATCH 05/14] kvmtool: introduce pseek Date: Thu, 30 Jul 2015 11:52:22 +0100 Message-Id: <1438253551-2378-6-git-send-email-andre.przywara@arm.com> X-Mailer: git-send-email 2.3.5 In-Reply-To: <1438253551-2378-1-git-send-email-andre.przywara@arm.com> References: <1438253551-2378-1-git-send-email-andre.przywara@arm.com> Sender: kvm-ppc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm-ppc@vger.kernel.org pseek is a wrapper around lseek(2), which can cope with non-seekable file descriptors. The limitation is of course that we only can seek forward and only relative to the current position (hence the whence parameter is missing). In this case pseek will do dummy reads to skip over the requested amount of data. Signed-off-by: Andre Przywara --- include/kvm/read-write.h | 2 ++ util/read-write.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/include/kvm/read-write.h b/include/kvm/read-write.h index 67571f9..87eb167 100644 --- a/include/kvm/read-write.h +++ b/include/kvm/read-write.h @@ -40,4 +40,6 @@ int aio_pwritev(io_context_t ctx, struct iocb *iocb, int fd, const struct iovec off_t offset, int ev, void *param); #endif +int pseek(int fd, off_t offset); + #endif /* KVM_READ_WRITE_H */ diff --git a/util/read-write.c b/util/read-write.c index 44709df..401afd3 100644 --- a/util/read-write.c +++ b/util/read-write.c @@ -352,3 +352,43 @@ restart: return ret; } #endif + +/* + * A wrapper around lseek(fd, offset, SEEK_CUR), which can cope with being + * used on non-seekable file descriptors like pipes or sockets. If offset + * is positive, it will skip over the requested number of bytes by reading + * them into a dummy buffer. + */ +#define BUF_SIZE 256 +int pseek(int fd, off_t offset) +{ + off_t ret; + int to_read; + char skip_buf[BUF_SIZE]; + + ret = lseek(fd, offset, SEEK_CUR); + if (ret != (off_t)-1) + return 0; + + if (errno != ESPIPE) + return -1; + + if (offset < 0) { + errno = EINVAL; + return -1; + } + + while (offset > 0) { + to_read = offset > BUF_SIZE ? BUF_SIZE : offset; + ret = read(fd, skip_buf, to_read); + if (ret == -1 && errno != EINTR) + return -1; + if (ret == 0) { + errno = EINVAL; + return -1; + } + offset -= ret; + } + + return 0; +}