Пример #1
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;
    }
}
Пример #2
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;
	}
}
Пример #3
0
/* gcc 4.3.0 does better with NOINLINE */
static NOINLINE int do_rescan(void)
{
	DIR *dir;
	struct dirent *d;
	int i;
	struct stat s;
	int need_rescan = 0;

	dir = opendir(".");
	if (!dir) {
		warn2_cannot("open directory ", svdir);
		return 1; /* need to rescan again soon */
	}
	for (i = 0; i < svnum; i++)
		sv[i].isgone = 1;

	while (1) {
		errno = 0;
		d = readdir(dir);
		if (!d)
			break;
		if (d->d_name[0] == '.')
			continue;
		if (stat(d->d_name, &s) == -1) {
			warn2_cannot("stat ", d->d_name);
			continue;
		}
		if (!S_ISDIR(s.st_mode))
			continue;
		/* Do we have this service listed already? */
		for (i = 0; i < svnum; i++) {
			if ((sv[i].ino == s.st_ino)
#if CHECK_DEVNO_TOO
			 && (sv[i].dev == s.st_dev)
#endif
			) {
				if (sv[i].pid == 0) /* restart if it has died */
					goto run_ith_sv;
				sv[i].isgone = 0; /* "we still see you" */
				goto next_dentry;
			}
		}
		{ /* Not found, make new service */
			struct service *svnew = realloc(sv, (i+1) * sizeof(*sv));
			if (!svnew) {
				warn2_cannot("start runsv ", d->d_name);
				need_rescan = 1;
				continue;
			}
			sv = svnew;
			svnum++;
#if CHECK_DEVNO_TOO
			sv[i].dev = s.st_dev;
#endif
			sv[i].ino = s.st_ino;
 run_ith_sv:
			sv[i].pid = runsv(d->d_name);
			sv[i].isgone = 0;
		}
 next_dentry: ;
	}
	i = errno;
	closedir(dir);
	if (i) { /* readdir failed */
		warn2_cannot("read directory ", svdir);
		return 1; /* need to rescan again soon */
	}

	/* Send SIGTERM to runsv whose directories
	 * were no longer found (-> must have been removed) */
	for (i = 0; i < svnum; i++) {
		if (!sv[i].isgone)
			continue;
		if (sv[i].pid)
			kill(sv[i].pid, SIGTERM);
		svnum--;
		sv[i] = sv[svnum];
		i--; /* so that we don't skip new sv[i] (bug was here!) */
	}
	return need_rescan;
}