Change Guile license to LGPLv3+
[bpt/guile.git] / libguile / win32-dirent.c
CommitLineData
dbb605f5 1/* Copyright (C) 2001, 2006, 2008 Free Software Foundation, Inc.
8dd6dfdc 2 *
73be1d9e 3 * This library is free software; you can redistribute it and/or
53befeb7
NJ
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.
8dd6dfdc 7 *
53befeb7
NJ
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
8dd6dfdc 12 *
73be1d9e
MV
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
53befeb7
NJ
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301 USA
73be1d9e 17 */
8dd6dfdc 18
dbb605f5
LC
19#ifdef HAVE_CONFIG_H
20# include <config.h>
21#endif
22
8dd6dfdc
MV
23#include "libguile/__scm.h"
24
25#include <windows.h>
26#include <stdio.h>
27#include <string.h>
28
21e11a3b 29#include "win32-dirent.h"
8dd6dfdc
MV
30
31DIR *
32opendir (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;
2e945bcc 41 file = malloc (strlen (name) + 3);
8dd6dfdc
MV
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
2e945bcc 54 dir = malloc (sizeof (DIR));
8dd6dfdc
MV
55 dir->mask = file;
56 dir->fd = (int) hnd;
2e945bcc 57 dir->data = malloc (sizeof (WIN32_FIND_DATA));
8dd6dfdc
MV
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
65struct dirent *
66readdir (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
88int
89closedir (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
98void
99rewinddir (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
110void
111seekdir (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
123off_t
124telldir (DIR * dir)
125{
126 return dir->filepos;
127}
128
129int
130dirfd (DIR * dir)
131{
132 return dir->fd;
133}