ns-allinone-2.35/nam-1.15/nam_stream.cc
char *
NamStreamPipe::gets(char *buf, int len)
{
	char *ret = buf;
	off_t off = ftell(back_);

	read_pipe();

	/*
	 * Case 1: The pipe is just opened to read, but the other end
	 *         of the pipe has not open it to write. So, read_pipe()
	 *         will close it.
	 *         => Reopen the pipe, and return a fake initial command.
	 * Case 2: Both ends have opened the pipe, but the writer has not
	 *         produced any data.
	 *         => Return a fake initial command.
	 * The fake return value needs to be an initial command. Comment
	 * lines or empty lines are not accepted by nam (e.g. see animator.tcl)
	 *
	 */
	if (back_len_ == 0) {
#ifndef WIN32
		// Windows doesn't have O_NONBLOCK
		if (front_ == -1) {   // it may be closed by read_pipe()
			front_ = ::open(pipename_, O_RDONLY | O_NONBLOCK);
		}
#endif
		strcpy(buf, "V -t * -v 1.0a9 -a 0\n");
		return buf;
	}

	while (1) {
	/*
	 * Case 3: The backup file is over, but there is no new data in pipe.
	 *         => Busy waiting for new input.	XXX
	 *            This is not a good idea. Since nam is a
	 *            single-thread application, busy waiting makes nam
	 *            unable to handle other events (e.g. Window, I/O events).
	 *            The problem here is that we don't know what to return
	 *            when there is no new input from the pipe.
	 *            (see netmodel.cc#NetModel::handle())
	 */
		if (! fgets(buf, len, back_)) {	// EOF backup file
			if (front_ == -1)
				return NULL;
			else	read_pipe();
		}
	/*
	 * Case 4: The backup file is near to over and the last line is
	 *         not complete.
	 *         => Busy waiting for new input.	XXX
	 */
		else {
			int n = strlen(buf) - 1;
			if (buf[n] == '\n')	// here is the normal case
				return buf;
			if (front_ == -1)
				return NULL;
			fseek(back_, off, SEEK_SET);
			read_pipe();
		}
	}
	return ret;
}
/**********************************************************************
 * Read a line. Nam requires the following semantics:
 * RETURN: NULL to indicate end-of-file
 * RETURN: a COMPLETE line, i.e. a complete nam command. It can't return
 *         a partial line, otherwise nam will complain because nam
 *         assumes NamStream is line-buffered.
 * We assume that there always is new data in the pipe. It's the
 * responsibility of the pipe data producer (i.e. the application that
 * generates the nam events to the pipe) to ensure we always have new
 * input. If we have no new input, then we simply block.
 **********************************************************************/
Read a line. Nam requires the following semantics:
RETURN: NULL to indicate end-of-file
RETURN: a COMPLETE line, i.e. a complete nam command. It can't return
a partial line, otherwise nam will complain because nam
assumes NamStream is line-buffered.
We assume that there always is new data in the pipe. It's the
responsibility of the pipe data producer  to ensure we always have new
input. If we have no new input, then we simply block.
Read a line . Nam requires the following semantics : RETURN : NULL to indicate end - of - file RETURN : a COMPLETE line i . e . a complete nam command . It can ' t return a partial line otherwise nam will complain because nam assumes NamStream is line - buffered . We assume that there always is new data in the pipe . It ' s the responsibility of the pipe data producer to ensure we always have new input . If we have no new input then we simply block .
char *
NamStreamPipe::gets(char *buf, int len)
{
	char *ret = buf;
	off_t off = ftell(back_);
	read_pipe();
	if (back_len_ == 0) {
#ifndef WIN32
		if (front_ == -1) {   
			front_ = ::open(pipename_, O_RDONLY | O_NONBLOCK);
		}
#endif
		strcpy(buf, "V -t * -v 1.0a9 -a 0\n");
		return buf;
	}
	while (1) {
		if (! fgets(buf, len, back_)) {	
			if (front_ == -1)
				return NULL;
			else	read_pipe();
		}
		else {
			int n = strlen(buf) - 1;
			if (buf[n] == '\n')	
				return buf;
			if (front_ == -1)
				return NULL;
			fseek(back_, off, SEEK_SET);
			read_pipe();
		}
	}
	return ret;
}
char * NamStreamPipe :: gets ( char * buf , int len ) { char * ret = buf ; off_t off = ftell ( back_ ) ; read_pipe ( ) ; if ( back_len_ == 0 ) { #ifndef WIN32 if ( front_ == -1 ) { front_ = :: open ( pipename_ , O_RDONLY | O_NONBLOCK ) ; } #endif strcpy ( buf , " \n " ) ; return buf ; } while ( 1 ) { if ( ! fgets ( buf , len , back_ ) ) { if ( front_ == -1 ) return NULL ; else read_pipe ( ) ; } else { int n = strlen ( buf ) - 1 ; if ( buf [ n ] == ' \n ' ) return buf ; if ( front_ == -1 ) return NULL ; fseek ( back_ , off , SEEK_SET ) ; read_pipe ( ) ; } } return ret ; }
Read a line.
Read a line .
/*
	 * Case 1: The pipe is just opened to read, but the other end
	 *         of the pipe has not open it to write. So, read_pipe()
	 *         will close it.
	 *         => Reopen the pipe, and return a fake initial command.
	 * Case 2: Both ends have opened the pipe, but the writer has not
	 *         produced any data.
	 *         => Return a fake initial command.
	 * The fake return value needs to be an initial command. Comment
	 * lines or empty lines are not accepted by nam (e.g. see animator.tcl)
	 *
	 */ // Windows doesn't have O_NONBLOCK // it may be closed by read_pipe() /*
	 * Case 3: The backup file is over, but there is no new data in pipe.
	 *         => Busy waiting for new input.	XXX
	 *            This is not a good idea. Since nam is a
	 *            single-thread application, busy waiting makes nam
	 *            unable to handle other events (e.g. Window, I/O events).
	 *            The problem here is that we don't know what to return
	 *            when there is no new input from the pipe.
	 *            (see netmodel.cc#NetModel::handle())
	 */ // EOF backup file /*
	 * Case 4: The backup file is near to over and the last line is
	 *         not complete.
	 *         => Busy waiting for new input.	XXX
	 */ // here is the normal case