Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

readline.c

Go to the documentation of this file.
00001 
00008 /* {{{ Initial headers */
00009 /*
00010  * $LastChangedDate: 2003-11-27 01:55:17 +0100 (Thu, 27 Nov 2003) $
00011  * $LastChangedRevision: 5 $
00012  * $LastChangedBy: ckruse $
00013  *
00014  */
00015 /* }}} */
00016 
00017 /* {{{ Includes */
00018 #include "config.h"
00019 #include "defines.h"
00020 
00021 #include <stdlib.h>
00022 #include <stdio.h>
00023 #include <pthread.h>
00024 #include <errno.h>
00025 
00026 #include <sys/types.h>
00027 #include <unistd.h>
00028 
00029 #include "readline.h"
00030 /* }}} */
00031 
00032 /*
00033  * Returns: static ssize_t   number of characters read
00034  * Parameters:
00035  *    - rline_t *tsd   the readline structure
00036  *    - int fd         the socket descriptor
00037  *    - u_char *ptr     a pointer to a character variable
00038  *
00039  * this function reads a character from a socket stream
00040  *
00041  */
00042 static ssize_t my_read(rline_t *tsd,int fd,u_char *ptr) {
00043   int calls = 0;
00044 
00045   if(tsd->rl_cnt <= 0) {
00046     again:
00047     if((tsd->rl_cnt = read(fd,tsd->rl_buf,MAXLINE)) < 0) {
00048       if(errno == EINTR || errno == EAGAIN) {
00049         calls += 1;
00050         if(calls <= 3) {
00051           goto again;
00052         }
00053       }
00054 
00055       return -1;
00056     } else if(tsd->rl_cnt == 0) {
00057       return 0;
00058     }
00059 
00060     tsd->rl_bufptr = tsd->rl_buf;
00061   }
00062 
00063   tsd->rl_cnt--;
00064   *ptr = *tsd->rl_bufptr++;
00065 
00066   return 1;
00067 }
00068 
00069 /*
00070  * Returns: u_char *     a string read from the socket
00071  * Parameters:
00072  *    - int fd         the socket descriptor
00073  *    - rline_t *tsd   a thread structure
00074  *
00075  * this function reads a complete line from a socket
00076  *
00077  */
00078 u_char *readline(int fd,rline_t *tsd) {
00079   int  n,rc,len = MAXLINE;
00080   u_char c = '\0',*ptr,*line = malloc(MAXLINE);
00081 
00082   if(!line) return NULL;
00083 
00084   tsd->rl_mem = MAXLINE;
00085   tsd->rl_len = 0;
00086 
00087   ptr = line;
00088   for(n=1;c != '\n';n++) {
00089     if((rc = my_read(tsd,fd,&c)) == 1) {
00090 
00091       if(n >= len) {
00092         len += MAXLINE;
00093 
00094         line = realloc(line,len);
00095         if(!line) return NULL;
00096 
00097         ptr = &line[n-1];
00098 
00099         tsd->rl_mem = len;
00100       }
00101 
00102       *ptr++ = c;
00103       tsd->rl_len++;
00104 
00105       if(c == '\n') {
00106         break;
00107       }
00108     }
00109     else if(rc == 0) {
00110       if(n == 1) { /* no data read */
00111         free(line);
00112         return NULL;
00113       }
00114       else {
00115         break;
00116       }
00117     }
00118     else {
00119       free(line);
00120       return NULL;
00121     }
00122   }
00123 
00124   *ptr = '\0';
00125   return line;
00126 }
00127 
00128 /*
00129  * Returns: ssize_t       number of characters written
00130  * Parameters:
00131  *    - int fd            the socket descriptor
00132  *    - const void *vptr  the data pointer
00133  *    - size_t n          the length of the data
00134  *
00135  * this function writes data to a socket. It makes sure,
00136  * that all data is sent.
00137  *
00138  */
00139 ssize_t writen(int fd,const void *vptr,size_t n) {
00140   size_t  nleft;
00141   ssize_t nwritten;
00142   const u_char *ptr;
00143 
00144   ptr   = vptr;
00145   nleft = n;
00146   while(nleft > 0) {
00147     if((nwritten = write(fd,ptr,nleft)) <= 0) {
00148       if(errno == EINTR || errno == EAGAIN) {
00149         nwritten = 0;
00150       }
00151       else {
00152         return -1;
00153       }
00154     }
00155 
00156     nleft -= nwritten;
00157     ptr   += nwritten;
00158   }
00159 
00160   return n;
00161 }
00162 
00163 /* eof */

Generated on Sun Apr 25 16:37:39 2004 for Classic Forum by doxygen 1.3.5