Subversion Repositories shark

Rev

Rev 3 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Paolo Gai           <pj@gandalf.sssup.it>
10
 *   Massimiliano Giorgi <massy@gandalf.sssup.it>
11
 *   Luca Abeni          <luca@gandalf.sssup.it>
12
 *   (see the web pages for full authors list)
13
 *
14
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
15
 *
16
 * http://www.sssup.it
17
 * http://retis.sssup.it
18
 * http://shark.sssup.it
19
 */
20
 
21
/*
22
 * Copyright (C) 1999 Massimiliano Giorgi
23
 *
24
 * This program is free software; you can redistribute it and/or modify
25
 * it under the terms of the GNU General Public License as published by
26
 * the Free Software Foundation; either version 2 of the License, or
27
 * (at your option) any later version.
28
 *
29
 * This program is distributed in the hope that it will be useful,
30
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32
 * GNU General Public License for more details.
33
 *
34
 * You should have received a copy of the GNU General Public License
35
 * along with this program; if not, write to the Free Software
36
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
37
 *
38
 */
39
 
40
/*
41
 * CVS :        $Id: dir.c,v 1.1.1.1 2002-03-29 14:12:53 pj Exp $
42
 *
43
 * File:        $File$
44
 * Revision:    $Revision: 1.1.1.1 $
45
 * Last update: $Date: 2002-03-29 14:12:53 $
46
 */
47
 
48
#include <features.h>
49
 
50
#include <fs/syscall.h>
51
 
52
//#define __need_FOPEN_MAX
53
//#include <bits/stdio_li.h>
54
 
55
#include <sys/types.h>
56
#include <limits.h>
57
#include <dirent.h>
58
 
59
#include "errno.h"
60
#include "mutex.h"
61
 
62
#define MAXOPENDIR 256
63
 
64
struct __dirstream {
65
  int           dir_next;
66
 
67
  int           dir_h;
68
  struct dirent dir_e;
69
 
70
  int32_t       dir_used:1;
71
  int32_t       dir_inprogress:1;
72
};
73
 
74
#define NIL -1
75
 
76
static DIR     direntry[MAXOPENDIR];
77
static int     freedirentry;
78
static _priv_mutex_t direntrymutex;
79
 
80
extern int k_opendir(const char *pathname);
81
extern int k_closedir(int fd);
82
extern int k_readdir(int fd, struct dirent *den);
83
 
84
int dir_initialize(void)
85
{
86
  int i;
87
  _priv_mutex_init(&direntrymutex);
88
 
89
  //cprintf("<mutex on %p [DIR_INITIALIZE]>",&direntrymutex);
90
 
91
  freedirentry=0;
92
  for (i=0;i<MAXOPENDIR;i++) {
93
    direntry[i].dir_next=i+1;
94
    direntry[i].dir_h=-1;
95
    direntry[i].dir_used=0;
96
    direntry[i].dir_inprogress=0;
97
  }
98
  direntry[MAXOPENDIR-1].dir_next=NIL;
99
  return 0;
100
}
101
 
102
DIR *opendir(const char *pathname)    
103
{
104
  int ind,res;
105
 
106
  _priv_mutex_lock(&direntrymutex);
107
  ind=freedirentry;
108
  if (ind!=NIL) freedirentry=direntry[ind].dir_next;
109
  _priv_mutex_unlock(&direntrymutex);
110
 
111
  if (ind==NIL) {
112
    __set_errno(EMFILE);
113
    return NULL;
114
  }
115
 
116
  res=SYS_CALL1(k_opendir,pathname);
117
 
118
  if (ISERROR(res)) {
119
 
120
    _priv_mutex_lock(&direntrymutex);
121
    direntry[ind].dir_next=freedirentry;
122
    freedirentry=ind;
123
    _priv_mutex_unlock(&direntrymutex);
124
 
125
    __set_errno(-res);
126
    return NULL;
127
  }
128
 
129
  direntry[ind].dir_h=res;
130
  direntry[ind].dir_inprogress=0;
131
  direntry[ind].dir_used=1;
132
 
133
  return direntry+ind;
134
}
135
 
136
int closedir(DIR *d)
137
{
138
  int res;
139
 
140
  if (d<direntry||d>direntry+MAXOPENDIR) {
141
    __set_errno(EBADF);
142
    return -1;
143
  }
144
 
145
  _priv_mutex_lock(&direntrymutex);
146
  if (d->dir_used==0) {
147
    _priv_mutex_unlock(&direntrymutex);
148
    __set_errno(EBADF);
149
    return -1;
150
  }
151
  if (d->dir_inprogress) {
152
    _priv_mutex_unlock(&direntrymutex);
153
    __set_errno(EBUSY);
154
    return -1;
155
  }    
156
  d->dir_used=0;
157
  _priv_mutex_unlock(&direntrymutex);
158
 
159
  res=SYS_CALL1(k_closedir,d->dir_h);
160
 
161
  if (ISERROR(res)) {
162
    d->dir_used=1;
163
    __set_errno(-res);
164
    return -1;
165
  }
166
 
167
  _priv_mutex_lock(&direntrymutex);
168
  d->dir_h=-1;
169
  d->dir_used=0;
170
  d->dir_inprogress=0;
171
  d->dir_next=freedirentry;
172
  freedirentry=d-direntry;
173
  _priv_mutex_unlock(&direntrymutex);
174
 
175
  return 0;  
176
}
177
 
178
struct dirent *readdir(DIR *d)
179
{
180
  int res;
181
 
182
  if (d<direntry||d>direntry+MAXOPENDIR) {
183
    __set_errno(EBADF);
184
    return NULL;
185
  }
186
 
187
  _priv_mutex_lock(&direntrymutex);
188
  if (!d->dir_used) {
189
    _priv_mutex_unlock(&direntrymutex);
190
    __set_errno(EBADF);
191
    return NULL;
192
  }
193
  d->dir_inprogress=1;
194
  _priv_mutex_unlock(&direntrymutex);
195
 
196
  res=SYS_CALL2(k_readdir,d->dir_h,&d->dir_e);
197
  d->dir_inprogress=0;
198
  if (res==1) return NULL;
199
 
200
  if (ISERROR(res)) {
201
    __set_errno(-res);
202
    return NULL;
203
  }
204
 
205
  return &d->dir_e;
206
}
207
 
208
int readdir_t(DIR *d,struct dirent *den, struct dirent **result)
209
{
210
  int res;
211
 
212
  if (d<direntry||d>direntry+MAXOPENDIR) {
213
    __set_errno(EBADF);
214
    return -1;
215
  }
216
 
217
  _priv_mutex_lock(&direntrymutex);
218
  if (!d->dir_used) {
219
    _priv_mutex_unlock(&direntrymutex);
220
    __set_errno(EBADF);
221
    return -1;
222
  }
223
  d->dir_inprogress=1;
224
  _priv_mutex_unlock(&direntrymutex);
225
 
226
  res=SYS_CALL2(k_readdir,d->dir_h,den);
227
  d->dir_inprogress=0;
228
 
229
  if (res==1) {
230
    *result=NULL;
231
    return 0;
232
  }
233
 
234
  if (ISERROR(res)) {
235
    __set_errno(-res);
236
    return -1;
237
  }
238
 
239
  return 0;
240
}