bio_socket.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  $RCSfile$
00003  -------------------
00004  cvs         : $Id$
00005  begin       : Fri Feb 07 2003
00006  copyright   : (C) 2003 by Martin Preuss
00007  email       : martin@libchipcard.de
00008 
00009  ***************************************************************************
00010  *                                                                         *
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU Lesser General Public            *
00013  *   License as published by the Free Software Foundation; either          *
00014  *   version 2.1 of the License, or (at your option) any later version.    *
00015  *                                                                         *
00016  *   This library is distributed in the hope that it will be useful,       *
00017  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00018  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00019  *   Lesser General Public License for more details.                       *
00020  *                                                                         *
00021  *   You should have received a copy of the GNU Lesser General Public      *
00022  *   License along with this library; if not, write to the Free Software   *
00023  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00024  *   MA  02111-1307  USA                                                   *
00025  *                                                                         *
00026  ***************************************************************************/
00027 
00028 
00029 #ifdef HAVE_CONFIG_H
00030 # include <config.h>
00031 #endif
00032 
00033 #define DISABLE_DEBUGLOG
00034 
00035 
00036 #include "bio_socket_p.h"
00037 #include <gwenhywfar/misc.h>
00038 #include <gwenhywfar/text.h>
00039 #include <stdlib.h>
00040 #include <unistd.h>
00041 #include <string.h>
00042 #include <errno.h>
00043 
00044 #include <gwenhywfar/debug.h>
00045 
00046 
00047 GWEN_INHERIT(GWEN_BUFFEREDIO, GWEN_BUFFEREDIO_SOCKET)
00048 /* No trailing semicolon here because this is a macro call */
00049 
00050 
00051 GWEN_BUFFEREDIO_SOCKET *GWEN_BufferedIO_Socket_Table__new() {
00052   GWEN_BUFFEREDIO_SOCKET *bft;
00053 
00054   GWEN_NEW_OBJECT(GWEN_BUFFEREDIO_SOCKET, bft);
00055 
00056   return bft;
00057 }
00058 
00059 
00060 
00061 void GWEN_BufferedIO_Socket_Table__free(GWEN_BUFFEREDIO_SOCKET *bft) {
00062   if (bft) {
00063     GWEN_Socket_free(bft->sock);
00064     GWEN_FREE_OBJECT(bft);
00065   }
00066 }
00067 
00068 
00069 
00070 int GWEN_BufferedIO_Socket__Read(GWEN_BUFFEREDIO *dm,
00071                                  char *buffer,
00072                                  int *size,
00073                                  int timeout){
00074   int err;
00075   GWEN_BUFFEREDIO_SOCKET *bft;
00076   int retrycount;
00077 
00078   DBG_DEBUG(GWEN_LOGDOMAIN, "Reading %d bytes", *size);
00079   assert(dm);
00080   assert(buffer);
00081   assert(size);
00082   bft=GWEN_INHERIT_GETDATA(GWEN_BUFFEREDIO, GWEN_BUFFEREDIO_SOCKET, dm);
00083   assert(bft);
00084   assert(bft->sock);
00085   if (*size<1) {
00086     DBG_WARN(GWEN_LOGDOMAIN, "Nothing to read");
00087     *size=0;
00088     return 0;
00089   }
00090 
00091   if (timeout>=0) {
00092     retrycount=GWEN_BUFFEREDIO_SOCKET_TRIES;
00093     while(retrycount) {
00094       err=GWEN_Socket_WaitForRead(bft->sock, timeout);
00095       if (err) {
00096         if (err==GWEN_ERROR_TIMEOUT || err!=GWEN_ERROR_INTERRUPTED) {
00097           DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00098           return err;
00099         }
00100       }
00101       else
00102         break;
00103       retrycount--;
00104     } /* while */
00105     if (retrycount<1) {
00106       DBG_ERROR(GWEN_LOGDOMAIN, "Interrupted too often, giving up");
00107       return GWEN_ERROR_READ;
00108     }
00109   } /* if timeout */
00110 
00111   /* ok. socket seems to be ready now */
00112   retrycount=GWEN_BUFFEREDIO_SOCKET_TRIES;
00113   while(retrycount) {
00114     err=GWEN_Socket_Read(bft->sock, buffer, size);
00115     if (err && err!=GWEN_ERROR_INTERRUPTED) {
00116       DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00117       return err;
00118     }
00119     else
00120       break;
00121     retrycount--;
00122   } /* while */
00123   if (retrycount<1) {
00124     DBG_ERROR(GWEN_LOGDOMAIN, "Interrupted too often, giving up");
00125     return GWEN_ERROR_READ;
00126   }
00127 
00128   DBG_DEBUG(GWEN_LOGDOMAIN, "Reading ok (%d bytes)", *size);
00129   return 0;
00130 }
00131 
00132 
00133 
00134 int GWEN_BufferedIO_Socket__Write(GWEN_BUFFEREDIO *dm,
00135                                   const char *buffer,
00136                                   int *size,
00137                                   int timeout){
00138   int err;
00139   GWEN_BUFFEREDIO_SOCKET *bft;
00140   int retrycount;
00141 
00142   assert(dm);
00143   assert(buffer);
00144   assert(size);
00145   bft=GWEN_INHERIT_GETDATA(GWEN_BUFFEREDIO, GWEN_BUFFEREDIO_SOCKET, dm);
00146   assert(bft);
00147   assert(bft->sock);
00148   if (*size<1) {
00149     DBG_WARN(GWEN_LOGDOMAIN, "Nothing to write");
00150     *size=0;
00151     return 0;
00152   }
00153 
00154   if (timeout>=0) {
00155     retrycount=GWEN_BUFFEREDIO_SOCKET_TRIES;
00156     while(retrycount) {
00157       err=GWEN_Socket_WaitForWrite(bft->sock, timeout);
00158       if (err) {
00159         if (err==GWEN_ERROR_TIMEOUT || err!=GWEN_ERROR_INTERRUPTED) {
00160           DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00161           return err;
00162         }
00163       }
00164       else
00165         break;
00166       retrycount--;
00167     } /* while */
00168     if (retrycount<1) {
00169       DBG_ERROR(GWEN_LOGDOMAIN, "Interrupted too often, giving up");
00170       return GWEN_ERROR_WRITE;
00171     }
00172   } /* if timeout */
00173 
00174   /* ok. socket seems to be ready now */
00175   retrycount=GWEN_BUFFEREDIO_SOCKET_TRIES;
00176   while(retrycount) {
00177     err=GWEN_Socket_Write(bft->sock, buffer, size);
00178     if (err && err!=GWEN_ERROR_INTERRUPTED) {
00179       DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00180       return err;
00181     }
00182     else
00183       break;
00184     retrycount--;
00185   } /* while */
00186   if (retrycount<1) {
00187     DBG_ERROR(GWEN_LOGDOMAIN, "Interrupted too often, giving up");
00188     return GWEN_ERROR_WRITE;
00189   }
00190 
00191   DBG_VERBOUS(GWEN_LOGDOMAIN, "Writing ok");
00192   return 0;
00193 }
00194 
00195 
00196 
00197 int GWEN_BufferedIO_Socket__Close(GWEN_BUFFEREDIO *dm){
00198   GWEN_BUFFEREDIO_SOCKET *bft;
00199   int err;
00200 
00201   assert(dm);
00202   bft=GWEN_INHERIT_GETDATA(GWEN_BUFFEREDIO, GWEN_BUFFEREDIO_SOCKET, dm);
00203   assert(bft);
00204   assert(bft->sock);
00205   DBG_DEBUG(GWEN_LOGDOMAIN, "Closing socket");
00206   err=GWEN_Socket_Close(bft->sock);
00207   if (err) {
00208     DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00209     return err;
00210   }
00211   return 0;
00212 }
00213 
00214 
00215 
00216 void GWENHYWFAR_CB GWEN_BufferedIO_Socket_FreeData(GWEN_UNUSED void *bp, void *p) {
00217   GWEN_BUFFEREDIO_SOCKET *bft;
00218 
00219   bft=(GWEN_BUFFEREDIO_SOCKET*)p;
00220   GWEN_BufferedIO_Socket_Table__free(bft);
00221 }
00222 
00223 
00224 
00225 GWEN_BUFFEREDIO *GWEN_BufferedIO_Socket_new(GWEN_SOCKET *sock){
00226   GWEN_BUFFEREDIO *bt;
00227   GWEN_BUFFEREDIO_SOCKET *bft;
00228 
00229   bt=GWEN_BufferedIO_new();
00230   bft=GWEN_BufferedIO_Socket_Table__new();
00231   bft->sock=sock;
00232 
00233   GWEN_INHERIT_SETDATA(GWEN_BUFFEREDIO, GWEN_BUFFEREDIO_SOCKET,
00234                        bt, bft,
00235                        GWEN_BufferedIO_Socket_FreeData);
00236   GWEN_BufferedIO_SetReadFn(bt, GWEN_BufferedIO_Socket__Read);
00237   GWEN_BufferedIO_SetWriteFn(bt, GWEN_BufferedIO_Socket__Write);
00238   GWEN_BufferedIO_SetCloseFn(bt, GWEN_BufferedIO_Socket__Close);
00239   GWEN_BufferedIO_SetTimeout(bt, GWEN_BUFFEREDIO_SOCKET_TIMEOUT);
00240 
00241   return bt;
00242 }
00243 
00244 
00245 
Generated on Mon Jul 5 22:51:12 2010 for gwenhywfar by  doxygen 1.6.3