Esempio n. 1
0
char *realpath(const char *file_name, char *resolved_name, size_t resolv_buffer_length)
{
  long lRet;
  wchar_t szFile[_MAX_PATH + 1];
  wchar_t szRet[_MAX_PATH + 1];
  wchar_t *wresult;
  char *result = NULL;

  if (_plibc_utf8_mode == 1)
  {
    lRet = plibc_conv_to_win_pathwconv(file_name, szFile, _MAX_PATH );
    if (lRet != ERROR_SUCCESS)
    {
      SetErrnoFromWinError(lRet);
      return NULL;
    }
    wresult = _wfullpath(szRet, szFile, MAX_PATH);
    SetErrnoFromWinError(GetLastError());
    if (wresult)
      wchartostr (szRet, &result, CP_UTF8);
    return result;
  }
  else
  {
    lRet = plibc_conv_to_win_path(file_name, (char *) szFile, _MAX_PATH );
    if (lRet != ERROR_SUCCESS)
    {
      SetErrnoFromWinError(lRet);
      return NULL;
    }
    result = _fullpath(resolved_name, (char *) szFile, resolv_buffer_length);
    SetErrnoFromWinError(GetLastError());
    return result;
  }
}
Esempio n. 2
0
File: mmap.c Progetto: lihnux/plibc
/**
 * @brief Unmap files from memory
 * @author Cygwin team
 * @author Nils Durner
 */
int _win_munmap(void *start, size_t length)
{
  unsigned uiIndex;

  if (UnmapViewOfFile(start))
  {
    BOOL success = TRUE;
    errno = 0;

    /* Release mapping handle */
    WaitForSingleObject(hMappingsLock, INFINITE);

    for(uiIndex = 0; uiIndex <= uiMappingsCount; uiIndex++)
    {
      if (pMappings[uiIndex].pStart == start)
      {
        DWORD error;

        error = NO_ERROR;

        if (!CloseHandle(pMappings[uiIndex].hMapping))
        {
          success = FALSE;
          error = GetLastError();
        }

        if (!CloseHandle(pMappings[uiIndex].hFile))
        {
          success = FALSE;
          error = GetLastError();
        }

        if (error != NO_ERROR)
          SetErrnoFromWinError(error);

        pMappings[uiIndex].pStart = NULL;
        pMappings[uiIndex].hMapping = NULL;
        pMappings[uiIndex].hFile = NULL;

        break;
      }
    }

    ReleaseMutex(hMappingsLock);

    return success ? 0 : MAP_FAILED;
  }
  else
  {
    SetErrnoFromWinError(GetLastError());
    return MAP_FAILED;
  }
}
Esempio n. 3
0
File: pipe.c Progetto: lihnux/plibc
/**
 * Make a FIFO special file
 * @todo use mode
 */
int _win_mkfifo(const char *path, mode_t mode)
{
  HANDLE ret;
  SECURITY_ATTRIBUTES sec;

  ZeroMemory(&sec, sizeof(sec));
  sec.nLength = sizeof(sec);
  sec.bInheritHandle = TRUE;

  ret = CreateNamedPipe(path, PIPE_ACCESS_DUPLEX |
      FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE, 1, 0, 0, 0, &sec);
  if (ret == INVALID_HANDLE_VALUE)
  {
    SetErrnoFromWinError(GetLastError());

    return -1;
  }
  else
  {
    errno = 0;
    __win_SetHandleType((DWORD) ret, PIPE_HANDLE);

    return 0;
  }
}
Esempio n. 4
0
File: stat.c Progetto: lihnux/plibc
/**
 * @brief Get status information on a file
 */
