XrdWin32.cc

Go to the documentation of this file.
00001 //          $Id: XrdWin32.cc 30949 2009-11-02 16:37:58Z ganis $
00002 
00003 //const char *XrdWin32CVSID = "$Id: XrdWin32.cc 30949 2009-11-02 16:37:58Z ganis $";
00004 
00005 #include "XrdSys/XrdWin32.hh"
00006 #include <Windows.h>
00007 #include <errno.h>
00008 #include <malloc.h>
00009 
00010 int sysconf(int what)
00011 {
00012    SYSTEM_INFO info;
00013    GetSystemInfo(&info);
00014    return (int)(info.dwPageSize);
00015 }
00016 
00017 #if 0 // defined(_MSC_VER) && (_MSC_VER < 1400)
00018 //
00019 // Though working fine with MSVC++7.1, this definition gives problems
00020 // with MSVC++9.0; we comment it out and wait for better times
00021 int fcntl(int fd, int cmd, long arg)
00022 {
00023    u_long argp = 1;
00024    if ((cmd == F_SETFL) && (arg & O_NONBLOCK))
00025       return ioctlsocket((SOCKET)fd, FIONBIO, &argp);
00026    return 0;
00027 }
00028 #else
00029 int fcntl(int, int, long)
00030 {
00031    // Dummy version
00032    return 0;
00033 }
00034 #endif
00035 
00036 void gethostbyname_r(const char *inetName, struct hostent *hent, char *buff,
00037                      int buffsize, struct hostent **hp, int *rc)
00038 {
00039    struct hostent *hentry;
00040    hentry = gethostbyname(inetName);
00041    if (hentry == 0) {
00042       int err = WSAGetLastError();
00043       switch (err) {
00044          case WSAHOST_NOT_FOUND:
00045             *rc = 1; //HOST_NOT_FOUND
00046             break;
00047          case WSATRY_AGAIN:
00048             *rc = 2; //TRY_AGAIN
00049             break;
00050          case WSANO_RECOVERY:
00051             *rc = 3; //NO_RECOVERY
00052             break;
00053          case WSANO_DATA:
00054             *rc = 4; //NO_DATA;
00055             break;
00056          default:
00057             *rc = 1;
00058             break;
00059       }
00060       return;
00061    }
00062    hent->h_addr_list = hentry->h_addr_list;
00063    hent->h_addrtype  = hentry->h_addrtype;
00064    hent->h_aliases   = hentry->h_aliases;
00065    hent->h_length    = hentry->h_length;
00066    hent->h_name      = hentry->h_name;
00067 }
00068 
00069 void gethostbyaddr_r(char *addr, size_t len, int type, struct hostent *hent, char *buff,
00070                      size_t buffsize, struct hostent **hp, int *rc)
00071 {
00072    struct hostent *hentry;
00073    hentry = gethostbyaddr(addr, (int)len, type);
00074    if (hentry == 0) {
00075       int err = WSAGetLastError();
00076       switch (err) {
00077          case WSAHOST_NOT_FOUND:
00078             *rc = 1; //HOST_NOT_FOUND
00079             break;
00080          case WSATRY_AGAIN:
00081             *rc = 2; //TRY_AGAIN
00082             break;
00083          case WSANO_RECOVERY:
00084             *rc = 3; //NO_RECOVERY
00085             break;
00086          case WSANO_DATA:
00087             *rc = 4; //NO_DATA;
00088             break;
00089          default:
00090             *rc = 1;
00091             break;
00092       }
00093       return;
00094    }
00095    hent->h_addr_list = hentry->h_addr_list;
00096    hent->h_addrtype  = hentry->h_addrtype;
00097    hent->h_aliases   = hentry->h_aliases;
00098    hent->h_length    = hentry->h_length;
00099    hent->h_name      = hentry->h_name;
00100 }
00101 
00102 int getservbyname_r(const char *servname, const char *servtype, struct servent *sent,
00103                     char *buff, size_t buffsize, struct servent **sp)
00104 {
00105    sent = getservbyname(servname, servtype);
00106    if (sent != NULL)
00107       return 0;
00108    return -1;
00109 }
00110 
00111 /* FILETIME of Jan 1 1970 00:00:00. */
00112 static const unsigned __int64 epoch = 116444736000000000L;
00113 
00114 int gettimeofday(struct timeval * tp, struct timezone * tzp)
00115 {
00116    FILETIME       file_time;
00117    SYSTEMTIME     system_time;
00118    ULARGE_INTEGER ularge;
00119 
00120    GetSystemTime(&system_time);
00121    SystemTimeToFileTime(&system_time, &file_time);
00122    ularge.LowPart = file_time.dwLowDateTime;
00123    ularge.HighPart = file_time.dwHighDateTime;
00124 
00125    tp->tv_sec = (long) ((ularge.QuadPart - epoch) / 10000000L);
00126    tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
00127 
00128    return 0;
00129 }
00130 
00131 void *dlopen(const char *libPath, int opt)
00132 {
00133    return (void *)LoadLibrary(libPath);
00134 }
00135 
00136 BOOL dlclose(void *lib)
00137 {
00138    return FreeLibrary((HMODULE)lib);
00139 }
00140 
00141 void *dlsym(void *libHandle, const char *pname)
00142 {
00143    return (void *)GetProcAddress((HMODULE)libHandle, (LPCSTR)pname);
00144 }
00145 
00146 char *dlerror()
00147 {
00148    LPVOID lpMsgBuf;
00149    FormatMessage(
00150       FORMAT_MESSAGE_ALLOCATE_BUFFER |
00151       FORMAT_MESSAGE_FROM_SYSTEM |
00152       FORMAT_MESSAGE_IGNORE_INSERTS,
00153       NULL, GetLastError(),
00154       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00155       (LPTSTR) &lpMsgBuf, 0, NULL );
00156    return (char *)lpMsgBuf;
00157 }
00158 
00159 pid_t fork()
00160 {
00161    char *cmdline;
00162    STARTUPINFO startInfo;
00163    PROCESS_INFORMATION procInfo;
00164 
00165    cmdline = GetCommandLine();
00166 
00167    ZeroMemory(&startInfo, sizeof(startInfo));
00168    startInfo.cb = sizeof(startInfo);
00169    BOOL retval = CreateProcess(NULL, cmdline, NULL, NULL, TRUE,
00170                                DETACHED_PROCESS, NULL, NULL,
00171                                &startInfo, &procInfo);
00172    delete [] cmdline;
00173    return (pid_t)procInfo.hProcess;
00174 }
00175 
00176 LARGE_INTEGER LargeIntegerSubtract(LARGE_INTEGER a, LARGE_INTEGER b)
00177 {
00178    LARGE_INTEGER ret;
00179    ret.QuadPart = a.QuadPart - b.QuadPart;
00180    return ret;
00181 }
00182 
00183 /*
00184  * Copyright (c) 1999 Kungliga Tekniska Hgskolan
00185  * (Royal Institute of Technology, Stockholm, Sweden).
00186  * All rights reserved.
00187  *
00188  * Redistribution and use in source and binary forms, with or without
00189  * modification, are permitted provided that the following conditions
00190  * are met:
00191  *
00192  * 1. Redistributions of source code must retain the above copyright
00193  *    notice, this list of conditions and the following disclaimer.
00194  *
00195  * 2. Redistributions in binary form must reproduce the above copyright
00196  *    notice, this list of conditions and the following disclaimer in the
00197  *    documentation and/or other materials provided with the distribution.
00198  *
00199  * 3. All advertising materials mentioning features or use of this software
00200  *    must display the following acknowledgement:
00201  *      This product includes software developed by the Kungliga Tekniska
00202  *      Hgskolan and its contributors.
00203  *
00204  * 4. Neither the name of the Institute nor the names of its contributors
00205  *    may be used to endorse or promote products derived from this software
00206  *    without specific prior written permission.
00207  *
00208  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00209  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00210  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00211  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00212  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00213  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00214  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00215  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00216  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00217  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00218  * SUCH DAMAGE.
00219  */
00220 
00221 #define INET_ADDRSTRLEN 16
00222 #define EAFNOSUPPORT WSAEAFNOSUPPORT
00223 
00224 #ifndef IN6ADDRSZ
00225 #define IN6ADDRSZ   16   /* IPv6 T_AAAA */
00226 #endif
00227 
00228 #ifndef INT16SZ
00229 #define INT16SZ     2    /* word size */
00230 #endif
00231 
00232 static const char *
00233 inet_ntop_v4 (const void *src, char *dst, size_t size)
00234 {
00235    const char digits[] = "0123456789";
00236    int i;
00237    struct in_addr *addr = (struct in_addr *)src;
00238    u_long a = ntohl(addr->s_addr);
00239    const char *orig_dst = dst;
00240 
00241    if (size < INET_ADDRSTRLEN) {
00242       errno = ENOSPC;
00243       return NULL;
00244    }
00245    for (i = 0; i < 4; ++i) {
00246       int n = (a >> (24 - i * 8)) & 0xFF;
00247       int non_zerop = 0;
00248 
00249       if (non_zerop || n / 100 > 0) {
00250          *dst++ = digits[n / 100];
00251          n %= 100;
00252          non_zerop = 1;
00253       }
00254       if (non_zerop || n / 10 > 0) {
00255          *dst++ = digits[n / 10];
00256          n %= 10;
00257          non_zerop = 1;
00258       }
00259       *dst++ = digits[n];
00260       if (i != 3)
00261          *dst++ = '.';
00262    }
00263    *dst++ = '\0';
00264    return orig_dst;
00265 }
00266 
00267 #ifdef INET6
00268 /*
00269  * Convert IPv6 binary address into presentation (printable) format.
00270  */
00271 static const char *
00272 inet_ntop_v6 (const u_char *src, char *dst, size_t size)
00273 {
00274    /*
00275    * Note that int32_t and int16_t need only be "at least" large enough
00276    * to contain a value of the specified size.  On some systems, like
00277    * Crays, there is no such thing as an integer variable with 16 bits.
00278    * Keep this in mind if you think this function should have been coded
00279    * to use pointer overlays.  All the world's not a VAX.
00280    */
00281    char  tmp [INET6_ADDRSTRLEN+1];
00282    char *tp;
00283    struct {
00284       long base;
00285       long len;
00286    } best, cur;
00287    u_long words [IN6ADDRSZ / INT16SZ];
00288    int    i;
00289 
00290    /* Preprocess:
00291    *  Copy the input (bytewise) array into a wordwise array.
00292    *  Find the longest run of 0x00's in src[] for :: shorthanding.
00293    */
00294    memset (words, 0, sizeof(words));
00295    for (i = 0; i < IN6ADDRSZ; i++)
00296       words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));
00297 
00298    best.base = -1;
00299    cur.base  = -1;
00300    for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
00301       if (words[i] == 0) {
00302          if (cur.base == -1)
00303             cur.base = i, cur.len = 1;
00304          else cur.len++;
00305       }
00306       else if (cur.base != -1) {
00307          if (best.base == -1 || cur.len > best.len)
00308             best = cur;
00309          cur.base = -1;
00310       }
00311    }
00312    if ((cur.base != -1) && (best.base == -1 || cur.len > best.len))
00313       best = cur;
00314    if (best.base != -1 && best.len < 2)
00315       best.base = -1;
00316 
00317    /* Format the result.
00318    */
00319    tp = tmp;
00320    for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
00321       /* Are we inside the best run of 0x00's?
00322        */
00323       if (best.base != -1 && i >= best.base && i < (best.base + best.len)) {
00324          if (i == best.base)
00325             *tp++ = ':';
00326          continue;
00327       }
00328 
00329       /* Are we following an initial run of 0x00s or any real hex?
00330        */
00331       if (i != 0)
00332          *tp++ = ':';
00333 
00334       /* Is this address an encapsulated IPv4?
00335        */
00336       if (i == 6 && best.base == 0 && (best.len == 6 ||
00337          (best.len == 5 && words[5] == 0xffff))) {
00338          if (!inet_ntop_v4(src+12, tp, sizeof(tmp) - (tp - tmp))) {
00339             errno = ENOSPC;
00340             return (NULL);
00341          }
00342          tp += strlen(tp);
00343          break;
00344       }
00345       tp += sprintf (tp, "%lX", words[i]);
00346    }
00347 
00348    /* Was it a trailing run of 0x00's?
00349     */
00350    if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
00351       *tp++ = ':';
00352    *tp++ = '\0';
00353 
00354    /* Check for overflow, copy, and we're done.
00355     */
00356    if ((size_t)(tp - tmp) > size) {
00357       errno = ENOSPC;
00358       return (NULL);
00359    }
00360    return strcpy (dst, tmp);
00361    return (NULL);
00362 }
00363 #endif   /* INET6 */
00364 
00365 const char *inet_ntop(int af, const void *src, char *dst, size_t size)
00366 {
00367    switch (af) {
00368       case AF_INET :
00369          return inet_ntop_v4 (src, dst, size);
00370 #ifdef INET6
00371       case AF_INET6:
00372          return inet_ntop_v6 ((const u_char*)src, dst, size);
00373 #endif
00374       default :
00375          errno = EAFNOSUPPORT;
00376          return NULL;
00377    }
00378 }
00379 
00380 static void myerrcode(int err)
00381 {
00382    if (err == EIO)
00383       err = EBADF; // sometimes we get EIO when Unix would be EBADF
00384    if (err == WSAENOTSOCK)
00385       err = EBADF; // if it's not a socket, it's also not a fd
00386    SetLastError(err);
00387    errno = err;
00388 }
00389 
00390 // This is the simple and dirty method to check if fd is a socket
00391 #define IS_SOCKET(fd) ((fd)>=64)
00392 
00393 // And this is a more clever one
00394 static bool is_socket(SOCKET fd)
00395 {
00396    char sockbuf[80];
00397    int optlen;
00398    int retval;
00399 
00400    optlen = sizeof(sockbuf);
00401    retval = getsockopt(fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen);
00402    if (retval == SOCKET_ERROR) {
00403       int iRet;
00404       iRet = WSAGetLastError();
00405       if (iRet == WSAENOTSOCK || iRet == WSANOTINITIALISED)
00406          return FALSE;
00407    }
00408    //
00409    // If we get here, then fd is actually a socket.
00410    //
00411    return TRUE;
00412 }
00413 
00414 int close(int fd)
00415 {
00416    int ret;
00417    if (is_socket(fd)) {
00418       ret = closesocket(fd);
00419       myerrcode(GetLastError());
00420    }
00421    else {
00422       ret = _close(fd);
00423       myerrcode(errno);
00424    }
00425    return ret;
00426 }
00427 
00428 int writev(int fd, const struct iovec iov[], int nvecs)
00429 {
00430    DWORD ret;
00431    char *buffer, *bp;
00432    size_t i, bytes = 0;
00433    if (is_socket(fd)) {
00434       if (WSASend(fd, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL) == 0) {
00435          return ret;
00436       }
00437    }
00438    else {
00439 
00440       /* Find the total number of bytes to write */
00441       for (i = 0; i < (size_t)nvecs; i++)
00442          bytes += iov[i].iov_len;
00443 
00444       if (bytes == 0)   /* not an error */
00445          return (0);
00446 
00447       /* Allocate a temporary buffer to hold the data */
00448       buffer = bp = (char*) alloca (bytes);
00449       if (!buffer) {
00450          errno = ENOMEM;
00451          return (-1);
00452       }
00453 
00454       /* Copy the data into buffer. */
00455       for (i = 0; i < (size_t)nvecs; ++i) {
00456          memcpy (bp, iov[i].iov_base, iov[i].iov_len);
00457          bp += iov[i].iov_len;
00458       }
00459       return (int)_write(fd, buffer, bytes);
00460    }
00461    return -1;
00462 }
00463 
00464 char *index(const char *str, int c)
00465 {
00466    return strchr((char *)str, c);
00467 }
00468 
00469 char *getlogin()
00470 {
00471    static char user_name[256];
00472    DWORD  length = sizeof(user_name);
00473    if (GetUserName(user_name, &length))
00474       return user_name;
00475    return NULL;
00476 }
00477 
00478 char *cuserid(char * s)
00479 {
00480    char * name = getlogin();
00481    if (s)
00482       return strcpy(s, name ? name : "");
00483    return name;
00484 }
00485 
00486 int posix_memalign(void **memptr, size_t alignment, size_t size)
00487 {
00488    void *mem = malloc(size);
00489    if (mem != NULL) {
00490       *memptr = mem;
00491       return 0;
00492    }
00493    return ENOMEM;
00494 }
00495 

Generated on Tue Jul 5 14:47:03 2011 for ROOT_528-00b_version by  doxygen 1.5.1