Minor change to path lookup that fixes the bug that creating a file
[minix3.git] / servers / vfs / filedes.c
blob2503d2a628430f9f7e12e11e615d174e31d4cbd3
1 /* This file contains the procedures that manipulate file descriptors.
3 * The entry points into this file are
4 * get_fd: look for free file descriptor and free filp slots
5 * get_filp: look up the filp entry for a given file descriptor
6 * find_filp: find a filp slot that points to a given vnode
7 * inval_filp: invalidate a filp and associated fd's, only let close()
8 * happen on it
9 */
11 #include <sys/select.h>
12 #include <minix/u64.h>
13 #include <assert.h>
15 #include "fs.h"
16 #include "file.h"
17 #include "fproc.h"
19 #include "vnode.h"
21 /*===========================================================================*
22 * get_fd *
23 *===========================================================================*/
24 PUBLIC int get_fd(int start, mode_t bits, int *k, struct filp **fpt)
26 /* Look for a free file descriptor and a free filp slot. Fill in the mode word
27 * in the latter, but don't claim either one yet, since the open() or creat()
28 * may yet fail.
31 register struct filp *f;
32 register int i;
34 /* Search the fproc fp_filp table for a free file descriptor. */
35 for (i = start; i < OPEN_MAX; i++) {
36 if (fp->fp_filp[i] == NIL_FILP && !FD_ISSET(i, &fp->fp_filp_inuse)) {
37 /* A file descriptor has been located. */
38 *k = i;
39 break;
43 /* Check to see if a file descriptor has been found. */
44 if (i >= OPEN_MAX) return(EMFILE);
46 /* Now that a file descriptor has been found, look for a free filp slot. */
47 for (f = &filp[0]; f < &filp[NR_FILPS]; f++) {
48 assert(f->filp_count >= 0);
49 if (f->filp_count == 0) {
50 f->filp_mode = bits;
51 f->filp_pos = cvu64(0);
52 f->filp_selectors = 0;
53 f->filp_select_ops = 0;
54 f->filp_pipe_select_ops = 0;
55 f->filp_flags = 0;
56 *fpt = f;
57 return(OK);
61 /* If control passes here, the filp table must be full. Report that back. */
62 return(ENFILE);
65 /*===========================================================================*
66 * get_filp *
67 *===========================================================================*/
68 PUBLIC struct filp *get_filp(fild)
69 int fild; /* file descriptor */
71 /* See if 'fild' refers to a valid file descr. If so, return its filp ptr. */
73 return get_filp2(fp, fild);
76 /*===========================================================================*
77 * get_filp2 *
78 *===========================================================================*/
79 PUBLIC struct filp *get_filp2(rfp, fild)
80 register struct fproc *rfp;
81 int fild; /* file descriptor */
83 /* See if 'fild' refers to a valid file descr. If so, return its filp ptr. */
85 err_code = EBADF;
86 if (fild < 0 || fild >= OPEN_MAX ) return(NIL_FILP);
87 return(rfp->fp_filp[fild]); /* may also be NIL_FILP */
90 /*===========================================================================*
91 * find_filp *
92 *===========================================================================*/
93 PUBLIC struct filp *find_filp(register struct vnode *vp, mode_t bits)
95 /* Find a filp slot that refers to the vnode 'vp' in a way as described
96 * by the mode bit 'bits'. Used for determining whether somebody is still
97 * interested in either end of a pipe. Also used when opening a FIFO to
98 * find partners to share a filp field with (to shared the file position).
99 * Like 'get_fd' it performs its job by linear search through the filp table.
102 register struct filp *f;
104 for (f = &filp[0]; f < &filp[NR_FILPS]; f++) {
105 if (f->filp_count != 0 && f->filp_vno == vp && (f->filp_mode & bits)){
106 assert(f->filp_count > 0);
107 return(f);
111 /* If control passes here, the filp wasn't there. Report that back. */
112 return(NIL_FILP);
115 /*===========================================================================*
116 * inval_filp *
117 *===========================================================================*/
118 PUBLIC int inval_filp(struct filp *fp)
120 int f, fd, n = 0;
121 for(f = 0; f < NR_PROCS; f++) {
122 if(fproc[f].fp_pid == PID_FREE) continue;
123 for(fd = 0; fd < OPEN_MAX; fd++) {
124 if(fproc[f].fp_filp[fd] && fproc[f].fp_filp[fd] == fp) {
125 fproc[f].fp_filp[fd] = NIL_FILP;
126 n++;
131 return n;