Introduction
Introduction Statistics Contact Development Disclaimer Help
util.c - blind - suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log
Files
Refs
README
LICENSE
---
util.c (5434B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include "common.h"
3
4 char *argv0;
5
6 void
7 weprintf(const char *fmt, ...)
8 {
9 char end;
10 va_list ap;
11 va_start(ap, fmt);
12
13 if (argv0 && strncmp(fmt, "usage", strlen("usage")))
14 fprintf(stderr, "%s: ", argv0);
15
16 vfprintf(stderr, fmt, ap);
17
18 end = *fmt ? strchr(fmt, '\0')[-1] : '\n';
19 if (end == ':') {
20 fputc(' ', stderr);
21 perror(NULL);
22 } else if (end != '\n') {
23 fputc('\n', stderr);
24 }
25
26 va_end(ap);
27 }
28
29
30 int
31 tollu(const char *s, unsigned long long int min, unsigned long long int …
32 {
33 char *end;
34 errno = 0;
35 if (*s == '-') {
36 errno = ERANGE;
37 return -1;
38 }
39 if (!isdigit(s[*s == 'x' || *s == 'X' || *s == '#']) ||
40 (*s == '0' && s[1] && !isdigit(s[1 + (*s == 'x' || *s == 'o'…
41 errno = EINVAL;
42 return -1;
43 }
44 if (tolower(*s) == 'x' || *s == '#')
45 *out = strtoull(s + 1, &end, 16);
46 else if (*s == '0' && tolower(s[1]) == 'x')
47 *out = strtoull(s + 2, &end, 16);
48 else if (*s == '0' && tolower(s[1]) == 'o')
49 *out = strtoull(s + 2, &end, 8);
50 else if (*s == '0' && tolower(s[1]) == 'b')
51 *out = strtoull(s + 2, &end, 2);
52 else
53 *out = strtoull(s, &end, 10);
54 if (errno)
55 return -1;
56 if (*end) {
57 errno = EINVAL;
58 return -1;
59 }
60 if (*out < min || *out > max) {
61 errno = ERANGE;
62 return -1;
63 }
64 return 0;
65 }
66
67 int
68 tolli(const char *s, long long int min, long long int max, long long int…
69 {
70 int sign = 1;
71 unsigned long long int inter;
72 errno = 0;
73 if (*s == '-') {
74 s++;
75 sign = -1;
76 }
77 if (tollu(s, 0, ULLONG_MAX, &inter))
78 return -1;
79 if (sign > 0) {
80 if (max < 0 || inter > (unsigned long long int)max)
81 goto erange;
82 *out = (long long int)inter;
83 if (*out < min)
84 goto erange;
85 } else {
86 #if LLONG_MIN == -LLONG_MAX
87 if (inter > -LLONG_MIN)
88 goto erange;
89 #else
90 if (inter > (unsigned long long int)LLONG_MAX + 1ULL)
91 goto erange;
92 #endif
93 *out = -(long long int)inter;
94 if (*out < min || *out > max)
95 goto erange;
96 }
97 return 0;
98
99 erange:
100 errno = ERANGE;
101 return -1;
102 }
103
104
105 int
106 writeall(int fd, const void *buf, size_t n)
107 {
108 const char *buffer = buf;
109 ssize_t r;
110 while (n) {
111 r = write(fd, buffer, n);
112 if (r < 0)
113 return -1;
114 buffer += (size_t)r;
115 n -= (size_t)r;
116 }
117 return 0;
118 }
119
120 ssize_t
121 readall(int fd, void *buf, size_t n)
122 {
123 char *buffer = buf;
124 size_t ptr = 0;
125 ssize_t r;
126 for (;;) {
127 r = read(fd, buffer + ptr, n - ptr);
128 if (r < 0)
129 return -1;
130 if (r == 0)
131 break;
132 ptr += (size_t)r;
133 }
134 return (ssize_t)ptr;
135 }
136
137 int
138 pwriteall(int fd, const void *buf, size_t n, off_t ptr)
139 {
140 const char *buffer = buf;
141 ssize_t r;
142 while (n) {
143 r = pwrite(fd, buffer, n, (off_t)ptr);
144 if (r < 0)
145 return -1;
146 buffer += (size_t)r;
147 n -= (size_t)r;
148 ptr += (off_t)r;
149 }
150 return 0;
151 }
152
153 int
154 writezeroes(int fd, const void *buf, size_t bufsize, size_t n)
155 {
156 size_t p, m;
157 for (p = 0; p < n; p += m) {
158 m = MIN(bufsize, n - p);
159 if (writeall(fd, buf, m))
160 return -1;
161 }
162 return 0;
163 }
164
165 int
166 getfile(int fd, void *buffer, size_t *restrict ptr, size_t *restrict siz…
167 {
168 char *restrict *restrict buf = buffer;
169 void *new;
170 size_t new_size;
171 ssize_t r;
172
173 for (;;) {
174 if (*ptr == *size) {
175 new_size = *size ? *size << 1 : BUFSIZ;
176 if (!(new = realloc(*buf, new_size))) {
177 errno = ENOMEM;
178 return -1;
179 }
180 *buf = new;
181 *size = new_size;
182 }
183 r = read(fd, *buf + *ptr, *size - *ptr);
184 if (r <= 0) {
185 if (r)
186 return -1;
187 break;
188 }
189 *ptr += (size_t)r;
190 }
191
192 return 0;
193 }
194
195
196 static inline pid_t
197 enfork(int status)
198 {
199 pid_t pid = fork();
200 if (pid == -1)
201 enprintf(status, "fork:");
202 return pid;
203 }
204
205
206 /* If <() is used in Bash (possibily other shells), that process becomes
207 * child of the process for each <() is used. Therefore, we cannot simply
208 * wait until the last child has been reaped, or even the expected number
209 * of children has been reaped, we must instead remember the PID of each
210 * child we created and wait for all of them to be reaped. { */
211
212 int
213 enfork_jobs(int status, size_t *start, size_t *end, size_t jobs, pid_t *…
214 {
215 size_t j, s = *start, n = *end - *start;
216 pid_t pid;
217 if (jobs < 2) {
218 *pids = NULL;
219 return 1;
220 }
221 *end = n / jobs + s;
222 *pids = enmalloc2(status, jobs, sizeof(**pids));
223 for (j = 1; j < jobs; j++) {
224 pid = enfork(status);
225 if (!pid) {
226 pdeath(SIGKILL);
227 *start = n * (j + 0) / jobs + s;
228 *end = n * (j + 1) / jobs + s;
229 return 0;
230 } else {
231 (*pids)[j - 1] = pid;
232 }
233 }
234 (*pids)[jobs - 1] = -1;
235 return 1;
236 }
237
238 void
239 enjoin_jobs(int status, int is_master, pid_t *pids)
240 {
241 int stat;
242 size_t i;
243 if (!is_master)
244 free(pids), exit(0);
245 if (!pids)
246 return;
247 for (i = 0; pids[i] != -1; i++) {
248 if (waitpid(pids[i], &stat, 0) == -1)
249 enprintf(status, "waitpid:");
250 if (stat)
251 exit(WIFEXITED(stat) ? WEXITSTATUS(stat) : WTERM…
252 }
253 free(pids);
254 }
255
256 /* } */
257
258
259 int
260 xenopen(int status, const char *path, int flags, int mode, ...)
261 {
262 int fd;
263 if (!strncmp(path, "/dev/fd/", STRLEN("/dev/fd/"))) {
264 if (!toi(path + STRLEN("/dev/fd/"), 0, INT_MAX, &fd))
265 return fd;
266 } else if (!strcmp(path, "/dev/stdin")) {
267 return STDIN_FILENO;
268 } else if (!strcmp(path, "/dev/stdout")) {
269 return STDOUT_FILENO;
270 } else if (!strcmp(path, "/dev/stderr")) {
271 return STDERR_FILENO;
272 } else if (!strcmp(path, "-")) {
273 if ((flags & O_ACCMODE) == O_WRONLY)
274 return STDOUT_FILENO;
275 else
276 return STDIN_FILENO;
277 }
278 fd = open(path, flags, mode);
279 if (fd < 0)
280 enprintf(status, "open %s:", path);
281 return fd;
282 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.