Logo Search packages:      
Sourcecode: mingw-w64 version File versions  Download package

dirent.c

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <io.h>
#include <direct.h>
#include <dirent.h>

#include <windows.h>

#include <tchar.h>
#define SUFFIX _T("*")
#define SLASH _T("\\")

/* Helper for opendir().  */
static inline unsigned _tGetFileAttributes (const _TCHAR * tPath)
{
#ifdef _UNICODE
  /* GetFileAttributesW does not work on W9x, so convert to ANSI */
  if (_osver & 0x8000)
    {
      char aPath [MAX_PATH];
      WideCharToMultiByte (CP_ACP, 0, tPath, -1, aPath, MAX_PATH, NULL,
                           NULL);
      return GetFileAttributesA (aPath);
    }
  return GetFileAttributesW (tPath);
#else
  return GetFileAttributesA (tPath);
#endif
}

_TDIR *
_topendir (const _TCHAR *szPath)
{
  _TDIR *nd;
  unsigned int rc;
  _TCHAR szFullPath[MAX_PATH];

  errno = 0;

  if (!szPath)
    {
      errno = EFAULT;
      return (_TDIR *) 0;
    }

  if (szPath[0] == _T('\0'))
    {
      errno = ENOTDIR;
      return (_TDIR *) 0;
    }

  rc = _tGetFileAttributes (szPath);
  if (rc == (unsigned int)-1)
    {

      errno = ENOENT;
      return (_TDIR *) 0;
    }
  if (!(rc & FILE_ATTRIBUTE_DIRECTORY))
    {

      errno = ENOTDIR;
      return (_TDIR *) 0;
    }

  _tfullpath (szFullPath,szPath,MAX_PATH);

  nd = (_TDIR *) malloc (sizeof (_TDIR) + (_tcslen (szFullPath)
                                 + _tcslen (SLASH)
                                 + _tcslen (SUFFIX) + 1)
                                * sizeof (_TCHAR));

  if (!nd)
    {

      errno = ENOMEM;
      return (_TDIR *) 0;
    }

  _tcscpy (nd->dd_name,szFullPath);

  if (nd->dd_name[0] != _T('\0')
      && _tcsrchr (nd->dd_name,_T('/')) != nd->dd_name
                                  + _tcslen (nd->dd_name) - 1
      && _tcsrchr (nd->dd_name,_T('\\')) != nd->dd_name
                                         + _tcslen (nd->dd_name) - 1)
    {
      _tcscat (nd->dd_name,SLASH);
    }

  _tcscat (nd->dd_name,SUFFIX);

  nd->dd_handle = -1;

  nd->dd_stat = 0;

  nd->dd_dir.d_ino = 0;
  nd->dd_dir.d_reclen = 0;
  nd->dd_dir.d_namlen = 0;
  memset (nd->dd_dir.d_name,0,FILENAME_MAX);

  return nd;
}

struct _tdirent *
_treaddir (_TDIR * dirp)
{
  errno = 0;

  if (!dirp)
    {
      errno = EFAULT;
      return (struct _tdirent *) 0;
    }

  if (dirp->dd_stat < 0)
    {

      return (struct _tdirent *) 0;
    }
  else if (dirp->dd_stat == 0)
    {

      dirp->dd_handle = _tfindfirst (dirp->dd_name,&(dirp->dd_dta));

      if (dirp->dd_handle == -1)
      {

        dirp->dd_stat = -1;
      }
      else
      {
        dirp->dd_stat = 1;
      }
    }
  else
    {

      if (_tfindnext (dirp->dd_handle,&(dirp->dd_dta)))
      {

        DWORD winerr = GetLastError ();
        if (winerr == ERROR_NO_MORE_FILES)
          errno = 0;
        _findclose (dirp->dd_handle);
        dirp->dd_handle = -1;
        dirp->dd_stat = -1;
      }
      else
      {

        dirp->dd_stat++;
      }
    }

  if (dirp->dd_stat > 0)
    {

      dirp->dd_dir.d_namlen = _tcslen (dirp->dd_dta.name);
      _tcscpy (dirp->dd_dir.d_name,dirp->dd_dta.name);
      return &dirp->dd_dir;
    }

  return (struct _tdirent *) 0;
}

int
_tclosedir (_TDIR * dirp)
{
  int rc;

  errno = 0;
  rc = 0;

  if (!dirp)
    {
      errno = EFAULT;
      return -1;
    }

  if (dirp->dd_handle != -1)
    {
      rc = _findclose (dirp->dd_handle);
    }

  free (dirp);

  return rc;
}

void
_trewinddir (_TDIR * dirp)
{
  errno = 0;

  if (!dirp)
    {
      errno = EFAULT;
      return;
    }

  if (dirp->dd_handle != -1)
    {
      _findclose (dirp->dd_handle);
    }

  dirp->dd_handle = -1;
  dirp->dd_stat = 0;
}

long
_ttelldir (_TDIR * dirp)
{
  errno = 0;

  if (!dirp)
    {
      errno = EFAULT;
      return -1;
    }
  return dirp->dd_stat;
}

void
_tseekdir (_TDIR * dirp,long lPos)
{
  errno = 0;

  if (!dirp)
    {
      errno = EFAULT;
      return;
    }

  if (lPos < -1)
    {

      errno = EINVAL;
      return;
    }
  else if (lPos == -1)
    {

      if (dirp->dd_handle != -1)
      {
        _findclose (dirp->dd_handle);
      }
      dirp->dd_handle = -1;
      dirp->dd_stat = -1;
    }
  else
    {

      _trewinddir (dirp);

      while ((dirp->dd_stat < lPos) && _treaddir (dirp));
    }
}

Generated by  Doxygen 1.6.0   Back to index