Fixed compatibility of output.
[AROS.git] / compiler / posixc / readdir.c
blob9731740c4d70d8a3bce4c4a58f5513d2b452df4c
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 $Id$
5 POSIX.1-2008 function readdir().
6 */
8 #include "__posixc_intbase.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()
63 INTERNALS
65 ******************************************************************************/
67 struct PosixCIntBase *PosixCBase =
68 (struct PosixCIntBase *)__aros_getbase_PosixCBase();
69 int const max = MAXFILENAMELENGTH > NAME_MAX ? NAME_MAX : MAXFILENAMELENGTH;
70 fdesc *desc;
72 D(bug("readdir("));
74 if (!dir)
76 D(bug("null)=EFAULT\n"));
77 errno = EFAULT;
78 return NULL;
81 desc = __getfdesc(dir->fd);
82 if (!desc)
84 D(bug("fd=%d)=EBADF\n", (int)dir->fd));
85 errno = EBADF;
86 return NULL;
89 if (PosixCBase->doupath && dir->pos == 0)
91 dir->ent.d_type = DT_DIR;
92 dir->ent.d_name[0]='.';
93 dir->ent.d_name[1]='\0';
94 dir->ent.d_reclen = 1;
96 else
97 if (PosixCBase->doupath && dir->pos == 1)
99 dir->ent.d_type = DT_DIR;
100 dir->ent.d_name[0]='.';
101 dir->ent.d_name[1]='.';
102 dir->ent.d_name[2]='\0';
103 dir->ent.d_reclen = 2;
105 else
107 struct FileInfoBlock *fib = (struct FileInfoBlock *)dir->priv;
109 if (!ExNext(desc->fcb->handle, fib))
111 dir->pos--;
112 if (IoErr() != ERROR_NO_MORE_ENTRIES)
114 errno = __stdc_ioerr2errno(IoErr());
115 D(bug(") errno=%d\n", (int)errno));
117 D(else
118 bug("NO_MORE_ENTRIES)\n"));
119 return NULL;
122 CONST_STRPTR name = fib->fib_FileName;
123 while (TRUE)
126 if (PosixCBase->doupath && name[0] == '.')
128 if (name[1] == '.')
130 if (name[2] == '\0')
131 continue;
133 else
134 if (name[1] == '\0')
135 continue;
138 strncpy(dir->ent.d_name, name, max);
139 dir->ent.d_reclen = strlen(name);
141 switch (fib->fib_DirEntryType)
143 case ST_FILE:
144 dir->ent.d_type = DT_REG;
145 break;
146 case ST_ROOT:
147 case ST_USERDIR:
148 dir->ent.d_type = DT_DIR;
149 break;
150 case ST_SOFTLINK:
151 case ST_LINKFILE:
152 case ST_LINKDIR:
153 dir->ent.d_type = DT_LNK;
154 break;
155 case ST_PIPEFILE:
156 dir->ent.d_type = DT_FIFO;
157 break;
158 default:
159 dir->ent.d_type = DT_UNKNOWN;
160 break;
163 break;
167 D(bug("%s) d_type=%d\n", dir->ent.d_name, (int)dir->ent.d_type));
168 dir->pos++;
169 return &(dir->ent);