📄 pgetl.c
字号:
/*
* 18-Feb-1987 bw Fix off-by-one errors.
* 22-Dec-1987 bw Fix strncrlf hang, redo buffer handling.
* Pay attention to max argument
*---------------------------------------------------------------------------
*
* pgetl.c - do fgetl() from a pipe without blocking. In particular, do this:
*
* If ( Buffer is empty )
* Fill Buffer
* If ( 0 length request ) return ( there is more data )?
* { - 1 allows for '\0' byte in target }
* set max to min(max - 1, count of valid bytes);
* If ( "full line" is buffered )
* Transfer Full line.
* Clean up and go
* Move partial line to base of buffer
* Fill rest of buffer
* If ( we have a "full line" now ) transfer it
* Else
* return FALSE
*
* A "full line" is either LF terminated or len bytes long, whichever
* comes first.
*
* The Fill Buffer method is this:
*
* Set Read Semaphore
* Read Asynch
* Wait on Read Semaphore with Timeout ( ~.1 seconds )
*
* Note that if a 0 length read is requested, the effect is to check for
* unread data.
*
* Note that if the destination buffer is NULL, one line is read and flushed.
*/
#include <os2.h>
#include "..\h\tools.h"
static int FilBuf( int, char *, int );
pgetl ( buf, max, fh )
char *buf;
int max;
int fh;
{
static char buffer[BUFSIZ];
static int cnt = 0; /* Valid bytes remaining in buffer */
static char * pValid = buffer; /* First valid byte */
char * eos;
if ( ! cnt )
if ( ! (cnt = FilBuf( fh, buffer, BUFSIZ )) ) return FALSE;
else pValid = buffer;
/* There is now at least 1 character in buffer */
if ( ! max-- ) return cnt; /* max == 0 means ret unread chars */
/* dec max for '\0' byte */
max = min( max , BUFSIZ );
/* Check for full line already present */
if ( (eos = strncrlfend(pValid, cnt)) || max <= cnt ) goto full_line;
/* Move partial line down to base of buffer */
Move ((char far *)pValid, (char far *)buffer, cnt);
pValid = buffer;
cnt += FilBuf( fh, buffer + cnt, BUFSIZ - cnt );
if ( (eos = strncrlfend(buffer, cnt)) || max <= cnt ) goto full_line;
return FALSE;
full_line:
{
int linelen, deadchars;
if ((linelen = eos ? eos - pValid : max) > max)
linelen = max;
if ( buf ) /* Give user their line, if they want it */
{
Move( (char far *)pValid, (char far *)buf, linelen );
buf[linelen] = '\0';
}
deadchars = linelen + (eos != 0) + (eos && *eos == '\r');
cnt -= deadchars;
/* Now remove it from my buffer */
pValid += deadchars;
return TRUE;
}
}
/*
* strncrlfend - Return a pointer to the first of:
*
* The CR in a CR/LF pair
* A lone LF
* The 0 byte.
*
* or return NULL if none of these can be found in the first 'max' characters.
*
* Note: If the LF in a CR/LF pair is the 'max' + 1st character, return NULL.
*/
char * strncrlfend( str, max )
char * str;
int max;
{
int i;
for (i = 0; i < max; i++)
if (!str[i] || str[i] == '\n')
return str + i - (i && str[i-1] == '\r');
return NULL;
}
/*
* FilBuf - read from handle, assuming that the read may block. If the block
* last more than .1 seconds, return 0 bytes read. In this case, assume that
* the caller is willing to have 'buf' filled at some random later time.
*/
static int FilBuf( fh, buf, amt )
int fh;
char * buf;
int amt;
{
static unsigned long semRead;
static unsigned BytesRead, retC;
static flagType pending = FALSE;
if ( ! pending )
{
DosSemSet ( (HSEM)&semRead );
DosReadAsync ( fh,
(unsigned long far *)&semRead,
(PUSHORT)&retC,
(char far *)buf,
amt,
(PUSHORT)&BytesRead );
}
if ( DosSemWait ( (HSEM)&semRead, 100L ) )
{
pending = TRUE;
return 0;
}
else
{
pending = FALSE;
return BytesRead;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -