Restored work-around for hangs when trying to use disk-based handlers
[tangerine.git] / compiler / clib / readdir.c
blob6110a657c3aefac7ff61cd19c5b8b3f24dd799f6
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 $Id$
5 POSIX function readdir().
6 */
8 #include "__arosc_privdata.h"
10 #include <dos/dos.h>
11 #include <proto/dos.h>
13 #include <string.h>
14 #include <errno.h>
16 #include "__errno.h"
17 #include "__open.h"
18 #include "__upath.h"
20 #define DEBUG 0
21 #include <aros/debug.h>
23 /*****************************************************************************
25 NAME */
26 #include <dirent.h>
28 struct dirent *readdir(
30 /* SYNOPSIS */
31 DIR *dir)
33 /* FUNCTION
34 Reads a directory
36 INPUTS
37 dir - the directory stream pointing to the directory being read
39 RESULT
40 The readdir() function returns a pointer to a dirent
41 structure, or NULL if an error occurs or end-of-file is
42 reached.
44 The data returned by readdir() is overwritten by subse­
45 quent calls to readdir() for the same directory stream.
47 According to POSIX, the dirent structure contains a field
48 char d_name[] of unspecified size, with at most NAME_MAX
49 characters preceding the terminating null character. Use
50 of other fields will harm the portability of your pro­
51 grams.
53 NOTES
55 EXAMPLE
57 BUGS
59 SEE ALSO
60 read(), opendir(), closedir(), rewinddir(), seekdir(),
61 telldir(), scandir()
63 INTERNALS
65 ******************************************************************************/
67 int const max = MAXFILENAMELENGTH > NAME_MAX ? NAME_MAX : MAXFILENAMELENGTH;
68 fdesc *desc;
70 D(bug("readdir("));
72 if (!dir)
74 D(bug("null)=EFAULT\n"));
75 errno = EFAULT;
76 return NULL;
79 desc = __getfdesc(dir->fd);
80 if (!desc)
82 D(bug("fd=%d)=EBADF\n", (int)dir->fd));
83 errno = EBADF;
84 return NULL;
87 if (__doupath && dir->pos == 0)
89 dir->ent.d_type = DT_DIR;
90 dir->ent.d_name[0]='.';
91 dir->ent.d_name[1]='\0';
92 dir->ent.d_reclen = 1;
94 else
95 if (__doupath && dir->pos == 1)
97 dir->ent.d_type = DT_DIR;
98 dir->ent.d_name[0]='.';
99 dir->ent.d_name[1]='.';
100 dir->ent.d_name[2]='\0';
101 dir->ent.d_reclen = 2;
103 else
105 struct FileInfoBlock *fib = (struct FileInfoBlock *)dir->priv;
107 if (!ExNext(desc->fh, fib))
109 dir->pos--;
110 if (IoErr() != ERROR_NO_MORE_ENTRIES)
112 errno = IoErr2errno(IoErr());
113 D(bug(") errno=%d\n", (int)errno));
115 D(else
116 bug("NO_MORE_ENTRIES)\n"));
117 return NULL;
120 CONST_STRPTR name = fib->fib_FileName;
121 while (TRUE)
124 if (__doupath && name[0] == '.')
126 if (name[1] == '.')
128 if (name[2] == '\0')
129 continue;
131 else
132 if (name[1] == '\0')
133 continue;
136 strncpy(dir->ent.d_name, name, max);
137 dir->ent.d_reclen = strlen(name);
139 switch (fib->fib_DirEntryType)
141 case ST_FILE:
142 dir->ent.d_type = DT_REG;
143 break;
144 case ST_ROOT:
145 case ST_USERDIR:
146 dir->ent.d_type = DT_DIR;
147 break;
148 case ST_SOFTLINK:
149 case ST_LINKFILE:
150 case ST_LINKDIR:
151 dir->ent.d_type = DT_LNK;
152 break;
153 case ST_PIPEFILE:
154 dir->ent.d_type = DT_FIFO;
155 break;
156 default:
157 dir->ent.d_type = DT_UNKNOWN;
158 break;
161 break;
165 D(bug("%s) d_type=%d\n", dir->ent.d_name, (int)dir->ent.d_type));
166 dir->pos++;
167 return &(dir->ent);