busybox/runit/runit_lib.c
<<
>>
Prefs
   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 Denys 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
  53#ifdef UNUSED
  54static /* as it isn't used anywhere else */
  55void tai_pack(char *s, const struct tai *t)
  56{
  57        uint64_t x;
  58
  59        x = t->x;
  60        s[7] = x & 255; x >>= 8;
  61        s[6] = x & 255; x >>= 8;
  62        s[5] = x & 255; x >>= 8;
  63        s[4] = x & 255; x >>= 8;
  64        s[3] = x & 255; x >>= 8;
  65        s[2] = x & 255; x >>= 8;
  66        s[1] = x & 255; x >>= 8;
  67        s[0] = x;
  68}
  69
  70void tai_unpack(const char *s,struct tai *t)
  71{
  72        uint64_t x;
  73
  74        x = (unsigned char) s[0];
  75        x <<= 8; x += (unsigned char) s[1];
  76        x <<= 8; x += (unsigned char) s[2];
  77        x <<= 8; x += (unsigned char) s[3];
  78        x <<= 8; x += (unsigned char) s[4];
  79        x <<= 8; x += (unsigned char) s[5];
  80        x <<= 8; x += (unsigned char) s[6];
  81        x <<= 8; x += (unsigned char) s[7];
  82        t->x = x;
  83}
  84
  85
  86void taia_add(struct taia *t,const struct taia *u,const struct taia *v)
  87{
  88        t->sec.x = u->sec.x + v->sec.x;
  89        t->nano = u->nano + v->nano;
  90        t->atto = u->atto + v->atto;
  91        if (t->atto > 999999999UL) {
  92                t->atto -= 1000000000UL;
  93                ++t->nano;
  94        }
  95        if (t->nano > 999999999UL) {
  96                t->nano -= 1000000000UL;
  97                ++t->sec.x;
  98        }
  99}
 100
 101int taia_less(const struct taia *t, const struct taia *u)
 102{
 103        if (t->sec.x < u->sec.x) return 1;
 104        if (t->sec.x > u->sec.x) return 0;
 105        if (t->nano < u->nano) return 1;
 106        if (t->nano > u->nano) return 0;
 107        return t->atto < u->atto;
 108}
 109
 110void taia_now(struct taia *t)
 111{
 112        struct timeval now;
 113        gettimeofday(&now, NULL);
 114        tai_unix(&t->sec, now.tv_sec);
 115        t->nano = 1000 * now.tv_usec + 500;
 116        t->atto = 0;
 117}
 118
 119/* UNUSED
 120void taia_pack(char *s, const struct taia *t)
 121{
 122        unsigned long x;
 123
 124        tai_pack(s, &t->sec);
 125        s += 8;
 126
 127        x = t->atto;
 128        s[7] = x & 255; x >>= 8;
 129        s[6] = x & 255; x >>= 8;
 130        s[5] = x & 255; x >>= 8;
 131        s[4] = x;
 132        x = t->nano;
 133        s[3] = x & 255; x >>= 8;
 134        s[2] = x & 255; x >>= 8;
 135        s[1] = x & 255; x >>= 8;
 136        s[0] = x;
 137}
 138*/
 139
 140void taia_sub(struct taia *t, const struct taia *u, const struct taia *v)
 141{
 142        unsigned long unano = u->nano;
 143        unsigned long uatto = u->atto;
 144
 145        t->sec.x = u->sec.x - v->sec.x;
 146        t->nano = unano - v->nano;
 147        t->atto = uatto - v->atto;
 148        if (t->atto > uatto) {
 149                t->atto += 1000000000UL;
 150                --t->nano;
 151        }
 152        if (t->nano > unano) {
 153                t->nano += 1000000000UL;
 154                --t->sec.x;
 155        }
 156}
 157
 158/* XXX: breaks tai encapsulation */
 159void taia_uint(struct taia *t, unsigned s)
 160{
 161        t->sec.x = s;
 162        t->nano = 0;
 163        t->atto = 0;
 164}
 165
 166static
 167uint64_t taia2millisec(const struct taia *t)
 168{
 169        return (t->sec.x * 1000) + (t->nano / 1000000);
 170}
 171
 172void iopause(iopause_fd *x, unsigned len, struct taia *deadline, struct taia *stamp)
 173{
 174        int millisecs;
 175        int i;
 176
 177        if (taia_less(deadline, stamp))
 178                millisecs = 0;
 179        else {
 180                uint64_t m;
 181                struct taia t;
 182                t = *stamp;
 183                taia_sub(&t, deadline, &t);
 184                millisecs = m = taia2millisec(&t);
 185                if (m > 1000) millisecs = 1000;
 186                millisecs += 20;
 187        }
 188
 189        for (i = 0; i < len; ++i)
 190                x[i].revents = 0;
 191
 192        poll(x, len, millisecs);
 193        /* XXX: some kernels apparently need x[0] even if len is 0 */
 194        /* XXX: how to handle EAGAIN? are kernels really this dumb? */
 195        /* XXX: how to handle EINVAL? when exactly can this happen? */
 196}
 197#endif
 198
 199int lock_ex(int fd)
 200{
 201        return flock(fd,LOCK_EX);
 202}
 203
 204int lock_exnb(int fd)
 205{
 206        return flock(fd,LOCK_EX | LOCK_NB);
 207}
 208
 209int open_append(const char *fn)
 210{
 211        return open(fn, O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0600);
 212}
 213
 214int open_read(const char *fn)
 215{
 216        return open(fn, O_RDONLY|O_NDELAY);
 217}
 218
 219int open_trunc(const char *fn)
 220{
 221        return open(fn,O_WRONLY | O_NDELAY | O_TRUNC | O_CREAT,0644);
 222}
 223
 224int open_write(const char *fn)
 225{
 226        return open(fn, O_WRONLY|O_NDELAY);
 227}
 228
 229unsigned pmatch(const char *p, const char *s, unsigned len)
 230{
 231        for (;;) {
 232                char c = *p++;
 233                if (!c) return !len;
 234                switch (c) {
 235                case '*':
 236                        c = *p;
 237                        if (!c) return 1;
 238                        for (;;) {
 239                                if (!len) return 0;
 240                                if (*s == c) break;
 241                                ++s;
 242                                --len;
 243                        }
 244                        continue;
 245                case '+':
 246                        c = *p++;
 247                        if (c != *s) return 0;
 248                        for (;;) {
 249                                if (!len) return 1;
 250                                if (*s != c) break;
 251                                ++s;
 252                                --len;
 253                        }
 254                        continue;
 255                        /*
 256                case '?':
 257                        if (*p == '?') {
 258                                if (*s != '?') return 0;
 259                                ++p;
 260                        }
 261                        ++s; --len;
 262                        continue;
 263                        */
 264                default:
 265                        if (!len) return 0;
 266                        if (*s != c) return 0;
 267                        ++s;
 268                        --len;
 269                        continue;
 270                }
 271        }
 272        return 0;
 273}
 274