📄 write.c
字号:
/* * =========================================================================== * PRODUCTION $Log: write.c,v $ * PRODUCTION Revision 1000.0 2003/10/29 20:35:53 gouriano * PRODUCTION PRODUCTION: IMPORTED [ORIGINAL] Dev-tree R1.2 * PRODUCTION * =========================================================================== *//* FreeTDS - Library of routines accessing Sybase and Microsoft databases * Copyright (C) 1998-1999 Brian Bruns * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include <tds_config.h>#include "tds.h"#include "tdsutil.h"#include <signal.h> /* GW ADDED */#ifdef DMALLOC#include <dmalloc.h>#endif#ifdef WIN32#define WRITE(a,b,c) send((a),(b),(c), 0L)#else #define WRITE(a,b,c) write(a,b,c)#endifstatic char software_version[] = "$Id: write.c,v 1000.0 2003/10/29 20:35:53 gouriano Exp $";static void *no_unused_var_warn[] = {software_version, no_unused_var_warn};/* * CRE 01262002 making buf a void * means we can put any type without casting * much like read() and memcpy() */inttds_put_n(TDSSOCKET *tds, const unsigned char *buf, int n){#ifdef NCBI_FTDS int left,to_copy; while(n > 0){ left = tds->env->block_size - tds->out_pos; if (left <= 0){ tds_write_packet(tds,0x0); tds_init_write_buf(tds); left = tds->env->block_size - tds->out_pos; } to_copy = (n < left)?n:left; if(buf){ memcpy(tds->out_buf+tds->out_pos,buf,to_copy); buf+=to_copy; } else { memset(tds->out_buf+tds->out_pos,'\0',to_copy); } tds->out_pos+=to_copy; n-=to_copy; if(to_copy == 0 && tds->s == 0) break; }#elseint i;const unsigned char *bufp = buf; if (bufp) { for (i=0;i<n;i++) tds_put_byte(tds, bufp[i]); } else { for (i=0;i<n;i++) tds_put_byte(tds, '\0'); }#endif return 0;}int tds_put_string(TDSSOCKET *tds, const char *buf, int n){int buf_len = ( buf ? strlen(buf) : 0); return tds_put_buf(tds,(const unsigned char *)buf,n,buf_len);}int tds_put_buf(TDSSOCKET *tds, const unsigned char *buf, int dsize, int ssize){int cpsize; cpsize = ssize > dsize ? dsize : ssize; tds_put_n(tds,buf,cpsize); dsize -= cpsize; tds_put_n(tds,NULL,dsize); return tds_put_byte(tds,cpsize);}int tds_put_int(TDSSOCKET *tds, TDS_INT i){#if WORDS_BIGENDIAN if (tds->emul_little_endian) { tds_put_byte(tds, i & 0x000000FF); tds_put_byte(tds, (i & 0x0000FF00) >> 8); tds_put_byte(tds, (i & 0x00FF0000) >> 16); tds_put_byte(tds, (i & 0xFF000000) >> 24); return 0; }#endif return tds_put_n(tds,(const unsigned char *)&i,sizeof(TDS_INT));}int tds_put_smallint(TDSSOCKET *tds, TDS_SMALLINT si){#if WORDS_BIGENDIAN if (tds->emul_little_endian) { tds_put_byte(tds, si & 0x000000FF); tds_put_byte(tds, (si & 0x0000FF00) >> 8); return 0; }#endif return tds_put_n(tds,(const unsigned char *)&si,sizeof(TDS_SMALLINT));}int tds_put_tinyint(TDSSOCKET *tds, TDS_TINYINT ti){ return tds_put_byte(tds,(unsigned char)ti);}int tds_put_byte(TDSSOCKET *tds, unsigned char c){ if (tds->out_pos >= tds->env->block_size) { tds_write_packet(tds,0x0); tds_init_write_buf(tds); } tds->out_buf[tds->out_pos++]=c; return 0;}int tds_put_bulk_data(TDSSOCKET *tds, const unsigned char * buf, TDS_INT bufsize){ tds->out_flag = 0x07; return tds_put_n(tds,buf,bufsize);}int tds_init_write_buf(TDSSOCKET *tds){ memset(tds->out_buf,'\0',tds->env->block_size); tds->out_pos=8; return 0;}/* TODO this code should be similar to read one... */static int tds_check_socket_write(TDSSOCKET *tds){int retcode = 0;struct timeval selecttimeout;time_t start, now;fd_set fds; /* Jeffs hack *** START OF NEW CODE */ FD_ZERO (&fds); if (!tds->timeout) { for(;;) { FD_SET (tds->s, &fds); retcode = select (tds->s + 1, NULL, &fds, NULL, NULL); /* write available */ if (retcode >= 0) return 0; /* interrupted */ if (errno == EINTR) continue; /* error, leave caller handle problems*/ return -1; } } start = time(NULL); now = start; while ((retcode == 0) && ((now-start) < tds->timeout)) { FD_SET (tds->s, &fds); selecttimeout.tv_sec = tds->timeout - (now-start); selecttimeout.tv_usec = 0; retcode = select (tds->s + 1, NULL, &fds, NULL, &selecttimeout); if (retcode < 0 && errno == EINTR) { retcode = 0; } now = time (NULL); } return retcode; /* Jeffs hack *** END OF NEW CODE */}/* goodwrite function adapted from patch by freddy77 */static intgoodwrite(TDSSOCKET *tds){int left;char *p;int result = 1;int retval; left = tds->out_pos; p = tds->out_buf; while (left > 0) { /* If there's a timeout, we need to sit and wait for socket */ /* writability */ /* moved socket writability check to own function -- bsb */ tds_check_socket_write(tds); retval = WRITE(tds->s,p,left); if (retval <= 0) { tdsdump_log(TDS_DBG_NETWORK, "TDS: Write failed in tds_write_packet\nError: %d (%s)\n", errno, strerror(errno)); tds_client_msg(tds->tds_ctx, tds, 10018, 9, 0, 0, "The connection was closed"); tds->in_pos=0; tds->in_len=0; close(tds->s); tds->s=0; result = 0; break; } left -= retval; p += retval; } return result;}int tds_write_packet(TDSSOCKET *tds,unsigned char final){int retcode;void (*oldsig)(int); tds->out_buf[0]=tds->out_flag; tds->out_buf[1]=final;#ifdef NCBI_FTDS tds->out_buf[2]=(tds->out_pos) >> 8; tds->out_buf[3]=(tds->out_pos) & 0xFF;#else tds->out_buf[2]=(tds->out_pos)/256u; tds->out_buf[3]=(tds->out_pos)%256u;#endif if (IS_TDS70(tds) || IS_TDS80(tds)) { tds->out_buf[6]=0x01; } tdsdump_log(TDS_DBG_NETWORK, "Sending packet @ %L\n%D\n", tds->out_buf, tds->out_pos);#ifdef NCBI_FTDS tds_block_sigpipe();#else oldsig=signal (SIGPIPE, SIG_IGN); if (oldsig==SIG_ERR) { tdsdump_log(TDS_DBG_WARN, "TDS: Warning: Couldn't set SIGPIPE signal to be ignored\n"); }#endif retcode=goodwrite(tds);#ifdef NCBI_FTDS tds_reset_sigpipe();#else if (signal(SIGPIPE, oldsig)==SIG_ERR) { tdsdump_log(TDS_DBG_WARN, "TDS: Warning: Couldn't reset SIGPIPE signal to previous value\n"); }#endif/* GW added in check for write() returning <0 and SIGPIPE checking */ return retcode;}int tds_flush_packet(TDSSOCKET *tds){ if (tds->s) { tds_write_packet(tds,0x01); tds_init_write_buf(tds); } /* GW added check for tds->s */ return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -