root/library/bdm/dirent.c @ 661

Revision 661, 3.1 kB (checked in by smidl, 15 years ago)

doc

Line 
1/*
2
3    Implementation of POSIX directory browsing functions and types for Win32.
4
5    Author:  Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com)
6    History: Created March 1997. Updated June 2003.
7    Rights:  See end of file.
8
9*/
10
11#include "dirent.h"
12#include <errno.h>
13#include <io.h> /* _findfirst and _findnext set errno iff they return -1 */
14#include <stdlib.h>
15#include <string.h>
16
17#ifdef __cplusplus
18extern "C"
19{
20#endif
21
22//! directory info
23struct DIR
24{
25    long                handle; /* -1 for failed rewind */
26    struct _finddata_t  info;
27    struct dirent       result; /* d_name null iff first time */
28    char                *name;  /* null-terminated char string */
29};
30
31DIR *opendir(const char *name)
32{
33    DIR *dir = 0;
34
35    if(name && name[0])
36    {
37        size_t base_length = strlen(name);
38        const char *all = /* search pattern must end with suitable wildcard */
39            strchr("/\\", name[base_length - 1]) ? "*" : "/*";
40
41        if((dir = (DIR *) malloc(sizeof *dir)) != 0 &&
42           (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0)
43        {
44            strcat(strcpy(dir->name, name), all);
45
46            if((dir->handle = (long) _findfirst(dir->name, &dir->info)) != -1)
47            {
48                dir->result.d_name = 0;
49            }
50            else /* rollback */
51            {
52                free(dir->name);
53                free(dir);
54                dir = 0;
55            }
56        }
57        else /* rollback */
58        {
59            free(dir);
60            dir   = 0;
61            errno = ENOMEM;
62        }
63    }
64    else
65    {
66        errno = EINVAL;
67    }
68
69    return dir;
70}
71
72int closedir(DIR *dir)
73{
74    int result = -1;
75
76    if(dir)
77    {
78        if(dir->handle != -1)
79        {
80            result = _findclose(dir->handle);
81        }
82
83        free(dir->name);
84        free(dir);
85    }
86
87    if(result == -1) /* map all errors to EBADF */
88    {
89        errno = EBADF;
90    }
91
92    return result;
93}
94
95struct dirent *readdir(DIR *dir)
96{
97    struct dirent *result = 0;
98
99    if(dir && dir->handle != -1)
100    {
101        if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1)
102        {
103            result         = &dir->result;
104            result->d_name = dir->info.name;
105        }
106    }
107    else
108    {
109        errno = EBADF;
110    }
111
112    return result;
113}
114
115void rewinddir(DIR *dir)
116{
117    if(dir && dir->handle != -1)
118    {
119        _findclose(dir->handle);
120        dir->handle = (long) _findfirst(dir->name, &dir->info);
121        dir->result.d_name = 0;
122    }
123    else
124    {
125        errno = EBADF;
126    }
127}
128
129#ifdef __cplusplus
130}
131#endif
132
133/*
134
135    Copyright Kevlin Henney, 1997, 2003. All rights reserved.
136
137    Permission to use, copy, modify, and distribute this software and its
138    documentation for any purpose is hereby granted without fee, provided
139    that this copyright and permissions notice appear in all copies and
140    derivatives.
141   
142    This software is supplied "as is" without express or implied warranty.
143
144    But that said, if there are any problems please get in touch.
145
146*/
Note: See TracBrowser for help on using the browser.