int __win_stat(const char *path, struct stat *buffer, int iDeref)
{
  char szFile[_MAX_PATH + 1];
  long lRet;

  if ((lRet = plibc_conv_to_win_path(path, szFile)) != ERROR_SUCCESS)
  {
    SetErrnoFromWinError(lRet);
    return -1;
  }

  /* Remove trailing slash */
  lRet = strlen(szFile) - 1;
  if (szFile[lRet] == '\\')
  {
    szFile[lRet] = 0;
  }

  /* Dereference symlinks */
  if (iDeref)
  {
    if (__win_deref(szFile) == -1 && errno != EINVAL)
      return -1;
  }

  /* stat sets errno */
  return stat(szFile, buffer);
}
Esempio n. 5
0
DWORD WINAPI __win_Read(TReadWriteInfo *pInfo)
{
    int iRet;

    if (__win_GetHandleType(pInfo->fildes) == FD_HANDLE)
    {
        _setmode(pInfo->fildes, _O_BINARY);
        errno = 0;
        iRet = _read(pInfo->fildes, pInfo->buf, pInfo->nbyte);
        free(pInfo);

        return iRet;
    }
    else
    {
        DWORD dwRead;

        errno = 0;
        if (!ReadFile((HANDLE) pInfo->fildes, pInfo->buf, pInfo->nbyte, &dwRead,
                      NULL))
        {
            free(pInfo);
            SetErrnoFromWinError(GetLastError());
            return -1;
        }
        else
        {
            free(pInfo);
            return dwRead;
        }
    }
}
Esempio n. 6
0
File: mmap.c Progetto: lihnux/plibc
int _win_msync(void *start, size_t length, int flags)
{
  unsigned uiIndex;
  /* Can't have sync and async at the same time */
  if ((flags & MS_SYNC) && (flags & MS_ASYNC))
  {
    errno = EINVAL;
    return -1;
  }
  /* Not sure what to make of it. It's either the default, or unsupported */
  if (flags & MS_INVALIDATE)
  {
    errno = ENOSYS;
    return -1;
  }

  if (FlushViewOfFile (start, length))
  {
    BOOL success = TRUE;
    errno = 0;

    if (flags & MS_SYNC)
    {
      /* Flush to the file */
      WaitForSingleObject(hMappingsLock, INFINITE);

      for(uiIndex = 0; uiIndex <= uiMappingsCount; uiIndex++)
      {
        if (pMappings[uiIndex].pStart == start)
        {
          success = FlushFileBuffers (pMappings[uiIndex].hFile);
          SetErrnoFromWinError(GetLastError());
          break;
        }
      }

      ReleaseMutex(hMappingsLock);
    }
    return success ? 0 : -1;
  }
  else
  {
    SetErrnoFromWinError(GetLastError());
    return -1;
  }
}
Esempio n. 7
0
/**
 * @brief Writes data to a stream
 */
size_t _win_fwrite(const void *buffer, size_t size, size_t count, FILE *stream)
{
  DWORD dwWritten;

  WriteFile((HANDLE) _get_osfhandle(_fileno(stream)), buffer, size, &dwWritten,
            NULL);
  SetErrnoFromWinError(GetLastError());

  return dwWritten;
}
Esempio n. 8
0
/**
 * @brief Synchronize changes to a file
 */
int fsync(int fildes)
{
  if (!FlushFileBuffers((HANDLE) _get_osfhandle(fildes)))
  {
    SetErrnoFromWinError(GetLastError());
    return -1;
  }
  else
  {
    errno = 0;
    return 0;
  }
}
Esempio n. 9
0
File: stat.c Progetto: lihnux/plibc
/**
 * @brief Get status information on a file
 */
int __win_stat64(const char *path, struct stat64 *buffer, int iDeref)
{
  char szFile[_MAX_PATH + 1];
  long lRet;

  if ((lRet = plibc_conv_to_win_path(path, szFile)) != ERROR_SUCCESS)
  {
    SetErrnoFromWinError(lRet);
    return -1;
  }

  /* Remove trailing slash */
  lRet = strlen(szFile) - 1;
  if (szFile[lRet] == '\\')
  {
    szFile[lRet] = 0;
  }

  /* Dereference symlinks */
  if (iDeref)
  {
    if (__win_deref(szFile) == -1 && errno != EINVAL)
      return -1;
  }

  if (!_plibc_stat64)
  {
    /* not supported under Windows 9x */
    struct stat theStat;
    int iRet;
    
    iRet = __win_stat(path, &theStat, iDeref);
    
    buffer->st_dev = theStat.st_dev;
    buffer->st_ino = theStat.st_ino;
    buffer->st_mode = theStat.st_mode;
    buffer->st_nlink = theStat.st_nlink;
    buffer->st_uid = theStat.st_uid;
    buffer->st_gid = theStat.st_gid;
    buffer->st_rdev = theStat.st_rdev;
    buffer->st_size = (theStat.st_size > LONG_MAX) ? LONG_MAX : theStat.st_size;
    buffer->st_atime = (theStat.st_atime > LONG_MAX) ? LONG_MAX : theStat.st_atime;
    buffer->st_mtime = (theStat.st_mtime > LONG_MAX) ? LONG_MAX : theStat.st_mtime;
    buffer->st_ctime = (theStat.st_ctime > LONG_MAX) ? LONG_MAX : theStat.st_ctime;
    
    return iRet;
  }
  else
    /* stat sets errno */
    return _plibc_stat64(szFile, buffer);
}
Esempio n. 10
0
/**
 * @brief Delete a file
 *        If filename is a link, the link itself it removed.
 */
int _win_unlink(const char *filename)
{
  char szFile[_MAX_PATH + 1];
  long lRet;

  if ((lRet = plibc_conv_to_win_path_ex(filename, szFile, 0)) != ERROR_SUCCESS)
  {
    SetErrnoFromWinError(lRet);
    return -1;
  }

  /* unlink sets errno */
  return unlink(szFile);
}
Esempio n. 11
0
/**
 * @brief Determine file-access permission.
 */
int _win_access( const char *path, int mode )
{
  char szFile[_MAX_PATH + 1];
  long lRet;

  mode &= 6;

  if ((lRet = plibc_conv_to_win_path(path, szFile)) != ERROR_SUCCESS)
  {
    SetErrnoFromWinError(lRet);
    return -1;
  }

  /* access sets errno */
  return access(szFile, mode);
}
Esempio n. 12
0
File: intl.c Progetto: lihnux/plibc
char *_win_bindtextdomain(const char *domainname, const char *dirname)
{
#ifdef HAVE_LIBINTL
  char szDirname[_MAX_PATH + 1];
  int i;
  
  if ((i = plibc_conv_to_win_path(dirname, szDirname)) != ERROR_SUCCESS)
  {
    SetErrnoFromWinError(i);

    return NULL;
  }

  return bindtextdomain(domainname, szDirname);
#else
  errno = ENOSYS;
  return NULL;
#endif
}
Esempio n. 13
0
File: pipe.c Progetto: lihnux/plibc
/**
 * Create a pipe for reading and writing
 */
int _win_pipe(int *phandles)
{
  /* To get non-blocking pipes we could use CreateNamedPipe here. But it isn't
     implemented under Win9x. */
  if (!CreatePipe((HANDLE *) &phandles[0],(HANDLE *) &phandles[1], NULL, 0))
  {
    SetErrnoFromWinError(GetLastError());

    return -1;
  }
  else
  {
    errno = 0;
    __win_SetHandleType((DWORD) phandles[0], PIPE_HANDLE);
    __win_SetHandleType((DWORD) phandles[1], PIPE_HANDLE);
    
    return 0;
  }
}
Esempio n. 14
0
File: close.c Progetto: 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;
}
Esempio n. 15
0
/**
 * @brief Delete a file
 *        If filename is a link, the link itself it removed.
 */
