update mappings to reflect recent changes
[AROS.git] / compiler / clib / readdir.c
blobbf723461ae6d1feb3c1da37aadc17807960727b5
1 /*
2 Copyright © 1995-2012, 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 "__fdesc.h"
17 #include "__upath.h"
18 #include "__dirdesc.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 struct aroscbase *aroscbase = __aros_getbase_aroscbase();
68 int const max = MAXFILENAMELENGTH > NAME_MAX ? NAME_MAX : MAXFILENAMELENGTH;
69 fdesc *desc;
71 D(bug("readdir("));
73 if (!dir)
75 D(bug("null)=EFAULT\n"));
76 errno = EFAULT;
77 return NULL;
80 desc = __getfdesc(dir->fd);
81 if (!desc)
83 D(bug("fd=%d)=EBADF\n", (int)dir->fd));
84 errno = EBADF;
85 return NULL;
88 if (aroscbase->acb_doupath && dir->pos == 0)
90 dir->ent.d_type = DT_DIR;
91 dir->ent.d_name[0]='.';
92 dir->ent.d_name[1]='\0';
93 dir->ent.d_reclen = 1;
95 else
96 if (aroscbase->acb_doupath && dir->pos == 1)
98 dir->ent.d_type = DT_DIR;
99 dir->ent.d_name[0]='.';
100 dir->ent.d_name[1]='.';
101 dir->ent.d_name[2]='\0';
102 dir->ent.d_reclen = 2;
104 else
106 struct FileInfoBlock *fib = (struct FileInfoBlock *)dir->priv;
108 if (!ExNext(desc->fcb->fh, fib))
110 dir->pos--;
111 if (IoErr() != ERROR_NO_MORE_ENTRIES)
113 errno = __arosc_ioerr2errno(IoErr());
114 D(bug(") errno=%d\n", (int)errno));
116 D(else
117 bug("NO_MORE_ENTRIES)\n"));
118 return NULL;
121 CONST_STRPTR name = fib->fib_FileName;
122 while (TRUE)
125 if (aroscbase->acb_doupath && name[0] == '.')
127 if (name[1] == '.')
129 if (name[2] == '\0')
130 continue;
132 else
133 if (name[1] == '\0')
134 continue;
137 strncpy(dir->ent.d_name, name, max);
138 dir->ent.d_reclen = strlen(name);
140 switch (fib->fib_DirEntryType)
142 case ST_FILE:
143 dir->ent.d_type = DT_REG;
144 break;
145 case ST_ROOT:
146 case ST_USERDIR:
147 dir->ent.d_type = DT_DIR;
148 break;
149 case ST_SOFTLINK:
150 case ST_LINKFILE:
151 case ST_LINKDIR:
152 dir->ent.d_type = DT_LNK;
153 break;
154 case ST_PIPEFILE:
155 dir->ent.d_type = DT_FIFO;
156 break;
157 default:
158 dir->ent.d_type = DT_UNKNOWN;
159 break;
162 break;
166 D(bug("%s) d_type=%d\n", dir->ent.d_name, (int)dir->ent.d_type));
167 dir->pos++;
168 return &(dir->ent);