提交 17078842871dd86dd372cb4f69388cfc6b127204

作者 LJH 李佳桓
1 个父辈 dc9955c1

add

正在显示 1 个修改的文件 包含 260 行增加0 行删除
  1 +/*
  2 + * Copyright 2007 Stephen Liu
  3 + * For license terms, see the file COPYING along with this library.
  4 + */
  5 +
  6 +#include <stdio.h>
  7 +#include <fcntl.h>
  8 +#include <errno.h>
  9 +#include <string.h>
  10 +#include <assert.h>
  11 +#include <sys/types.h>
  12 +#include <sys/stat.h>
  13 +
  14 +#include "spporting.hpp"
  15 +
  16 +#include "spioutils.hpp"
  17 +
  18 +void SP_IOUtils :: inetNtoa( in_addr * addr, char * ip, int size )
  19 +{
  20 +#if defined (linux) || defined (__sgi) || defined (__hpux) \
  21 + || defined (__FreeBSD__) || defined (__APPLE__)
  22 + const unsigned char *p = ( const unsigned char *) addr;
  23 + snprintf( ip, size, "%i.%i.%i.%i", p[0], p[1], p[2], p[3] );
  24 +#else
  25 + snprintf( ip, size, "%i.%i.%i.%i", addr->s_net, addr->s_host, addr->s_lh, addr->s_impno );
  26 +#endif
  27 +}
  28 +
  29 +int SP_IOUtils :: setNonblock( int fd )
  30 +{
  31 +#ifdef WIN32
  32 + unsigned long nonblocking = 1;
  33 + ioctlsocket( fd, FIONBIO, (unsigned long*) &nonblocking );
  34 +#else
  35 + int flags;
  36 +
  37 + flags = fcntl( fd, F_GETFL );
  38 + if( flags < 0 ) return flags;
  39 +
  40 + flags |= O_NONBLOCK;
  41 + if( fcntl( fd, F_SETFL, flags ) < 0 ) return -1;
  42 +#endif
  43 +
  44 + return 0;
  45 +}
  46 +
  47 +int SP_IOUtils :: setBlock( int fd )
  48 +{
  49 +#ifdef WIN32
  50 +
  51 + unsigned long nonblocking = 0;
  52 + ioctlsocket( fd, FIONBIO, (unsigned long*) &nonblocking );
  53 +
  54 +#else
  55 +
  56 + int flags;
  57 +
  58 + flags = fcntl( fd, F_GETFL );
  59 + if( flags < 0 ) return flags;
  60 +
  61 + flags &= ~O_NONBLOCK;
  62 + if( fcntl( fd, F_SETFL, flags ) < 0 ) return -1;
  63 +#endif
  64 +
  65 + return 0;
  66 +}
  67 +
  68 +int SP_IOUtils :: tcpListen( const char * ip, int port, int * fd, int blocking )
  69 +{
  70 + int ret = 0;
  71 +
  72 + int listenFd = socket( AF_INET, SOCK_STREAM, 0 );
  73 + if( listenFd < 0 ) {
  74 + sp_syslog( LOG_WARNING, "socket failed, errno %d, %s", errno, strerror( errno ) );
  75 + ret = -1;
  76 + }
  77 +
  78 + if( 0 == ret && 0 == blocking ) {
  79 + if( setNonblock( listenFd ) < 0 ) {
  80 + sp_syslog( LOG_WARNING, "failed to set socket to non-blocking" );
  81 + ret = -1;
  82 + }
  83 + }
  84 +
  85 + if( 0 == ret ) {
  86 + int flags = 1;
  87 + if( setsockopt( listenFd, SOL_SOCKET, SO_REUSEADDR, (char*)&flags, sizeof( flags ) ) < 0 ) {
  88 + sp_syslog( LOG_WARNING, "failed to set setsock to reuseaddr" );
  89 + ret = -1;
  90 + }
  91 + if( setsockopt( listenFd, IPPROTO_TCP, TCP_NODELAY, (char*)&flags, sizeof(flags) ) < 0 ) {
  92 + sp_syslog( LOG_WARNING, "failed to set socket to nodelay" );
  93 + ret = -1;
  94 + }
  95 + }
  96 +
  97 + struct sockaddr_in addr;
  98 +
  99 + if( 0 == ret ) {
  100 + memset( &addr, 0, sizeof( addr ) );
  101 + addr.sin_family = AF_INET;
  102 + addr.sin_port = htons( port );
  103 +
  104 + addr.sin_addr.s_addr = INADDR_ANY;
  105 + if( '\0' != *ip ) {
  106 + if( 0 == sp_inet_aton( ip, &addr.sin_addr ) ) {
  107 + sp_syslog( LOG_WARNING, "failed to convert %s to inet_addr", ip );
  108 + ret = -1;
  109 + }
  110 + }
  111 + }
  112 +
  113 + if( 0 == ret ) {
  114 + if( bind( listenFd, (struct sockaddr*)&addr, sizeof( addr ) ) < 0 ) {
  115 + sp_syslog( LOG_WARNING, "bind failed, errno %d, %s", errno, strerror( errno ) );
  116 + ret = -1;
  117 + }
  118 + }
  119 +
  120 + if( 0 == ret ) {
  121 + if( ::listen( listenFd, 1024 ) < 0 ) {
  122 + sp_syslog( LOG_WARNING, "listen failed, errno %d, %s", errno, strerror( errno ) );
  123 + ret = -1;
  124 + }
  125 + }
  126 +
  127 + if( 0 != ret && listenFd >= 0 ) sp_close( listenFd );
  128 +
  129 + if( 0 == ret ) {
  130 + * fd = listenFd;
  131 + sp_syslog( LOG_NOTICE, "Listen on port [%d]", port );
  132 + }
  133 +
  134 + return ret;
  135 +}
  136 +
  137 +int SP_IOUtils :: tcpListen( const char * path, int * fd, int blocking, int mode )
  138 +{
  139 + int ret = 0;
  140 +
  141 +#ifndef WIN32
  142 +
  143 + struct sockaddr_un addr;
  144 + memset( &addr, 0, sizeof( addr ) );
  145 +
  146 + if( strlen( path ) > ( sizeof( addr.sun_path ) - 1 ) ) {
  147 + sp_syslog( LOG_WARNING, "UNIX socket name %s too long", path );
  148 + return -1;
  149 + }
  150 +
  151 + if( 0 == access( path, F_OK ) ) {
  152 + if( 0 != unlink( path ) ) {
  153 + sp_syslog( LOG_WARNING, "unlink %s failed, errno %d, %s",
  154 + path, errno, strerror( errno ) );
  155 + return -1;
  156 + }
  157 + }
  158 +
  159 + addr.sun_family = AF_UNIX;
  160 + strncpy( addr.sun_path, path, sizeof( addr.sun_path ) - 1 );
  161 +
  162 + int listenFd = socket( AF_UNIX, SOCK_STREAM, 0 );
  163 + if( listenFd < 0 ) {
  164 + sp_syslog( LOG_WARNING, "listen failed, errno %d, %s", errno, strerror( errno ) );
  165 + ret = -1;
  166 + }
  167 +
  168 + if( 0 == ret && 0 == blocking ) {
  169 + if( setNonblock( listenFd ) < 0 ) {
  170 + sp_syslog( LOG_WARNING, "failed to set socket to non-blocking" );
  171 + ret = -1;
  172 + }
  173 + }
  174 +
  175 + if( 0 == ret ) {
  176 + int flags = 1;
  177 + if( setsockopt( listenFd, SOL_SOCKET, SO_REUSEADDR, (char*)&flags, sizeof( flags ) ) < 0 ) {
  178 + sp_syslog( LOG_WARNING, "failed to set setsock to reuseaddr" );
  179 + ret = -1;
  180 + }
  181 + }
  182 +
  183 + if( 0 == ret ) {
  184 + if( bind( listenFd, (struct sockaddr*)&addr, sizeof( addr ) ) < 0 ) {
  185 + sp_syslog( LOG_WARNING, "bind failed, errno %d, %s", errno, strerror( errno ) );
  186 + ret = -1;
  187 + }
  188 + }
  189 +
  190 + if( 0 == ret ) {
  191 + if( ::listen( listenFd, 1024 ) < 0 ) {
  192 + sp_syslog( LOG_WARNING, "listen failed, errno %d, %s", errno, strerror( errno ) );
  193 + ret = -1;
  194 + }
  195 + }
  196 +
  197 + if( 0 != ret && listenFd >= 0 ) sp_close( listenFd );
  198 +
  199 + if( 0 == ret ) {
  200 + * fd = listenFd;
  201 +
  202 + if( mode > 0 ) {
  203 + if( 0 != fchmod( *fd, (mode_t)mode ) ) {
  204 + sp_syslog( LOG_WARNING, "fchmod fail, errno %d, %s", errno, strerror( errno ) );
  205 + }
  206 + }
  207 +
  208 + sp_syslog( LOG_NOTICE, "Listen on [%s]", path );
  209 + }
  210 +
  211 +#endif
  212 +
  213 + return ret;
  214 +}
  215 +
  216 +int SP_IOUtils :: initDaemon( const char * workdir )
  217 +{
  218 +#ifndef WIN32
  219 +
  220 + int i;
  221 + pid_t pid;
  222 +
  223 + if ( (pid = fork()) < 0)
  224 + return (-1);
  225 + else if (pid)
  226 + _exit(0); /* parent terminates */
  227 +
  228 + /* child 1 continues... */
  229 +
  230 + if (setsid() < 0) /* become session leader */
  231 + return (-1);
  232 +
  233 + assert( signal( SIGHUP, SIG_IGN ) != SIG_ERR );
  234 + assert( signal( SIGPIPE, SIG_IGN ) != SIG_ERR );
  235 + assert( signal( SIGALRM, SIG_IGN ) != SIG_ERR );
  236 + assert( signal( SIGCHLD, SIG_IGN ) != SIG_ERR );
  237 +
  238 + if ( (pid = fork()) < 0)
  239 + return (-1);
  240 + else if (pid)
  241 + _exit(0); /* child 1 terminates */
  242 +
  243 + /* child 2 continues... */
  244 +
  245 + if( NULL != workdir ) chdir( workdir ); /* change working directory */
  246 +
  247 + /* close off file descriptors */
  248 + for (i = 0; i < 64; i++)
  249 + close(i);
  250 +
  251 + /* redirect stdin, stdout, and stderr to /dev/null */
  252 + open("/dev/null", O_RDONLY);
  253 + open("/dev/null", O_RDWR);
  254 + open("/dev/null", O_RDWR);
  255 +
  256 +#endif
  257 +
  258 + return (0); /* success */
  259 +}
  260 +
... ...
注册登录 后发表评论