XINU
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  */
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;
84  if (! Lf_data.lf_dirpresent) {
85  retval = read(Lf_data.lf_dskdev,(char *)dirptr,LF_AREA_DIR);
86  if (retval == SYSERR ) {
88  return SYSERR;
89  }
90  if (lfscheck(dirptr) == SYSERR ) {
91  kprintf("Disk does not contain a Xinu file system\n");
93  return SYSERR;
94  }
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 */
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) {
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 */
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 
183 
184  return lfptr->lfdev;
185 }
syscall kprintf(char *fmt,...)
ポーリングI/Oを使用して、フォーマットされた文字列をコンソールに出力する。
Definition: kprintf.c:98
struct ldentry lfd_files[LF_NUM_DIR_ENT]
Definition: lfilesys.h:123
char * lfbyte
Definition: lfilesys.h:161
struct ldentry * lfdirptr
Definition: lfilesys.h:147
#define Nlfl
Definition: conf.h:70
devcall lfsopen(struct dentry *devptr, char *name, char *mode)
Definition: lfsopen.c:9
ibid32 ld_ilist
Definition: lfilesys.h:99
sid32 lf_mutex
Definition: lfilesys.h:132
全てのシステムヘッダファイルをインクルードする。
#define SYSERR
処理が失敗した場合
Definition: kernel.h:79
struct lfdata Lf_data
Definition: lfsinit.c:5
#define LF_USED
Definition: lfilesys.h:53
syscall read(did32, char *, uint32)
Definition: read.c:9
did32 lf_dskdev
Definition: lfilesys.h:131
struct lflcblk lfltab[]
Definition: lflinit.c:5
#define LF_NAME_LEN
Definition: lfilesys.h:49
byte bool8
Boolean値
Definition: kernel.h:36
#define LF_MODE_O
Definition: lfilesys.h:45
bool8 lf_dirpresent
Definition: lfilesys.h:135
#define LF_INULL
Definition: lfilesys.h:55
#define LF_AREA_DIR
Definition: lfilesys.h:67
Definition: conf.h:6
char lfname[LF_NAME_LEN]
Definition: lfilesys.h:152
ibid32 lfinum
Definition: lfilesys.h:153
#define LF_BLKSIZ
Definition: lfilesys.h:48
struct lfdir lf_dir
Definition: lfilesys.h:134
char ld_name[LF_NAME_LEN]
Definition: lfilesys.h:101
#define LF_MODE_N
Definition: lfilesys.h:46
#define FALSE
Boolean False(0)
Definition: kernel.h:63
byte lfstate
Definition: lfilesys.h:144
#define TRUE
Boolean True(1)
Definition: kernel.h:65
dbid32 lfdnum
Definition: lfilesys.h:157
uint32 ld_size
Definition: lfilesys.h:98
bool8 lfdbdirty
Definition: lfilesys.h:166
int int32
符号あり32ビット整数(int)
Definition: kernel.h:11
#define LF_DNULL
Definition: lfilesys.h:56
int32 lfd_nfiles
Definition: lfilesys.h:122
int32 did32
デバイスID
Definition: kernel.h:28
#define LF_FREE
Definition: lfilesys.h:52
did32 lfdev
Definition: lfilesys.h:145
int32 lfmode
Definition: lfilesys.h:149
bool8 lfibdirty
Definition: lfilesys.h:165
syscall wait(sid32)
Definition: wait.c:9
syscall signal(sid32)
セマフォにシグナルを送り、待機プロセスがある場合は解除する。
Definition: signal.c:18
uint32 lfpos
Definition: lfilesys.h:150
char lfdblock[LF_BLKSIZ]
Definition: lfilesys.h:159
status lfscheck(struct lfdir *)
Definition: lfscheck.c:10
int32 devcall
デバイスコール関数 返り値の型
Definition: kernel.h:49
int32 lfgetmode(char *)
Definition: lfgetmode.c:9
#define LF_MODE_RW
Definition: lfilesys.h:44
#define NULLCH
NULL文字(NULL終端)
Definition: kernel.h:70
#define LF_NUM_DIR_ENT
Definition: lfilesys.h:50