int _win_unlink(const char *filename)
{
  wchar_t szFile[_MAX_PATH + 1];
  long lRet;

  if (plibc_utf8_mode() == 1)
    lRet = plibc_conv_to_win_pathwconv_ex(filename, szFile, 0);
  else
    lRet = plibc_conv_to_win_path_ex(filename, (char *) szFile, 0);
  if (lRet != ERROR_SUCCESS)
  {
    SetErrnoFromWinError(lRet);
    return -1;
  }

  /* unlink sets errno */
  if (plibc_utf8_mode() == 1)
    return _wunlink(szFile);
  else
    return unlink((char *) szFile);
}
Esempio n. 16
0
/**
 * @brief Set errno according to a HRESULT (COM error code)
 */
void SetErrnoFromHRESULT(HRESULT hRes)
{
  switch(hRes)
  {
    case NOERROR:
      errno = 0;
      break;
    case E_UNEXPECTED:
    case E_FAIL:
    case S_FALSE:
      errno = ESTALE;
    case E_NOTIMPL:
      errno = ENOSYS;
      break;
    case E_OUTOFMEMORY:
      errno = ENOMEM;
      break;
    case E_INVALIDARG:
    case E_NOINTERFACE:
      errno = EINVAL;
      break;
    case E_POINTER:
    case E_ABORT:
      errno = EFAULT;
      break;
    case E_HANDLE:
      errno = EBADF;
      break;
    case E_ACCESSDENIED:
      errno = EACCES;
      break;
    case E_PENDING:
      errno = EBUSY;
      break;
    default:
      SetErrnoFromWinError(HRESULT_CODE(hRes));
  }
}
Esempio n. 17
0
/**
 * Change the file-permission settings.
 */
int _win_chmod(const char *filename, int pmode)
{
  wchar_t szFile[_MAX_PATH + 1];
  long lRet;

  pmode &= (_S_IREAD | _S_IWRITE);

  if (_plibc_utf8_mode == 1)
    lRet = plibc_conv_to_win_pathwconv(filename, szFile, _MAX_PATH);
  else
    lRet = plibc_conv_to_win_path(filename, (char *) szFile, _MAX_PATH);
  if (lRet != ERROR_SUCCESS)
  {
    SetErrnoFromWinError(lRet);
    return -1;
  }

  /* chmod sets errno */
  if (_plibc_utf8_mode == 1)
    return _wchmod(szFile, pmode);
  else
    return chmod((char *) szFile, pmode);
}
Esempio n. 18
0
char *_win_bindtextdomain(const char *domainname, const char *dirname)
{
#ifdef HAVE_LIBINTL
  char szDirname[_MAX_PATH + 1];
  int i;
  
  if ((i = plibc_conv_to_win_path(dirname, szDirname, _MAX_PATH)) != ERROR_SUCCESS)
  {
    SetErrnoFromWinError(i);

    return NULL;
  }
  /* There is nothing we could do: libintl will internally call CRT with
   * szDirname, so we can't convert it to UTF-8, and can't convince
   * libintl to use wide-character functions either.
   * So only call BINDTEXTDOMAIN() with ASCII/CP*-encoded dirnames.
   */
  return bindtextdomain(domainname, szDirname);
#else
  errno = ENOSYS;
  return NULL;
#endif
}
Esempio n. 19
0
File: mmap.c Progetto: lihnux/plibc
/**
 * @brief map files into memory
 * @author Cygwin team
 * @author Nils Durner
 */
