00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
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 }
00105 if (retrycount<1) {
00106 DBG_ERROR(GWEN_LOGDOMAIN, "Interrupted too often, giving up");
00107 return GWEN_ERROR_READ;
00108 }
00109 }
00110
00111
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 }
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 }
00168 if (retrycount<1) {
00169 DBG_ERROR(GWEN_LOGDOMAIN, "Interrupted too often, giving up");
00170 return GWEN_ERROR_WRITE;
00171 }
00172 }
00173
00174
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 }
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(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