Annotation of embedaddon/strongswan/src/libstrongswan/utils/compat/windows.c, revision 1.1.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>