void *_win_mmap(void *start, size_t len, int access, int flags, int fd,
                unsigned long long off) {
  DWORD protect, high, low, access_param;
  HANDLE h, hFile;
  SECURITY_ATTRIBUTES sec_none;
  void *base;
  BOOL bFound = FALSE;
  unsigned int uiIndex;

  errno = 0;

  switch(access)
  {
    case PROT_WRITE:
      protect = PAGE_READWRITE;
      access_param = FILE_MAP_WRITE;
      break;
    case PROT_READ:
      protect = PAGE_READONLY;
      access_param = FILE_MAP_READ;
      break;
    default:
      protect = PAGE_WRITECOPY;
      access_param = FILE_MAP_COPY;
      break;
  }

  sec_none.nLength = sizeof(SECURITY_ATTRIBUTES);
  sec_none.bInheritHandle = TRUE;
  sec_none.lpSecurityDescriptor = NULL;

  hFile = (HANDLE) _get_osfhandle(fd);

  h = CreateFileMapping(hFile, &sec_none, protect, 0, 0, NULL);

  if (! h)
  {
    SetErrnoFromWinError(GetLastError());
    return MAP_FAILED;
  }

  high = off >> 32;
  low = off & ULONG_MAX;
  base = NULL;

  /* If a non-zero start is given, try mapping using the given address first.
     If it fails and flags is not MAP_FIXED, try again with NULL address. */
  if (start)
    base = MapViewOfFileEx(h, access_param, high, low, len, start);
  if (!base && !(flags & MAP_FIXED))
    base = MapViewOfFileEx(h, access_param, high, low, len, NULL);

  if (!base || ((flags & MAP_FIXED) && base != start))
  {
    if (!base)
      SetErrnoFromWinError(GetLastError());
    else
      errno = EINVAL;

    CloseHandle(h);
    return MAP_FAILED;
  }

  /* Save mapping handle */
  WaitForSingleObject(hMappingsLock, INFINITE);

  for(uiIndex = 0; uiIndex <= uiMappingsCount; uiIndex++)
  {
    if (pMappings[uiIndex].pStart == base)
    {
      bFound = 1;
      break;
    }
  }

  if (! bFound)
  {
    int inserted = 0;
    HANDLE hOwnFile;

    if (!DuplicateHandle (GetCurrentProcess (), hFile, GetCurrentProcess (),
        &hOwnFile, 0, FALSE, DUPLICATE_SAME_ACCESS))
    {
      ReleaseMutex(hMappingsLock);
      SetErrnoFromWinError(GetLastError());
      CloseHandle(h);
      return MAP_FAILED;
    }
    
    uiIndex = 0;

    while(!inserted)
    {
      if (pMappings[uiIndex].pStart == NULL)
      {
        pMappings[uiIndex].pStart = base;
        pMappings[uiIndex].hMapping = h;
        pMappings[uiIndex].hFile = hOwnFile;
        inserted = 1;
      }
      if (uiIndex == uiMappingsCount)
      {
        uiMappingsCount++;
        pMappings = (TMapping *) realloc(pMappings, (uiMappingsCount + 1) * sizeof(TMapping));
        pMappings[uiMappingsCount].pStart = NULL;
      }
      uiIndex++;
    }
  }
  ReleaseMutex(hMappingsLock);

  return base;
}
Esempio n. 20
0
/**
 * Complete filename (a la shell) from abbrevition.
 * @param fil the name of the file, may contain ~/ or
 *        be relative to the current directory
 * @returns the full file name,
 *          NULL is returned on error
 */
