示例#1
0
int setup_log()
{
    if ((rploglen =str_len(rplog)) < 7)
    {
        warn3x("log must have at least seven characters.", 0, 0);
        return(0);
    }
    if (pipe(logpipe) == -1)
    {
        warn3x("unable to create pipe for log.", 0, 0);
        return(-1);
    }
    coe(logpipe[1]);
    coe(logpipe[0]);
    ndelay_on(logpipe[0]);
    ndelay_on(logpipe[1]);
    if (fd_copy(2, logpipe[1]) == -1)
    {
        warn3x("unable to set filedescriptor for log.", 0, 0);
        return(-1);
    }
    io[0].fd =logpipe[0];
    io[0].events =IOPAUSE_READ;
    taia_now(&stamplog);
    return(1);
}
示例#2
0
static void warnx(const char *m1)
{
	warn3x(m1, "", "");
}
示例#3
0
static void warn2_cannot(const char *m1, const char *m2)
{
	warn3x("cannot ", m1, m2);
}
示例#4
0
static void runsvdir(void)
{
	DIR *dir;
	direntry *d;
	int i;
	struct stat s;

	dir = opendir(".");
	if (!dir) {
		warn2_cannot("open directory ", svdir);
		return;
	}
	for (i = 0; i < svnum; i++)
		sv[i].isgone = 1;
	errno = 0;
	while ((d = readdir(dir))) {
		if (d->d_name[0] == '.')
			continue;
		if (stat(d->d_name, &s) == -1) {
			warn2_cannot("stat ", d->d_name);
			errno = 0;
			continue;
		}
		if (!S_ISDIR(s.st_mode))
			continue;
		for (i = 0; i < svnum; i++) {
			if ((sv[i].ino == s.st_ino) && (sv[i].dev == s.st_dev)) {
				sv[i].isgone = 0;
				if (!sv[i].pid)
					runsv(i, d->d_name);
				break;
			}
		}
		if (i == svnum) {
			/* new service */
			struct service *svnew = realloc(sv, (i+1) * sizeof(*sv));
			if (!svnew) {
				warn3x("cannot start runsv ", d->d_name,
						" too many services");
				continue;
			}
			sv = svnew;
			svnum++;
			memset(&sv[i], 0, sizeof(sv[i]));
			sv[i].ino = s.st_ino;
			sv[i].dev = s.st_dev;
			/*sv[i].pid = 0;*/
			/*sv[i].isgone = 0;*/
			runsv(i, d->d_name);
			check = 1;
		}
	}
	if (errno) {
		warn2_cannot("read directory ", svdir);
		closedir(dir);
		check = 1;
		return;
	}
	closedir(dir);

	/* SIGTERM removed runsv's */
	for (i = 0; i < svnum; i++) {
		if (!sv[i].isgone)
			continue;
		if (sv[i].pid)
			kill(sv[i].pid, SIGTERM);
		sv[i] = sv[--svnum];
		check = 1;
	}
}
示例#5
0
void runsvdir()
{
    DIR *dir;
    direntry *d;
    int i;
    struct stat s;

    if (! (dir =opendir(".")))
    {
        warn("unable to open directory ", svdir);
        return;
    }
    for (i =0; i < svnum; i++) sv[i].isgone =1;
    errno =0;
    while ((d =readdir(dir)))
    {
        if (d->d_name[0] == '.') continue;
        if (stat(d->d_name, &s) == -1)
        {
            warn("unable to stat ", d->d_name);
            errno =0;
            continue;
        }
        if (! S_ISDIR(s.st_mode)) continue;
        for (i =0; i < svnum; i++)
        {
            if ((sv[i].ino == s.st_ino) && (sv[i].dev == s.st_dev))
            {
                sv[i].isgone =0;
                if (! sv[i].pid) runsv(i, d->d_name);
                break;
            }
        }
        if (i == svnum)
        {
            /* new service */
            if (svnum >= MAXSERVICES)
            {
                warn3x("unable to start runsv ", d->d_name, ": too many services.");
                continue;
            }
            sv[i].ino =s.st_ino;
            sv[i].dev =s.st_dev;
            sv[i].pid =0;
            sv[i].isgone =0;
            svnum++;
            runsv(i, d->d_name);
            check =1;
        }
    }
    if (errno)
    {
        warn("unable to read directory ", svdir);
        closedir(dir);
        check =1;
        return;
    }
    closedir(dir);

    /* SIGTERM removed runsv's */
    for (i =0; i < svnum; i++)
    {
        if (! sv[i].isgone) continue;
        if (sv[i].pid) kill(sv[i].pid, SIGTERM);
        sv[i] =sv[--svnum];
        check =1;
    }
}
示例#6
0
int main(int argc, char **argv)
{
    struct stat s;
    time_t mtime =0;
    int wstat;
    int curdir;
    int pid;
    struct taia deadline;
    struct taia now;
    struct taia stampcheck;
    char ch;
    int i;

    progname =*argv++;
    if (! argv || ! *argv) usage();
    if (**argv == '-')
    {
        switch (*(*argv +1))
        {
        case 'P':
            pgrp =1;
        case '-':
            ++argv;
        }
        if (! argv || ! *argv) usage();
    }

    sig_catch(sig_term, s_term);
    sig_catch(sig_hangup, s_hangup);
    svdir =*argv++;
    if (argv && *argv)
    {
        rplog =*argv;
        if (setup_log() != 1)
        {
            rplog =0;
            warn3x("log service disabled.", 0, 0);
        }
    }
    if ((curdir =open_read(".")) == -1)
        fatal("unable to open current directory", 0);
    coe(curdir);

    taia_now(&stampcheck);

    for (;;)
    {
        /* collect children */
        for (;;)
        {
            if ((pid =wait_nohang(&wstat)) <= 0) break;
            for (i =0; i < svnum; i++)
            {
                if (pid == sv[i].pid)
                {
                    /* runsv has gone */
                    sv[i].pid =0;
                    check =1;
                    break;
                }
            }
        }

        taia_now(&now);
        if (now.sec.x < (stampcheck.sec.x -3))
        {
            /* time warp */
            warn3x("time warp: resetting time stamp.", 0, 0);
            taia_now(&stampcheck);
            taia_now(&now);
            if (rplog) taia_now(&stamplog);
        }
        if (taia_less(&now, &stampcheck) == 0)
        {
            /* wait at least a second */
            taia_uint(&deadline, 1);
            taia_add(&stampcheck, &now, &deadline);

            if (stat(svdir, &s) != -1)
            {
                if (check || \
                        s.st_mtime != mtime || s.st_ino != ino || s.st_dev != dev)
                {
                    /* svdir modified */
                    if (chdir(svdir) != -1)
                    {
                        mtime =s.st_mtime;
                        dev =s.st_dev;
                        ino =s.st_ino;
                        check =0;
                        if (now.sec.x <= (4611686018427387914ULL +(uint64)mtime))
                            sleep(1);
                        runsvdir();
                        while (fchdir(curdir) == -1)
                        {
                            warn("unable to change directory, pausing", 0);
                            sleep(5);
                        }
                    }
                    else
                        warn("unable to change directory to ", svdir);
                }
            }
            else
                warn("unable to stat ", svdir);
        }

        if (rplog)
            if (taia_less(&now, &stamplog) == 0)
            {
                write(logpipe[1], ".", 1);
                taia_uint(&deadline, 900);
                taia_add(&stamplog, &now, &deadline);
            }
        /* half a second */
        deadline.sec.x =0;
        deadline.nano =500000000UL;
        deadline.atto =0;
        taia_add(&deadline, &now, &deadline);

        sig_block(sig_child);
        if (rplog)
            iopause(io, 1, &deadline, &now);
        else
            iopause(0, 0, &deadline, &now);
        sig_unblock(sig_child);

        if (rplog && (io[0].revents | IOPAUSE_READ))
            while (read(logpipe[0], &ch, 1) > 0)
                if (ch)
                {
                    for (i =6; i < rploglen; i++)
                        rplog[i -1] =rplog[i];
                    rplog[rploglen -1] =ch;
                }

        switch(exitsoon)
        {
        case 1:
            _exit(0);
        case 2:
            for (i =0; i < svnum; i++) if (sv[i].pid) kill(sv[i].pid, SIGTERM);
            _exit(111);
        }
    } /* for (;;) */
    /* not reached */
    _exit(0);
}