(ice-9 optargs) based on the new lambda* work
[bpt/guile.git] / libguile / win32-dirent.c
1 /* Copyright (C) 2001, 2006, 2008 Free Software Foundation, Inc.
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public License
5 * as published by the Free Software Foundation; either version 3 of
6 * the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301 USA
17 */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include "libguile/__scm.h"
24
25 #include <windows.h>
26 #include <stdio.h>
27 #include <string.h>
28
29 #include "win32-dirent.h"
30
31 DIR *
32 opendir (const char * name)
33 {
34 DIR *dir;
35 HANDLE hnd;
36 char *file;
37 WIN32_FIND_DATA find;
38
39 if (!name || !*name)
40 return NULL;
41 file = malloc (strlen (name) + 3);
42 strcpy (file, name);
43 if (file[strlen (name) - 1] != '/' && file[strlen (name) - 1] != '\\')
44 strcat (file, "/*");
45 else
46 strcat (file, "*");
47
48 if ((hnd = FindFirstFile (file, &find)) == INVALID_HANDLE_VALUE)
49 {
50 free (file);
51 return NULL;
52 }
53
54 dir = malloc (sizeof (DIR));
55 dir->mask = file;
56 dir->fd = (int) hnd;
57 dir->data = malloc (sizeof (WIN32_FIND_DATA));
58 dir->allocation = sizeof (WIN32_FIND_DATA);
59 dir->size = dir->allocation;
60 dir->filepos = 0;
61 memcpy (dir->data, &find, sizeof (WIN32_FIND_DATA));
62 return dir;
63 }
64
65 struct dirent *
66 readdir (DIR * dir)
67 {
68 static struct dirent entry;
69 WIN32_FIND_DATA *find;
70
71 entry.d_ino = 0;
72 entry.d_type = 0;
73 find = (WIN32_FIND_DATA *) dir->data;
74
75 if (dir->filepos)
76 {
77 if (!FindNextFile ((HANDLE) dir->fd, find))
78 return NULL;
79 }
80
81 entry.d_off = dir->filepos;
82 strncpy (entry.d_name, find->cFileName, sizeof (entry.d_name));
83 entry.d_reclen = strlen (find->cFileName);
84 dir->filepos++;
85 return &entry;
86 }
87
88 int
89 closedir (DIR * dir)
90 {
91 HANDLE hnd = (HANDLE) dir->fd;
92 free (dir->data);
93 free (dir->mask);
94 free (dir);
95 return FindClose (hnd) ? 0 : -1;
96 }
97
98 void
99 rewinddir (DIR * dir)
100 {
101 HANDLE hnd = (HANDLE) dir->fd;
102 WIN32_FIND_DATA *find = (WIN32_FIND_DATA *) dir->data;
103
104 FindClose (hnd);
105 hnd = FindFirstFile (dir->mask, find);
106 dir->fd = (int) hnd;
107 dir->filepos = 0;
108 }
109
110 void
111 seekdir (DIR * dir, off_t offset)
112 {
113 off_t n;
114
115 rewinddir (dir);
116 for (n = 0; n < offset; n++)
117 {
118 if (FindNextFile ((HANDLE) dir->fd, (WIN32_FIND_DATA *) dir->data))
119 dir->filepos++;
120 }
121 }
122
123 off_t
124 telldir (DIR * dir)
125 {
126 return dir->filepos;
127 }
128
129 int
130 dirfd (DIR * dir)
131 {
132 return dir->fd;
133 }