static char * expandFileName(const char * fil) {
  char buffer[512];
  char * fn;
#ifndef MINGW
  char * fm;
  const char *fil_ptr;
#else
  long lRet;
#endif

  if (fil == NULL)
    return NULL;

#ifndef MINGW
  if (fil[0] == DIR_SEPARATOR) {
    /* absolute path, just copy */
    return STRDUP(fil);
  }
  if (fil[0] == '~') {
    fm = getenv("HOME");
    if (fm == NULL) {
      /* keep it symbolic to show error to user! */
      fm = "$HOME";
    }

    /* do not copy '~' */
    fil_ptr = fil + 1;

	/* skip over dir seperator to be consistent */
    if (fil_ptr[0] == DIR_SEPARATOR)
      fil_ptr++;
  } else {
    fil_ptr = fil;
    if (getcwd(buffer, 512) != NULL)
      fm = buffer;
    else
      fm = "$PWD";
  }
  fn = MALLOC(strlen(fm) + 1 + strlen(fil_ptr) + 1);

  sprintf(fn, "%s/%s", fm, fil_ptr);
#else
  fn = MALLOC(MAX_PATH + 1);

  if ((lRet = conv_to_win_path(fil, buffer)) != ERROR_SUCCESS)
  {
  	SetErrnoFromWinError(lRet);

    return NULL;
  }
  /* is the path relative? */
  if ((strncmp(buffer + 1, ":\\", 2) != 0) &&
      (strncmp(buffer, "\\\\", 2) != 0))
  {
    char szCurDir[MAX_PATH + 1];
    lRet = GetCurrentDirectory(MAX_PATH + 1, szCurDir);
    if (lRet + strlen(fn) + 1 > (_MAX_PATH + 1))
    {
      SetErrnoFromWinError(ERROR_BUFFER_OVERFLOW);

      return NULL;
    }
    sprintf(fn, "%s\\%s", szCurDir, buffer);
  }
  else
  {
    strcpy(fn, buffer);
  }
#endif
  return fn;
}
Esempio n. 21
0
/**
 * Win32 select() will only work with sockets, so we roll our own
 * implementation here.
 * - If you supply only sockets, this simply passes through to winsock select().
 * - If you supply file handles, there is no way to distinguish between
 *   ready for read/write or OOB, so any set in which the handle is found will
 *   be marked as ready.
 * - If you supply a mixture of handles and sockets, the system will interleave
 *   calls between select() and WaitForMultipleObjects(). The time slicing may
 *   cause this function call to take up to 100 ms longer than you specified.
 * - Pipes are not checked for writability or errors (errno = ENOSYS)
 */
