home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD1.bin
/
useful
/
comm
/
tcp
/
amitcp
/
src
/
netlib
/
lineread.c
< prev
next >
Wrap
Text File
|
1994-02-05
|
12KB
|
430 lines
/*
* lineread.c
*
* Author: Tomi Ollila <too@cs.hut.fi>
*
* This module is FREEWARE. Standard "NO WARRANTY" disclaimer applies.
*
* Created: Thu Jul 12 16:40:03 EET 1990 too
* Last modified: Sat Feb 5 15:13:01 1994 too
*
* $Id: lineread.c,v 3.2 1994/02/05 13:00:45 too Exp $
*
* HISTORY
* $Log: lineread.c,v $
* Revision 3.2 1994/02/05 13:00:45 too
* Added charRead autodoc
*
* Revision 3.1 1994/02/03 19:22:31 ppessi
* Added autodoc
*
* Revision 1.3 1993/07/13 15:15:53 too
* Made lineread.c compile without <sys/cdefs.h> file
*
* Revision 1.1 1993/06/16 16:43:52 too
* Initial revision
*/
/*
* since charRead is a macro package and having no `.c' -file, it's
* documentation is added here
*/
/****** net.lib/charRead ****************************************************
*
* NAME
* charRead -- read characters from socket one by one.
*
* SYNOPSIS
* initCharRead(rc, fd)
*
* void initCharRead(struct CharRead *, int);
*
*
* character = charRead(rc)
*
* int charRead(struct CharRead *);
*
*
* DESCRIPTION
* charRead is a macro package which return characters one by one
* from given socket input stream. The socket where data is to be read
* is set by calling initCharRead(): rc is the pointer to charread
* structure previously allocated. fd is the (socket) descriptor where
* reading is to be done.
*
* charRead() returns the next character from input stream or one of
* the following:
*
* RC_DO_SELECT (-3) - read input buffer is returned. Do select
* before next call if you don't want charread
* to block.
*
* RC_EOF (-2) - end-of-file condition has occurred.
*
* RC_ERROR (-1) - there has been an error while filling new
* charread buffer. Check the value of Errno()
*
* NOTE
* Always use variable of type int to store return value from charRead()
* since the numeric value of characters returned may vary between
* 0 -255 (or even greater). As you may know, -3 equals 253 if of type
* unsigned char.
*
* EXAMPLE
* \*
* * This piece of code shows how to use charread with select()
* *\
* #include <sys/types.h>
* #include <sys/socket.h>
* #include <charread.h>
*
* main_loop(int sock)
* {
* struct CharRead rc;
* fd_set readfds;
* int c;
*
* initCharRead(&rc, sock);
*
* FD_ZERO(&readfds);
*
* while(1) {
* FD_SET(sock, &readfds);
*
* if (select(sock + 1. &readfds, NULL, NULL, NULL)) < 0) {
* perror("select");
* break;
* }
* if (FD_ISSET(sock, &readfds)) {
* while((c = charRead(&rc)) >= 0)
* handle_next_input_character(c);
* if (c == RC_EOF)
* break;
* if (c == RC_ERROR) {
* perror("charRead");
* break;
* }
* }
* }
* }
*
* PORTABILITY
* The source file charread.h should be able to be used in
* UNIX programs as is.
*
* AUTHORS
* Tomi Ollila,
* the AmiTCP/IP Group <amitcp-group@hut.fi>,
*
* SEE ALSO
* lineRead(), bsdsocket.library/recv()
*****************************************************************************
*
*/
/****** net.lib/lineRead *****************************************************
NAME
lineRead -- read newline terminated strings from socket
SYNOPSIS
initLineRead(rl, fd, lftype, bufsize)
void initLineRead(struct LineRead *, int, int, int);
length = lineRead(rl)
int lineread(struct LineRead *);
FUNCTION
lineRead() reads newline terminated strings from given descriptor
very efficiently. All the options needed are set by calling
initLineRead(): rl is the pointer to lineread structure previously
allocated. fd is the (socket) descriptor where reading is to be
done. lftype can have following 3 values:
RL_LFNOTREQ - Newline terminated strings are returned unless
there is no newlines left in currently buffered
input. In this case remaining buffer is returned.
RL_LFREQLF - If there is no newlines left in currently buffered
input the remaining input data is copied at the
start of buffer. Caller is informed that next
call will fill the buffer (and it may block).
Lines are always returned with newline at the end
unless the string is longer than whole buffer.
RL_LFREQNUL - Like LF_REQLF, but remaining newline is removed.
Note here that lenght is one longer that actual
string length since line that has only one
newline at the end would return length as 0
which indigate string incomplete condition.
bufsize is used to tell lineread how big the receive buffer is.
always put RL_BUFSIZE here since that value is used to determine
the memory allocated for the buffer. This option is given to you
so you may decide to use different buffer size than the default
1024.
lineRead() returns the newline terminated string in rl_line field
of lineread structure. Return values of lineRead() are:
1 - RL_BUFSIZE - normal length of returned string.
0 - If zero is returned just after select(),
end-of-file condition has occurred.
Otherwise string is not completed yet.
Make sure you call select() (or use non-
blocking IO) if you don't want next call
to block.
-1 - if rl_Line field of lineread structure
is NULL, it indicates error condition.
If rl_Line points to start of string
buffer, input string has been longer
than buffer. In this case rl_Line points
to zero terminated string of length
RL_BUFSIZE.
You may modify the zero terminated string returned by lineRead() in
any way, but memory around the string is private lineread memory.
EXAMPLE
\*
* The following code shows how to use lineread with select()
*\
#ifdef USE_LOW_MEMORY_BUFFER
#define RL_BUFSIZE 256
#endif
#include <sys/types.h>
#ifdef AMIGA
#include <bsdsocket.h>
#endif
#include <lineread.h>
#define NULL 0
...
main_loop(int sock)
{
struct LineRead * rl;
int length;
fd_set reafdfs;
if (rl = (struct LineRead *)AllocMem(sizeof (*rl), 0)) {
initLineRead(rl, sock, LF_REQLF, RL_BUFSIZE);
FD_ZERO(&readfds);
while(1) {
FD_SET(sock, &readfds);
if (select(sock + 1, &readfds, NULL, NULL, NULL)) < 0) {
perror("select");
break;
}
if (FD_ISSET(sock, &readfds))
if ((length = lineRead(rl)) == 0) \* EOF *\
break;
do {
if (length > 0)
write(1, rl->rl_Line, length); \* stdout. write() for *\
\* speed demonstration *\
else { \* length == -1 *\
if (rl->rl_Line == NULL); {
perror("lineRead");
break;
}
else {
fprintf(stderr, "lineread in