1 /* $OpenBSD: misc.c,v 1.1 2001/08/19 13:05:57 deraadt Exp $ */
2
3 /*
4 * Miscellaneous syscall wrappers. See misc.h for the descriptions.
5 */
6
7 #include <unistd.h>
8 #include <fcntl.h>
9 #include <string.h>
10 #include <errno.h>
11 #include <sys/time.h>
12 #include <sys/file.h>
13
14 #include "params.h"
15
sleep_select(int sec,int usec)16 int sleep_select(int sec, int usec)
17 {
18 struct timeval timeout;
19
20 timeout.tv_sec = sec;
21 timeout.tv_usec = usec;
22
23 return select(0, NULL, NULL, NULL, &timeout);
24 }
25
lock_fd(int fd,int shared)26 int lock_fd(int fd, int shared)
27 {
28 #if LOCK_FCNTL
29 struct flock l;
30
31 memset(&l, 0, sizeof(l));
32 l.l_whence = SEEK_SET;
33 l.l_type = shared ? F_RDLCK : F_WRLCK;
34 while (fcntl(fd, F_SETLKW, &l)) {
35 if (errno != EBUSY) return -1;
36 sleep_select(1, 0);
37 }
38 #endif
39
40 #if LOCK_FLOCK
41 while (flock(fd, shared ? LOCK_SH : LOCK_EX)) {
42 if (errno != EBUSY) return -1;
43 sleep_select(1, 0);
44 }
45 #endif
46
47 return 0;
48 }
49
unlock_fd(int fd)50 int unlock_fd(int fd)
51 {
52 #if LOCK_FCNTL
53 struct flock l;
54
55 memset(&l, 0, sizeof(l));
56 l.l_whence = SEEK_SET;
57 l.l_type = F_UNLCK;
58 if (fcntl(fd, F_SETLK, &l)) return -1;
59 #endif
60
61 #if LOCK_FLOCK
62 if (flock(fd, LOCK_UN)) return -1;
63 #endif
64
65 return 0;
66 }
67
write_loop(int fd,char * buffer,int count)68 int write_loop(int fd, char *buffer, int count)
69 {
70 int offset, block;
71
72 offset = 0;
73 while (count > 0) {
74 block = write(fd, &buffer[offset], count);
75
76 /* If any write(2) fails, we consider that the entire write_loop() has
77 * failed to do its job. We don't even ignore EINTR here. We also don't
78 * retry when a write(2) returns zero, as we could start eating up the
79 * CPU if we did. */
80 if (block < 0) return block;
81 if (!block) return offset;
82
83 offset += block;
84 count -= block;
85 }
86
87 /* Should be equal to the requested size, unless our kernel got crazy. */
88 return offset;
89 }
90