int _win_select(int max_fd, fd_set * rfds, fd_set * wfds, fd_set * efds,
                const struct timeval *tv)
{
  DWORD ms_total, limit;
  HANDLE handles[MAXIMUM_WAIT_OBJECTS], hPipes[MAXIMUM_WAIT_OBJECTS];
  int handle_slot_to_fd[MAXIMUM_WAIT_OBJECTS];
  int n_handles, i, iPipes;
  fd_set sock_read, sock_write, sock_except;
  fd_set aread, awrite, aexcept;
  int sock_max_fd;
  struct timeval tvslice;
  int retcode;

#define SAFE_FD_ISSET(fd, set)	(set != NULL && FD_ISSET(fd, set))

  n_handles = 0;
  sock_max_fd = -1;
  iPipes = 0;

  /* calculate how long we need to wait in milliseconds */
  if(tv == NULL)
    ms_total = INFINITE;
  else
  {
    ms_total = tv->tv_sec * 1000;
    ms_total += tv->tv_usec / 1000;
  }

  /* select() may be used as a portable way to sleep */
  if (!(rfds || wfds || efds))
  {
    Sleep(ms_total);

    return 0;
  }

  FD_ZERO(&sock_read);
  FD_ZERO(&sock_write);
  FD_ZERO(&sock_except);

  /* build an array of handles for non-sockets */
  for(i = 0; i < max_fd; i++)
  {
    if(SAFE_FD_ISSET(i, rfds) || SAFE_FD_ISSET(i, wfds) ||
       SAFE_FD_ISSET(i, efds))
    {
      unsigned long ulVal;

      if (__win_GetHandleType((DWORD) i) == SOCKET_HANDLE) 
      {
        /* socket */
        if(SAFE_FD_ISSET(i, rfds))
          FD_SET(i, &sock_read);

        if(SAFE_FD_ISSET(i, wfds))
          FD_SET(i, &sock_write);

        if(SAFE_FD_ISSET(i, efds))
          FD_SET(i, &sock_except);

        if(i > sock_max_fd)
          sock_max_fd = i;
      }
      else
      {
        if (__win_GetHandleType((DWORD) i) == PIPE_HANDLE)
          hPipes[iPipes++] = (HANDLE) i;  /* Pipe */
        else
        {
          handles[n_handles] = (HANDLE) _get_osfhandle(i);
          if ((DWORD) handles[n_handles] == 0xffffffff)
            handles[n_handles] = (HANDLE) i;
          handle_slot_to_fd[n_handles] = i;
          n_handles++;
        }
      }
    }
  }

  /* multiplex between winsock select() and waiting on the handles */

  FD_ZERO(&aread);
  FD_ZERO(&awrite);
  FD_ZERO(&aexcept);

  limit = GetTickCount() + ms_total;
  do
  {
    retcode = 0;

    if(sock_max_fd >= 0)
    {
      /* overwrite the zero'd sets here; the select call
       * will clear those that are not active */
      aread = sock_read;
      awrite = sock_write;
      aexcept = sock_except;

      tvslice.tv_sec = 0;
      tvslice.tv_usec = 100000;

      if ((retcode = select(sock_max_fd + 1, &aread, &awrite, &aexcept,
                            &tvslice)) == SOCKET_ERROR)
      {
        SetErrnoFromWinsockError(WSAGetLastError());
        if (errno == ENOTSOCK)
          errno = EBADF;

        return retcode;
      }
    }

    if(n_handles > 0)
    {
      /* check handles */
      DWORD wret;

      wret =
        MsgWaitForMultipleObjects(n_handles, handles, FALSE,
                                  retcode > 0 ? 0 : 100, QS_ALLEVENTS);

      if(wret == WAIT_TIMEOUT)
      {
        /* set retcode to 0; this is the default.
         * select() may have set it to something else,
         * in which case we leave it alone, so this branch
         * does nothing */
        ;
      }
      else if(wret == WAIT_FAILED)
      {
        SetErrnoFromWinError(GetLastError());

        return -1;
      }
      else
      {
        for(i = 0; i < n_handles; i++)
        {
          if(WAIT_OBJECT_0 == WaitForSingleObject(handles[i], 0))
          {
            if(SAFE_FD_ISSET(handle_slot_to_fd[i], rfds))
            {
              FD_SET(handle_slot_to_fd[i], &aread);
            }

            if(SAFE_FD_ISSET(handle_slot_to_fd[i], wfds))
              FD_SET(handle_slot_to_fd[i], &awrite);

            if(SAFE_FD_ISSET(handle_slot_to_fd[i], efds))
              FD_SET(handle_slot_to_fd[i], &aexcept);

            retcode++;
          }
        }
      }
    }

    /* Poll Pipes */
    for(i = 0; i < iPipes; i++)
    {
      DWORD dwBytes;
      if(SAFE_FD_ISSET(hPipes[i], rfds))
      {
	    if (! PeekNamedPipe(hPipes[i], NULL, 0, NULL, &dwBytes, NULL))
	    {
	      retcode = -1;
	      SetErrnoFromWinError(GetLastError());
	    }
	    else if (dwBytes)
	    {
	      FD_SET((int) hPipes[i], &aread);
	      retcode++;
	    }
      }
      else if (SAFE_FD_ISSET(hPipes[i], wfds) || SAFE_FD_ISSET(hPipes[i], efds))
      {
        errno = ENOSYS;
        return -1;  /* Not implemented */
      }
    }
    
    /* Check for closed sockets */
    for(i = 0; i < sock_max_fd; i++)
    {
      if(SAFE_FD_ISSET(i, &sock_read))
      {
        struct sockaddr addr;
        int len;

        if (getpeername(i, &addr, &len) == SOCKET_ERROR)
        {
          int err, len;

          len = sizeof(err);          
          if (getsockopt(i, SOL_SOCKET, SO_ERROR, (char *) &err, &len) == 0 &&
                err == WSAENOTCONN)
          {
            if (! SAFE_FD_ISSET(i, &aread))
            {
              FD_SET(i, &aread);
              retcode++;
            }
          }
        }
      }
    }
  }
  while(retcode == 0 && (ms_total == INFINITE || GetTickCount() < limit));

  if(rfds)
    *rfds = aread;

  if(wfds)
    *wfds = awrite;

  if(efds)
    *efds = aexcept;

  return retcode;
}
Esempio n. 22
0
/**
 * Complete filename (a la shell) from abbrevition.
 * @param fil the name of the file, may contain ~/ or
 *        be relative to the current directory
 * @returns the full file name,
 *          NULL is returned on error
 */
