Added setting position while duplicating file handles with FMF_WRITE mode. It's neede...
[cake.git] / compiler / clib / opendir.c
blob6680418a2043543f67770c0062092f3421391a5e
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 $Id$
5 POSIX function opendir().
6 */
8 #include <dos/dos.h>
9 #include <proto/dos.h>
11 #include <stdlib.h>
12 #ifndef ExNext_IS_WORKING_WITHOUT_ASSIGN
13 #include <stdio.h>
14 #endif
15 #include <unistd.h>
16 #include <errno.h>
17 #include <fcntl.h>
19 #include "__open.h"
20 #include "__errno.h"
21 #include "__upath.h"
23 #define DEBUG 0
24 #include <aros/debug.h>
26 /*****************************************************************************
28 NAME */
29 #include <dirent.h>
31 DIR *opendir(
33 /* SYNOPSIS */
34 const char *name)
36 /* FUNCTION
37 Opens a directory
39 INPUTS
40 pathname - Path and filename of the directory you want to open.
42 RESULT
43 NULL for error or a directory stream
45 NOTES
47 EXAMPLE
49 BUGS
51 SEE ALSO
52 open(), readdir(), closedir(), rewinddir(), seekdir(),
53 telldir(), scandir()
55 INTERNALS
57 ******************************************************************************/
59 DIR *dir;
60 int fd;
61 fdesc *desc;
62 BPTR lock;
63 char *aname;
64 #ifndef ExNext_IS_WORKING_WITHOUT_ASSIGN
65 char assign[32];
66 #endif
68 if (!name)
70 errno = EFAULT;
71 goto err1;
74 dir = malloc(sizeof(DIR));
75 if (!dir)
77 errno = ENOMEM;
78 goto err1;
81 dir->priv = AllocDosObject(DOS_FIB, NULL);
82 if (!dir->priv)
84 errno = ENOMEM;
85 goto err2;
88 /* Lock is used instead of open to allow opening "" */
89 aname = __path_u2a(name);
90 lock = Lock(aname, SHARED_LOCK);
91 if (!lock)
93 errno = IoErr2errno(IoErr());
94 goto err3;
97 #ifndef ExNext_IS_WORKING_WITHOUT_ASSIGN
98 sprintf(assign, "READDIR%x", (unsigned)dir);
100 if (!AssignLock(assign, DupLock(lock)))
102 D(bug("!AssignLock err=%d\n", IoErr()));
105 UnLock(lock);
106 lock = Lock(aname, SHARED_LOCK);
108 AssignLock(assign, NULL);
109 #endif
111 if (!Examine(lock, dir->priv))
113 errno = IoErr2errno(IoErr());
114 goto err4;
117 if (((struct FileInfoBlock *)dir->priv)->fib_DirEntryType<=0)
119 errno = ENOTDIR;
120 goto err4;
123 desc = malloc(sizeof(fdesc));
124 desc->fh = lock;
125 desc->flags = O_RDONLY;
126 desc->opencount = 1;
128 fd = __getfdslot(__getfirstfd(3));
129 __setfdesc(fd, desc);
131 dir->fd = fd;
132 dir->pos = 0;
133 dir->ent.d_name[NAME_MAX] = '\0';
135 D(bug("opendir(%s) fd=%d\n", name, fd));
136 return dir;
138 err4:
139 UnLock(lock);
140 err3:
141 FreeDosObject(DOS_FIB, dir->priv);
142 err2:
143 free(dir);
144 err1:
145 D(bug("opendir(%s) errno=%d\n", name, errno));
146 return NULL;