示例#1
0
void FAST_FUNC write_pidfile(const char *path)
{
	int pid_fd;
	char *end;
	char buf[sizeof(int)*3 + 2];
	struct stat sb;

	if (!path)
		return;
	/* we will overwrite stale pidfile */
	pid_fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0666);
	if (pid_fd < 0)
		return;

	/* path can be "/dev/null"! Test for such cases */
	wrote_pidfile = (fstat(pid_fd, &sb) == 0) && S_ISREG(sb.st_mode);

	if (wrote_pidfile) {
		/* few bytes larger, but doesn't use stdio */
		end = utoa_to_buf(getpid(), buf, sizeof(buf));
		*end = '\n';
		full_write(pid_fd, buf, end - buf + 1);
	}
	close(pid_fd);
}
示例#2
0
// Convert signed integer to ascii, like utoa_to_buf()
char *itoa_to_buf(int n, char *buf, unsigned buflen)
{
	if (buflen && n<0) {
		n = -n;
		*buf++ = '-';
		buflen--;
	}
	return utoa_to_buf((unsigned)n, buf, buflen);
}
示例#3
0
int write_pidfile(const char *path)
{
	int pid_fd;
	char *end;
	char buf[sizeof(int)*3 + 2];

	/* we will overwrite stale pidfile */
	pid_fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0666);
	if (pid_fd < 0)
		return 0;
	/* few bytes larger, but doesn't use stdio */
	end = utoa_to_buf(getpid(), buf, sizeof(buf));
	end[0] = '\n';
	full_write(pid_fd, buf, end - buf + 1);
	close(pid_fd);
	return 1;
}
示例#4
0
// Convert unsigned integer to ascii using a static buffer (returned).
char *utoa(unsigned n)
{
	*(utoa_to_buf(n, local_buf, sizeof(local_buf))) = '\0';

	return local_buf;
}
示例#5
0
static void startservice(struct svdir *s)
{
	int p;
	const char *arg[4];
	char exitcode[sizeof(int)*3 + 2];

	if (s->state == S_FINISH) {
/* Two arguments are given to ./finish. The first one is ./run exit code,
 * or -1 if ./run didnt exit normally. The second one is
 * the least significant byte of the exit status as determined by waitpid;
 * for instance it is 0 if ./run exited normally, and the signal number
 * if ./run was terminated by a signal. If runsv cannot start ./run
 * for some reason, the exit code is 111 and the status is 0.
 */
		arg[0] = "./finish";
		arg[1] = "-1";
		if (WIFEXITED(s->wstat)) {
			*utoa_to_buf(WEXITSTATUS(s->wstat), exitcode, sizeof(exitcode)) = '\0';
			arg[1] = exitcode;
		}
		//arg[2] = "0";
		//if (WIFSIGNALED(s->wstat)) {
			arg[2] = utoa(WTERMSIG(s->wstat));
		//}
		arg[3] = NULL;
	} else {
		arg[0] = "./run";
		arg[1] = NULL;
		custom(s, 'u');
	}

	if (s->pid != 0)
		stopservice(s); /* should never happen */
	while ((p = vfork()) == -1) {
		warn_cannot("vfork, sleeping");
		sleep(5);
	}
	if (p == 0) {
		/* child */
		if (haslog) {
			/* NB: bug alert! right order is close, then dup2 */
			if (s->islog) {
				xchdir("./log");
				close(logpipe.wr);
				xdup2(logpipe.rd, 0);
			} else {
				close(logpipe.rd);
				xdup2(logpipe.wr, 1);
			}
		}
		/* Non-ignored signals revert to SIG_DFL on exec anyway */
		/*bb_signals(0
			+ (1 << SIGCHLD)
			+ (1 << SIGTERM)
			, SIG_DFL);*/
		sig_unblock(SIGCHLD);
		sig_unblock(SIGTERM);
		execv(arg[0], (char**) arg);
		fatal2_cannot(s->islog ? "start log/" : "start ", arg[0]);
	}
	/* parent */
	if (s->state != S_FINISH) {
		gettimeofday_ns(&s->start);
		s->state = S_RUN;
	}
	s->pid = p;
	pidchanged = 1;
	s->ctrl = C_NOOP;
	update_status(s);
}