tsort: replace with openbsd version
[unleashed.git] / contrib / libjeffpc / io.c
blob2e1e85eb26239198117b78f197c87d517015940f
1 /*
2 * Copyright (c) 2011-2016 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
23 #include <unistd.h>
24 #include <errno.h>
25 #include <stdlib.h>
26 #include <stdbool.h>
27 #include <stdio.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31 #include <string.h>
32 #include <sys/uio.h>
34 #include <jeffpc/io.h>
35 #include <jeffpc/error.h>
37 static inline ssize_t rw(int fd, void *buf, size_t nbyte, off_t off,
38 const bool useoff, const bool readfxns)
40 char *ptr = buf;
41 size_t total;
42 ssize_t ret;
44 total = 0;
46 while (nbyte) {
47 if (readfxns) {
48 if (useoff)
49 ret = pread(fd, ptr, nbyte, off);
50 else
51 ret = read(fd, ptr, nbyte);
52 } else {
53 if (useoff)
54 ret = pwrite(fd, ptr, nbyte, off);
55 else
56 ret = write(fd, ptr, nbyte);
59 if (ret < 0)
60 return -errno;
62 if (ret == 0)
63 return -EPIPE;
65 nbyte -= ret;
66 total += ret;
67 ptr += ret;
68 off += ret;
71 return 0;
74 int xread(int fd, void *buf, size_t nbyte)
76 return rw(fd, buf, nbyte, 0, false, true);
79 int xpread(int fd, void *buf, size_t nbyte, off_t off)
81 return rw(fd, buf, nbyte, off, true, true);
84 int xwrite(int fd, const void *buf, size_t nbyte)
86 return rw(fd, (void *) buf, nbyte, 0, false, false);
89 int xpwrite(int fd, const void *buf, size_t nbyte, off_t off)
91 return rw(fd, (void *) buf, nbyte, off, true, false);
94 char *read_file_common(int dirfd, const char *fname, struct stat *sb)
96 struct stat statbuf;
97 char *out;
98 int ret;
99 int fd;
101 fd = xopenat(dirfd, fname, O_RDONLY, 0);
102 if (fd < 0) {
103 out = ERR_PTR(fd);
104 goto err;
107 ret = fstat(fd, &statbuf);
108 if (ret == -1) {
109 out = ERR_PTR(-errno);
110 goto err_close;
113 out = malloc(statbuf.st_size + 1);
114 if (!out) {
115 out = ERR_PTR(-ENOMEM);
116 goto err_close;
119 ret = xread(fd, out, statbuf.st_size);
120 if (ret) {
121 free(out);
122 out = ERR_PTR(ret);
123 } else {
124 out[statbuf.st_size] = '\0';
126 if (sb)
127 *sb = statbuf;
130 err_close:
131 xclose(fd);
133 err:
134 return out;
137 int write_file(const char *fname, const char *data, size_t len)
139 int ret;
140 int fd;
142 fd = xopen(fname, O_WRONLY | O_CREAT | O_EXCL,
143 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
144 if (fd < 0)
145 return fd;
147 ret = xwrite(fd, data, len);
149 xclose(fd);
151 return ret;