modernc.org/cc@v1.0.1/v2/testdata/_sqlite/src/test_windirent.c (about)

     1  /*
     2  ** 2015 November 30
     3  **
     4  ** The author disclaims copyright to this source code.  In place of
     5  ** a legal notice, here is a blessing:
     6  **
     7  **    May you do good and not evil.
     8  **    May you find forgiveness for yourself and forgive others.
     9  **    May you share freely, never taking more than you give.
    10  **
    11  *************************************************************************
    12  ** This file contains code to implement most of the opendir() family of
    13  ** POSIX functions on Win32 using the MSVCRT.
    14  */
    15  
    16  #if defined(_WIN32) && defined(_MSC_VER)
    17  
    18  #include "test_windirent.h"
    19  
    20  /*
    21  ** Implementation of the POSIX getenv() function using the Win32 API.
    22  ** This function is not thread-safe.
    23  */
    24  const char *windirent_getenv(
    25    const char *name
    26  ){
    27    static char value[32768]; /* Maximum length, per MSDN */
    28    DWORD dwSize = sizeof(value) / sizeof(char); /* Size in chars */
    29    DWORD dwRet; /* Value returned by GetEnvironmentVariableA() */
    30  
    31    memset(value, 0, sizeof(value));
    32    dwRet = GetEnvironmentVariableA(name, value, dwSize);
    33    if( dwRet==0 || dwRet>dwSize ){
    34      /*
    35      ** The function call to GetEnvironmentVariableA() failed -OR-
    36      ** the buffer is not large enough.  Either way, return NULL.
    37      */
    38      return 0;
    39    }else{
    40      /*
    41      ** The function call to GetEnvironmentVariableA() succeeded
    42      ** -AND- the buffer contains the entire value.
    43      */
    44      return value;
    45    }
    46  }
    47  
    48  /*
    49  ** Implementation of the POSIX opendir() function using the MSVCRT.
    50  */
    51  LPDIR opendir(
    52    const char *dirname
    53  ){
    54    struct _finddata_t data;
    55    LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR));
    56    SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]);
    57  
    58    if( dirp==NULL ) return NULL;
    59    memset(dirp, 0, sizeof(DIR));
    60  
    61    /* TODO: Remove this if Unix-style root paths are not used. */
    62    if( sqlite3_stricmp(dirname, "/")==0 ){
    63      dirname = windirent_getenv("SystemDrive");
    64    }
    65  
    66    memset(&data, 0, sizeof(struct _finddata_t));
    67    _snprintf(data.name, namesize, "%s\\*", dirname);
    68    dirp->d_handle = _findfirst(data.name, &data);
    69  
    70    if( dirp->d_handle==BAD_INTPTR_T ){
    71      closedir(dirp);
    72      return NULL;
    73    }
    74  
    75    /* TODO: Remove this block to allow hidden and/or system files. */
    76    if( is_filtered(data) ){
    77  next:
    78  
    79      memset(&data, 0, sizeof(struct _finddata_t));
    80      if( _findnext(dirp->d_handle, &data)==-1 ){
    81        closedir(dirp);
    82        return NULL;
    83      }
    84  
    85      /* TODO: Remove this block to allow hidden and/or system files. */
    86      if( is_filtered(data) ) goto next;
    87    }
    88  
    89    dirp->d_first.d_attributes = data.attrib;
    90    strncpy(dirp->d_first.d_name, data.name, NAME_MAX);
    91    dirp->d_first.d_name[NAME_MAX] = '\0';
    92  
    93    return dirp;
    94  }
    95  
    96  /*
    97  ** Implementation of the POSIX readdir() function using the MSVCRT.
    98  */
    99  LPDIRENT readdir(
   100    LPDIR dirp
   101  ){
   102    struct _finddata_t data;
   103  
   104    if( dirp==NULL ) return NULL;
   105  
   106    if( dirp->d_first.d_ino==0 ){
   107      dirp->d_first.d_ino++;
   108      dirp->d_next.d_ino++;
   109  
   110      return &dirp->d_first;
   111    }
   112  
   113  next:
   114  
   115    memset(&data, 0, sizeof(struct _finddata_t));
   116    if( _findnext(dirp->d_handle, &data)==-1 ) return NULL;
   117  
   118    /* TODO: Remove this block to allow hidden and/or system files. */
   119    if( is_filtered(data) ) goto next;
   120  
   121    dirp->d_next.d_ino++;
   122    dirp->d_next.d_attributes = data.attrib;
   123    strncpy(dirp->d_next.d_name, data.name, NAME_MAX);
   124    dirp->d_next.d_name[NAME_MAX] = '\0';
   125  
   126    return &dirp->d_next;
   127  }
   128  
   129  /*
   130  ** Implementation of the POSIX readdir_r() function using the MSVCRT.
   131  */
   132  INT readdir_r(
   133    LPDIR dirp,
   134    LPDIRENT entry,
   135    LPDIRENT *result
   136  ){
   137    struct _finddata_t data;
   138  
   139    if( dirp==NULL ) return EBADF;
   140  
   141    if( dirp->d_first.d_ino==0 ){
   142      dirp->d_first.d_ino++;
   143      dirp->d_next.d_ino++;
   144  
   145      entry->d_ino = dirp->d_first.d_ino;
   146      entry->d_attributes = dirp->d_first.d_attributes;
   147      strncpy(entry->d_name, dirp->d_first.d_name, NAME_MAX);
   148      entry->d_name[NAME_MAX] = '\0';
   149  
   150      *result = entry;
   151      return 0;
   152    }
   153  
   154  next:
   155  
   156    memset(&data, 0, sizeof(struct _finddata_t));
   157    if( _findnext(dirp->d_handle, &data)==-1 ){
   158      *result = NULL;
   159      return ENOENT;
   160    }
   161  
   162    /* TODO: Remove this block to allow hidden and/or system files. */
   163    if( is_filtered(data) ) goto next;
   164  
   165    entry->d_ino = (ino_t)-1; /* not available */
   166    entry->d_attributes = data.attrib;
   167    strncpy(entry->d_name, data.name, NAME_MAX);
   168    entry->d_name[NAME_MAX] = '\0';
   169  
   170    *result = entry;
   171    return 0;
   172  }
   173  
   174  /*
   175  ** Implementation of the POSIX closedir() function using the MSVCRT.
   176  */
   177  INT closedir(
   178    LPDIR dirp
   179  ){
   180    INT result = 0;
   181  
   182    if( dirp==NULL ) return EINVAL;
   183  
   184    if( dirp->d_handle!=NULL_INTPTR_T && dirp->d_handle!=BAD_INTPTR_T ){
   185      result = _findclose(dirp->d_handle);
   186    }
   187  
   188    sqlite3_free(dirp);
   189    return result;
   190  }
   191  
   192  #endif /* defined(WIN32) && defined(_MSC_VER) */