📄 rsinit.c
字号:
/***********************************************************************/
/* */
/* Module: rsinit.c */
/* Release: 2004.5 */
/* Version: 2003.0 */
/* Purpose: Initialization functions for RAM file system */
/* */
/*---------------------------------------------------------------------*/
/* */
/* Copyright 2004, Blunk Microsystems */
/* ALL RIGHTS RESERVED */
/* */
/* Licensees have the non-exclusive right to use, modify, or extract */
/* this computer program for software development at a single site. */
/* This program may be resold or disseminated in executable format */
/* only. The source code may not be redistributed or resold. */
/* */
/***********************************************************************/
#include "ramfsp.h"
#if NUM_RFS_VOLS
/***********************************************************************/
/* Global Variable Declarations */
/***********************************************************************/
SEM RamSem;
RamGlob *Ram;
RamGlob RamGlobals[NUM_RFS_VOLS];
/***********************************************************************/
/* Local Function Definitions */
/***********************************************************************/
/***********************************************************************/
/* free_files: Clear memory associated with files in a table */
/* */
/* Input: table = pointer to files table */
/* */
/***********************************************************************/
static void free_files(const RFSEnts *table)
{
int i;
RamSect *curr_sect, *next_sect;
/*-------------------------------------------------------------------*/
/* For each file, free its sector list. */
/*-------------------------------------------------------------------*/
for (i = 0; i < FNUM_ENT; ++i)
if (table->tbl[i].type == FCOMMN)
{
for (curr_sect = (RamSect *)table->tbl[i].entry.comm.frst_sect;
curr_sect;)
{
next_sect = curr_sect->next;
free(curr_sect);
curr_sect = next_sect;
}
}
}
/***********************************************************************/
/* Global Function Definitions */
/***********************************************************************/
/***********************************************************************/
/* GetRamTable: Allocate new RAM file system table */
/* */
/* Returns: pointer to allocated table or NULL on error */
/* */
/***********************************************************************/
RFSEnts *GetRamTable(void)
{
RFSEnts *r_value = malloc(sizeof(RFSEnts));
int i;
/*-------------------------------------------------------------------*/
/* If malloc() succeeded, allocate new table. */
/*-------------------------------------------------------------------*/
if (r_value)
{
r_value->next_tbl = NULL;
r_value->free = FNUM_ENT - 1;
/*-----------------------------------------------------------------*/
/* Empty out all the table. */
/*-----------------------------------------------------------------*/
for (i = 0; i < FNUM_ENT; ++i)
r_value->tbl[i].type = FEMPTY;
}
else
set_errno(ENOSPC);
return r_value;
}
/***********************************************************************/
/* RfsModule: RAM file system interface to software object manager */
/* */
/* Input: req = module request code */
/* ... = additional parameters specific to request */
/* */
/***********************************************************************/
void *RfsModule(int req, ...)
{
void *r_value = NULL;
va_list ap;
char *device;
int i, v;
RamGlob *vol;
switch (req)
{
case kInitMod:
{
/*---------------------------------------------------------------*/
/* Allocate the synchronization mechanism data structures. */
/*---------------------------------------------------------------*/
RamSem = semCreate("RAM_SEM", 1, OS_FIFO);
if (RamSem == NULL)
r_value = (void *)-1;
/*---------------------------------------------------------------*/
/* Mark all potential volume holders as empty. */
/*---------------------------------------------------------------*/
for (i = 0; i < NUM_RFS_VOLS; ++i)
RamGlobals[i].num_sects = (ui32)-1;
break;
}
case kFormat:
{
RFSEnts *temp_table, *prev_table;
RFSEnt *curr_dir;
ui32 dummy;
/*---------------------------------------------------------------*/
/* Use the va_arg mechanism to fetch the device name. */
/*---------------------------------------------------------------*/
va_start(ap, req);
device = va_arg(ap, char *);
va_end(ap);
/*---------------------------------------------------------------*/
/* Go through all the existing volumes (mounted and not mounted) */
/* and if any has the given name, format it. */
/*---------------------------------------------------------------*/
for (v = 0; v < NUM_RFS_VOLS; ++v)
{
vol = &RamGlobals[v];
/*-------------------------------------------------------------*/
/* If this entry contains a valid volume and the names match, */
/* format the volume. */
/*-------------------------------------------------------------*/
if (vol->num_sects != (ui32)-1 && !strcmp(device, vol->sys.name))
{
/*-----------------------------------------------------------*/
/* Acquire exclusive access to RAM. */
/*-----------------------------------------------------------*/
semPend(RamSem, WAIT_FOREVER);
/*-----------------------------------------------------------*/
/* If there are more than one FileTables, delete the rest. */
/*-----------------------------------------------------------*/
FsReadCWD(&dummy, (void *)&curr_dir);
for (temp_table = vol->files_tbl->next_tbl; temp_table;)
{
/*---------------------------------------------------------*/
/* If the current directory is in this table set it to */
/* first entry for this volume, the root directory. */
/*---------------------------------------------------------*/
if (curr_dir >= &temp_table->tbl[0] &&
curr_dir <= &temp_table->tbl[FNUM_ENT])
{
++vol->files_tbl->tbl[0].entry.dir.cwds;
FsSaveCWD(dummy, (ui32)&vol->files_tbl->tbl[0]);
}
/*---------------------------------------------------------*/
/* Free all sectors from all files in this table. */
/*---------------------------------------------------------*/
free_files(temp_table);
/*---------------------------------------------------------*/
/* Free table. */
/*---------------------------------------------------------*/
prev_table = temp_table;
temp_table = temp_table->next_tbl;
free(prev_table);
}
vol->files_tbl->next_tbl = NULL;
/*-----------------------------------------------------------*/
/* Set all FileTable entries to empty, except for first two. */
/*-----------------------------------------------------------*/
free_files(vol->files_tbl);
for (i = 2; i < FNUM_ENT; ++i)
{
vol->files_tbl->tbl[i].type = FEMPTY;
/*---------------------------------------------------------*/
/* If the current directory is this entry, set it to first */
/* entry in the table, the root directory. */
/*---------------------------------------------------------*/
if (curr_dir == &vol->files_tbl->tbl[i])
{
++vol->files_tbl->tbl[0].entry.dir.cwds;
FsSaveCWD(dummy, (ui32)&vol->files_tbl->tbl[0]);
}
}
vol->total_free = FNUM_ENT - 2;
/*-----------------------------------------------------------*/
/* Set the root dir's first entry to NULL. */
/*-----------------------------------------------------------*/
vol->files_tbl->tbl[0].entry.dir.first = NULL;
/*-----------------------------------------------------------*/
/* Release exclusive access to RAM. */
/*-----------------------------------------------------------*/
semPost(RamSem);
/*-----------------------------------------------------------*/
/* If volume is not mounted, just return success. */
/*-----------------------------------------------------------*/
if ((vol->sys.next == NULL) && (vol->sys.prev == NULL) &&
(&vol->sys != MountedList.head))
return (void *)1;
/*-----------------------------------------------------------*/
/* Make sure no FILE* or DIR* is associated with the system. */
/*-----------------------------------------------------------*/
for (i = 0; i < FOPEN_MAX; ++i)
{
/*---------------------------------------------------------*/
/* If a FILE is associated with this volume, clear it. */
/*---------------------------------------------------------*/
if (Files[i].volume == vol)
{
Files[i].ioctl = NULL;
Files[i].volume = NULL;
Files[i].handle = Files[i].cached = NULL;
}
}
r_value = (void *)1;
}
}
break;
}
case kVolName:
{
/*---------------------------------------------------------------*/
/* Use the va_arg mechanism to fetch the name to look for. */
/*---------------------------------------------------------------*/
va_start(ap, req);
device = va_arg(ap, char *);
va_end(ap);
/*---------------------------------------------------------------*/
/* Look for name duplication. */
/*---------------------------------------------------------------*/
for (i = 0; i < NUM_RFS_VOLS; ++i)
if (RamGlobals[i].num_sects != (ui32)-1 &&
!strcmp(device, RamGlobals[i].sys.name))
{
set_errno(EEXIST);
r_value = (void *)-1;
break;
}
break;
}
case kMount:
{
char **device_name;
/*---------------------------------------------------------------*/
/* Use the va_arg mechanism to fetch the device name. */
/*---------------------------------------------------------------*/
va_start(ap, req);
device = va_arg(ap, char *);
device_name = va_arg(ap, char **);
va_end(ap);
/*---------------------------------------------------------------*/
/* Look for the device name among the RAM volumes. */
/*---------------------------------------------------------------*/
for (v = 0; v < NUM_RFS_VOLS; ++v)
{
Ram = &RamGlobals[v];
/*-------------------------------------------------------------*/
/* If matching entry found, mount it. */
/*-------------------------------------------------------------*/
if (Ram->num_sects != (ui32)-1 &&
((device == NULL || !strcmp(device, Ram->sys.name)) &&
Ram->sys.prev == NULL && Ram->sys.next == NULL &&
&Ram->sys != MountedList.head))
{
*device_name = Ram->sys.name;
r_value = &Ram->sys;
break;
}
}
break;
}
default:
break;
}
return r_value;
}
/***********************************************************************/
/* RamNewSect: Allocate space for new sector and add it to file */
/* */
/* Input: entry = file entry */
/* */
/* Returns: 0 on success, -1 on failure */
/* */
/***********************************************************************/
int RamNewSect(RCOM_T *entry)
{
RamSect *new_sect;
int i;
/*-------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -