Simple tools for networking / objects in plain C Snapshot
ioutils.c
Go to the documentation of this file.
00001 #include "ioutils.h"
00002 #include <sys/ioctl.h>
00003 #include <sys/types.h>
00004 #include <sys/socket.h>
00005 #include <sys/ioctl.h>
00006 #include <netinet/tcp.h>
00007 #include <unistd.h>
00008 #include <signal.h>
00009 
00010 //static int has_disabled_sigpipe;
00011 
00012 int disable_sigpipe()
00013 {
00014   //if (!has_disabled_sigpipe) {
00015     if (signal(SIGPIPE,SIG_IGN) == SIG_ERR) {
00016       return -1;
00017     }
00018   //has_disabled_sigpipe = 1;
00019   //}
00020 
00021   return 0;
00022 }
00023 
00024 int  fd_set_blocking(int fd,  int is_blocking)
00025 {
00026   unsigned long cmd = is_blocking ? 0 : 1;
00027   int res;
00028 
00029 #ifdef _WIN32
00030   res = ioctlsocket( fd, FIONBIO, &cmd);
00031 #else    
00032   res = ioctl( fd, FIONBIO, &cmd);
00033 #endif
00034   return res;
00035 }
00036 
00037 int fd_get_bytes_available(int fd) 
00038 {
00039   int ret = 0;
00040 
00041   ioctl( fd, FIONREAD,  &ret );
00042         
00043   return ret;
00044 }
00045 
00046 int fd_get_error(int fd) 
00047 {
00048   int err = 0;
00049 
00050   socklen_t sz = sizeof(err);
00051 
00052   if (getsockopt( fd, SOL_SOCKET, SO_ERROR, (char *) &err, &sz ) != 0) {
00053     return -1;
00054   }
00055         
00056   return err;
00057 }
00058 
00059 int fd_set_buf_size( int fd, Buffsize_op op, int size)
00060 {
00061   int rt;
00062 
00063   rt = setsockopt( fd,
00064                     SOL_SOCKET,
00065                     op == Send_buffer ? SO_SNDBUF : SO_RCVBUF,
00066                     (const char *) &size,
00067                     sizeof(int));
00068   if (rt != 0) {
00069      return rt;
00070   }
00071   return 0;
00072         
00073 }
00074 
00075 int fd_get_buf_size( int fd, Buffsize_op op )
00076 {
00077   int size;
00078   socklen_t ln = sizeof(size);
00079         
00080   if (getsockopt(fd,
00081                  SOL_SOCKET,
00082                  op == Send_buffer ? SO_SNDBUF : SO_RCVBUF ,
00083                  (char *) &size,
00084                  &ln)  != 0) {
00085     return -1;
00086   }
00087   return size;
00088         
00089 }
00090 
00091 int fd_set_reuse_address(int fd, int reuse_on)
00092 {
00093   int flag_on = reuse_on ? 1 : 0;
00094   int rt;
00095 
00096   rt = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*) &flag_on, sizeof(flag_on)); 
00097   if (rt != 0) {
00098     return -1;
00099   }
00100   return 0;  
00101 }
00102 
00103 int fd_get_reuse_address(int fd) 
00104 {
00105   int flag_on;
00106   socklen_t sz = sizeof(flag_on);
00107 
00108   if (getsockopt(fd, SOL_SOCKET, SO_REUSEADDR , (char *) &flag_on, &sz)  != 0) {
00109 
00110     return -1;
00111   }  
00112   return flag_on;
00113 }
00114 
00115 
00116 int fd_set_nagling(int fd, int on)
00117 {
00118   if (on) {
00119     on = 1;
00120   }
00121   return setsockopt( fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on) );
00122 }
00123 
00124 int fd_set_linger_option(int fd, int on, int linger_value)
00125 {
00126   struct linger l;
00127    
00128   l.l_onoff = on ? 1 : 0; 
00129   l.l_linger = linger_value;
00130 
00131   return setsockopt( fd, SOL_SOCKET, SO_LINGER, &l, sizeof(struct linger) );
00132 }
00133  
00134 int fd_close_by_RST( int fd )
00135 {
00136   fd_set_linger_option( fd, 1, 0 );
00137   return close(fd);
00138 }
00139 
00140 
00141 int fd_make_tcp_listener(SOCKADDR *saddr, int backlog)
00142 {
00143   int fd;
00144  
00145   fd = socket( SOCKADDR_family(saddr), SOCK_STREAM, IPPROTO_TCP );
00146   if (fd == -1) {
00147     return -1;
00148   }
00149 
00150   if (fd_set_reuse_address( fd, 1 )) {
00151     goto err;
00152   }
00153 
00154   if (bind( fd, SOCKADDR_saddr( saddr ), SOCKADDR_length( saddr )) ) {
00155     goto err;
00156   }
00157 
00158   if (listen( fd, backlog )) {
00159     goto err;
00160   }
00161   return fd;
00162 
00163 err:
00164   close(fd);
00165   return -1;
00166 }
00167 
00168