#include <types.h>
#include <lib.h>
#include <kern/errno.h>
#include <filedesc.h>
int
fd_attach( struct filedesc *fdesc, struct file *f, int *fd ) {
int i = 0;
FD_LOCK( fdesc );
for( i = 0; i < MAX_OPEN_FILES; ++i ) {
if( fdesc->fd_ofiles[i] == NULL ) {
fdesc->fd_ofiles[i] = f;
fdesc->fd_nfiles++;
*fd = i;
FD_UNLOCK( fdesc );
return 0;
}
}
FD_UNLOCK( fdesc );
return ENFILE;
}
void
fd_detach( struct filedesc *fdesc, int fd ) {
FD_LOCK( fdesc );
fdesc->fd_ofiles[fd] = NULL;
fdesc->fd_nfiles--;
FD_UNLOCK( fdesc );
}
void
fd_destroy( struct filedesc *fdesc ) {
KASSERT( fdesc->fd_nfiles == 0 );
lock_destroy( fdesc->fd_lk );
kfree( fdesc );
}
int
fd_create( struct filedesc **fdesc ) {
struct filedesc *fd = NULL;
int i = 0;
fd = kmalloc( sizeof( struct filedesc ) );
if( fd == NULL )
return ENOMEM;
fd->fd_lk = lock_create( "fd_lk" );
if( fd->fd_lk == NULL ) {
kfree( fd );
return ENOMEM;
}
for( i = 0; i < MAX_OPEN_FILES; ++i )
fd->fd_ofiles[i] = NULL;
fd->fd_nfiles = 0;
*fdesc = fd;
return 0;
}
int
fd_attach_into( struct filedesc *fdesc, struct file *f, int fd ) {
FD_LOCK( fdesc );
if( fdesc->fd_ofiles[fd] != NULL ) {
FD_UNLOCK( fdesc );
return EMFILE;
}
fdesc->fd_ofiles[fd] = f;
fdesc->fd_nfiles++;
FD_UNLOCK( fdesc );
return 0;
}
void
fd_clone( struct filedesc *source, struct filedesc *fdesc ) {
struct file *f = NULL;
int i = 0;
FD_LOCK( source );
for( i = 0; i < MAX_OPEN_FILES; ++i ) {
if( source->fd_ofiles[i] != NULL ) {
f = source->fd_ofiles[i];
F_LOCK( f );
fdesc->fd_ofiles[i] = f;
fdesc->fd_nfiles++;
f->f_refcount++;
VOP_INCREF( f->f_vnode );
F_UNLOCK( f );
}
}
KASSERT( source->fd_nfiles == fdesc->fd_nfiles );
FD_UNLOCK( source );
}