XINU
device
lfs
lfsopen.c
Go to the documentation of this file.
1
/* lfsopen.c - lfsopen */
2
3
#include <
xinu.h
>
4
5
/*------------------------------------------------------------------------
6
* lfsopen - Open a file and allocate a local file pseudo-device
7
*------------------------------------------------------------------------
8
*/
9
devcall
lfsopen
(
10
struct
dentry
*devptr,
/* Entry in device switch table */
11
char
*name,
/* Name of file to open */
12
char
*mode
/* Mode chars: 'r' 'w' 'o' 'n' */
13
)
14
{
15
struct
lfdir
*dirptr;
/* Ptr to in-memory directory */
16
char
*from, *to;
/* Ptrs used during copy */
17
char
*nam, *cmp;
/* Ptrs used during comparison */
18
int32
i;
/* General loop index */
19
did32
lfnext;
/* Minor number of an unused */
20
/* file pseudo-device */
21
struct
ldentry
*ldptr;
/* Ptr to an entry in directory */
22
struct
lflcblk
*lfptr;
/* Ptr to open file table entry */
23
bool8
found;
/* Was the name found? */
24
int32
retval;
/* Value returned from function */
25
int32
mbits;
/* Mode bits */
26
27
/* Check length of name file (leaving space for NULLCH */
28
29
from = name;
30
for
(i=0; i<
LF_NAME_LEN
; i++) {
31
if
(*from++ ==
NULLCH
) {
32
break
;
33
}
34
}
35
if
(i >= LF_NAME_LEN) {
/* Name is too long */
36
return
SYSERR
;
37
}
38
39
/* Parse mode argument and convert to binary */
40
41
mbits =
lfgetmode
(mode);
42
if
(mbits ==
SYSERR
) {
43
return
SYSERR
;
44
}
45
46
/* If named file is already open, return SYSERR */
47
48
lfnext =
SYSERR
;
49
for
(i=0; i<
Nlfl
; i++) {
/* Search file pseudo-devices */
50
lfptr = &
lfltab
[i];
51
if
(lfptr->
lfstate
==
LF_FREE
) {
52
if
(lfnext ==
SYSERR
) {
53
lfnext = i;
/* Record index */
54
}
55
continue
;
56
}
57
58
/* Compare requested name to name of open file */
59
60
nam = name;
61
cmp = lfptr->
lfname
;
62
while
(*nam !=
NULLCH
) {
63
if
(*nam != *cmp) {
64
break
;
65
}
66
nam++;
67
cmp++;
68
}
69
70
/* See if comparison succeeded */
71
72
if
( (*nam==
NULLCH
) && (*cmp ==
NULLCH
) ) {
73
return
SYSERR
;
74
}
75
}
76
if
(lfnext ==
SYSERR
) {
/* No slave file devices are available */
77
return
SYSERR
;
78
}
79
80
/* Obtain copy of directory if not already present in memory */
81
82
dirptr = &
Lf_data
.
lf_dir
;
83
wait
(
Lf_data
.
lf_mutex
);
84
if
(!
Lf_data
.
lf_dirpresent
) {
85
retval =
read
(
Lf_data
.
lf_dskdev
,(
char
*)dirptr,
LF_AREA_DIR
);
86
if
(retval ==
SYSERR
) {
87
signal
(
Lf_data
.
lf_mutex
);
88
return
SYSERR
;
89
}
90
if
(
lfscheck
(dirptr) ==
SYSERR
) {
91
kprintf
(
"Disk does not contain a Xinu file system\n"
);
92
signal
(
Lf_data
.
lf_mutex
);
93
return
SYSERR
;
94
}
95
Lf_data
.
lf_dirpresent
=
TRUE
;
96
}
97
98
/* Search directory to see if file exists */
99
100
found =
FALSE
;
101
for
(i=0; i<dirptr->
lfd_nfiles
; i++) {
102
ldptr = &dirptr->
lfd_files
[i];
103
nam = name;
104
cmp = ldptr->
ld_name
;
105
while
(*nam !=
NULLCH
) {
106
if
(*nam != *cmp) {
107
break
;
108
}
109
nam++;
110
cmp++;
111
}
112
if
( (*nam==
NULLCH
) && (*cmp==
NULLCH
) ) {
/* Name found */
113
found =
TRUE
;
114
break
;
115
}
116
}
117
118
/* Case #1 - file is not in directory (i.e., does not exist) */
119
120
if
(! found) {
121
if
(mbits &
LF_MODE_O
) {
/* File *must* exist */
122
signal
(
Lf_data
.
lf_mutex
);
123
return
SYSERR
;
124
}
125
126
/* Take steps to create new file and add to directory */
127
128
/* Verify that space remains in the directory */
129
130
if
(dirptr->
lfd_nfiles
>=
LF_NUM_DIR_ENT
) {
131
signal
(
Lf_data
.
lf_mutex
);
132
return
SYSERR
;
133
}
134
135
/* Allocate next dir. entry & initialize to empty file */
136
137
ldptr = &dirptr->
lfd_files
[dirptr->
lfd_nfiles
++];
138
ldptr->
ld_size
= 0;
139
from = name;
140
to = ldptr->
ld_name
;
141
while
( (*to++ = *from++) !=
NULLCH
) {
142
;
143
}
144
ldptr->
ld_ilist
=
LF_INULL
;
145
146
/* Case #2 - file is in directory (i.e., already exists) */
147
148
}
else
if
(mbits &
LF_MODE_N
) {
/* File must not exist */
149
signal
(
Lf_data
.
lf_mutex
);
150
return
SYSERR
;
151
}
152
153
/* Initialize the local file pseudo-device */
154
155
lfptr = &
lfltab
[lfnext];
156
lfptr->
lfstate
=
LF_USED
;
157
lfptr->
lfdirptr
= ldptr;
/* Point to directory entry */
158
lfptr->
lfmode
= mbits &
LF_MODE_RW
;
159
160
/* File starts at position 0 */
161
162
lfptr->
lfpos
= 0;
163
164
to = lfptr->
lfname
;
165
from = name;
166
while
( (*to++ = *from++) !=
NULLCH
) {
167
;
168
}
169
170
/* Neither index block nor data block are initially valid */
171
172
lfptr->
lfinum
=
LF_INULL
;
173
lfptr->
lfdnum
=
LF_DNULL
;
174
175
/* Initialize byte pointer to address beyond the end of the */
176
/* buffer (i.e., invalid pointer triggers setup) */
177
178
lfptr->
lfbyte
= &lfptr->
lfdblock
[
LF_BLKSIZ
];
179
lfptr->
lfibdirty
=
FALSE
;
180
lfptr->
lfdbdirty
=
FALSE
;
181
182
signal
(
Lf_data
.
lf_mutex
);
183
184
return
lfptr->
lfdev
;
185
}
kprintf
syscall kprintf(char *fmt,...)
ポーリングI/Oを使用して、フォーマットされた文字列をコンソールに出力する。
Definition:
kprintf.c:98
lfdir::lfd_files
struct ldentry lfd_files[LF_NUM_DIR_ENT]
Definition:
lfilesys.h:123
lflcblk::lfbyte
char * lfbyte
Definition:
lfilesys.h:161
lflcblk::lfdirptr
struct ldentry * lfdirptr
Definition:
lfilesys.h:147
Nlfl
#define Nlfl
Definition:
conf.h:70
lfsopen
devcall lfsopen(struct dentry *devptr, char *name, char *mode)
Definition:
lfsopen.c:9
ldentry::ld_ilist
ibid32 ld_ilist
Definition:
lfilesys.h:99
lfdata::lf_mutex
sid32 lf_mutex
Definition:
lfilesys.h:132
xinu.h
全てのシステムヘッダファイルをインクルードする。
SYSERR
#define SYSERR
処理が失敗した場合
Definition:
kernel.h:79
lflcblk
Definition:
lfilesys.h:142
Lf_data
struct lfdata Lf_data
Definition:
lfsinit.c:5
LF_USED
#define LF_USED
Definition:
lfilesys.h:53
read
syscall read(did32, char *, uint32)
Definition:
read.c:9
lfdata::lf_dskdev
did32 lf_dskdev
Definition:
lfilesys.h:131
lfltab
struct lflcblk lfltab[]
Definition:
lflinit.c:5
LF_NAME_LEN
#define LF_NAME_LEN
Definition:
lfilesys.h:49
lfdir
Definition:
lfilesys.h:114
bool8
byte bool8
Boolean値
Definition:
kernel.h:36
LF_MODE_O
#define LF_MODE_O
Definition:
lfilesys.h:45
lfdata::lf_dirpresent
bool8 lf_dirpresent
Definition:
lfilesys.h:135
LF_INULL
#define LF_INULL
Definition:
lfilesys.h:55
LF_AREA_DIR
#define LF_AREA_DIR
Definition:
lfilesys.h:67
dentry
Definition:
conf.h:6
lflcblk::lfname
char lfname[LF_NAME_LEN]
Definition:
lfilesys.h:152
lflcblk::lfinum
ibid32 lfinum
Definition:
lfilesys.h:153
LF_BLKSIZ
#define LF_BLKSIZ
Definition:
lfilesys.h:48
lfdata::lf_dir
struct lfdir lf_dir
Definition:
lfilesys.h:134
ldentry::ld_name
char ld_name[LF_NAME_LEN]
Definition:
lfilesys.h:101
LF_MODE_N
#define LF_MODE_N
Definition:
lfilesys.h:46
FALSE
#define FALSE
Boolean False(0)
Definition:
kernel.h:63
lflcblk::lfstate
byte lfstate
Definition:
lfilesys.h:144
TRUE
#define TRUE
Boolean True(1)
Definition:
kernel.h:65
ldentry
Definition:
lfilesys.h:96
lflcblk::lfdnum
dbid32 lfdnum
Definition:
lfilesys.h:157
ldentry::ld_size
uint32 ld_size
Definition:
lfilesys.h:98
lflcblk::lfdbdirty
bool8 lfdbdirty
Definition:
lfilesys.h:166
int32
int int32
符号あり32ビット整数(int)
Definition:
kernel.h:11
LF_DNULL
#define LF_DNULL
Definition:
lfilesys.h:56
lfdir::lfd_nfiles
int32 lfd_nfiles
Definition:
lfilesys.h:122
did32
int32 did32
デバイスID
Definition:
kernel.h:28
LF_FREE
#define LF_FREE
Definition:
lfilesys.h:52
lflcblk::lfdev
did32 lfdev
Definition:
lfilesys.h:145
lflcblk::lfmode
int32 lfmode
Definition:
lfilesys.h:149
lflcblk::lfibdirty
bool8 lfibdirty
Definition:
lfilesys.h:165
wait
syscall wait(sid32)
Definition:
wait.c:9
signal
syscall signal(sid32)
セマフォにシグナルを送り、待機プロセスがある場合は解除する。
Definition:
signal.c:18
lflcblk::lfpos
uint32 lfpos
Definition:
lfilesys.h:150
lflcblk::lfdblock
char lfdblock[LF_BLKSIZ]
Definition:
lfilesys.h:159
lfscheck
status lfscheck(struct lfdir *)
Definition:
lfscheck.c:10
devcall
int32 devcall
デバイスコール関数 返り値の型
Definition:
kernel.h:49
lfgetmode
int32 lfgetmode(char *)
Definition:
lfgetmode.c:9
LF_MODE_RW
#define LF_MODE_RW
Definition:
lfilesys.h:44
NULLCH
#define NULLCH
NULL文字(NULL終端)
Definition:
kernel.h:70
LF_NUM_DIR_ENT
#define LF_NUM_DIR_ENT
Definition:
lfilesys.h:50
Generated by
1.8.13