su_errno.c 4.99 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
/*
 * This file is part of the Sofia-SIP package
 *
 * Copyright (C) 2005 Nokia Corporation.
 *
 * Contact: Pekka Pessi <pekka.pessi@nokia.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

/**@CFILE su_errno.c errno compatibility
 * 
 * @author Pekka Pessi <Pekka.Pessi@nokia.com>
 * 
 * @date Original: Thu Mar 18 19:40:51 1999 pessi
 * @date Split to su_errno.c: Thu Dec 22 18:37:02 EET 2005 pessi
 */

#include "config.h" 

35 36
#include <sofia-sip/su_errno.h>
#include <sofia-sip/su.h>
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59

#include <string.h>

#if SU_HAVE_WINSOCK

#include <stdio.h>

/** Get the latest socket error. */
int su_errno(void)
{
  return WSAGetLastError();
}

/** Set the socket error. */
int su_seterrno(int errcode)
{
  WSASetLastError(errcode);

  return -1;
}

const char *su_strerror(int errcode)
{
60 61 62
  struct errmsg { int no; const char *msg; };
  static struct errmsg *msgp;
  static struct errmsg msgs[] = {
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
    { 0, "Success" },
    { WSAEINTR, "Interrupted system call" },
    { WSAEBADF, "Bad file descriptor" },
    { WSAEACCES, "Permission denied" },
    { WSAEFAULT, "Bad address" },
    { WSAEINVAL, "Invalid argument" },
    { WSAEMFILE, "Too many open files" },
    { WSAEWOULDBLOCK, "Another winsock call while a "
      "blocking function was in progress" },
    { WSAEINPROGRESS, "Operation now in progress" },
    { WSAEALREADY, "Operation already in progress" },
    { WSAENOTSOCK, "Socket operation on non-socket" },
    { WSAEDESTADDRREQ, "Destination address required" },
    { WSAEMSGSIZE, "Message too long" },
    { WSAEPROTOTYPE, "Protocol wrong type for socket" },
    { WSAENOPROTOOPT, "Protocol not available" },
    { WSAEPROTONOSUPPORT, "Protocol not supported" },
    { WSAESOCKTNOSUPPORT, "Socket type not supported" },
    { WSAEOPNOTSUPP, "Operation not supported" },
    { WSAEPFNOSUPPORT, "Protocol family not supported" },
    { WSAEAFNOSUPPORT, "Address family not supported" },
    { WSAEADDRINUSE, "Address already in use" },
    { WSAEADDRNOTAVAIL, "Can't assign requested address" },
    { WSAENETDOWN, "Network is down" },
    { WSAENETUNREACH, "Network is unreachable" },
    { WSAENETRESET, "Network dropped connection on reset" },
    { WSAECONNABORTED, "Software caused connection abort" },
    { WSAECONNRESET, "Connection reset by peer" },
    { WSAENOBUFS, "No buffer space available" },
    { WSAEISCONN, "Socket is already connected" },
    { WSAENOTCONN, "Socket is not connected" },
    { WSAESHUTDOWN, "Can't send after socket shutdown" },
    { WSAETOOMANYREFS, "Too many references: "
      "can't splice" },
    { WSAETIMEDOUT, "Operation timed out" },
    { WSAECONNREFUSED, "Connection refused" },
    { WSAELOOP, "Too many levels of symbolic links" },
    { WSAENAMETOOLONG, "File name too long" },
    { WSAEHOSTDOWN, "Host is down" },
    { WSAEHOSTUNREACH, "No route to host" },
    { WSAENOTEMPTY, "Directory not empty" },
    { WSAEPROCLIM, "Too many processes" },
    { WSAEUSERS, "Too many users" },
    { WSAEDQUOT, "Disc quota exceeded" },
    { WSAESTALE, "Stale NFS file handle" },
    { WSAEREMOTE, "Too many levels of remote in path" },
    { WSASYSNOTREADY, "Network subsystem is unvailable" },
    { WSAVERNOTSUPPORTED, "WinSock version is not "
      "supported" },
    { WSANOTINITIALISED, "Successful WSAStartup() not yet "
      "performed" },
    { WSAEDISCON, "Graceful shutdown in progress" },
    /* Resolver errors */
    { WSAHOST_NOT_FOUND, "No such host is known" },
    { WSATRY_AGAIN, "Host not found, or server failed" },
    { WSANO_RECOVERY, "Unexpected server error "
      "encountered" },
    { WSANO_DATA, "Valid name without requested data" },
    { WSANO_ADDRESS, "No address, look for MX record" },
    { 0, NULL }
  };
124 125 126 127 128
  static struct errmsg sofia_msgs[] = {
    { EBADMSG, "Bad message" },
    { EPROTO, "Protocol error" },
    { 0, NULL }
  };
129 130
  static char buf[64];

131 132 133 134 135 136 137 138 139 140 141 142 143 144
  if (errcode < WSABASEERR) 
    return strerror(errcode);

  if (errcode < 20000)
    for (msgp = msgs; msgp->msg; msgp++) {
      if (errcode == msgp->no) {
	return msgp->msg;
      }
    }
  else
    for (msgp = sofia_msgs; msgp->msg; msgp++) {
      if (errcode == msgp->no) {
	return msgp->msg;
      }
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
    }

  /* This can not overflow, but in other hand, it is not thread-safe */
  sprintf(buf, "winsock error %d", errcode);

  return buf;
}

#else

const char *su_strerror(int errcode)
{
  return strerror(errcode);
}

#endif /* SU_HAVE_WINSOCK */