Back to index

im-sdk  12.3.91
stream-socket.c
Go to the documentation of this file.
00001 #if defined(HAVE_CONFIG_H)
00002 #include "config.h"
00003 #endif /* HAVE_CONFIG_H */
00004 
00005 #include <unistd.h>
00006 #include <sys/types.h>
00007 #include <sys/socket.h>
00008 #include <netdb.h>
00009 #include <netinet/in.h>
00010 #include <stdlib.h>
00011 #include <string.h>
00012 #include <fcntl.h>
00013 #include <errno.h>
00014 #if defined(HAVE_UNIX_SOCKET)
00015 #if defined(HAVE_STDDEF_H)
00016 #include <stddef.h>
00017 #endif
00018 #include <sys/un.h>
00019 #endif
00020 #if defined(HAVE_POLL)
00021 #include <poll.h>
00022 #else /* !HAVE_POLL */
00023 #include <sys/time.h>
00024 #endif /* !HAVE_POLL */
00025 #if defined(WIN32)
00026 #include <winsock.h>
00027 #endif /* WIN32 */
00028 
00029 #ifdef HAVE_SIGNAL
00030 #include <signal.h>
00031 #endif
00032 
00033 #include <iiimp.h>
00034 
00035 #include "stream.h"
00036 
00037 /* function declarations */
00038 
00039 static IIIMF_status
00040 stream_socket_read(
00041     IIIMF_stream_private private,
00042     void *buf,
00043     size_t nbyte
00044 );
00045 
00046 static IIIMF_status
00047 stream_socket_write(
00048     IIIMF_stream_private private,
00049     const void* buf,
00050     size_t nbyte
00051 );
00052 
00053 /* enum and structure */
00054 
00055 enum IIIMF_STREAM_SOCKET_FLAGS {
00056        IIIMF_STREAM_SOCKET_LISTEN,
00057        IIIMF_STREAM_SOCKET_OPEN
00058 };
00059 
00060 typedef struct IIIMF_stream_socket_private IIIMF_stream_socket_private;
00061 struct IIIMF_stream_socket_private {
00062     int flags;
00063     int fd;
00064     int timeout;
00065 };
00066 
00067 static IIIMF_stream_socket_private*
00068 create_sockpriv(
00069     int flags,
00070     int fd,
00071     int timeout
00072 )
00073 {
00074     IIIMF_stream_socket_private *p;
00075 
00076 #ifdef HAVE_SO_NOSIGPIPE
00077     int optval = 1;
00078 #endif
00079     p = (IIIMF_stream_socket_private*) malloc(sizeof(*p));
00080     if (!p) return NULL;
00081     p->timeout = timeout;
00082     p->flags = flags;
00083     p->fd = fd;
00084 #ifdef HAVE_SO_NOSIGPIPE
00085     /* need error handling ? */
00086     setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof (int));
00087 #endif
00088     return p;
00089 }
00090 
00091 static void
00092 delete_sockpriv(
00093     IIIMF_stream_socket_private *psockpriv
00094 )
00095 {
00096     free(psockpriv);
00097 }
00098 
00099 #if defined(HAVE_UNIX_SOCKET)
00100 static IIIMF_status
00101 create_socket_stream_unix(
00102     const char *node,
00103     const char *service,
00104     int timeout,
00105     IIIMF_stream ** stream_ret
00106 )
00107 {
00108     int fd;
00109     int fd_flag;
00110     int r;
00111     size_t size;
00112     struct sockaddr_un sun_addr;
00113 
00114     fd = -1;
00115 
00116     fd = socket(AF_UNIX, SOCK_STREAM, 0);
00117     if (fd == -1) {
00118        return IIIMF_STATUS_STREAM;
00119     }
00120 
00121     sun_addr.sun_family = AF_UNIX;
00122     if ((NULL == service) || ('\0' == (*service))) {
00123        strncpy(sun_addr.sun_path, node, sizeof(sun_addr.sun_path));
00124     } else {
00125        snprintf(sun_addr.sun_path, sizeof(sun_addr.sun_path), "%s/%s",
00126                node, service);
00127     }
00128 
00129     size = (offsetof(struct sockaddr_un, sun_path)
00130              + strlen (sun_addr.sun_path) + 1);
00131 
00132     r = connect(fd, (struct sockaddr *)(&sun_addr), size);
00133 
00134     if (r < 0) {
00135        (void)close(fd);
00136        return IIIMF_STATUS_STREAM;
00137     }
00138 
00139     fd_flag = fcntl(fd, F_GETFD);
00140     fd_flag |= FD_CLOEXEC;
00141     (void)fcntl(fd, F_SETFD, fd_flag);
00142     {
00143        IIIMF_status st;
00144        IIIMF_stream *stream;
00145        IIIMF_stream_socket_private *sockpriv;
00146 
00147        sockpriv = create_sockpriv(IIIMF_STREAM_SOCKET_OPEN, fd,
00148                                timeout);
00149 
00150        if (!sockpriv) {
00151            close(fd);
00152            return IIIMF_STATUS_MALLOC;
00153        }
00154 
00155        st = iiimf_create_stream(stream_socket_read, stream_socket_write,
00156                              sockpriv, timeout, &stream);
00157        if (st != IIIMF_STATUS_SUCCESS) return st;
00158        *stream_ret = stream;
00159     }
00160 
00161     return IIIMF_STATUS_SUCCESS;
00162 
00163 }
00164 #endif
00165 
00166 IIIMF_status
00167 iiimf_connect_socket_stream(
00168     const char *     node,
00169     const char *     service,
00170     int                 timeout,
00171     IIIMF_stream ** stream_ret
00172 )
00173 {
00174     int                     fd;
00175     int                     fd_flag;
00176 
00177 #if defined(HAVE_GETADDRINFO)
00178     int                     e;
00179     struct addrinfo *       res;
00180     struct addrinfo *       aip;
00181     struct addrinfo  hints;
00182 
00183 #if defined(HAVE_UNIX_SOCKET)
00184     if (*node == '/') {
00185        return create_socket_stream_unix(node, service, timeout, stream_ret);
00186     }
00187 #endif
00188     fd = -1;
00189 
00190     (void)memset(&hints, 0, sizeof (hints));
00191     hints.ai_flags = AI_CANONNAME;
00192     hints.ai_socktype = SOCK_STREAM;
00193 
00194     e = getaddrinfo(node, service, &hints, &res);
00195     if (0 != e) {
00196        return -1;
00197     }
00198 
00199     for (aip = res; NULL != aip; aip = aip->ai_next) {
00200        fd = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol);
00201        if (-1 == fd) {
00202            break;
00203        }
00204 
00205        if (-1 == connect(fd, aip->ai_addr, aip->ai_addrlen)) {
00206            (void)close(fd);
00207            fd = -1;
00208            continue;
00209        } else {
00210            break;
00211        }
00212     }
00213 
00214     freeaddrinfo(res);
00215 
00216     if (-1 == fd) return IIIMF_STATUS_STREAM;
00217 
00218 #else /* !HAVE_GETADDRINFO */
00219 
00220 #if defined(WIN32)
00221     unsigned short int      port_number;
00222 #else /* !WIN32 */
00223     int                     port_number;
00224 #endif /* !WIN32 */
00225     int                     r;
00226     int                     optval;
00227     unsigned long    in_addr;
00228     struct hostent * hostp;
00229     struct sockaddr_in      addr;
00230     struct servent * srvp;
00231 
00232 #if defined(HAVE_UNIX_SOCKET)
00233     if (*node == '/') {
00234        return create_socket_stream_unix(node, service, timeout, stream_ret);
00235     }
00236 #endif
00237 #if defined(WIN32)
00238     start_winsock(1, 1);
00239 #endif
00240 
00241     fd = socket(PF_INET, SOCK_STREAM, 0);
00242     if (fd < 0 ) return IIIMF_STATUS_STREAM;
00243 
00244     port_number = 0;
00245 
00246     (void)memset((char *)(&addr), 0, sizeof (addr));
00247     addr.sin_family = PF_INET;
00248 
00249     if (0 < strlen(service)) {
00250        srvp = getservbyname(service, "tcp");
00251        if (NULL != srvp) {
00252            port_number = srvp->s_port;
00253        }
00254        (void)endservent();
00255        if (0 == port_number) {
00256            port_number = atoi(service);
00257        }
00258     }
00259     if (0 == port_number) {
00260        port_number = 9010;
00261     }
00262     addr.sin_port = htons(port_number);
00263     in_addr = inet_addr(node);
00264     if ((unsigned long)(-1) != in_addr) {
00265        (void)memcpy(&addr.sin_addr, &in_addr, sizeof (in_addr));
00266     } else {
00267        hostp = gethostbyname(node);
00268        if (NULL == hostp) {
00269 #if defined(WIN32)
00270            (void)sock_close(fd);
00271 #else /* !WIN32 */
00272            (void)close(fd);
00273 #endif /* !WIN32 */
00274            return IIIMF_STATUS_STREAM;
00275        }
00276 
00277        if (0 < hostp->h_length) {
00278            (void)memcpy(&addr.sin_addr, hostp->h_addr,
00279                       hostp->h_length);
00280        } else {
00281 #if defined(WIN32)
00282            sock_close(fd);
00283 #else /* !WIN32 */
00284            (void)close(fd);
00285 #endif /* !WIN32 */
00286            return IIIMF_STATUS_STREAM;
00287        }
00288     }
00289 
00290     r = connect(fd, (struct sockaddr *)(&addr), sizeof (addr));
00291 #if defined(WIN32)
00292     if (SOCKET_ERROR == r) {
00293        sock_close(fd);
00294        return IIIMF_STATUS_STREAM;
00295     }
00296 #else /* !WIN32 */
00297     if (r < 0) {
00298        (void)close(fd);
00299        return IIIMF_STATUS_STREAM;
00300     }
00301 #endif /* !WIN32 */
00302 #endif /* !HAVE_GETADDRINFO */
00303 
00304     fd_flag = fcntl(fd, F_GETFD);
00305     fd_flag |= FD_CLOEXEC;
00306     (void)fcntl(fd, F_SETFD, fd_flag);
00307 
00308     {
00309        IIIMF_status st;
00310        IIIMF_stream *stream;
00311        IIIMF_stream_socket_private *sockpriv;
00312 
00313        sockpriv = create_sockpriv(IIIMF_STREAM_SOCKET_OPEN, fd,
00314                                timeout);
00315        if (!sockpriv) {
00316            close(fd);
00317            return IIIMF_STATUS_MALLOC;
00318        }
00319 
00320        st = iiimf_create_stream(stream_socket_read, stream_socket_write,
00321                              sockpriv, timeout, &stream);
00322        if (st != IIIMF_STATUS_SUCCESS) return st;
00323        *stream_ret = stream;
00324     }
00325 
00326     return IIIMF_STATUS_SUCCESS;
00327 }
00328 
00329 IIIMF_status
00330 iiimf_listen_socket_stream(
00331     const char *     node,
00332     const char *     service,
00333     int                 timeout,
00334     IIIMF_stream ** stream_ret
00335 )
00336 {
00337     int                     fd;
00338     int                     fd_flag;
00339     int                     optval;
00340     int                     r = 0;
00341 
00342 #if defined(HAVE_GETADDRINFO)
00343     int                     e;
00344     struct addrinfo *       a;
00345     struct addrinfo *       aip;
00346     struct addrinfo  hints;
00347 
00348     fd = -1;
00349 
00350     (void)memset(&hints, 0, sizeof (hints));
00351     hints.ai_flags = AI_PASSIVE;
00352     hints.ai_socktype = SOCK_STREAM;
00353 
00354     e = getaddrinfo(NULL, service, &hints, &aip);
00355     if (0 != e) return IIIMF_STATUS_STREAM;
00356 
00357     for (a = aip; NULL != a; a = a->ai_next) {
00358        fd = socket(a->ai_family, a->ai_socktype, a->ai_protocol);
00359        if (-1 != fd) {
00360            r = bind(fd, aip->ai_addr, sizeof (struct sockaddr));
00361            if (-1 != r) break;
00362            (void)close(fd);
00363            fd = -1;
00364        }
00365     }
00366     freeaddrinfo(aip);
00367     if ((-1 == fd) || (-1 == r)) return IIIMF_STATUS_STREAM;
00368     r = listen(fd, 5);
00369     if (-1 == r) return IIIMF_STATUS_STREAM;
00370 #else /* !HAVE_GETADDRINFO */
00371 
00372 #if defined(WIN32)
00373     unsigned short int      port_number;
00374 #else /* !WIN32 */
00375     int                     port_number;
00376 #endif /* !WIN32 */
00377 #if defined(PF_INET6) && defined(ENABLE_IPV6)
00378     struct sockaddr_in6     addr;
00379 #else /* !PF_INET6 && ENABLE_IPV6 */
00380     struct sockaddr_in      addr;
00381 #endif /* !PF_INET6 && ENABLE_IPV6 */
00382     struct servent * srvp;
00383 
00384 #if defined(WIN32)
00385     start_winsock(1, 1);
00386 #endif
00387 
00388 #if defined(PF_INET6) && defined(ENABLE_IPV6)
00389     fd = socket(PF_INET6, SOCK_STREAM, 0);
00390 #else /* !PF_INET6 && ENABLE_IPV6 */
00391     fd = socket(PF_INET, SOCK_STREAM, 0);
00392 #endif /* !PF_INET6 && ENABLE_IPV6 */
00393 
00394     if (fd < 0 ) return IIIMF_STATUS_STREAM;
00395 
00396     port_number = 0;
00397 
00398     if (0 < strlen(service)) {
00399        srvp = getservbyname(service, "tcp");
00400        if (NULL != srvp) {
00401            port_number = srvp->s_port;
00402        }
00403        (void)endservent();
00404        if (0 == port_number) {
00405            port_number = atoi(service);
00406        }
00407     }
00408     if (0 == port_number) {
00409        port_number = 9010;
00410     }
00411 
00412     (void)memset((char *)(&addr), 0, sizeof (addr));
00413 #if defined(PF_INET6) && defined(ENABLE_IPV6)
00414     addr.sin6_family = PF_INET6;
00415     addr.sin6_flowinfo = 0;
00416     addr.sin6_port = htons(port_number);
00417     addr.sin6_addr = in6addr_any;
00418 #else /* !PF_INET6 && ENABLE_IPV6 */
00419     addr.sin_family = PF_INET;
00420     addr.sin_port = htons(port_number);
00421 #endif /* !PF_INET6 && ENABLE_IPV6 */
00422 
00423     if ((bind(fd, (struct sockaddr *)(&addr), sizeof (addr)) < 0) ||
00424        (listen(fd, 5) < 0) ) {
00425 #if defined(WIN32)
00426        sock_close(fd);
00427 #else /* !WIN32 */
00428        (void)close(fd);
00429 #endif /* !WIN32 */
00430        return IIIMF_STATUS_STREAM;
00431     }
00432 #endif /* !HAVE_GETADDRINFO */
00433 
00434     optval = 1;
00435     r = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (int));
00436     if (-1 == r) {
00437 #if defined(WIN32)
00438        sock_close(fd);
00439 #else /* !WIN32 */
00440        (void)close(fd);
00441 #endif /* !WIN32 */
00442        return IIIMF_STATUS_STREAM;
00443     }
00444 
00445     fd_flag = fcntl(fd, F_GETFD);
00446     fd_flag |= FD_CLOEXEC;
00447     (void)fcntl(fd, F_SETFD, fd_flag);
00448 
00449     {
00450        IIIMF_status st;
00451        IIIMF_stream *stream;
00452        IIIMF_stream_socket_private *sockpriv;
00453 
00454        sockpriv = create_sockpriv(IIIMF_STREAM_SOCKET_LISTEN, fd, timeout);
00455        if (!sockpriv) {
00456            close(fd);
00457            return IIIMF_STATUS_MALLOC;
00458        }
00459 
00460        st = iiimf_create_stream(NULL, NULL, sockpriv, timeout, &stream);
00461        if (st != IIIMF_STATUS_SUCCESS) return st;
00462        *stream_ret = stream;
00463     }
00464 
00465     return IIIMF_STATUS_SUCCESS;
00466 }
00467 
00468 IIIMF_status
00469 iiimf_accept_socket_stream(
00470     IIIMF_stream *  stream,
00471     IIIMF_stream ** stream_ret
00472 )
00473 {
00474     IIIMF_stream_socket_private *sockpriv = (IIIMF_stream_socket_private*) stream->private_data;
00475     IIIMF_status     status;
00476     struct sockaddr  address;
00477     socklen_t        address_len;
00478     int                     fd;
00479 #if defined(HAVE_POLL)
00480     struct pollfd    fds[1];
00481     int                     poll_ret;
00482 #else /* !HAVE_POLL */
00483     fd_set           fdvar;
00484     struct timeval   timeout;
00485     int                     select_ret;
00486 
00487     timeout.tv_sec = sockpriv->timeout / 1000;
00488     timeout.tv_usec = sockpriv->timeout % 1000;
00489 #endif /* !HAVE_POLL */
00490 
00491     if (sockpriv->flags != IIIMF_STREAM_SOCKET_LISTEN)
00492        return IIIMF_STATUS_ARGUMENT;
00493 
00494     if (0 <= sockpriv->timeout) {
00495 #if defined(HAVE_POLL)
00496        fds[0].fd = sockpriv->fd;
00497        fds[0].events = POLLIN;
00498        poll_ret = poll(fds, 1, sockpriv->timeout);
00499        if (0 == poll_ret) {
00500            return IIIMF_STATUS_TIMEOUT;
00501        } else if (-1 == poll_ret) {
00502            return IIIMF_STATUS_STREAM;
00503        }
00504 #else /* !HAVE_POLL */
00505        do {
00506            FD_ZERO(&fdvar);
00507            FD_SET(sockpriv->fd, &fdvar);
00508            select_ret = select(sockpriv->fd + 1, NULL,
00509                             &fdvar, NULL, &timeout);
00510        } while ((-1 == select_ret) && (EINTR == errno));
00511        if (-1 == select_ret) return IIIMF_STATUS_TIMEOUT;
00512 #endif /* !HAVE_POLL */
00513     }
00514     address_len = (sizeof (address));
00515     fd = accept(sockpriv->fd, &address, &address_len);
00516     if (-1 == fd) return IIIMF_STATUS_STREAM;
00517 
00518     {
00519        IIIMF_stream *stream_new;
00520        IIIMF_stream_socket_private *sockpriv_new;
00521 
00522        sockpriv_new = create_sockpriv(IIIMF_STREAM_SOCKET_OPEN, fd,
00523                                    sockpriv->timeout);
00524        if (!sockpriv_new) {
00525            close(fd);
00526            return IIIMF_STATUS_MALLOC;
00527        }
00528        status = iiimf_create_stream(stream_socket_read, stream_socket_write,
00529                                  sockpriv_new, sockpriv->timeout, &stream_new);
00530        if (status != IIIMF_STATUS_SUCCESS) return status;
00531        *stream_ret = stream_new;
00532     }
00533 
00534     return IIIMF_STATUS_SUCCESS;
00535 }
00536 
00537 IIIMF_status
00538 iiimf_delete_socket_stream(
00539     IIIMF_stream *  stream
00540 )
00541 {
00542     IIIMF_stream_socket_private *sockpriv = (IIIMF_stream_socket_private*) stream->private_data;
00543     
00544     if (sockpriv->fd > 0) close(sockpriv->fd);
00545     delete_sockpriv(sockpriv);
00546     iiimf_stream_delete(stream);
00547     return IIIMF_STATUS_SUCCESS;
00548 }
00549 
00550 static IIIMF_status
00551 stream_socket_read(
00552     IIIMF_stream_private        private,
00553     void *                  buf,
00554     size_t                  nbyte)
00555 {
00556     IIIMF_stream_socket_private *sockpriv = (IIIMF_stream_socket_private*) private;
00557     char *           p;
00558     ssize_t          n;
00559     ssize_t          r;
00560 
00561 #if !defined(HAVE_SO_NOSIGPIPE) && !defined(HAVE_MSG_NOSIGNAL) && defined(HAVE_SIGNAL)
00562     RETSIGTYPE (*old_sighandler)(int);
00563 #endif
00564 
00565 #if defined(HAVE_POLL)
00566     struct pollfd    fds[1];
00567     int                     poll_ret;
00568 #else /* !HAVE_POLL */
00569     fd_set           fdvar;
00570     struct timeval   timeout;
00571     int                     select_ret;
00572 
00573     timeout.tv_sec = sockpriv->timeout / 1000;
00574     timeout.tv_usec = sockpriv->timeout % 1000;
00575 #endif /* !HAVE_POLL */
00576 
00577 #if !defined(HAVE_SO_NOSIGPIPE) && !defined(HAVE_MSG_NOSIGNAL) && defined(HAVE_SIGNAL)
00578     /* block SIGPIPE */
00579     old_sighandler = signal(SIGPIPE, SIG_IGN);
00580 #endif
00581 
00582     if (sockpriv->fd < 0) return IIIMF_STATUS_STREAM_RECEIVE;
00583     for (p = buf, n = nbyte; 0 < n; p += r, n -= r) {
00584        if (0 <= sockpriv->timeout) {
00585 #if defined(HAVE_POLL)
00586            fds[0].fd = sockpriv->fd;
00587            fds[0].events = POLLIN;
00588            poll_ret = poll(fds, 1, sockpriv->timeout);
00589            if (0 == poll_ret) {
00590               return IIIMF_STATUS_TIMEOUT;
00591            } else if (-1 == poll_ret) {
00592               return IIIMF_STATUS_STREAM;
00593            }
00594 #else /* !HAVE_POLL */
00595            do {
00596               FD_ZERO(&fdvar);
00597               FD_SET(sockpriv->fd, &fdvar);
00598               select_ret = select(sockpriv->fd + 1, NULL,
00599                                 &fdvar, NULL, &timeout);
00600            } while ((-1 == select_ret) && (EINTR == errno));
00601 #endif /* !HAVE_POLL */
00602        }
00603 
00604 #ifdef HAVE_MSG_NOSIGNAL
00605         r = recv(sockpriv->fd, p, n, MSG_NOSIGNAL);
00606 #else
00607        r = recv(sockpriv->fd, p, n, 0);
00608 #endif
00609        if (r == 0) {
00610            return IIIMF_STATUS_CONNECTION_CLOSED;
00611        }
00612        if (r < 0) {
00613            if (EINTR == errno) {
00614               continue;
00615            } else {
00616 #if !defined(HAVE_SO_NOSIGPIPE) && !defined(HAVE_MSG_NOSIGNAL) && defined(HAVE_SIGNAL)
00617                 /* restore old handler */
00618                 signal(SIGPIPE, old_sighandler);
00619 #endif
00620                 if (EPIPE == errno) {
00621                     sockpriv->fd = -1;
00622                     return IIIMF_STATUS_CONNECTION_CLOSED;
00623                 }
00624               return IIIMF_STATUS_STREAM_RECEIVE;
00625            }
00626        }
00627     }
00628 
00629 #if !defined(HAVE_SO_NOSIGPIPE) && !defined(HAVE_MSG_NOSIGNAL) && defined(HAVE_SIGNAL)
00630     /* restore old handler */
00631     signal(SIGPIPE, old_sighandler);
00632 #endif
00633 
00634     return IIIMF_STATUS_SUCCESS;
00635 }
00636 
00637 static IIIMF_status
00638 stream_socket_write(
00639     IIIMF_stream_private        private,
00640     const void *            buf,
00641     size_t                  nbyte)
00642 {
00643     IIIMF_stream_socket_private *sockpriv = (IIIMF_stream_socket_private*) private;
00644     const char *     p;
00645     ssize_t          n;
00646     ssize_t          r;
00647 
00648 #if !defined(HAVE_SO_NOSIGPIPE) && !defined(HAVE_MSG_NOSIGNAL) && defined(HAVE_SIGNAL)
00649     RETSIGTYPE (*old_sighandler)(int);
00650     /* block SIGPIPE */
00651     old_sighandler = signal(SIGPIPE, SIG_IGN);
00652 #endif
00653 
00654     if (sockpriv->fd < 0) return IIIMF_STATUS_STREAM_SEND;
00655 
00656     for (p = buf, n = nbyte; 0 < n; p += r, n -= r) {
00657         #ifdef HAVE_MSG_NOSIGNAL
00658         r = send(sockpriv->fd, p, n, MSG_NOSIGNAL);
00659         #else
00660         r = send(sockpriv->fd, p, n, 0);
00661         #endif
00662        if (r < 0) {
00663             #if !defined(HAVE_SO_NOSIGPIPE) && !defined(HAVE_MSG_NOSIGNAL) && defined(HAVE_SIGNAL)
00664             /* restore old handler */
00665             signal(SIGPIPE, old_sighandler);
00666             #endif
00667             if (EPIPE == errno) {
00668                 sockpriv->fd = -1;
00669                 return IIIMF_STATUS_CONNECTION_CLOSED;
00670             }
00671             return IIIMF_STATUS_STREAM_SEND;
00672         }
00673     }
00674 
00675 #if !defined(HAVE_SO_NOSIGPIPE) && !defined(HAVE_MSG_NOSIGNAL) && defined(HAVE_SIGNAL)
00676     /* restore old handler */
00677     signal(SIGPIPE, old_sighandler);
00678 #endif
00679 
00680     return IIIMF_STATUS_SUCCESS;
00681 }
00682 
00683 #if defined(WIN32)
00684 static int
00685 start_winsock(int major, int minor)
00686 {
00687     WORD      wVersionRequested;
00688     WSADATA   wsaData;
00689     int       r;
00690 
00691     wVersionRequested = MAKEWORD(major, minor);
00692 
00693     r = WSAStartup(wVersionRequested, &wsaData);
00694 
00695     if (0 != r) return -1;
00696 
00697 #ifdef CHK_WSOCK_VERSION
00698     if ((1 != LOBYTE(wnsaData.wVersion)) ||
00699        (1 != HIBYTE(wsaData.wVersion))) {
00700        /* wrong version */
00701        return 1;
00702     }
00703 #endif /* CHK_WSOCK_VERSION */
00704 
00705        return 0;
00706 }
00707 
00708 
00709 static int
00710 end_winsock()
00711 {
00712     return WSACleanup();
00713 }
00714 
00715 
00716 static int
00717 sock_close(int fd)
00718 {
00719     int r;
00720     if (INVALID_SOCKET != fd) {
00721        r = closesocket(fd);
00722        end_winsock();
00723        fd = INVALID_SOCKET;
00724        return r;
00725     }
00726     return 0;
00727 }
00728 #endif /* WIN32 */
00729 
00730 
00731 /* Local Variables: */
00732 /* c-file-style: "iiim-project" */
00733 /* End: */