Implemented tty_read () - tty_t obtain backlog (512bytes) created ondemand; telnetd...
[ZeXOS.git] / libc / dirent / opendir.c
blob64f8ad063f2d405bfdc8b1e2c7ef2552f98a8236
1 /*
2 * ZeX/OS
3 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <vfs.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <dirent.h>
27 static vfs_dirent_t *getdir (const char *path)
29 vfs_dirent_t *d;
31 char *cwd = getcwd (0, 0);
33 if (!cwd)
34 return 0;
36 chdir (path);
38 asm volatile (
39 "movl $25, %%eax;"
40 "int $0x80;"
41 "movl %%eax, %0;"
42 : "=g" (d) :: "%eax");
44 chdir (cwd);
46 free (cwd);
48 return d;
51 DIR *opendir (const char *name)
53 if (!name) {
54 errno = ENOENT;
55 return 0;
58 vfs_dirent_t *ent = getdir (name);
60 if (!ent) {
61 errno = ENOENT;
62 return 0;
65 DIR *dir = (DIR *) malloc (sizeof (DIR));
67 if (!dir) {
68 errno = ENOMEM;
69 return 0;
72 unsigned l = strlen (name);
74 if (l > NAME_MAX)
75 l = NAME_MAX;
77 memcpy (dir->name, name, l);
78 dir->name[l] = '\0';
80 unsigned id, m;
82 /* count entries in dir structure */
83 for (id = 0; ent[id].next; id ++);
85 m = id + 1;
87 dir->entry = (struct dirent *) malloc (sizeof (struct dirent) * (m + 1));
89 if (!dir->entry) {
90 free (dir);
91 errno = ENOMEM;
92 return 0;
95 /* create entires as dirents */
96 for (id = 0; id < m; id ++) {
97 dir->entry[id].d_ino = 0; /* TODO */
98 dir->entry[id].d_off = id * sizeof (struct dirent);
99 dir->entry[id].d_reclen = sizeof (struct dirent);
101 if (!ent[id].name)
102 continue;
104 l = strlen (ent[id].name);
106 if (l > NAME_MAX)
107 l = NAME_MAX;
109 memcpy (dir->entry[id].d_name, ent[id].name, l);
110 dir->entry[id].d_name[l] = '\0';
113 /* create last entry as eof */
114 dir->entry[m].d_ino = -1;
115 dir->entry[m].d_off = m * sizeof (struct dirent);
116 dir->entry[m].d_reclen = 0;
117 dir->entry[m].d_name[0] = '\0';
119 return dir;