123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982 |
- /*
- Copyright (c) 2001-2006, Gerrit Pape
- All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- /* Busyboxed by Denis Vlasenko <vda.linux@googlemail.com> */
- /* Collected into one file from runit's many tiny files */
- /* TODO: review, eliminate unneeded stuff, move good stuff to libbb */
- #include <sys/poll.h>
- #include <sys/file.h>
- #include "libbb.h"
- #include "runit_lib.h"
- /*** buffer.c ***/
- void buffer_init(buffer *s,int (*op)(int fd,char *buf,unsigned len),int fd,char *buf,unsigned len)
- {
- s->x = buf;
- s->fd = fd;
- s->op = op;
- s->p = 0;
- s->n = len;
- }
- /*** buffer_get.c ***/
- static int oneread(int (*op)(int fd,char *buf,unsigned len),int fd,char *buf,unsigned len)
- {
- int r;
- for (;;) {
- r = op(fd,buf,len);
- if (r == -1) if (errno == EINTR) continue;
- return r;
- }
- }
- static int getthis(buffer *s,char *buf,unsigned len)
- {
- if (len > s->p) len = s->p;
- s->p -= len;
- memcpy(buf,s->x + s->n,len);
- s->n += len;
- return len;
- }
- int buffer_feed(buffer *s)
- {
- int r;
- if (s->p) return s->p;
- r = oneread(s->op,s->fd,s->x,s->n);
- if (r <= 0) return r;
- s->p = r;
- s->n -= r;
- if (s->n > 0) memmove(s->x + s->n,s->x,r);
- return r;
- }
- int buffer_bget(buffer *s,char *buf,unsigned len)
- {
- int r;
-
- if (s->p > 0) return getthis(s,buf,len);
- if (s->n <= len) return oneread(s->op,s->fd,buf,s->n);
- r = buffer_feed(s); if (r <= 0) return r;
- return getthis(s,buf,len);
- }
- int buffer_get(buffer *s,char *buf,unsigned len)
- {
- int r;
-
- if (s->p > 0) return getthis(s,buf,len);
- if (s->n <= len) return oneread(s->op,s->fd,buf,len);
- r = buffer_feed(s); if (r <= 0) return r;
- return getthis(s,buf,len);
- }
- char *buffer_peek(buffer *s)
- {
- return s->x + s->n;
- }
- void buffer_seek(buffer *s,unsigned len)
- {
- s->n += len;
- s->p -= len;
- }
- /*** buffer_put.c ***/
- static int allwrite(int (*op)(int fd,char *buf,unsigned len),int fd,const char *buf,unsigned len)
- {
- int w;
- while (len) {
- w = op(fd,(char*)buf,len);
- if (w == -1) {
- if (errno == EINTR) continue;
- return -1; /* note that some data may have been written */
- }
- if (w == 0) ; /* luser's fault */
- buf += w;
- len -= w;
- }
- return 0;
- }
- int buffer_flush(buffer *s)
- {
- int p;
-
- p = s->p;
- if (!p) return 0;
- s->p = 0;
- return allwrite(s->op,s->fd,s->x,p);
- }
- int buffer_putalign(buffer *s,const char *buf,unsigned len)
- {
- unsigned n;
-
- while (len > (n = s->n - s->p)) {
- memcpy(s->x + s->p,buf,n);
- s->p += n;
- buf += n;
- len -= n;
- if (buffer_flush(s) == -1) return -1;
- }
- /* now len <= s->n - s->p */
- memcpy(s->x + s->p,buf,len);
- s->p += len;
- return 0;
- }
- int buffer_put(buffer *s,const char *buf,unsigned len)
- {
- unsigned n;
-
- n = s->n;
- if (len > n - s->p) {
- if (buffer_flush(s) == -1) return -1;
- /* now s->p == 0 */
- if (n < BUFFER_OUTSIZE) n = BUFFER_OUTSIZE;
- while (len > s->n) {
- if (n > len) n = len;
- if (allwrite(s->op,s->fd,buf,n) == -1) return -1;
- buf += n;
- len -= n;
- }
- }
- /* now len <= s->n - s->p */
- memcpy(s->x + s->p,buf,len);
- s->p += len;
- return 0;
- }
- int buffer_putflush(buffer *s,const char *buf,unsigned len)
- {
- if (buffer_flush(s) == -1) return -1;
- return allwrite(s->op,s->fd,buf,len);
- }
- int buffer_putsalign(buffer *s,const char *buf)
- {
- return buffer_putalign(s,buf,strlen(buf));
- }
- int buffer_puts(buffer *s,const char *buf)
- {
- return buffer_put(s,buf,strlen(buf));
- }
- int buffer_putsflush(buffer *s,const char *buf)
- {
- return buffer_putflush(s,buf,strlen(buf));
- }
- /*** buffer_read.c ***/
- int buffer_unixread(int fd,char *buf,unsigned len)
- {
- return read(fd,buf,len);
- }
- /*** buffer_write.c ***/
- int buffer_unixwrite(int fd,char *buf,unsigned len)
- {
- return write(fd,buf,len);
- }
- /*** byte_chr.c ***/
- unsigned byte_chr(char *s,unsigned n,int c)
- {
- char ch;
- char *t;
- ch = c;
- t = s;
- for (;;) {
- if (!n) break; if (*t == ch) break; ++t; --n;
- if (!n) break; if (*t == ch) break; ++t; --n;
- if (!n) break; if (*t == ch) break; ++t; --n;
- if (!n) break; if (*t == ch) break; ++t; --n;
- }
- return t - s;
- }
- /*** coe.c ***/
- int coe(int fd)
- {
- return fcntl(fd,F_SETFD,FD_CLOEXEC);
- }
- /*** fd_copy.c ***/
- int fd_copy(int to,int from)
- {
- if (to == from) return 0;
- if (fcntl(from,F_GETFL,0) == -1) return -1;
- close(to);
- if (fcntl(from,F_DUPFD,to) == -1) return -1;
- return 0;
- }
- /*** fd_move.c ***/
- int fd_move(int to,int from)
- {
- if (to == from) return 0;
- if (fd_copy(to,from) == -1) return -1;
- close(from);
- return 0;
- }
- /*** fifo.c ***/
- int fifo_make(const char *fn,int mode) { return mkfifo(fn,mode); }
- /*** fmt_ptime.c ***/
- unsigned fmt_ptime(char *s, struct taia *ta) {
- struct tm *t;
- unsigned long u;
- if (ta->sec.x < 4611686018427387914ULL) return 0; /* impossible? */
- u = ta->sec.x -4611686018427387914ULL;
- if (!(t = gmtime((time_t*)&u))) return 0;
- fmt_ulong(s, 1900 + t->tm_year);
- s[4] = '-'; fmt_uint0(&s[5], t->tm_mon+1, 2);
- s[7] = '-'; fmt_uint0(&s[8], t->tm_mday, 2);
- s[10] = '_'; fmt_uint0(&s[11], t->tm_hour, 2);
- s[13] = ':'; fmt_uint0(&s[14], t->tm_min, 2);
- s[16] = ':'; fmt_uint0(&s[17], t->tm_sec, 2);
- s[19] = '.'; fmt_uint0(&s[20], ta->nano, 9);
- return 25;
- }
- unsigned fmt_taia(char *s, struct taia *t) {
- static char hex[16] = "0123456789abcdef";
- static char pack[TAIA_PACK];
- int i;
- taia_pack(pack, t);
- s[0] = '@';
- for (i = 0; i < 12; ++i) {
- s[i*2+1] = hex[(pack[i] >> 4) &15];
- s[i*2+2] = hex[pack[i] &15];
- }
- return 25;
- }
- /*** fmt_uint.c ***/
- unsigned fmt_uint(char *s,unsigned u)
- {
- return fmt_ulong(s,u);
- }
- /*** fmt_uint0.c ***/
- unsigned fmt_uint0(char *s,unsigned u,unsigned n)
- {
- unsigned len;
- len = fmt_uint(FMT_LEN,u);
- while (len < n) { if (s) *s++ = '0'; ++len; }
- if (s) fmt_uint(s,u);
- return len;
- }
- /*** fmt_ulong.c ***/
- unsigned fmt_ulong(char *s,unsigned long u)
- {
- unsigned len; unsigned long q;
- len = 1; q = u;
- while (q > 9) { ++len; q /= 10; }
- if (s) {
- s += len;
- do { *--s = '0' + (u % 10); u /= 10; } while(u); /* handles u == 0 */
- }
- return len;
- }
- /*** tai_now.c ***/
- void tai_now(struct tai *t)
- {
- tai_unix(t,time((time_t *) 0));
- }
- /*** tai_pack.c ***/
- void tai_pack(char *s,const struct tai *t)
- {
- uint64_t x;
- x = t->x;
- s[7] = x & 255; x >>= 8;
- s[6] = x & 255; x >>= 8;
- s[5] = x & 255; x >>= 8;
- s[4] = x & 255; x >>= 8;
- s[3] = x & 255; x >>= 8;
- s[2] = x & 255; x >>= 8;
- s[1] = x & 255; x >>= 8;
- s[0] = x;
- }
- /*** tai_sub.c ***/
- void tai_sub(struct tai *t,const struct tai *u,const struct tai *v)
- {
- t->x = u->x - v->x;
- }
- /*** tai_unpack.c ***/
- void tai_unpack(const char *s,struct tai *t)
- {
- uint64_t x;
- x = (unsigned char) s[0];
- x <<= 8; x += (unsigned char) s[1];
- x <<= 8; x += (unsigned char) s[2];
- x <<= 8; x += (unsigned char) s[3];
- x <<= 8; x += (unsigned char) s[4];
- x <<= 8; x += (unsigned char) s[5];
- x <<= 8; x += (unsigned char) s[6];
- x <<= 8; x += (unsigned char) s[7];
- t->x = x;
- }
- /*** taia_add.c ***/
- /* XXX: breaks tai encapsulation */
- void taia_add(struct taia *t,const struct taia *u,const struct taia *v)
- {
- t->sec.x = u->sec.x + v->sec.x;
- t->nano = u->nano + v->nano;
- t->atto = u->atto + v->atto;
- if (t->atto > 999999999UL) {
- t->atto -= 1000000000UL;
- ++t->nano;
- }
- if (t->nano > 999999999UL) {
- t->nano -= 1000000000UL;
- ++t->sec.x;
- }
- }
- /*** taia_approx.c ***/
- double taia_approx(const struct taia *t)
- {
- return tai_approx(&t->sec) + taia_frac(t);
- }
- /*** taia_frac.c ***/
- double taia_frac(const struct taia *t)
- {
- return (t->atto * 0.000000001 + t->nano) * 0.000000001;
- }
- /*** taia_less.c ***/
- /* XXX: breaks tai encapsulation */
- int taia_less(const struct taia *t,const struct taia *u)
- {
- if (t->sec.x < u->sec.x) return 1;
- if (t->sec.x > u->sec.x) return 0;
- if (t->nano < u->nano) return 1;
- if (t->nano > u->nano) return 0;
- return t->atto < u->atto;
- }
- /*** taia_now.c ***/
- void taia_now(struct taia *t)
- {
- struct timeval now;
- gettimeofday(&now,(struct timezone *) 0);
- tai_unix(&t->sec,now.tv_sec);
- t->nano = 1000 * now.tv_usec + 500;
- t->atto = 0;
- }
- /*** taia_pack.c ***/
- void taia_pack(char *s,const struct taia *t)
- {
- unsigned long x;
- tai_pack(s,&t->sec);
- s += 8;
- x = t->atto;
- s[7] = x & 255; x >>= 8;
- s[6] = x & 255; x >>= 8;
- s[5] = x & 255; x >>= 8;
- s[4] = x;
- x = t->nano;
- s[3] = x & 255; x >>= 8;
- s[2] = x & 255; x >>= 8;
- s[1] = x & 255; x >>= 8;
- s[0] = x;
- }
- /*** taia_sub.c ***/
- /* XXX: breaks tai encapsulation */
- void taia_sub(struct taia *t,const struct taia *u,const struct taia *v)
- {
- unsigned long unano = u->nano;
- unsigned long uatto = u->atto;
-
- t->sec.x = u->sec.x - v->sec.x;
- t->nano = unano - v->nano;
- t->atto = uatto - v->atto;
- if (t->atto > uatto) {
- t->atto += 1000000000UL;
- --t->nano;
- }
- if (t->nano > unano) {
- t->nano += 1000000000UL;
- --t->sec.x;
- }
- }
- /*** taia_uint.c ***/
- /* XXX: breaks tai encapsulation */
- void taia_uint(struct taia *t,unsigned s)
- {
- t->sec.x = s;
- t->nano = 0;
- t->atto = 0;
- }
- /*** stralloc_cat.c ***/
- #if 0
- int stralloc_cat(stralloc *sato,const stralloc *safrom)
- {
- return stralloc_catb(sato,safrom->s,safrom->len);
- }
- /*** stralloc_catb.c ***/
- int stralloc_catb(stralloc *sa,const char *s,unsigned n)
- {
- if (!sa->s) return stralloc_copyb(sa,s,n);
- if (!stralloc_readyplus(sa,n + 1)) return 0;
- memcpy(sa->s + sa->len,s,n);
- sa->len += n;
- sa->s[sa->len] = 'Z'; /* ``offensive programming'' */
- return 1;
- }
- /*** stralloc_cats.c ***/
- int stralloc_cats(stralloc *sa,const char *s)
- {
- return stralloc_catb(sa,s,strlen(s));
- }
- /*** stralloc_eady.c ***/
- GEN_ALLOC_ready(stralloc,char,s,len,a,i,n,x,30,stralloc_ready)
- GEN_ALLOC_readyplus(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus)
- /*** stralloc_opyb.c ***/
- int stralloc_copyb(stralloc *sa,const char *s,unsigned n)
- {
- if (!stralloc_ready(sa,n + 1)) return 0;
- memcpy(sa->s,s,n);
- sa->len = n;
- sa->s[n] = 'Z'; /* ``offensive programming'' */
- return 1;
- }
- /*** stralloc_opys.c ***/
- int stralloc_copys(stralloc *sa,const char *s)
- {
- return stralloc_copyb(sa,s,strlen(s));
- }
- /*** stralloc_pend.c ***/
- GEN_ALLOC_append(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus,stralloc_append)
- #endif /* stralloc */
- /*** iopause.c ***/
- void iopause(iopause_fd *x,unsigned len,struct taia *deadline,struct taia *stamp)
- {
- struct taia t;
- int millisecs;
- double d;
- int i;
- if (taia_less(deadline,stamp))
- millisecs = 0;
- else {
- t = *stamp;
- taia_sub(&t,deadline,&t);
- d = taia_approx(&t);
- if (d > 1000.0) d = 1000.0;
- millisecs = d * 1000.0 + 20.0;
- }
- for (i = 0;i < len;++i)
- x[i].revents = 0;
- poll(x,len,millisecs);
- /* XXX: some kernels apparently need x[0] even if len is 0 */
- /* XXX: how to handle EAGAIN? are kernels really this dumb? */
- /* XXX: how to handle EINVAL? when exactly can this happen? */
- }
- /*** lock_ex.c ***/
- int lock_ex(int fd)
- {
- return flock(fd,LOCK_EX);
- }
- /*** lock_exnb.c ***/
- int lock_exnb(int fd)
- {
- return flock(fd,LOCK_EX | LOCK_NB);
- }
- /*** open_append.c ***/
- int open_append(const char *fn)
- {
- return open(fn, O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0600);
- }
- /*** open_read.c ***/
- int open_read(const char *fn)
- {
- return open(fn, O_RDONLY|O_NDELAY);
- }
- /*** open_trunc.c ***/
- int open_trunc(const char *fn)
- {
- return open(fn,O_WRONLY | O_NDELAY | O_TRUNC | O_CREAT,0644);
- }
- /*** open_write.c ***/
- int open_write(const char *fn)
- {
- return open(fn, O_WRONLY|O_NDELAY);
- }
- /*** openreadclose.c ***/
- #if 0
- int openreadclose(const char *fn,stralloc *sa,unsigned bufsize)
- {
- int fd;
- fd = open_read(fn);
- if (fd == -1) {
- if (errno == ENOENT) return 0;
- return -1;
- }
- if (readclose(fd,sa,bufsize) == -1) return -1;
- return 1;
- }
- #endif
- /*** pathexec_env.c ***/
- #if 0
- static stralloc plus;
- static stralloc tmp;
- int pathexec_env(const char *s,const char *t)
- {
- if (!s) return 1;
- if (!stralloc_copys(&tmp,s)) return 0;
- if (t) {
- if (!stralloc_cats(&tmp,"=")) return 0;
- if (!stralloc_cats(&tmp,t)) return 0;
- }
- if (!stralloc_0(&tmp)) return 0;
- return stralloc_cat(&plus,&tmp);
- }
- void pathexec(char **argv)
- {
- char **e;
- unsigned elen;
- unsigned i;
- unsigned j;
- unsigned split;
- unsigned t;
- if (!stralloc_cats(&plus,"")) return;
- elen = 0;
- for (i = 0;environ[i];++i)
- ++elen;
- for (i = 0;i < plus.len;++i)
- if (!plus.s[i])
- ++elen;
- e = malloc((elen + 1) * sizeof(char *));
- if (!e) return;
- elen = 0;
- for (i = 0;environ[i];++i)
- e[elen++] = environ[i];
- j = 0;
- for (i = 0;i < plus.len;++i)
- if (!plus.s[i]) {
- split = str_chr(plus.s + j,'=');
- for (t = 0;t < elen;++t)
- if (memcmp(plus.s + j,e[t],split) == 0)
- if (e[t][split] == '=') {
- --elen;
- e[t] = e[elen];
- break;
- }
- if (plus.s[j + split])
- e[elen++] = plus.s + j;
- j = i + 1;
- }
- e[elen] = 0;
- pathexec_run(*argv,argv,e);
- free(e);
- }
- #endif
- /*** pathexec_run.c ***/
- #if 0
- static stralloc tmp;
- void pathexec_run(const char *file,char *const *argv,char *const *envp)
- {
- const char *path;
- unsigned split;
- int savederrno;
- if (file[str_chr(file,'/')]) {
- execve(file,argv,envp);
- return;
- }
- path = getenv("PATH");
- if (!path) path = "/bin:/usr/bin";
- savederrno = 0;
- for (;;) {
- split = str_chr(path,':');
- if (!stralloc_copyb(&tmp,path,split)) return;
- if (!split)
- if (!stralloc_cats(&tmp,".")) return;
- if (!stralloc_cats(&tmp,"/")) return;
- if (!stralloc_cats(&tmp,file)) return;
- if (!stralloc_0(&tmp)) return;
- execve(tmp.s,argv,envp);
- if (errno != ENOENT) {
- savederrno = errno;
- if ((errno != EACCES) && (errno != EPERM) && (errno != EISDIR)) return;
- }
- if (!path[split]) {
- if (savederrno) errno = savederrno;
- return;
- }
- path += split;
- path += 1;
- }
- }
- #endif
- /*** pmatch.c ***/
- unsigned pmatch(const char *p, const char *s, unsigned len) {
- for (;;) {
- char c = *p++;
- if (!c) return !len;
- switch (c) {
- case '*':
- if (!(c = *p)) return 1;
- for (;;) {
- if (!len) return 0;
- if (*s == c) break;
- ++s; --len;
- }
- continue;
- case '+':
- if ((c = *p++) != *s) return 0;
- for (;;) {
- if (!len) return 1;
- if (*s != c) break;
- ++s; --len;
- }
- continue;
- /*
- case '?':
- if (*p == '?') {
- if (*s != '?') return 0;
- ++p;
- }
- ++s; --len;
- continue;
- */
- default:
- if (!len) return 0;
- if (*s != c) return 0;
- ++s; --len;
- continue;
- }
- }
- return 0;
- }
- /*** prot.c ***/
- int prot_gid(int gid)
- {
- gid_t x = gid;
- if (setgroups(1,&x) == -1) return -1;
- return setgid(gid); /* _should_ be redundant, but on some systems it isn't */
- }
- int prot_uid(int uid)
- {
- return setuid(uid);
- }
- /*** readclose.c ***/
- #if 0
- int readclose_append(int fd,stralloc *sa,unsigned bufsize)
- {
- int r;
- for (;;) {
- if (!stralloc_readyplus(sa,bufsize)) { close(fd); return -1; }
- r = read(fd,sa->s + sa->len,bufsize);
- if (r == -1) if (errno == EINTR) continue;
- if (r <= 0) { close(fd); return r; }
- sa->len += r;
- }
- }
- int readclose(int fd,stralloc *sa,unsigned bufsize)
- {
- if (!stralloc_copys(sa,"")) { close(fd); return -1; }
- return readclose_append(fd,sa,bufsize);
- }
- #endif
- /*** scan_ulong.c ***/
- unsigned scan_ulong(const char *s,unsigned long *u)
- {
- unsigned pos = 0;
- unsigned long result = 0;
- unsigned long c;
- while ((c = (unsigned long) (unsigned char) (s[pos] - '0')) < 10) {
- result = result * 10 + c;
- ++pos;
- }
- *u = result;
- return pos;
- }
- /*** seek_set.c ***/
- int seek_set(int fd,seek_pos pos)
- {
- if (lseek(fd,(off_t) pos,SEEK_SET) == -1) return -1; return 0;
- }
- /*** sig.c ***/
- int sig_alarm = SIGALRM;
- int sig_child = SIGCHLD;
- int sig_cont = SIGCONT;
- int sig_hangup = SIGHUP;
- int sig_int = SIGINT;
- int sig_pipe = SIGPIPE;
- int sig_term = SIGTERM;
- void (*sig_defaulthandler)(int) = SIG_DFL;
- void (*sig_ignorehandler)(int) = SIG_IGN;
- /*** sig_block.c ***/
- void sig_block(int sig)
- {
- sigset_t ss;
- sigemptyset(&ss);
- sigaddset(&ss,sig);
- sigprocmask(SIG_BLOCK,&ss,(sigset_t *) 0);
- }
- void sig_unblock(int sig)
- {
- sigset_t ss;
- sigemptyset(&ss);
- sigaddset(&ss,sig);
- sigprocmask(SIG_UNBLOCK,&ss,(sigset_t *) 0);
- }
- void sig_blocknone(void)
- {
- sigset_t ss;
- sigemptyset(&ss);
- sigprocmask(SIG_SETMASK,&ss,(sigset_t *) 0);
- }
- /*** sig_catch.c ***/
- void sig_catch(int sig,void (*f)(int))
- {
- struct sigaction sa;
- sa.sa_handler = f;
- sa.sa_flags = 0;
- sigemptyset(&sa.sa_mask);
- sigaction(sig,&sa,(struct sigaction *) 0);
- }
- /*** sig_pause.c ***/
- void sig_pause(void)
- {
- sigset_t ss;
- sigemptyset(&ss);
- sigsuspend(&ss);
- }
- /*** str_chr.c ***/
- unsigned str_chr(const char *s,int c)
- {
- char ch;
- const char *t;
- ch = c;
- t = s;
- for (;;) {
- if (!*t) break; if (*t == ch) break; ++t;
- if (!*t) break; if (*t == ch) break; ++t;
- if (!*t) break; if (*t == ch) break; ++t;
- if (!*t) break; if (*t == ch) break; ++t;
- }
- return t - s;
- }
- /*** wait_nohang.c ***/
- int wait_nohang(int *wstat)
- {
- return waitpid(-1,wstat,WNOHANG);
- }
- /*** wait_pid.c ***/
- int wait_pid(int *wstat, int pid)
- {
- int r;
- do
- r = waitpid(pid,wstat,0);
- while ((r == -1) && (errno == EINTR));
- return r;
- }
|