ISIS Logo
UTILITIES
EPICS Utilities
win32_dirent.c
Go to the documentation of this file.
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 and July 2012.
7  Modified for EPICS build system Freddie Akeroyd 28/10/2014 (freddie.akeroyd@stfc.ac.uk)
8  Rights: See end of file.
9 
10 */
11 
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
18 extern "C"
19 {
20 #endif
21 
22 #include <epicsExport.h>
23 
24 #include <win32_dirent.h>
25 
26 typedef ptrdiff_t handle_type; /* C99's intptr_t not sufficiently portable */
27 
28 struct DIR
29 {
30  handle_type handle; /* -1 for failed rewind */
31  struct _finddata_t info;
32  struct dirent result; /* d_name null iff first time */
33  char *name; /* null-terminated char string */
34 };
35 
36 epicsShareFunc DIR *opendir(const char *name)
37 {
38  DIR *dir = 0;
39 
40  if(name && name[0])
41  {
42  size_t base_length = strlen(name);
43  const char *all = /* search pattern must end with suitable wildcard */
44  strchr("/\\", name[base_length - 1]) ? "*" : "/*";
45 
46  if((dir = (DIR *) malloc(sizeof *dir)) != 0 &&
47  (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0)
48  {
49  strcat(strcpy(dir->name, name), all);
50 
51  if((dir->handle =
52  (handle_type) _findfirst(dir->name, &dir->info)) != -1)
53  {
54  dir->result.d_name = 0;
55  }
56  else /* rollback */
57  {
58  free(dir->name);
59  free(dir);
60  dir = 0;
61  }
62  }
63  else /* rollback */
64  {
65  free(dir);
66  dir = 0;
67  errno = ENOMEM;
68  }
69  }
70  else
71  {
72  errno = EINVAL;
73  }
74 
75  return dir;
76 }
77 
78 epicsShareFunc int closedir(DIR *dir)
79 {
80  int result = -1;
81 
82  if(dir)
83  {
84  if(dir->handle != -1)
85  {
86  result = _findclose(dir->handle);
87  }
88 
89  free(dir->name);
90  free(dir);
91  }
92 
93  if(result == -1) /* map all errors to EBADF */
94  {
95  errno = EBADF;
96  }
97 
98  return result;
99 }
100 
101 epicsShareFunc struct dirent *readdir(DIR *dir)
102 {
103  struct dirent *result = 0;
104 
105  if(dir && dir->handle != -1)
106  {
107  if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1)
108  {
109  result = &dir->result;
110  result->d_name = dir->info.name;
111  }
112  }
113  else
114  {
115  errno = EBADF;
116  }
117 
118  return result;
119 }
120 
121 epicsShareFunc void rewinddir(DIR *dir)
122 {
123  if(dir && dir->handle != -1)
124  {
125  _findclose(dir->handle);
126  dir->handle = (handle_type) _findfirst(dir->name, &dir->info);
127  dir->result.d_name = 0;
128  }
129  else
130  {
131  errno = EBADF;
132  }
133 }
134 
135 #ifdef __cplusplus
136 }
137 #endif
138 
139 /*
140 
141  Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved.
142 
143  Permission to use, copy, modify, and distribute this software and its
144  documentation for any purpose is hereby granted without fee, provided
145  that this copyright and permissions notice appear in all copies and
146  derivatives.
147 
148  This software is supplied "as is" without express or implied warranty.
149 
150  But that said, if there are any problems please get in touch.
151 
152 */
ptrdiff_t handle_type
Definition: win32_dirent.c:26
epicsShareFunc struct dirent * readdir(DIR *dir)
Definition: win32_dirent.c:101
struct dirent result
Definition: win32_dirent.c:32
struct _finddata_t info
Definition: win32_dirent.c:31
char * d_name
Definition: win32_dirent.h:26
epicsShareFunc DIR * opendir(const char *name)
Definition: win32_dirent.c:36
epicsShareFunc int closedir(DIR *dir)
Definition: win32_dirent.c:78
char * name
Definition: win32_dirent.c:33
epicsShareFunc void rewinddir(DIR *dir)
Definition: win32_dirent.c:121
handle_type handle
Definition: win32_dirent.c:30
Copyright © 2013 Science and Technology Facilities Council | Generated by   doxygen 1.8.5