LTKCPP-- LLRP Toolkit C Plus Plus Library
dirent.cpp
00001 /*
00002 
00003     Implementation of POSIX directory browsing functions and types for Win32.
00004 
00005     Author:  Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com)
00006     History: Created March 1997. Updated June 2003.
00007     Rights:  See end of file.
00008 
00009 */
00010 
00011 #include "dirent.h"
00012 #include <errno.h>
00013 #include <io.h> /* _findfirst and _findnext set errno iff they return -1 */
00014 #include <stdlib.h>
00015 #include <string.h>
00016 
00017 #ifdef __cplusplus
00018 extern "C"
00019 {
00020 #endif
00021 
00022 struct DIR
00023 {
00024     long                handle; /* -1 for failed rewind */
00025     struct _finddata_t  info;
00026     struct dirent       result; /* d_name null iff first time */
00027     char                *name;  /* null-terminated char string */
00028 };
00029 
00030 DIR *opendir(const char *name)
00031 {
00032     DIR *dir = 0;
00033 
00034     if(name && name[0])
00035     {
00036         size_t base_length = strlen(name);
00037         const char *all = /* search pattern must end with suitable wildcard */
00038             strchr("/\\", name[base_length - 1]) ? "*" : "/*";
00039 
00040         if((dir = (DIR *) malloc(sizeof *dir)) != 0 &&
00041            (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0)
00042         {
00043             strcat(strcpy(dir->name, name), all);
00044 
00045             if((dir->handle = (long) _findfirst(dir->name, &dir->info)) != -1)
00046             {
00047                 dir->result.d_name = 0;
00048             }
00049             else /* rollback */
00050             {
00051                 free(dir->name);
00052                 free(dir);
00053                 dir = 0;
00054             }
00055         }
00056         else /* rollback */
00057         {
00058             free(dir);
00059             dir   = 0;
00060             errno = ENOMEM;
00061         }
00062     }
00063     else
00064     {
00065         errno = EINVAL;
00066     }
00067 
00068     return dir;
00069 }
00070 
00071 int closedir(DIR *dir)
00072 {
00073     int result = -1;
00074 
00075     if(dir)
00076     {
00077         if(dir->handle != -1)
00078         {
00079             result = _findclose(dir->handle);
00080         }
00081 
00082         free(dir->name);
00083         free(dir);
00084     }
00085 
00086     if(result == -1) /* map all errors to EBADF */
00087     {
00088         errno = EBADF;
00089     }
00090 
00091     return result;
00092 }
00093 
00094 struct dirent *readdir(DIR *dir)
00095 {
00096     struct dirent *result = 0;
00097 
00098     if(dir && dir->handle != -1)
00099     {
00100         if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1)
00101         {
00102             result         = &dir->result;
00103             result->d_name = dir->info.name;
00104         }
00105     }
00106     else
00107     {
00108         errno = EBADF;
00109     }
00110 
00111     return result;
00112 }
00113 
00114 void rewinddir(DIR *dir)
00115 {
00116     if(dir && dir->handle != -1)
00117     {
00118         _findclose(dir->handle);
00119         dir->handle = (long) _findfirst(dir->name, &dir->info);
00120         dir->result.d_name = 0;
00121     }
00122     else
00123     {
00124         errno = EBADF;
00125     }
00126 }
00127 
00128 #ifdef __cplusplus
00129 }
00130 #endif
00131 
00132 /*
00133 
00134     Copyright Kevlin Henney, 1997, 2003. All rights reserved.
00135 
00136     Permission to use, copy, modify, and distribute this software and its
00137     documentation for any purpose is hereby granted without fee, provided
00138     that this copyright and permissions notice appear in all copies and
00139     derivatives.
00140     
00141     This software is supplied "as is" without express or implied warranty.
00142 
00143     But that said, if there are any problems please get in touch.
00144 
00145 */