char *
GNUNET_STRINGS_filename_expand (const char *fil)
{
  char *buffer;
#ifndef MINGW
  size_t len;
  size_t n;
  char *fm;
  const char *fil_ptr;
#else
  char *fn;
  long lRet;
#endif

  if (fil == NULL)
    return NULL;

#ifndef MINGW
  if (fil[0] == DIR_SEPARATOR)
    /* absolute path, just copy */
    return GNUNET_strdup (fil);
  if (fil[0] == '~')
  {
    fm = getenv ("HOME");
    if (fm == NULL)
    {
      LOG (GNUNET_ERROR_TYPE_WARNING,
           _("Failed to expand `$HOME': environment variable `HOME' not set"));
      return NULL;
    }
    fm = GNUNET_strdup (fm);
    /* do not copy '~' */
    fil_ptr = fil + 1;

    /* skip over dir seperator to be consistent */
    if (fil_ptr[0] == DIR_SEPARATOR)
      fil_ptr++;
  }
  else
  {
    /* relative path */
    fil_ptr = fil;
    len = 512;
    fm = NULL;
    while (1)
    {
      buffer = GNUNET_malloc (len);
      if (getcwd (buffer, len) != NULL)
      {
        fm = buffer;
        break;
      }
      if ((errno == ERANGE) && (len < 1024 * 1024 * 4))
      {
        len *= 2;
        GNUNET_free (buffer);
        continue;
      }
      GNUNET_free (buffer);
      break;
    }
    if (fm == NULL)
    {
      LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "getcwd");
      buffer = getenv ("PWD");  /* alternative */
      if (buffer != NULL)
        fm = GNUNET_strdup (buffer);
    }
    if (fm == NULL)
      fm = GNUNET_strdup ("./");        /* give up */
  }
  n = strlen (fm) + 1 + strlen (fil_ptr) + 1;
  buffer = GNUNET_malloc (n);
  GNUNET_snprintf (buffer, n, "%s%s%s", fm,
                   (fm[strlen (fm) - 1] ==
                    DIR_SEPARATOR) ? "" : DIR_SEPARATOR_STR, fil_ptr);
  GNUNET_free (fm);
  return buffer;
#else
  fn = GNUNET_malloc (MAX_PATH + 1);

  if ((lRet = plibc_conv_to_win_path (fil, fn)) != ERROR_SUCCESS)
  {
    SetErrnoFromWinError (lRet);
    LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "plibc_conv_to_win_path");
    return NULL;
  }
  /* is the path relative? */
  if ((strncmp (fn + 1, ":\\", 2) != 0) && (strncmp (fn, "\\\\", 2) != 0))
  {
    char szCurDir[MAX_PATH + 1];

    lRet = GetCurrentDirectory (MAX_PATH + 1, szCurDir);
    if (lRet + strlen (fn) + 1 > (MAX_PATH + 1))
    {
      SetErrnoFromWinError (ERROR_BUFFER_OVERFLOW);
      LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "GetCurrentDirectory");
      return NULL;
    }
    buffer = GNUNET_malloc (MAX_PATH + 1);
    GNUNET_snprintf (buffer, MAX_PATH + 1, "%s\\%s", szCurDir, fn);
    GNUNET_free (fn);
    fn = buffer;
  }

  return fn;
#endif
}