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

Last change on this file since 3085 was 1765, checked in by bruno, 12 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.