00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <unistd.h>
00004 #include <errno.h>
00005 #include <string.h>
00006 #include <sys/types.h>
00007 #include <sys/socket.h>
00008 #include <sys/types.h>
00009 #include <sys/uio.h>
00010 #include <arpa/inet.h>
00011 #include <sys/wait.h>
00012 #include <netinet/in.h>
00013 #include <zlib.h>
00014 #include <pthread.h>
00015 #include <alloca.h>
00016 #include "db.h"
00017 #include "xassert.h"
00018 #include "byteswap.h"
00019
00020
00021
00022 void send_string(int fd, const char *str)
00023 {
00024 int len;
00025 struct iovec vec[2];
00026
00027 vec[1].iov_len = strlen(str);
00028 vec[1].iov_base = str;
00029 len = htonl(vec[1].iov_len);
00030 vec[0].iov_len = sizeof(len);
00031 vec[0].iov_base = &len;
00032
00033 Writevn(fd, vec, 2);
00034 }
00035
00036 int db_getsocketbufsize(int sockfd, int *sndbuf, int *rcvbuf)
00037 {
00038 union val {
00039 int i_val;
00040 long l_val;
00041 char c_val[10];
00042 struct linger linger_val;
00043 struct timeval timeval_val;
00044 } val;
00045 unsigned int val_size = sizeof(val);
00046
00047 if (sndbuf)
00048 {
00049 if ( getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&val, &val_size) == -1)
00050 {
00051 perror("getsockopt error");
00052 return -1;
00053 }
00054 *sndbuf = val.i_val;
00055 }
00056
00057 if (rcvbuf)
00058 {
00059 if ( getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (char *)&val, &val_size) == -1)
00060 {
00061 perror("getsockopt error");
00062 return -1;
00063 }
00064 *rcvbuf = val.i_val;
00065 }
00066 return 0;
00067 }
00068
00069
00070 int db_setsocketbufsize(int sockfd, int sndbuf, int rcvbuf)
00071 {
00072 if ( setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) == -1)
00073 {
00074 perror("getsockopt error");
00075 return -1;
00076 }
00077
00078 if ( setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) == -1)
00079 {
00080 perror("getsockopt error");
00081 return -1;
00082 }
00083 return 0;
00084 }
00085
00086
00087
00088
00089 char *receive_string(int fd)
00090 {
00091 int len;
00092 char *str;
00093
00094 len = Readint(fd);
00095 if (len<0)
00096 return NULL;
00097 str = malloc(len+1);
00098 XASSERT(str);
00099 Readn(fd, str, len);
00100 str[len] = '\0';
00101 return str;
00102 }
00103
00104
00105
00106 ssize_t readn(int fd, void *vptr, size_t n)
00107 {
00108 size_t nleft;
00109 ssize_t nread;
00110 char *ptr;
00111
00112 ptr = vptr;
00113 nleft = n;
00114 while (nleft > 0) {
00115 if ( (nread = read(fd, ptr, nleft)) < 0) {
00116 if (errno == EINTR)
00117 nread = 0;
00118 else
00119 return(-1);
00120 } else if (nread == 0)
00121 break;
00122
00123 nleft -= nread;
00124 ptr += nread;
00125 }
00126 return(n - nleft);
00127 }
00128
00129
00130
00131 ssize_t Readn(int fd, void *ptr, size_t nbytes)
00132 {
00133 ssize_t n;
00134
00135 if ( (n = readn(fd, ptr, nbytes)) < 0)
00136 {
00137 perror("readn error");
00138 fprintf(stderr, "aborted: exit called in file %s, line %d\n",__FILE__,__LINE__);
00139 exit(1);
00140 }
00141 return(n);
00142 }
00143
00144 ssize_t Readn_ntoh(int fd, void *ptr, size_t size)
00145 {
00146 ssize_t ret = Readn(fd, ptr, size);
00147
00148 if (ret == size)
00149 {
00150 #if __BYTE_ORDER == __LITTLE_ENDIAN
00151 byteswap(size, 1, (char *)ptr);
00152 #endif
00153 }
00154 else
00155 {
00156 ret = 0;
00157 }
00158
00159 return ret;
00160 }
00161
00162
00163 ssize_t writen(int fd, const void *vptr, size_t n)
00164 {
00165 size_t nleft;
00166 ssize_t nwritten;
00167 const char *ptr;
00168
00169 ptr = vptr;
00170 nleft = n;
00171 while (nleft > 0) {
00172 if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
00173 if (errno == EINTR)
00174 nwritten = 0;
00175 else
00176 return(-1);
00177 }
00178
00179 nleft -= nwritten;
00180 ptr += nwritten;
00181 }
00182 return(n);
00183 }
00184
00185
00186 void
00187 Writen(int fd, const void *ptr, size_t nbytes)
00188 {
00189 if (writen(fd, ptr, nbytes) != nbytes)
00190 {
00191 perror("writen error");
00192 fprintf(stderr, "aborted: exit called in file %s, line %d\n",__FILE__,__LINE__);
00193 exit(1);
00194 }
00195 }
00196
00197 void Writen_ntoh(int fd, const void *ptr, size_t size)
00198 {
00199 void *p = NULL;
00200 memcpy(&p, &ptr, size);
00201
00202 #if __BYTE_ORDER == __LITTLE_ENDIAN
00203 byteswap(size, 1, (char *)p);
00204 #endif
00205
00206 Writen(fd, &p, size);
00207
00208 }
00209
00210
00211 ssize_t writevn(int fd, struct iovec *vector, int count, size_t n)
00212 {
00213 int i;
00214 size_t nleft;
00215 ssize_t nwritten;
00216
00217 nleft = n;
00218 while (nleft > 0) {
00219 if ( (nwritten = writev(fd, vector, count)) <= 0) {
00220 if (errno == EINTR)
00221 nwritten = 0;
00222 else
00223 return(-1);
00224 }
00225 #ifdef DEBUG
00226 printf("n=%d, nleft=%d, nwritten = %d\n",n,nleft,nwritten);
00227 #endif
00228 nleft -= nwritten;
00229 if (nwritten>0 && nleft>0)
00230 {
00231
00232 i = 0;
00233 while (i<count && nwritten>0)
00234 {
00235 if (vector[i].iov_len<=nwritten)
00236 {
00237
00238 nwritten -= vector[i].iov_len;
00239 vector[i].iov_len = 0;
00240 }
00241 else
00242 {
00243
00244
00245
00246 vector[i].iov_len -= nwritten;
00247 vector[i].iov_base = (void *) ((char *) vector[i].iov_base + nwritten);
00248 nwritten = 0;
00249 }
00250 i++;
00251 }
00252 }
00253 }
00254 return(n);
00255 }
00256
00257
00258 void
00259 Writevn(int fd, struct iovec *vector, int count )
00260 {
00261 int i;
00262 size_t nbytes;
00263 nbytes = 0;
00264 for (i=0; i<count; i++)
00265 nbytes += vector[i].iov_len;
00266 #ifdef DEBUG
00267 printf("nbytes = %d\n",nbytes);
00268 #endif
00269 if (writevn(fd, vector, count, nbytes) != nbytes)
00270 {
00271 perror("writen error");
00272 fprintf(stderr, "aborted: exit called in file %s, line %d\n",__FILE__,__LINE__);
00273 exit(1);
00274 }
00275 }
00276
00277
00278
00279 int readlonglong(int fd, long long *val)
00280 {
00281 long long tmp;
00282 int n;
00283 if ( (n = readn(fd, &tmp, sizeof(long long))) == sizeof(long long))
00284 *val = htonll(tmp);
00285 return n;
00286 }
00287
00288
00289 int readint(int fd, int *val)
00290 {
00291 int tmp;
00292 int n;
00293 if ( (n = readn(fd, &tmp, sizeof(int))) == sizeof(int))
00294 *val = htonl(tmp);
00295 return n;
00296 }
00297
00298
00299 int readshort(int fd, int *val)
00300 {
00301 short tmp;
00302 int n;
00303 if ( (n = readn(fd, &tmp, sizeof(short))) == sizeof(short))
00304 *val = htons(tmp);
00305 return n;
00306 }
00307
00308
00309
00310 long long Readlonglong(int fd)
00311 {
00312 long long tmp;
00313 Readn(fd, &tmp, sizeof(long long));
00314
00315 return htonll(tmp);
00316 }
00317
00318 int Readint(int fd)
00319 {
00320 int tmp;
00321 Readn(fd, &tmp, sizeof(int));
00322
00323 return htonl(tmp);
00324 }
00325
00326 short Readshort(int fd)
00327 {
00328 short tmp;
00329 Readn(fd, &tmp, sizeof(short));
00330
00331 return htons(tmp);
00332 }
00333
00334
00335 void *Read_dbtype(DB_Type_t *type, int fd)
00336 {
00337 void *value;
00338 int size;
00339
00340 *type = (DB_Type_t) Readint(fd);
00341 if (*type == DB_STRING || *type==DB_VARCHAR)
00342 value = (void *)receive_string(fd);
00343 else
00344 {
00345 size = db_sizeof(*type);
00346 value = malloc(size);
00347 XASSERT(value);
00348 Readn(fd, value, size);
00349 db_byteswap(*type, 1, value);
00350 }
00351 return value;
00352 }
00353
00354 void Write_dbtype(DB_Type_t type, char *val, int fd)
00355 {
00356 int tmp, len;
00357 struct iovec vec[3];
00358
00359 tmp = htonl((int)type);
00360 vec[0].iov_len = sizeof(tmp);
00361 vec[0].iov_base = &tmp;
00362 if (type == DB_STRING || type==DB_VARCHAR)
00363 {
00364 vec[2].iov_len = strlen(val);
00365 vec[2].iov_base = val;
00366 len = htonl(vec[2].iov_len);
00367 vec[1].iov_len = sizeof(len);
00368 vec[1].iov_base = &len;
00369 Writevn(fd, vec, 3);
00370 }
00371 else
00372 {
00373 db_byteswap(type, 1, val);
00374 vec[1].iov_len = db_sizeof(type);
00375 vec[1].iov_base = val;
00376 Writevn(fd, vec, 2);
00377 db_byteswap(type, 1, val);
00378 }
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396 }
00397
00398
00399 long long htonll(long long val)
00400 {
00401 #if __BYTE_ORDER == __LITTLE_ENDIAN
00402 char *p,tmp;
00403 p = (char *)&val;
00404 tmp = *p;
00405 *p = *(p+7);
00406 *(p+7) = tmp;
00407 tmp = *(p+1);
00408 *(p+1) = *(p+6);
00409 *(p+6) = tmp;
00410 tmp = *(p+2);
00411 *(p+2) = *(p+5);
00412 *(p+5) = tmp;
00413 tmp = *(p+3);
00414 *(p+3) = *(p+4);
00415 *(p+4) = tmp;
00416 #endif
00417 return val;
00418 }
00419
00420 long long ntohll(long long val)
00421 {
00422 return htonll(val);
00423 }