1330449Seadler/*-
2330449Seadler * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3330449Seadler *
448905Srnordier * Copyright (c) 1999 Global Technology Associates, Inc.
548905Srnordier * All rights reserved.
648905Srnordier *
748905Srnordier * Redistribution and use in source and binary forms, with or without
848905Srnordier * modification, are permitted provided that the following conditions
948905Srnordier * are met:
1048905Srnordier * 1. Redistributions of source code must retain the above copyright
1148905Srnordier *    notice, this list of conditions and the following disclaimer.
1248905Srnordier * 2. Redistributions in binary form must reproduce the above copyright
1348905Srnordier *    notice, this list of conditions and the following disclaimer in the
1448905Srnordier *    documentation and/or other materials provided with the distribution.
1548905Srnordier *
1648905Srnordier * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND
1748905Srnordier * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1848905Srnordier * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1948905Srnordier * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
2048905Srnordier * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
2148905Srnordier * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
2248905Srnordier * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
2348905Srnordier * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2448905Srnordier * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
2548905Srnordier * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
2648905Srnordier * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2748905Srnordier *
2850479Speter * $FreeBSD: stable/11/usr.sbin/kgzip/xio.c 330449 2018-03-05 07:26:05Z eadler $
2948905Srnordier */
3048905Srnordier
3148905Srnordier#include <err.h>
3248905Srnordier#include <string.h>
3348905Srnordier#include <unistd.h>
3448905Srnordier
3548905Srnordier#include "kgzip.h"
3648905Srnordier
3748905Srnordier/*
3848905Srnordier * Close a file.
3948905Srnordier */
4048905Srnordiervoid
4148905Srnordierxclose(const struct iodesc *id)
4248905Srnordier{
4348905Srnordier    if (close(id->fd))
4448905Srnordier	err(1, "%s", id->fname);
4548905Srnordier}
4648905Srnordier
4748905Srnordier/*
4848905Srnordier * Copy bytes from one file to another.
4948905Srnordier */
5048905Srnordiervoid
5148905Srnordierxcopy(const struct iodesc * idi, const struct iodesc * ido,
5248905Srnordier      size_t nbyte, off_t offset)
5348905Srnordier{
5448905Srnordier    char buf[8192];
5548905Srnordier    size_t n;
5648905Srnordier
5748905Srnordier    while (nbyte) {
5848905Srnordier	if ((n = sizeof(buf)) > nbyte)
5948905Srnordier	    n = nbyte;
6048905Srnordier	if (xread(idi, buf, n, offset) != n)
6148905Srnordier	    errx(1, "%s: Short read", idi->fname);
6248905Srnordier	xwrite(ido, buf, n);
6348905Srnordier	nbyte -= n;
6448905Srnordier	offset = -1;
6548905Srnordier    }
6648905Srnordier}
6748905Srnordier
6848905Srnordier/*
6948905Srnordier * Write binary zeroes to a file.
7048905Srnordier */
7148905Srnordiervoid
7248905Srnordierxzero(const struct iodesc * id, size_t nbyte)
7348905Srnordier{
7448905Srnordier    char buf[8192];
7548905Srnordier    size_t n;
7648905Srnordier
7748905Srnordier    memset(buf, 0, sizeof(buf));
7848905Srnordier    while (nbyte) {
7948905Srnordier	if ((n = sizeof(buf)) > nbyte)
8048905Srnordier	    n = nbyte;
8148905Srnordier	xwrite(id, buf, n);
8248905Srnordier	nbyte -= n;
8348905Srnordier    }
8448905Srnordier}
8548905Srnordier
8648905Srnordier/*
8748905Srnordier * Read from a file.
8848905Srnordier */
8948905Srnordiersize_t
9048905Srnordierxread(const struct iodesc * id, void *buf, size_t nbyte, off_t offset)
9148905Srnordier{
9248905Srnordier    ssize_t n;
9348905Srnordier
9448905Srnordier    if (offset != -1 && lseek(id->fd, offset, SEEK_SET) != offset)
9548905Srnordier	err(1, "%s", id->fname);
9648905Srnordier    if ((n = read(id->fd, buf, nbyte)) == -1)
9748905Srnordier	err(1, "%s", id->fname);
9848905Srnordier    return (size_t)n;
9948905Srnordier}
10048905Srnordier
10148905Srnordier/*
10248905Srnordier * Write to a file.
10348905Srnordier */
10448905Srnordiervoid
10548905Srnordierxwrite(const struct iodesc * id, const void *buf, size_t nbyte)
10648905Srnordier{
10748905Srnordier    ssize_t n;
10848905Srnordier
10948905Srnordier    if ((n = write(id->fd, buf, nbyte)) == -1)
11048905Srnordier	err(1, "%s", id->fname);
11148905Srnordier    if ((size_t)n != nbyte)
11248905Srnordier	errx(1, "%s: Short write", id->fname);
11348905Srnordier}
11448905Srnordier
11548905Srnordier/*
11648905Srnordier * Reposition within a file.
11748905Srnordier */
11848905Srnordiervoid
11948905Srnordierxseek(const struct iodesc *id, off_t offset)
12048905Srnordier{
12148905Srnordier    if (lseek(id->fd, offset, SEEK_SET) != offset)
12248905Srnordier	err(1, "%s", id->fname);
12348905Srnordier}
124