busybox-1.32.0/util-linux/mdev.c
static int
wait_for_seqfile(unsigned expected_seq)
{
	/* We time out after 2 sec */
	static const struct timespec ts = { 0, 32*1000*1000 };
	int timeout = 2000 / 32;
	int seq_fd = -1;
	int do_once = 1;
	sigset_t set_CHLD;

	sigemptyset(&set_CHLD);
	sigaddset(&set_CHLD, SIGCHLD);
	sigprocmask(SIG_BLOCK, &set_CHLD, NULL);

	for (;;) {
		int seqlen;
		char seqbuf[sizeof(long)*3 + 2];
		unsigned seqbufnum;

		if (seq_fd < 0) {
			seq_fd = open("mdev.seq", O_RDWR);
			if (seq_fd < 0)
				break;
			close_on_exec_on(seq_fd);
		}
		seqlen = pread(seq_fd, seqbuf, sizeof(seqbuf) - 1, 0);
		if (seqlen < 0) {
			close(seq_fd);
			seq_fd = -1;
			break;
		}
		seqbuf[seqlen] = '\0';
		if (seqbuf[0] == '\n' || seqbuf[0] == '\0') {
			/* seed file: write out seq ASAP */
			xwrite_str(seq_fd, utoa(expected_seq));
			xlseek(seq_fd, 0, SEEK_SET);
			dbg2s("first seq written");
			break;
		}
		seqbufnum = atoll(seqbuf);
		if (seqbufnum == expected_seq) {
			/* correct idx */
			break;
		}
		if (seqbufnum > expected_seq) {
			/* a later mdev runs already (this was seen by users to happen) */
			/* do not overwrite seqfile on exit */
			close(seq_fd);
			seq_fd = -1;
			break;
		}
		if (do_once) {
			dbg2("%s mdev.seq='%s', need '%u'", curtime(), seqbuf, expected_seq);
			do_once = 0;
		}
		if (sigtimedwait(&set_CHLD, NULL, &ts) >= 0) {
			dbg3("woken up");
			continue; /* don't decrement timeout! */
		}
		if (--timeout == 0) {
			dbg1("%s mdev.seq='%s'", "timed out", seqbuf);
			break;
		}
	}
	sigprocmask(SIG_UNBLOCK, &set_CHLD, NULL);
	return seq_fd;
}
/* If it exists, does /dev/mdev.seq match $SEQNUM?
 * If it does not match, earlier mdev is running
 * in parallel, and we need to wait.
 * Active mdev pokes us with SIGCHLD to check the new file.
 */
If it exists, does /dev/mdev.seq match $SEQNUM.
If it does not match, earlier mdev is running
in parallel, and we need to wait.
Active mdev pokes us with SIGCHLD to check the new file.
If it exists does / dev / mdev . seq match $SEQNUM . If it does not match earlier mdev is running in parallel and we need to wait . Active mdev pokes us with SIGCHLD to check the new file .
static int
wait_for_seqfile(unsigned expected_seq)
{
	static const struct timespec ts = { 0, 32*1000*1000 };
	int timeout = 2000 / 32;
	int seq_fd = -1;
	int do_once = 1;
	sigset_t set_CHLD;
	sigemptyset(&set_CHLD);
	sigaddset(&set_CHLD, SIGCHLD);
	sigprocmask(SIG_BLOCK, &set_CHLD, NULL);
	for (;;) {
		int seqlen;
		char seqbuf[sizeof(long)*3 + 2];
		unsigned seqbufnum;
		if (seq_fd < 0) {
			seq_fd = open("mdev.seq", O_RDWR);
			if (seq_fd < 0)
				break;
			close_on_exec_on(seq_fd);
		}
		seqlen = pread(seq_fd, seqbuf, sizeof(seqbuf) - 1, 0);
		if (seqlen < 0) {
			close(seq_fd);
			seq_fd = -1;
			break;
		}
		seqbuf[seqlen] = '\0';
		if (seqbuf[0] == '\n' || seqbuf[0] == '\0') {
			xwrite_str(seq_fd, utoa(expected_seq));
			xlseek(seq_fd, 0, SEEK_SET);
			dbg2s("first seq written");
			break;
		}
		seqbufnum = atoll(seqbuf);
		if (seqbufnum == expected_seq) {
			break;
		}
		if (seqbufnum > expected_seq) {
			close(seq_fd);
			seq_fd = -1;
			break;
		}
		if (do_once) {
			dbg2("%s mdev.seq='%s', need '%u'", curtime(), seqbuf, expected_seq);
			do_once = 0;
		}
		if (sigtimedwait(&set_CHLD, NULL, &ts) >= 0) {
			dbg3("woken up");
			continue; 
		}
		if (--timeout == 0) {
			dbg1("%s mdev.seq='%s'", "timed out", seqbuf);
			break;
		}
	}
	sigprocmask(SIG_UNBLOCK, &set_CHLD, NULL);
	return seq_fd;
}
static int wait_for_seqfile ( unsigned expected_seq ) { static const struct timespec ts = { 0 , 32 * 1000 * 1000 } ; int timeout = 2000 / 32 ; int seq_fd = -1 ; int do_once = 1 ; sigset_t set_CHLD ; sigemptyset ( & set_CHLD ) ; sigaddset ( & set_CHLD , SIGCHLD ) ; sigprocmask ( SIG_BLOCK , & set_CHLD , NULL ) ; for ( ; ; ) { int seqlen ; char seqbuf [ sizeof ( long ) * 3 + 2 ] ; unsigned seqbufnum ; if ( seq_fd < 0 ) { seq_fd = open ( " " , O_RDWR ) ; if ( seq_fd < 0 ) break ; close_on_exec_on ( seq_fd ) ; } seqlen = pread ( seq_fd , seqbuf , sizeof ( seqbuf ) - 1 , 0 ) ; if ( seqlen < 0 ) { close ( seq_fd ) ; seq_fd = -1 ; break ; } seqbuf [ seqlen ] = ' \0 ' ; if ( seqbuf [ 0 ] == ' \n ' || seqbuf [ 0 ] == ' \0 ' ) { xwrite_str ( seq_fd , utoa ( expected_seq ) ) ; xlseek ( seq_fd , 0 , SEEK_SET ) ; dbg2s ( " " ) ; break ; } seqbufnum = atoll ( seqbuf ) ; if ( seqbufnum == expected_seq ) { break ; } if ( seqbufnum > expected_seq ) { close ( seq_fd ) ; seq_fd = -1 ; break ; } if ( do_once ) { dbg2 ( " " , curtime ( ) , seqbuf , expected_seq ) ; do_once = 0 ; } if ( sigtimedwait ( & set_CHLD , NULL , & ts ) >= 0 ) { dbg3 ( " " ) ; continue ; } if ( -- timeout == 0 ) { dbg1 ( " " , " " , seqbuf ) ; break ; } } sigprocmask ( SIG_UNBLOCK , & set_CHLD , NULL ) ; return seq_fd ; }
If it exists, does /dev/mdev.seq match $SEQNUM?
If it exists does / dev / mdev . seq match $SEQNUM?
/* We time out after 2 sec */ /* seed file: write out seq ASAP */ /* correct idx */ /* a later mdev runs already (this was seen by users to happen) */ /* do not overwrite seqfile on exit */ /* don't decrement timeout! */