Annotation of embedaddon/strongswan/src/libstrongswan/utils/compat/windows.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2013 Martin Willi
        !             3:  * Copyright (C) 2013 revosec AG
        !             4:  *
        !             5:  * This program is free software; you can redistribute it and/or modify it
        !             6:  * under the terms of the GNU General Public License as published by the
        !             7:  * Free Software Foundation; either version 2 of the License, or (at your
        !             8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !             9:  *
        !            10:  * This program is distributed in the hope that it will be useful, but
        !            11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            13:  * for more details.
        !            14:  */
        !            15: 
        !            16: /* WSAPoll() */
        !            17: #define _WIN32_WINNT 0x0600
        !            18: 
        !            19: #include <utils/utils.h>
        !            20: 
        !            21: #include <errno.h>
        !            22: 
        !            23: /**
        !            24:  * See header
        !            25:  */
        !            26: void windows_init()
        !            27: {
        !            28:        WSADATA wsad;
        !            29: 
        !            30:        /* initialize winsock2 */
        !            31:        WSAStartup(MAKEWORD(2, 2), &wsad);
        !            32: }
        !            33: 
        !            34: /**
        !            35:  * See header
        !            36:  */
        !            37: void windows_deinit()
        !            38: {
        !            39:        WSACleanup();
        !            40: }
        !            41: 
        !            42: /**
        !            43:  * See header
        !            44:  */
        !            45: int usleep(useconds_t usec)
        !            46: {
        !            47:        if (usec > 0 && usec < 1000)
        !            48:        {       /* do not Sleep(0) for small values */
        !            49:                usec = 1000;
        !            50:        }
        !            51:        SleepEx(usec / 1000, TRUE);
        !            52:        return 0;
        !            53: }
        !            54: 
        !            55: /**
        !            56:  * See header.
        !            57:  */
        !            58: char* strndup(const char *s, size_t n)
        !            59: {
        !            60:        char *dst;
        !            61: 
        !            62:        n = min(strnlen(s, n), n);
        !            63:        dst = malloc(n + 1);
        !            64:        memcpy(dst, s, n);
        !            65:        dst[n] = '\0';
        !            66: 
        !            67:        return dst;
        !            68: }
        !            69: 
        !            70: /*
        !            71:  * See header.
        !            72:  */
        !            73: void *dlopen(const char *filename, int flag)
        !            74: {
        !            75:        return LoadLibrary(filename);
        !            76: }
        !            77: 
        !            78: /**
        !            79:  * Load a symbol from known default libs (monolithic build)
        !            80:  */
        !            81: static void* dlsym_default(const char *name)
        !            82: {
        !            83:        const char *dlls[] = {
        !            84:                "libstrongswan-0.dll",
        !            85:                "libcharon-0.dll",
        !            86:                "libtnccs-0.dll",
        !            87:                NULL /* .exe */
        !            88:        };
        !            89:        HANDLE handle;
        !            90:        void *sym = NULL;
        !            91:        int i;
        !            92: 
        !            93:        for (i = 0; i < countof(dlls); i++)
        !            94:        {
        !            95:                handle = GetModuleHandle(dlls[i]);
        !            96:                if (handle)
        !            97:                {
        !            98:                        sym = GetProcAddress(handle, name);
        !            99:                        if (sym)
        !           100:                        {
        !           101:                                break;
        !           102:                        }
        !           103:                }
        !           104:        }
        !           105:        return sym;
        !           106: }
        !           107: 
        !           108: /**
        !           109:  * Emulate RTLD_NEXT for some known symbols
        !           110:  */
        !           111: static void* dlsym_next(const char *name)
        !           112: {
        !           113:        struct {
        !           114:                const char *dll;
        !           115:                const char *syms[4];
        !           116:        } dlls[] = {
        !           117:                /* for leak detective */
        !           118:                { "msvcrt",
        !           119:                        { "malloc", "calloc", "realloc", "free" }
        !           120:                },
        !           121:        };
        !           122:        HANDLE handle = NULL;
        !           123:        int i, j;
        !           124: 
        !           125:        for (i = 0; i < countof(dlls); i++)
        !           126:        {
        !           127:                for (j = 0; j < countof(dlls[0].syms); j++)
        !           128:                {
        !           129:                        if (dlls[i].syms[j] && streq(dlls[i].syms[j], name))
        !           130:                        {
        !           131:                                handle = GetModuleHandle(dlls[i].dll);
        !           132:                                break;
        !           133:                        }
        !           134:                }
        !           135:        }
        !           136:        if (handle)
        !           137:        {
        !           138:                return GetProcAddress(handle, name);
        !           139:        }
        !           140:        return handle;
        !           141: }
        !           142: 
        !           143: /**
        !           144:  * See header.
        !           145:  */
        !           146: void* dlsym(void *handle, const char *symbol)
        !           147: {
        !           148:        if (handle == RTLD_DEFAULT)
        !           149:        {
        !           150:                return dlsym_default(symbol);
        !           151:        }
        !           152:        if (handle == RTLD_NEXT)
        !           153:        {
        !           154:                return dlsym_next(symbol);
        !           155:        }
        !           156:        return GetProcAddress((HMODULE)handle, symbol);
        !           157: }
        !           158: 
        !           159: /**
        !           160:  * See header.
        !           161:  */
        !           162: char* dlerror(void)
        !           163: {
        !           164:        static char buf[128];
        !           165:        char *pos;
        !           166:        DWORD err;
        !           167: 
        !           168:        err = GetLastError();
        !           169:        if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        !           170:                                          NULL, err, 0, buf, sizeof(buf), NULL) > 0)
        !           171:        {
        !           172:                pos = strchr(buf, '\n');
        !           173:                if (pos)
        !           174:                {
        !           175:                        *pos = '\0';
        !           176:                }
        !           177:        }
        !           178:        else
        !           179:        {
        !           180:                snprintf(buf, sizeof(buf), "(%u)", err);
        !           181:        }
        !           182:        return buf;
        !           183: }
        !           184: 
        !           185: /**
        !           186:  * See header.
        !           187:  */
        !           188: int dlclose(void *handle)
        !           189: {
        !           190:        return FreeLibrary((HMODULE)handle);
        !           191: }
        !           192: 
        !           193: /**
        !           194:  * See header
        !           195:  */
        !           196: int socketpair(int domain, int type, int protocol, int sv[2])
        !           197: {
        !           198:        struct sockaddr_in addr = {
        !           199:                .sin_family = AF_INET,
        !           200:                .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
        !           201:        };
        !           202:        socklen_t len = sizeof(addr);
        !           203:        int s, c, sc;
        !           204:        BOOL on;
        !           205: 
        !           206:        /* We don't check domain for AF_INET, as we use it as replacement for
        !           207:         * AF_UNIX. */
        !           208:        if (type != SOCK_STREAM)
        !           209:        {
        !           210:                errno = EINVAL;
        !           211:                return -1;
        !           212:        }
        !           213:        if (protocol != 0 && protocol != IPPROTO_TCP)
        !           214:        {
        !           215:                errno = EINVAL;
        !           216:                return -1;
        !           217:        }
        !           218:        s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        !           219:        if (s == -1)
        !           220:        {
        !           221:                return -1;
        !           222:        }
        !           223:        c = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        !           224:        if (c == -1)
        !           225:        {
        !           226:                closesocket(s);
        !           227:                return -1;
        !           228:        }
        !           229:        if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) == 0 &&
        !           230:                getsockname(s,(struct sockaddr*)&addr, &len) == 0 &&
        !           231:                listen(s, 0) == 0 &&
        !           232:                connect(c, (struct sockaddr*)&addr, sizeof(addr)) == 0)
        !           233:        {
        !           234:                sc = accept(s, NULL, NULL);
        !           235:                if (sc >= 0)
        !           236:                {
        !           237:                        closesocket(s);
        !           238:                        s = sc;
        !           239:                        if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
        !           240:                                                   (void*)&on, sizeof(on)) == 0 &&
        !           241:                                setsockopt(c, IPPROTO_TCP, TCP_NODELAY,
        !           242:                                                   (void*)&on, sizeof(on)) == 0)
        !           243:                        {
        !           244:                                sv[0] = s;
        !           245:                                sv[1] = c;
        !           246:                                return 0;
        !           247:                        }
        !           248:                }
        !           249:        }
        !           250:        closesocket(s);
        !           251:        closesocket(c);
        !           252:        return -1;
        !           253: }
        !           254: 
        !           255: /**
        !           256:  * See header
        !           257:  */
        !           258: char* getpass(const char *prompt)
        !           259: {
        !           260:        static char buf[64] = "";
        !           261:        char *pos;
        !           262:        HANDLE in, out;
        !           263:        DWORD mode, written = 0, total, done;
        !           264: 
        !           265:        out = GetStdHandle(STD_OUTPUT_HANDLE);
        !           266:        in = GetStdHandle(STD_INPUT_HANDLE);
        !           267: 
        !           268:        if (out == INVALID_HANDLE_VALUE || in == INVALID_HANDLE_VALUE ||
        !           269:                !GetConsoleMode(out, &mode) || !GetConsoleMode(in, &mode))
        !           270:        {
        !           271:                return NULL;
        !           272:        }
        !           273: 
        !           274:        total = strlen(prompt);
        !           275:        while (written < total)
        !           276:        {
        !           277:                if (!WriteConsole(out, prompt + written, total - written, &done, NULL))
        !           278:                {
        !           279:                        return NULL;
        !           280:                }
        !           281:                written += done;
        !           282:        }
        !           283: 
        !           284:        if (!SetConsoleMode(in, mode & ~ENABLE_ECHO_INPUT))
        !           285:        {
        !           286:                return NULL;
        !           287:        }
        !           288: 
        !           289:        while (TRUE)
        !           290:        {
        !           291:                if (!ReadConsole(in, buf, sizeof(buf), &done, NULL))
        !           292:                {
        !           293:                        SetConsoleMode(in, mode);
        !           294:                        return NULL;
        !           295:                }
        !           296:                buf[sizeof(buf)-1] = '\0';
        !           297: 
        !           298:                if (done)
        !           299:                {
        !           300:                        pos = strchr(buf, '\r');
        !           301:                        if (pos)
        !           302:                        {
        !           303:                                *pos = '\0';
        !           304:                        }
        !           305:                        break;
        !           306:                }
        !           307:        }
        !           308:        SetConsoleMode(in, mode);
        !           309: 
        !           310:        /* append a newline, as we have no echo during input */
        !           311:        WriteConsole(out, "\r\n", 2, &done, NULL);
        !           312: 
        !           313:        return buf;
        !           314: }
        !           315: 
        !           316: /**
        !           317:  * See header.
        !           318:  */
        !           319: #undef strerror_s
        !           320: int strerror_s_extended(char *buf, size_t buflen, int errnum)
        !           321: {
        !           322:        const char *errstr [] = {
        !           323:                /* EADDRINUSE */                "Address in use",
        !           324:                /* EADDRNOTAVAIL */             "Address not available",
        !           325:                /* EAFNOSUPPORT */              "Address family not supported",
        !           326:                /* EALREADY */                  "Connection already in progress",
        !           327:                /* EBADMSG */                   "Bad message",
        !           328:                /* ECANCELED */                 "Operation canceled",
        !           329:                /* ECONNABORTED */              "Connection aborted",
        !           330:                /* ECONNREFUSED */              "Connection refused",
        !           331:                /* ECONNRESET */                "Connection reset",
        !           332:                /* EDESTADDRREQ */              "Destination address required",
        !           333:                /* EHOSTUNREACH */              "Host is unreachable",
        !           334:                /* EIDRM */                             "Identifier removed",
        !           335:                /* EINPROGRESS */               "Operation in progress",
        !           336:                /* EISCONN */                   "Socket is connected",
        !           337:                /* ELOOP */                             "Too many levels of symbolic links",
        !           338:                /* EMSGSIZE */                  "Message too large",
        !           339:                /* ENETDOWN */                  "Network is down",
        !           340:                /* ENETRESET */                 "Connection aborted by network",
        !           341:                /* ENETUNREACH */               "Network unreachable",
        !           342:                /* ENOBUFS */                   "No buffer space available",
        !           343:                /* ENODATA */                   "No message is available",
        !           344:                /* ENOLINK */                   "No link",
        !           345:                /* ENOMSG */                    "No message of the desired type",
        !           346:                /* ENOPROTOOPT */               "Protocol not available",
        !           347:                /* ENOSR */                             "No stream resources",
        !           348:                /* ENOSTR */                    "Not a stream",
        !           349:                /* ENOTCONN */                  "The socket is not connected",
        !           350:                /* ENOTRECOVERABLE */   "State not recoverable",
        !           351:                /* ENOTSOCK */                  "Not a socket",
        !           352:                /* ENOTSUP */                   "Not supported",
        !           353:                /* EOPNOTSUPP */                "Operation not supported on socket",
        !           354:                /* EOTHER */                    "Other error",
        !           355:                /* EOVERFLOW */                 "Value too large to be stored in data type",
        !           356:                /* EOWNERDEAD */                "Previous owner died",
        !           357:                /* EPROTO */                    "Protocol error",
        !           358:                /* EPROTONOSUPPORT */   "Protocol not supported",
        !           359:                /* EPROTOTYPE */                "Protocol wrong type for socket",
        !           360:                /* ETIME */                             "Timeout",
        !           361:                /* ETIMEDOUT */                 "Connection timed out",
        !           362:                /* ETXTBSY */                   "Text file busy",
        !           363:                /* EWOULDBLOCK */               "Operation would block",
        !           364:        };
        !           365:        int offset = EADDRINUSE;
        !           366: 
        !           367:        if (errnum < offset || errnum >= offset + countof(errstr))
        !           368:        {
        !           369:                return strerror_s(buf, buflen, errnum);
        !           370:        }
        !           371:        strncpy(buf, errstr[errnum - offset], buflen);
        !           372:        buf[buflen - 1] = '\0';
        !           373:        return 0;
        !           374: }
        !           375: 
        !           376: /**
        !           377:  * Set errno for a function setting WSA error on failure
        !           378:  */
        !           379: static int wserr(int retval)
        !           380: {
        !           381:        if (retval < 0)
        !           382:        {
        !           383:                static const struct {
        !           384:                        DWORD wsa;
        !           385:                        int err;
        !           386:                } map[] = {
        !           387:                        { WSANOTINITIALISED,                    EBADF                                           },
        !           388:                        { WSAENETDOWN,                                  ENETDOWN                                        },
        !           389:                        { WSAENETRESET,                                 ENETRESET                                       },
        !           390:                        { WSAECONNABORTED,                              ECONNABORTED                            },
        !           391:                        { WSAESHUTDOWN,                                 ECONNABORTED                            },
        !           392:                        { WSAEACCES,                                    EACCES                                          },
        !           393:                        { WSAEINTR,                                             EINTR                                           },
        !           394:                        { WSAEINPROGRESS,                               EINPROGRESS                                     },
        !           395:                        { WSAEFAULT,                                    EFAULT                                          },
        !           396:                        { WSAENOBUFS,                                   ENOBUFS                                         },
        !           397:                        { WSAENOTSOCK,                                  ENOTSOCK                                        },
        !           398:                        { WSAEOPNOTSUPP,                                EOPNOTSUPP                                      },
        !           399:                        { WSAEWOULDBLOCK,                               EWOULDBLOCK                                     },
        !           400:                        { WSAEMSGSIZE,                                  EMSGSIZE                                        },
        !           401:                        { WSAEINVAL,                                    EINVAL                                          },
        !           402:                        { WSAENOTCONN,                                  ENOTCONN                                        },
        !           403:                        { WSAEHOSTUNREACH,                              EHOSTUNREACH                            },
        !           404:                        { WSAENETUNREACH,                               ENETUNREACH                                     },
        !           405:                        { WSAECONNABORTED,                              ECONNABORTED                            },
        !           406:                        { WSAECONNRESET,                                ECONNRESET                                      },
        !           407:                        { WSAETIMEDOUT,                                 ETIMEDOUT                                       },
        !           408:                        { WSAEMFILE,                                    EMFILE                                          },
        !           409:                        { WSAEALREADY,                                  EALREADY                                        },
        !           410:                        { WSAEDESTADDRREQ,                              EDESTADDRREQ                            },
        !           411:                        { WSAEISCONN,                                   EISCONN                                         },
        !           412:                        { WSAEOPNOTSUPP,                                EOPNOTSUPP                                      },
        !           413:                        { WSAEPROTOTYPE,                                EPROTOTYPE                                      },
        !           414:                        { WSAENOPROTOOPT,                               ENOPROTOOPT                                     },
        !           415:                        { WSAEPROTONOSUPPORT,                   EPROTONOSUPPORT                         },
        !           416:                        { WSAEPFNOSUPPORT,                              EPROTONOSUPPORT                         },
        !           417:                        { WSAEAFNOSUPPORT,                              EAFNOSUPPORT                            },
        !           418:                        { WSAEADDRNOTAVAIL,                             EADDRNOTAVAIL                           },
        !           419:                        { WSAEADDRINUSE,                                EADDRINUSE                                      },
        !           420:                        { WSAETIMEDOUT,                                 ETIMEDOUT                                       },
        !           421:                        { WSAECONNREFUSED,                              ECONNREFUSED                            },
        !           422:                        { WSAELOOP,                                             ELOOP                                           },
        !           423:                        { WSAENAMETOOLONG,                              ENAMETOOLONG                            },
        !           424:                        { WSAENOTEMPTY,                                 ENOTEMPTY                                       },
        !           425:                        { WSAEPROTOTYPE,                                EPROTOTYPE                                      },
        !           426:                        { WSAVERNOTSUPPORTED,                   ENOTSUP                                         },
        !           427:                };
        !           428:                DWORD wsa, i;
        !           429: 
        !           430:                wsa = WSAGetLastError();
        !           431:                for (i = 0; i < countof(map); i++)
        !           432:                {
        !           433:                        if (map[i].wsa == wsa)
        !           434:                        {
        !           435:                                errno = map[i].err;
        !           436:                                return retval;
        !           437:                        }
        !           438:                }
        !           439:                errno = ENOENT;
        !           440:                return retval;
        !           441:        }
        !           442:        errno = 0;
        !           443:        return retval;
        !           444: }
        !           445: 
        !           446: /**
        !           447:  * Check and clear the dontwait flag
        !           448:  */
        !           449: static bool check_dontwait(int *flags)
        !           450: {
        !           451:        if (*flags & MSG_DONTWAIT)
        !           452:        {
        !           453:                *flags &= ~MSG_DONTWAIT;
        !           454:                return TRUE;
        !           455:        }
        !           456:        return FALSE;
        !           457: }
        !           458: 
        !           459: /**
        !           460:  * See header
        !           461:  */
        !           462: #undef shutdown
        !           463: int windows_shutdown(int sockfd, int how)
        !           464: {
        !           465:        return wserr(shutdown(sockfd, how));
        !           466: }
        !           467: 
        !           468: /**
        !           469:  * See header
        !           470:  */
        !           471: #undef accept
        !           472: int windows_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
        !           473: {
        !           474:        return wserr(accept(sockfd, addr, addrlen));
        !           475: }
        !           476: 
        !           477: /**
        !           478:  * See header
        !           479:  */
        !           480: #undef bind
        !           481: int windows_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
        !           482: {
        !           483:        return wserr(bind(sockfd, addr, addrlen));
        !           484: }
        !           485: 
        !           486: /**
        !           487:  * See header
        !           488:  */
        !           489: #undef connect
        !           490: int windows_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
        !           491: {
        !           492:        return wserr(connect(sockfd, addr, addrlen));
        !           493: }
        !           494: 
        !           495: /**
        !           496:  * See header
        !           497:  */
        !           498: #undef getsockname
        !           499: int windows_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
        !           500: {
        !           501:        return wserr(getsockname(sockfd, addr, addrlen));
        !           502: }
        !           503: 
        !           504: /**
        !           505:  * See header
        !           506:  */
        !           507: #undef getsockopt
        !           508: int windows_getsockopt(int sockfd, int level, int optname,
        !           509:                                           void *optval, socklen_t *optlen)
        !           510: {
        !           511:        return wserr(getsockopt(sockfd, level, optname, optval, optlen));
        !           512: }
        !           513: 
        !           514: /**
        !           515:  * See header
        !           516:  */
        !           517: #undef setsockopt
        !           518: int windows_setsockopt(int sockfd, int level, int optname,
        !           519:                                           const void *optval, socklen_t optlen)
        !           520: {
        !           521:        return wserr(setsockopt(sockfd, level, optname, optval, optlen));
        !           522: }
        !           523: 
        !           524: /**
        !           525:  * See header
        !           526:  */
        !           527: #undef socket
        !           528: int windows_socket(int domain, int type, int protocol)
        !           529: {
        !           530:        return wserr(socket(domain, type, protocol));
        !           531: }
        !           532: 
        !           533: /**
        !           534:  * See header
        !           535:  */
        !           536: #undef select
        !           537: int windows_select(int nfds, fd_set *readfds, fd_set *writefds,
        !           538:                                   fd_set *exceptfds, struct timeval *timeout)
        !           539: {
        !           540:        return wserr(select(nfds, readfds, writefds, exceptfds, timeout));
        !           541: }
        !           542: 
        !           543: /**
        !           544:  * See header
        !           545:  */
        !           546: #undef close
        !           547: int windows_close(int fd)
        !           548: {
        !           549:        int ret;
        !           550: 
        !           551:        ret = close(fd);
        !           552:        if (ret == -1 && errno == EBADF)
        !           553:        {       /* Winsock socket? */
        !           554:                ret = wserr(closesocket(fd));
        !           555:        }
        !           556:        return ret;
        !           557: }
        !           558: 
        !           559: /**
        !           560:  * See header
        !           561:  */
        !           562: #undef recv
        !           563: ssize_t windows_recv(int sockfd, void *buf, size_t len, int flags)
        !           564: {
        !           565:        u_long on = 1, off = 0;
        !           566:        ssize_t outlen = -1;
        !           567: 
        !           568:        if (!check_dontwait(&flags))
        !           569:        {
        !           570:                return wserr(recv(sockfd, buf, len, flags));
        !           571:        }
        !           572:        if (wserr(ioctlsocket(sockfd, FIONBIO, &on) == 0))
        !           573:        {
        !           574:                outlen = wserr(recv(sockfd, buf, len, flags));
        !           575:                ioctlsocket(sockfd, FIONBIO, &off);
        !           576:        }
        !           577:        return outlen;
        !           578: }
        !           579: 
        !           580: /**
        !           581:  * See header
        !           582:  */
        !           583: #undef recvfrom
        !           584: ssize_t windows_recvfrom(int sockfd, void *buf, size_t len, int flags,
        !           585:                                                 struct sockaddr *src_addr, socklen_t *addrlen)
        !           586: {
        !           587:        u_long on = 1, off = 0;
        !           588:        ssize_t outlen = -1;
        !           589: 
        !           590:        if (!check_dontwait(&flags))
        !           591:        {
        !           592:                return wserr(recvfrom(sockfd, buf, len, flags, src_addr, addrlen));
        !           593:        }
        !           594:        if (wserr(ioctlsocket(sockfd, FIONBIO, &on)) == 0)
        !           595:        {
        !           596:                outlen = wserr(recvfrom(sockfd, buf, len, flags, src_addr, addrlen));
        !           597:                ioctlsocket(sockfd, FIONBIO, &off);
        !           598:        }
        !           599:        return outlen;
        !           600: }
        !           601: 
        !           602: /**
        !           603:  * See header
        !           604:  */
        !           605: #undef send
        !           606: ssize_t windows_send(int sockfd, const void *buf, size_t len, int flags)
        !           607: {
        !           608:        u_long on = 1, off = 0;
        !           609:        ssize_t outlen = -1;
        !           610: 
        !           611:        if (!check_dontwait(&flags))
        !           612:        {
        !           613:                return wserr(send(sockfd, buf, len, flags));
        !           614:        }
        !           615:        if (wserr(ioctlsocket(sockfd, FIONBIO, &on)) == 0)
        !           616:        {
        !           617:                outlen = wserr(send(sockfd, buf, len, flags));
        !           618:                ioctlsocket(sockfd, FIONBIO, &off);
        !           619:        }
        !           620:        return outlen;
        !           621: }
        !           622: 
        !           623: /**
        !           624:  * See header
        !           625:  */
        !           626: #undef sendto
        !           627: ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags,
        !           628:                                           const struct sockaddr *dest_addr, socklen_t addrlen)
        !           629: {
        !           630:        u_long on = 1, off = 0;
        !           631:        ssize_t outlen = -1;
        !           632: 
        !           633:        if (!check_dontwait(&flags))
        !           634:        {
        !           635:                return wserr(sendto(sockfd, buf, len, flags, dest_addr, addrlen));
        !           636:        }
        !           637:        if (wserr(ioctlsocket(sockfd, FIONBIO, &on)) == 0)
        !           638:        {
        !           639:                outlen = wserr(sendto(sockfd, buf, len, flags, dest_addr, addrlen));
        !           640:                ioctlsocket(sockfd, FIONBIO, &off);
        !           641:        }
        !           642:        return outlen;
        !           643: }
        !           644: 
        !           645: /**
        !           646:  * See header
        !           647:  */
        !           648: #undef read
        !           649: ssize_t windows_read(int fd, void *buf, size_t count)
        !           650: {
        !           651:        ssize_t ret;
        !           652: 
        !           653:        ret = wserr(recv(fd, buf, count, 0));
        !           654:        if (ret == -1 && errno == ENOTSOCK)
        !           655:        {
        !           656:                ret = read(fd, buf, count);
        !           657:        }
        !           658:        return ret;
        !           659: }
        !           660: 
        !           661: /**
        !           662:  * See header
        !           663:  */
        !           664: #undef write
        !           665: ssize_t windows_write(int fd, void *buf, size_t count)
        !           666: {
        !           667:        ssize_t ret;
        !           668: 
        !           669:        ret = wserr(send(fd, buf, count, 0));
        !           670:        if (ret == -1 && errno == ENOTSOCK)
        !           671:        {
        !           672:                ret = write(fd, buf, count);
        !           673:        }
        !           674:        return ret;
        !           675: }
        !           676: 
        !           677: /**
        !           678:  * See header
        !           679:  */
        !           680: int poll(struct pollfd *fds, int nfds, int timeout)
        !           681: {
        !           682:        return wserr(WSAPoll(fds, nfds, timeout));
        !           683: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>