source: MondoRescue/branches/3.0/mindi-busybox/runit/runit_lib.c@ 3085

Last change on this file since 3085 was 1765, checked in by Bruno Cornec, 16 years ago

Update to busybox 1.7.2

  • Property svn:eol-style set to native
File size: 5.8 KB
Line 
1/*
2Copyright (c) 2001-2006, Gerrit Pape
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7
8 1. Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28/* Busyboxed by Denis Vlasenko <vda.linux@googlemail.com> */
29/* Collected into one file from runit's many tiny files */
30/* TODO: review, eliminate unneeded stuff, move good stuff to libbb */
31
32#include <sys/poll.h>
33#include <sys/file.h>
34#include "libbb.h"
35#include "runit_lib.h"
36
37unsigned byte_chr(char *s,unsigned n,int c)
38{
39 char ch;
40 char *t;
41
42 ch = c;
43 t = s;
44 for (;;) {
45 if (!n) break;
46 if (*t == ch) break;
47 ++t;
48 --n;
49 }
50 return t - s;
51}
52
53int coe(int fd)
54{
55 return fcntl(fd, F_SETFD, FD_CLOEXEC);
56}
57
58#ifdef UNUSED
59static /* as it isn't used anywhere else */
60void tai_pack(char *s, const struct tai *t)
61{
62 uint64_t x;
63
64 x = t->x;
65 s[7] = x & 255; x >>= 8;
66 s[6] = x & 255; x >>= 8;
67 s[5] = x & 255; x >>= 8;
68 s[4] = x & 255; x >>= 8;
69 s[3] = x & 255; x >>= 8;
70 s[2] = x & 255; x >>= 8;
71 s[1] = x & 255; x >>= 8;
72 s[0] = x;
73}
74
75void tai_unpack(const char *s,struct tai *t)
76{
77 uint64_t x;
78
79 x = (unsigned char) s[0];
80 x <<= 8; x += (unsigned char) s[1];
81 x <<= 8; x += (unsigned char) s[2];
82 x <<= 8; x += (unsigned char) s[3];
83 x <<= 8; x += (unsigned char) s[4];
84 x <<= 8; x += (unsigned char) s[5];
85 x <<= 8; x += (unsigned char) s[6];
86 x <<= 8; x += (unsigned char) s[7];
87 t->x = x;
88}
89
90
91void taia_add(struct taia *t,const struct taia *u,const struct taia *v)
92{
93 t->sec.x = u->sec.x + v->sec.x;
94 t->nano = u->nano + v->nano;
95 t->atto = u->atto + v->atto;
96 if (t->atto > 999999999UL) {
97 t->atto -= 1000000000UL;
98 ++t->nano;
99 }
100 if (t->nano > 999999999UL) {
101 t->nano -= 1000000000UL;
102 ++t->sec.x;
103 }
104}
105
106int taia_less(const struct taia *t, const struct taia *u)
107{
108 if (t->sec.x < u->sec.x) return 1;
109 if (t->sec.x > u->sec.x) return 0;
110 if (t->nano < u->nano) return 1;
111 if (t->nano > u->nano) return 0;
112 return t->atto < u->atto;
113}
114
115void taia_now(struct taia *t)
116{
117 struct timeval now;
118 gettimeofday(&now, NULL);
119 tai_unix(&t->sec, now.tv_sec);
120 t->nano = 1000 * now.tv_usec + 500;
121 t->atto = 0;
122}
123
124/* UNUSED
125void taia_pack(char *s, const struct taia *t)
126{
127 unsigned long x;
128
129 tai_pack(s, &t->sec);
130 s += 8;
131
132 x = t->atto;
133 s[7] = x & 255; x >>= 8;
134 s[6] = x & 255; x >>= 8;
135 s[5] = x & 255; x >>= 8;
136 s[4] = x;
137 x = t->nano;
138 s[3] = x & 255; x >>= 8;
139 s[2] = x & 255; x >>= 8;
140 s[1] = x & 255; x >>= 8;
141 s[0] = x;
142}
143*/
144
145void taia_sub(struct taia *t, const struct taia *u, const struct taia *v)
146{
147 unsigned long unano = u->nano;
148 unsigned long uatto = u->atto;
149
150 t->sec.x = u->sec.x - v->sec.x;
151 t->nano = unano - v->nano;
152 t->atto = uatto - v->atto;
153 if (t->atto > uatto) {
154 t->atto += 1000000000UL;
155 --t->nano;
156 }
157 if (t->nano > unano) {
158 t->nano += 1000000000UL;
159 --t->sec.x;
160 }
161}
162
163/* XXX: breaks tai encapsulation */
164void taia_uint(struct taia *t, unsigned s)
165{
166 t->sec.x = s;
167 t->nano = 0;
168 t->atto = 0;
169}
170
171static
172uint64_t taia2millisec(const struct taia *t)
173{
174 return (t->sec.x * 1000) + (t->nano / 1000000);
175}
176
177void iopause(iopause_fd *x, unsigned len, struct taia *deadline, struct taia *stamp)
178{
179 int millisecs;
180 int i;
181
182 if (taia_less(deadline, stamp))
183 millisecs = 0;
184 else {
185 uint64_t m;
186 struct taia t;
187 t = *stamp;
188 taia_sub(&t, deadline, &t);
189 millisecs = m = taia2millisec(&t);
190 if (m > 1000) millisecs = 1000;
191 millisecs += 20;
192 }
193
194 for (i = 0; i < len; ++i)
195 x[i].revents = 0;
196
197 poll(x, len, millisecs);
198 /* XXX: some kernels apparently need x[0] even if len is 0 */
199 /* XXX: how to handle EAGAIN? are kernels really this dumb? */
200 /* XXX: how to handle EINVAL? when exactly can this happen? */
201}
202#endif
203
204int lock_ex(int fd)
205{
206 return flock(fd,LOCK_EX);
207}
208
209int lock_exnb(int fd)
210{
211 return flock(fd,LOCK_EX | LOCK_NB);
212}
213
214int open_append(const char *fn)
215{
216 return open(fn, O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0600);
217}
218
219int open_read(const char *fn)
220{
221 return open(fn, O_RDONLY|O_NDELAY);
222}
223
224int open_trunc(const char *fn)
225{
226 return open(fn,O_WRONLY | O_NDELAY | O_TRUNC | O_CREAT,0644);
227}
228
229int open_write(const char *fn)
230{
231 return open(fn, O_WRONLY|O_NDELAY);
232}
233
234unsigned pmatch(const char *p, const char *s, unsigned len)
235{
236 for (;;) {
237 char c = *p++;
238 if (!c) return !len;
239 switch (c) {
240 case '*':
241 if (!(c = *p)) return 1;
242 for (;;) {
243 if (!len) return 0;
244 if (*s == c) break;
245 ++s; --len;
246 }
247 continue;
248 case '+':
249 if ((c = *p++) != *s) return 0;
250 for (;;) {
251 if (!len) return 1;
252 if (*s != c) break;
253 ++s; --len;
254 }
255 continue;
256 /*
257 case '?':
258 if (*p == '?') {
259 if (*s != '?') return 0;
260 ++p;
261 }
262 ++s; --len;
263 continue;
264 */
265 default:
266 if (!len) return 0;
267 if (*s != c) return 0;
268 ++s; --len;
269 continue;
270 }
271 }
272 return 0;
273}
Note: See TracBrowser for help on using the repository browser.