Example #1
0
File: close.c Project: lihnux/plibc
int _win_close(int fd)
{
  THandleType theType;
  int ret;

  theType = __win_GetHandleType((DWORD) fd);
  switch(theType)
  {
    case SOCKET_HANDLE:
      ret = closesocket(fd);
      if (ret == SOCKET_ERROR)
        SetErrnoFromWinsockError(WSAGetLastError());
      break;
    case PIPE_HANDLE:
      if (!CloseHandle((HANDLE) fd))
      {
        SetErrnoFromWinError(GetLastError());
        ret = -1;
      }
      else
        ret = 0;
      break;
    case FD_HANDLE:
      ret = close(fd);
      break;
    case UNKNOWN_HANDLE:
      ret = -1;
      errno = EBADF;
      SetLastError(ERROR_INVALID_HANDLE);
      __plibc_panic(5, "Cannot close() unknown handle\n");
      break;
  }

  if (theType != UNKNOWN_HANDLE)
  {
    __win_DiscardHandleBlockingMode(fd);
    __win_DiscardHandleType(fd);
  }

  return ret;
}
Example #2
0
/**
 * @brief Convert a POSIX-sytle path to a Windows-style path
 * @param pszUnix POSIX path
 * @param pszWindows Windows path
 * @param derefLinks 1 to dereference links
 * @return Error code from winerror.h, ERROR_SUCCESS on success
*/
int plibc_conv_to_win_path_ex(const char *pszUnix, char *pszWindows, int derefLinks)
{
  char *pSrc, *pDest;
  long iSpaceUsed;
  int iUnixLen;

  if (!pszUnix || !pszWindows)
    return ERROR_INVALID_PARAMETER;

  iUnixLen = strlen(pszUnix);

  /* Check if we already have a windows path */
  if((strchr(pszUnix, '\\') != NULL) || (strchr(pszUnix, ':') != NULL))
  {
    if(iUnixLen > MAX_PATH)
      return ERROR_BUFFER_OVERFLOW;
    strcpy(pszWindows, pszUnix);
  }

  /* Temp. dir? */
  if(strncmp(pszUnix, "/tmp", 4) == 0)
  {
    iSpaceUsed = GetTempPath(_MAX_PATH, pszWindows);
    if (iSpaceUsed > _MAX_PATH)
      return ERROR_BUFFER_OVERFLOW;
    pDest = pszWindows + iSpaceUsed;
    pSrc = (char *) pszUnix + 4;
  }
  /* Bit bucket? */
  else if (strncmp(pszUnix, "/dev/null", 9) == 0)
  {
    strcpy(pszWindows, "nul");
    iSpaceUsed = 3;
    pDest = pszWindows + lHomeDirLen;
    pSrc = (char *) pszUnix + 9;
  }
  /* Data directories */
  else if (strncmp(pszUnix, "/etc", 4) == 0 ||
    strncmp(pszUnix, "/com", 4) == 0 ||
    strncmp(pszUnix, "/var", 4) == 0)
  {
    strcpy(pszWindows, szDataDir);
    iSpaceUsed = lDataDirLen;
    pDest = pszWindows + lDataDirLen;
    pSrc = (char *) pszUnix + 1;
  }
  /* Is the unix path a full path? */
  else if(pszUnix[0] == '/')
  {
    strcpy(pszWindows, szRootDir);
    iSpaceUsed = lRootDirLen;
    pDest = pszWindows + lRootDirLen;
    pSrc = (char *) pszUnix + 1;
  }
  /* Home dir? */
  else if (pszUnix[0] == '~')
  {
    strcpy(pszWindows, szHomeDir);
    iSpaceUsed = lHomeDirLen;
    pDest = pszWindows + lHomeDirLen;
    pSrc = (char *) pszUnix + 1;
  }
  /* Home dir (env var)? */
  else if (strncmp(pszUnix, "$HOME", 5) == 0)
  {
    strcpy(pszWindows, szHomeDir);
    iSpaceUsed = lHomeDirLen;
    pDest = pszWindows + lHomeDirLen;
    pSrc = (char *) pszUnix + 5;  	
  }
  else
  {
    pDest = pszWindows;
    iSpaceUsed = 0;
    pSrc = (char *) pszUnix;
  }

  iSpaceUsed += strlen(pSrc);
  if(iSpaceUsed + 1 > _MAX_PATH)
    return ERROR_BUFFER_OVERFLOW;

  /* substitute all slashes */
  while(*pSrc)
  {
    if(*pSrc == '/')
      *pDest = '\\';
    else
      *pDest = *pSrc;

    pDest++;
    pSrc++;
  }
  *pDest = 0;

  if (derefLinks)
    __win_deref(pszWindows);
  else
  {
    /* The filename possibly refers to a symlink, but the .lnk extension may be
       missing.
        1. Check if the requested file seems to be a normal file
        2. Check if the file exists
         2.1. Yes: Finished
         2.2. No: Check if "filename.lnk" exists
          2.2.1 Yes: Append ".lnk" */
    if (strnicmp(pDest - 4, ".lnk", 4) != 0)
    {
      HANDLE h = CreateFile(pszWindows, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
      if (h == INVALID_HANDLE_VALUE)
      {
        /* File doesn't exist, try shortcut */
        char *pLnk;
        int mal;
        
        if (iSpaceUsed + 5 > _MAX_PATH)
        {
          pLnk = malloc(iSpaceUsed + 5);
          strcpy(pLnk, pszWindows);
          mal = 1;
        }
        else
        {
          pLnk = pszWindows;
          mal = 0;
        }
        strcat(pLnk, ".lnk");
        
        h = CreateFile(pLnk, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
          NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
          
        if (h != INVALID_HANDLE_VALUE)
        {
          /* Shortcut exists */
          CloseHandle(h);
          if (mal)
            /* Need to copy */
            if (iSpaceUsed + 5 <= _MAX_PATH)
              strcpy(pszWindows, pLnk);
            else
            {
              free(pLnk);
              return ERROR_BUFFER_OVERFLOW;
            }
        }
        else
          pLnk[iSpaceUsed] = 0;   
        
        if (mal)
          free(pLnk);
      }
      else
        CloseHandle(h);
    }
  }

#if DEBUG_WINPROC
	{
		char szInfo[1001];

  	_win_snprintf(szInfo, 1000, "Posix path %s resolved to %s\n", pszUnix,
  		pszWindows);
  	szInfo[1000] = 0;
  	__plibc_panic(INT_MAX, szInfo);
	}
#endif

  return ERROR_SUCCESS;
}
Example #3
0
/**
 * @brief Get the errno corresponding to the Winsock error
 * @param lWinError Error code defined in winsock.h
 */
int GetErrnoFromWinsockError(long lWinError)
{
  switch(lWinError)
  {
    case 0:
      return 0;

    case WSAEINTR:
      return EINTR;

    case WSAEWOULDBLOCK:
      return EWOULDBLOCK;

    case WSAEINPROGRESS:
      return EINPROGRESS;

    case WSAEALREADY:
      return EALREADY;

    case WSAENOTSOCK:
      return ENOTSOCK;

    case WSAEDESTADDRREQ:
      return EDESTADDRREQ;

    case WSAEMSGSIZE:
      return EMSGSIZE;

    case WSAEPROTOTYPE:
      return EPROTOTYPE;

    case WSAENOPROTOOPT:
      return ENOPROTOOPT;

    case WSAEPROTONOSUPPORT:
      return EPROTONOSUPPORT;

    case WSAESOCKTNOSUPPORT:
      return ESOCKTNOSUPPORT;

    case WSAEOPNOTSUPP:
      return EOPNOTSUPP;

    case WSAEPFNOSUPPORT:
      return EPFNOSUPPORT;

    case WSAEAFNOSUPPORT:
      return EAFNOSUPPORT;

    case WSAEADDRINUSE:
      return EADDRINUSE;

    case WSAEADDRNOTAVAIL:
      return EADDRNOTAVAIL;

    case WSAENETDOWN:
      return ENETDOWN;

    case WSAENETUNREACH:
      return ENETUNREACH;

    case WSAENETRESET:
      return ENETRESET;

    case WSAECONNABORTED:
      return ECONNABORTED;

    case WSAECONNRESET:
      return ECONNRESET;

    case WSAENOBUFS:
      return ENOBUFS;

    case WSAEISCONN:
      return EISCONN;

    case WSAENOTCONN:
      return ENOTCONN;

    case WSAESHUTDOWN:
      return ESHUTDOWN;

    case WSAETOOMANYREFS:
      return ETOOMANYREFS;

    case WSAETIMEDOUT:
      return ETIMEDOUT;

    case WSAECONNREFUSED:
      return ECONNREFUSED;

    case WSAELOOP:
      return ELOOP;

    case WSAENAMETOOLONG:
      return ENAMETOOLONG;

    case WSAEHOSTDOWN:
      return EHOSTDOWN;

    case WSAEHOSTUNREACH:
      return EHOSTUNREACH;

    case WSAENOTEMPTY:
      return ENOTEMPTY;

    case WSAEPROCLIM:
      return EPROCLIM;

    case WSAEUSERS:
      return EUSERS;

    case WSAEDQUOT:
      return EDQUOT;

    case WSAESTALE:
      return ESTALE;

    case WSAEREMOTE:
      return EREMOTE;

    case WSAEINVAL:
      return EINVAL;

    case WSAEFAULT:
      return EFAULT;

    case WSANO_DATA:
    	return ENODATA;

    default:
    	{
    		char szPanic[1001];

	      _win_snprintf(szPanic, 1000, "Unknown error %i in " \
	      		"SetErrnoFromWinsockError()\n", lWinError);
	      szPanic[1000] = 0;
	     	__plibc_panic(4, szPanic);

	      return ESTALE;
    	}
  }
}
Example #4
0
/**
 * @brief Set errno according to a Windows error
 * @param lWinError Error code defined in winerror.h
 */
void _SetErrnoFromWinError(long lWinError, char *pszCaller, int iLine)
{
  switch(lWinError)
  {
    case ERROR_SUCCESS:
      errno = 0;
      break;

    case ERROR_INVALID_FUNCTION:
      errno = EBADRQC;
      break;

    case ERROR_FILE_NOT_FOUND:
      errno = ENOENT;
      break;

    case ERROR_PATH_NOT_FOUND:
      errno = ENOENT;
      break;

    case ERROR_TOO_MANY_OPEN_FILES:
      errno = EMFILE;
      break;

    case ERROR_ACCESS_DENIED:
      errno = EACCES;
      break;

    case ERROR_INVALID_HANDLE:
      errno = EBADF;
      break;

    case ERROR_NOT_ENOUGH_MEMORY:
      errno = ENOMEM;
      break;

    case ERROR_INVALID_DATA:
      errno = EINVAL;
      break;

    case ERROR_OUTOFMEMORY:
      errno = ENOMEM;
      break;

    case ERROR_INVALID_DRIVE:
      errno = ENODEV;
      break;

    case ERROR_NOT_SAME_DEVICE:
      errno = EXDEV;
      break;

    case ERROR_NO_MORE_FILES:
      errno = ENMFILE;
      break;

    case ERROR_WRITE_PROTECT:
      errno = EROFS;
      break;

    case ERROR_BAD_UNIT:
      errno = ENODEV;
      break;

    case ERROR_SHARING_VIOLATION:
      errno = EACCES;
      break;

    case ERROR_LOCK_VIOLATION:
      errno = EACCES;
      break;

    case ERROR_SHARING_BUFFER_EXCEEDED:
      errno = ENOLCK;
      break;

    case ERROR_HANDLE_EOF:
      errno = ENODATA;
      break;

    case ERROR_HANDLE_DISK_FULL:
      errno = ENOSPC;
      break;

    case ERROR_NOT_SUPPORTED:
      errno = ENOSYS;
      break;

    case ERROR_REM_NOT_LIST:
      errno = ENONET;
      break;

    case ERROR_DUP_NAME:
      errno = ENOTUNIQ;
      break;

    case ERROR_BAD_NETPATH:
      errno = ENOSHARE;
      break;

    case ERROR_BAD_NET_NAME:
      errno = ENOSHARE;
      break;

    case ERROR_FILE_EXISTS:
      errno = EEXIST;
      break;

    case ERROR_CANNOT_MAKE:
      errno = EPERM;
      break;

    case ERROR_INVALID_PARAMETER:
      errno = EINVAL;
      break;

    case ERROR_NO_PROC_SLOTS:
      errno = EAGAIN;
      break;

    case ERROR_BROKEN_PIPE:
      errno = EPIPE;
      break;

    case ERROR_OPEN_FAILED:
      errno = EIO;
      break;

    case ERROR_NO_MORE_SEARCH_HANDLES:
      errno = ENFILE;
      break;

    case ERROR_CALL_NOT_IMPLEMENTED:
      errno = ENOSYS;
      break;

    case ERROR_INVALID_NAME:
      errno = ENOENT;
      break;

    case ERROR_WAIT_NO_CHILDREN:
      errno = ECHILD;
      break;

    case ERROR_CHILD_NOT_COMPLETE:
      errno = EBUSY;
      break;

    case ERROR_DIR_NOT_EMPTY:
      errno = ENOTEMPTY;
      break;

    case ERROR_SIGNAL_REFUSED:
      errno = EIO;
      break;

    case ERROR_BAD_PATHNAME:
      errno = ENOENT;
      break;

    case ERROR_SIGNAL_PENDING:
      errno = EBUSY;
      break;

    case ERROR_MAX_THRDS_REACHED:
      errno = EAGAIN;
      break;

    case ERROR_BUSY:
      errno = EBUSY;
      break;

    case ERROR_ALREADY_EXISTS:
      errno = EEXIST;
      break;

    case ERROR_NO_SIGNAL_SENT:
      errno = EIO;
      break;

    case ERROR_FILENAME_EXCED_RANGE:
      errno = EINVAL;
      break;

    case ERROR_META_EXPANSION_TOO_LONG:
      errno = EINVAL;
      break;

    case ERROR_INVALID_SIGNAL_NUMBER:
      errno = EINVAL;
      break;

    case ERROR_THREAD_1_INACTIVE:
      errno = EINVAL;
      break;

    case ERROR_BAD_PIPE:
      errno = EINVAL;
      break;

    case ERROR_PIPE_BUSY:
      errno = EBUSY;
      break;

    case ERROR_NO_DATA:
      errno = EPIPE;
      break;

    case ERROR_PIPE_NOT_CONNECTED:
      errno = ECOMM;
      break;

    case ERROR_MORE_DATA:
      errno = EAGAIN;
      break;

    case ERROR_DIRECTORY:
      errno = ENOTDIR;
      break;

    case ERROR_PIPE_CONNECTED:
      errno = EBUSY;
      break;

    case ERROR_PIPE_LISTENING:
      errno = ECOMM;
      break;

    case ERROR_NO_TOKEN:
      errno = EINVAL;
      break;

    case ERROR_PROCESS_ABORTED:
      errno = EFAULT;
      break;

    case ERROR_BAD_DEVICE:
      errno = ENODEV;
      break;

    case ERROR_BAD_USERNAME:
      errno = EINVAL;
      break;

    case ERROR_NOT_CONNECTED:
      errno = ENOLINK;
      break;

    case ERROR_OPEN_FILES:
      errno = EAGAIN;
      break;

    case ERROR_ACTIVE_CONNECTIONS:
      errno = EAGAIN;
      break;

    case ERROR_DEVICE_IN_USE:
      errno = EAGAIN;
      break;

    case ERROR_INVALID_AT_INTERRUPT_TIME:
      errno = EINTR;
      break;

    case ERROR_IO_DEVICE:
      errno = EIO;
      break;

    case ERROR_NOT_OWNER:
      errno = EPERM;
      break;

    case ERROR_END_OF_MEDIA:
      errno = ENOSPC;
      break;

    case ERROR_EOM_OVERFLOW:
      errno = ENOSPC;
      break;

    case ERROR_BEGINNING_OF_MEDIA:
      errno = ESPIPE;
      break;

    case ERROR_SETMARK_DETECTED:
      errno = ESPIPE;
      break;

    case ERROR_NO_DATA_DETECTED:
      errno = ENOSPC;
      break;

    case ERROR_POSSIBLE_DEADLOCK:
      errno = EDEADLOCK;
      break;

    case ERROR_CRC:
      errno = EIO;
      break;

    case ERROR_NEGATIVE_SEEK:
      errno = EINVAL;
      break;

    case ERROR_NOT_READY:
      errno = ENOMEDIUM;
      break;

    case ERROR_DISK_FULL:
      errno = ENOSPC;
      break;

    case ERROR_NOACCESS:
      errno = EFAULT;
      break;

    case ERROR_FILE_INVALID:
      errno = ENXIO;
      break;

    case ERROR_INVALID_ADDRESS:
      errno = EFAULT;
      break;

    case ERROR_BUFFER_OVERFLOW:
      errno = ENOMEM;
      break;

    case ERROR_SERVICE_DOES_NOT_EXIST:
      errno = ESRCH;
      break;

    case ERROR_SERVICE_EXISTS:
      errno = EEXIST;
      break;

    default:
    	{
    		char szPanic[1001];

	      errno = ESTALE;
	      _win_snprintf(szPanic, 1000, "Unknown error %i in PlibC "\
	      		"SetErrnoFromWinError(). Source: %s:%i\n", lWinError, pszCaller,
	      		iLine);
	      szPanic[1000] = 0;
	      __plibc_panic(3, szPanic);
	      break;
    	}
  }
}