Simple tools for networking / objects in plain C Snapshot
|
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