Subversion Repositories shark

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Project: HARTIK (HA-rd R-eal TI-me K-ernel)
 *
 * Coordinators: Giorgio Buttazzo <giorgio@sssup.it>
 *               Gerardo Lamastra <gerardo@sssup.it>
 *
 * Authors     : Massimiliano Giorgi <massy@hartik.sssup.it>
 * (see authors.txt for full list of hartik's authors)
 *
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
 *
 * http://www.sssup.it
 * http://retis.sssup.it
 * http://hartik.sssup.it
 */


/*
 * Copyright (C) 1999 Massimiliano Giorgi
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */


/*
 * CVS :        $Id: file.c,v 1.1.1.1 2002-03-29 14:12:50 pj Exp $
 *
 * File:        $File$
 * Revision:    $Revision: 1.1.1.1 $
 * Last update: $Date: 2002-03-29 14:12:50 $
 */


#include <fs/fsconf.h>
#include <fs/util.h>
#include <fs/types.h>
#include <fs/fcntl.h>
#include <fs/stat.h>
#include <fs/errno.h>
#include <fs/maccess.h>
#include <fs/limits.h>
#include <fs/task.h>

#include "mutex.h"
#include "fs.h"
#include "file.h"
#include "fsconst.h"
#include "dentry.h"
#include "fileop.h"
#include "inode.h"
#include "inodeop.h"

#include "debug.h"

/* OSKit stdio need this */
int getdtablesize(void)
{
  return MAXOPENFILES;
}

/*-----------*/

//#if !defined GLOB_DESC_TABLE
//#if !defined LOC_DESC_TABLE
//#error "GLOB_DESC_TABLE or LOC_DESC_TABLE must be defined! (see fsconfig.h)"
//#endif
//#else
//#if defined LOC_DESC_TABLE
//#error "GLOB_DESC_TABLE and LOC_DESC_TABLE are defined! (see fsconfig.h)"
//#endif
//#endif

/*-----------*/

//static __fs_mutex_t mutex;
static __fs_mutex_t mutexreq;

static struct file *freelist;
static struct file filetab[MAXSYSFILE];

//#ifdef GLOB_DESC_TABLE
//#include "fileg.inc"
//#else
//#include "filel.inc"
//#endif

struct file_descriptors desctable[MAXIMUMPROCESS];

int get_fd(__pid_t pid, struct file *f)
{
  int i;
  lock_desctable(pid);
  for (i=0;i<MAXOPENFILES;i++)
    if (desctable[pid].fd_file[i]==NULL) {
      desctable[pid].fd_file[i]=f;
      desctable[pid].fd_file[i]->f_count=1;
      desctable[pid].fd_flags[i]=0;
      desctable[pid].fd_fflags[i]=0;
      unlock_desctable(pid);
      return i;
    }
  unlock_desctable(pid);
  return -1;
}

int __duplicate_fd(__pid_t pid, int fd, int low)
{
  while (low<MAXOPENFILES) {
    if (desctable[pid].fd_file[low]==NULL) {
      desctable[pid].fd_file[low]=desctable[pid].fd_file[fd];
      desctable[pid].fd_file[fd]->f_count++;
      return low;
    }
    low++;
  }
  return -1;
}


int __isvalid_fd(__pid_t pid, int fd)
{
  return desctable[pid].fd_file[fd]!=NULL;
}


struct file *free_fd(__pid_t pid, int fd)
{
  struct file *ret;
  lock_desctable(pid);
  ret=desctable[pid].fd_file[fd];
  desctable[pid].fd_file[fd]=NULL;  
  unlock_desctable(pid);
  return ret;  
}

static int subfile_init(void)
{
  int i,j;
  for (j=0;j<MAXIMUMPROCESS;j++) {

    strcpy(desctable[j].fd_cwd,ROOTDIRNAME);
    desctable[j].fd_cwden=get_root_dentry();
    get_root_dentry()->d_lock++;
    desctable[j].fd_umask=__DEFUMASK;

    /* TO FIX : 0,1,2 are reserved file descriptors */
    /*
    desctable[j].fd_file[0]=(void*)(-1);
    desctable[j].fd_flags[0]=0;
    desctable[j].fd_fflags[0]=0;
    desctable[j].fd_file[1]=(void*)(-1);
    desctable[j].fd_flags[1]=0;
    desctable[j].fd_fflags[1]=0;
    desctable[j].fd_file[2]=(void*)(-1);
    desctable[j].fd_flags[2]=0;
    desctable[j].fd_fflags[2]=0;
    */

    for (i=0;i<MAXOPENFILES;i++) {
      desctable[j].fd_file[i]=NULL;
      desctable[j].fd_flags[i]=0;
      desctable[j].fd_fflags[i]=0;
    }

   
    init_mutex(j);
  }
 
  return 0;
}

/*-----------*/

/*
 * DANGER: must be called AFTER the mounting of the root device!
 * because the subfile_init() use get_root_dentry()
 */


int file_init(void)
{
  int i;
  //__fs_mutex_init(&mutex);
  __fs_mutex_init(&mutexreq);
  freelist=filetab;
  for (i=0;i<MAXSYSFILE;i++) {
    memset(filetab+i,0,sizeof(struct file));
    filetab[i].f_next=filetab+i+1;
    filetab[i].f_count=0;
  }
  filetab[MAXSYSFILE-1].f_next=NULL;

  return subfile_init();  
}

/**/

struct file *__get_file(void)
{
  struct file *f;
  if (freelist==NULL) return NULL;    
  f=freelist;
  freelist=f->f_next;
  _assert(f->f_count==0);
  f->f_count=1;
  return f;
}

/* get a file struct from the free queue */
struct file *get_file(struct inode *ptr)
{
  /* NB: ptr is not used yet */
  struct file *f;
  __fs_mutex_lock(&mutexreq);
  //cprintf("Û{");
  f=__get_file();
  __fs_mutex_unlock(&mutexreq);
  //cprintf("Û}");
  return f;
}

/**/

static void __free_file(struct file *f)
{
  _assert(f->f_count==1);
  f->f_count=0;
  f->f_next=freelist;
  freelist=f;
}

/* insert file struct into the free queue */
void free_file(struct file *f)
{
  __fs_mutex_lock(&mutexreq);
  //cprintf("Û{");
  __free_file(f);
  __fs_mutex_unlock(&mutexreq);
  //cprintf("Û}");
}

/* enumerate all files */
void enums_file(void (*func)(struct file *))
{
  int i;
  __fs_mutex_lock(&mutexreq);
  //cprintf("Û{");
  for (i=0;i<MAXSYSFILE;i++)
    if (filetab[i].f_count!=0) func(filetab+i);
  __fs_mutex_unlock(&mutexreq);
  //cprintf("Û}");
}


/*
 *
 * DUMMY file operations
 *
 */


__off_t dummy_lseek(struct file *f, __off_t off, int whence)
{
  return -ENOSYS;
}

__ssize_t dummy_read(struct file *f, char *p, __ssize_t d)
{
  return -ENOSYS;
}

__ssize_t dummy_write(struct file *f, char *p, __ssize_t d)
{
  return -ENOSYS;
}

int dummy_readdir(struct file *f, void *e)
{
  return -ENOSYS;
}

int dummy_open(struct inode *i, struct file *f)
{
  return -ENOSYS;
}

int dummy_close(struct inode *i, struct file *f)
{
  return -ENOSYS;
}

/*
 *
 * for function inlines
 *
 *
 */


#ifdef MULTITHREAD

void lock_desctable(__pid_t pid)
{
  __mutex_lock(&desctable[pid].fd_mutex);
}

void unlock_desctable(__pid_t pid)
{
  __mutex_unlock(&desctable[pid].fd_mutex);
}

void init_mutex(__pid_t pid)
{
  __mutex_init(&desctable[pid].fd_mutex,fsmutexattr);
}

#else

void lock_desctable(__pid_t pid)
{}

void unlock_desctable(__pid_t pid)
{}

void init_mutex(__pid_t pid)
{}

#endif

__mode_t *umask_ptr(__pid_t pid)
{
  return &desctable[pid].fd_umask;
}

char *cwd_ptr(__pid_t pid)
{
  return desctable[pid].fd_cwd;
}

struct dentry *cwden_ptr(__pid_t pid)
{
  return desctable[pid].fd_cwden;
}

struct file *file_ptr(__pid_t pid, int i)
{
  return desctable[pid].fd_file[i];
}