2005-04-21 16:53:53 +02:00
|
|
|
/* This file contains the procedures that manipulate file descriptors.
|
|
|
|
*
|
|
|
|
* The entry points into this file are
|
2006-03-09 17:00:33 +01:00
|
|
|
* get_fd: look for free file descriptor and free filp slots
|
|
|
|
* get_filp: look up the filp entry for a given file descriptor
|
|
|
|
* find_filp: find a filp slot that points to a given inode
|
|
|
|
* inval_filp: invalidate a filp and associated fd's, only let close()
|
|
|
|
* happen on it
|
2005-04-21 16:53:53 +02:00
|
|
|
*/
|
|
|
|
|
2006-03-09 17:00:33 +01:00
|
|
|
#include <sys/select.h>
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
#include "fs.h"
|
|
|
|
#include "file.h"
|
|
|
|
#include "fproc.h"
|
|
|
|
#include "inode.h"
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* get_fd *
|
|
|
|
*===========================================================================*/
|
2005-06-23 13:07:31 +02:00
|
|
|
PUBLIC int get_fd(int start, mode_t bits, int *k, struct filp **fpt)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
/* Look for a free file descriptor and a free filp slot. Fill in the mode word
|
|
|
|
* in the latter, but don't claim either one yet, since the open() or creat()
|
|
|
|
* may yet fail.
|
|
|
|
*/
|
|
|
|
|
|
|
|
register struct filp *f;
|
|
|
|
register int i;
|
|
|
|
|
|
|
|
*k = -1; /* we need a way to tell if file desc found */
|
|
|
|
|
|
|
|
/* Search the fproc fp_filp table for a free file descriptor. */
|
|
|
|
for (i = start; i < OPEN_MAX; i++) {
|
2006-03-09 17:00:33 +01:00
|
|
|
if (fp->fp_filp[i] == NIL_FILP && !FD_ISSET(i, &fp->fp_filp_inuse)) {
|
2005-04-21 16:53:53 +02:00
|
|
|
/* A file descriptor has been located. */
|
|
|
|
*k = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check to see if a file descriptor has been found. */
|
|
|
|
if (*k < 0) return(EMFILE); /* this is why we initialized k to -1 */
|
|
|
|
|
|
|
|
/* Now that a file descriptor has been found, look for a free filp slot. */
|
|
|
|
for (f = &filp[0]; f < &filp[NR_FILPS]; f++) {
|
|
|
|
if (f->filp_count == 0) {
|
|
|
|
f->filp_mode = bits;
|
|
|
|
f->filp_pos = 0L;
|
2005-06-17 15:41:12 +02:00
|
|
|
f->filp_selectors = 0;
|
|
|
|
f->filp_select_ops = 0;
|
|
|
|
f->filp_pipe_select_ops = 0;
|
2005-04-21 16:53:53 +02:00
|
|
|
f->filp_flags = 0;
|
|
|
|
*fpt = f;
|
|
|
|
return(OK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If control passes here, the filp table must be full. Report that back. */
|
|
|
|
return(ENFILE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* get_filp *
|
|
|
|
*===========================================================================*/
|
|
|
|
PUBLIC struct filp *get_filp(fild)
|
|
|
|
int fild; /* file descriptor */
|
|
|
|
{
|
2006-05-11 16:57:23 +02:00
|
|
|
/* See if 'fild' refers to a valid file descr. If so, return its filp ptr. */
|
|
|
|
|
|
|
|
return get_filp2(fp, fild);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* get_filp2 *
|
|
|
|
*===========================================================================*/
|
|
|
|
PUBLIC struct filp *get_filp2(rfp, fild)
|
|
|
|
register struct fproc *rfp;
|
|
|
|
int fild; /* file descriptor */
|
|
|
|
{
|
2005-04-21 16:53:53 +02:00
|
|
|
/* See if 'fild' refers to a valid file descr. If so, return its filp ptr. */
|
|
|
|
|
|
|
|
err_code = EBADF;
|
|
|
|
if (fild < 0 || fild >= OPEN_MAX ) return(NIL_FILP);
|
2006-05-11 16:57:23 +02:00
|
|
|
return(rfp->fp_filp[fild]); /* may also be NIL_FILP */
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* find_filp *
|
|
|
|
*===========================================================================*/
|
2005-06-23 13:07:31 +02:00
|
|
|
PUBLIC struct filp *find_filp(register struct inode *rip, mode_t bits)
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
/* Find a filp slot that refers to the inode 'rip' in a way as described
|
|
|
|
* by the mode bit 'bits'. Used for determining whether somebody is still
|
|
|
|
* interested in either end of a pipe. Also used when opening a FIFO to
|
|
|
|
* find partners to share a filp field with (to shared the file position).
|
|
|
|
* Like 'get_fd' it performs its job by linear search through the filp table.
|
|
|
|
*/
|
|
|
|
|
|
|
|
register struct filp *f;
|
|
|
|
|
|
|
|
for (f = &filp[0]; f < &filp[NR_FILPS]; f++) {
|
|
|
|
if (f->filp_count != 0 && f->filp_ino == rip && (f->filp_mode & bits)){
|
|
|
|
return(f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If control passes here, the filp wasn't there. Report that back. */
|
|
|
|
return(NIL_FILP);
|
|
|
|
}
|
2006-03-09 17:00:33 +01:00
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* inval_filp *
|
|
|
|
*===========================================================================*/
|
|
|
|
PUBLIC int inval_filp(struct filp *fp)
|
|
|
|
{
|
|
|
|
int f, fd, n = 0;
|
|
|
|
for(f = 0; f < NR_PROCS; f++) {
|
|
|
|
if(fproc[f].fp_pid == PID_FREE) continue;
|
|
|
|
for(fd = 0; fd < OPEN_MAX; fd++) {
|
|
|
|
if(fproc[f].fp_filp[fd] && fproc[f].fp_filp[fd] == fp) {
|
|
|
|
fproc[f].fp_filp[fd] = NIL_FILP;
|
2006-03-15 16:34:12 +01:00
|
|
|
n++;
|
2006-03-09 17:00:33 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|