crete an idle task to run when theres ... umm. .. nothing to do ..
[AROS.git] / compiler / clib / opendir.c
blob01fa47f3c56e24b8a468b8aa67f792f095caa3aa
1 /*
2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
3 $Id$
5 POSIX.1-2008 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 "__fdesc.h"
20 #include "__upath.h"
21 #include "__dirdesc.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 fcb *cblock;
62 fdesc *desc;
63 BPTR lock;
64 const char *aname;
65 #ifndef ExNext_IS_WORKING_WITHOUT_ASSIGN
66 char assign[32];
67 #endif
69 if (!name)
71 errno = EFAULT;
72 goto err1;
75 dir = malloc(sizeof(DIR));
76 if (!dir)
78 errno = ENOMEM;
79 goto err1;
82 dir->priv = AllocDosObject(DOS_FIB, NULL);
83 if (!dir->priv)
85 errno = ENOMEM;
86 goto err2;
89 /* Lock is used instead of open to allow opening "" */
90 aname = __path_u2a(name);
91 lock = Lock(aname, SHARED_LOCK);
92 if (!lock)
94 errno = __arosc_ioerr2errno(IoErr());
95 goto err3;
98 #ifndef ExNext_IS_WORKING_WITHOUT_ASSIGN
99 sprintf(assign, "READDIR%p", dir);
101 if (!AssignLock(assign, DupLock(lock)))
103 D(bug("!AssignLock err=%d\n", IoErr()));
106 UnLock(lock);
107 lock = Lock(aname, SHARED_LOCK);
109 AssignLock(assign, BNULL);
110 #endif
112 if (!Examine(lock, dir->priv))
114 errno = __arosc_ioerr2errno(IoErr());
115 goto err4;
118 if (((struct FileInfoBlock *)dir->priv)->fib_DirEntryType<=0)
120 errno = ENOTDIR;
121 goto err4;
124 cblock = AllocVec(sizeof(fcb), MEMF_ANY | MEMF_CLEAR);
125 if(!cblock)
127 errno = ENOMEM;
128 goto err4;
130 desc = __alloc_fdesc();
131 if(!desc)
133 errno = ENOMEM;
134 goto err5;
136 desc->fdflags = 0;
137 desc->fcb = cblock;
138 desc->fcb->fh = lock;
139 desc->fcb->flags = O_RDONLY;
140 desc->fcb->opencount = 1;
141 desc->fcb->isdir = 1;
143 fd = __getfdslot(__getfirstfd(3));
144 __setfdesc(fd, desc);
146 dir->fd = fd;
147 dir->pos = 0;
148 dir->ent.d_name[NAME_MAX] = '\0';
150 D(bug("opendir(%s) fd=%d\n", name, fd));
151 return dir;
153 err5:
154 FreeVec(cblock);
155 err4:
156 UnLock(lock);
157 err3:
158 FreeDosObject(DOS_FIB, dir->priv);
159 err2:
160 free(dir);
161 err1:
162 D(bug("opendir(%s) errno=%d\n", name, errno));
163 return NULL;