📄 rsinit.c
字号:
/* Assign space for new sector. */
/*-------------------------------------------------------------------*/
new_sect = malloc(sizeof(RamSect));
if (new_sect == NULL)
return -1;
/*-------------------------------------------------------------------*/
/* Append new sector to end of sector list. */
/*-------------------------------------------------------------------*/
if (entry->frst_sect == NULL)
{
entry->frst_sect = new_sect;
/*-----------------------------------------------------------------*/
/* In case it is the first sector, update current FCB pointer for */
/* all the ones pointing to this file. */
/*-----------------------------------------------------------------*/
for (i = 0; i < FOPEN_MAX; ++i)
if (Files[i].ioctl == RamIoctl && Files[i].volume == Ram &&
((RFIL_T *)Files[i].handle)->comm == entry)
{
PfAssert(Files[i].curr_ptr.sector == (ui32)NULL ||
Files[i].curr_ptr.sector == SEEK_PAST_END);
Files[i].curr_ptr.sector = (ui32)new_sect;
Files[i].curr_ptr.offset = 0;
Files[i].curr_ptr.sect_off = 0;
Files[i].old_ptr = Files[i].curr_ptr;
}
}
else
((RamSect *)entry->last_sect)->next = new_sect;
new_sect->next = NULL;
new_sect->prev = (RamSect *)entry->last_sect;
entry->last_sect = new_sect;
entry->one_past_last = 0;
++Ram->num_sects;
return 0;
}
/***********************************************************************/
/* RamFreeSect: Remove last sector from a file's sector list */
/* */
/* Input: entry = file entry */
/* */
/***********************************************************************/
void RamFreeSect(RCOM_T *entry)
{
RamSect *new_last_sect;
/*-------------------------------------------------------------------*/
/* Remove last sector from sector list. */
/*-------------------------------------------------------------------*/
entry->size -= entry->one_past_last;
new_last_sect = ((RamSect *)entry->last_sect)->prev;
if (new_last_sect == NULL)
{
entry->frst_sect = NULL;
PfAssert(entry->size == 0);
}
else
{
new_last_sect->next = NULL;
entry->one_past_last = RAM_SECT_SZ;
}
free(entry->last_sect);
entry->last_sect = new_last_sect;
--Ram->num_sects;
}
/***********************************************************************/
/* RfsDelVol: Remove volume from list of RAM volumes and free up its */
/* resources */
/* */
/* Input: name = name of volume to be deleted */
/* */
/* Returns: 0 on success, -1 on error */
/* */
/***********************************************************************/
int RfsDelVol(const char *name)
{
int i;
RFSEnts *curr_tbl, *next_tbl;
/*-------------------------------------------------------------------*/
/* Acquire exclusive acess to the RAM file system. */
/*-------------------------------------------------------------------*/
semPend(RamSem, WAIT_FOREVER);
/*-------------------------------------------------------------------*/
/* Look for volume in the RamGlobals array. */
/*-------------------------------------------------------------------*/
for (i = 0;; ++i)
{
/*-----------------------------------------------------------------*/
/* If the volume was not found, return error. */
/*-----------------------------------------------------------------*/
if (i == NUM_RFS_VOLS)
{
set_errno(ENOENT);
semPost(RamSem);
return -1;
}
/*-----------------------------------------------------------------*/
/* Break if match is found. */
/*-----------------------------------------------------------------*/
if (RamGlobals[i].num_sects != (ui32)-1 &&
!strcmp(name, RamGlobals[i].sys.name))
break;
}
/*-------------------------------------------------------------------*/
/* If volume is mounted, return error. */
/*-------------------------------------------------------------------*/
if (RamGlobals[i].sys.next != NULL ||
RamGlobals[i].sys.prev != NULL ||
&RamGlobals[i].sys == MountedList.head)
{
set_errno(EBUSY);
semPost(RamSem);
return -1;
}
/*-------------------------------------------------------------------*/
/* Free up volume resources. */
/*-------------------------------------------------------------------*/
for (curr_tbl = RamGlobals[i].files_tbl; curr_tbl; curr_tbl = next_tbl)
{
next_tbl = curr_tbl->next_tbl;
curr_tbl->next_tbl = curr_tbl->prev_tbl = NULL;
free_files(curr_tbl);
free(curr_tbl);
}
RamGlobals[i].files_tbl = NULL;
/*-------------------------------------------------------------------*/
/* Reset state variables. */
/*-------------------------------------------------------------------*/
Ram->fileno_gen = Ram->total_free = 0;
Ram->num_sects = (ui32)-1;
Ram->opendirs = 0;
/*-------------------------------------------------------------------*/
/* Release exclusive acess to TargetRFS and return success. */
/*-------------------------------------------------------------------*/
semPost(RamSem);
return 0;
}
/***********************************************************************/
/* RfsAddVol: Add a new RAM volume */
/* */
/* Input: name = volume name */
/* */
/* Returns: 0 on success, -1 on error */
/* */
/***********************************************************************/
int RfsAddVol(const char *name)
{
int i, r_value = -1;
RamGlob *vol = NULL;
RFSEnt *v_ent;
Module fp;
/*-------------------------------------------------------------------*/
/* If the volume name is invalid, return error. */
/*-------------------------------------------------------------------*/
if (InvalidName(name, FALSE))
{
set_errno(EINVAL);
return r_value;
}
/*-------------------------------------------------------------------*/
/* Acquire exclusive access to upper file system. */
/*-------------------------------------------------------------------*/
semPend(FileSysSem, WAIT_FOREVER);
/*-------------------------------------------------------------------*/
/* Acquire exclusive acess to the RAM file system. */
/*-------------------------------------------------------------------*/
semPend(RamSem, WAIT_FOREVER);
/*-------------------------------------------------------------------*/
/* First look that there is no name duplication. */
/*-------------------------------------------------------------------*/
for (i = 0; ; ++i)
{
fp = ModuleList[i];
if (fp == NULL)
break;
if (fp(kVolName, name))
{
semPost(FileSysSem);
set_errno(EEXIST);
goto RamAddVol_error_exit;
}
}
/*-------------------------------------------------------------------*/
/* Release exclusive access to upper file system. */
/*-------------------------------------------------------------------*/
semPost(FileSysSem);
/*-------------------------------------------------------------------*/
/* Look for an empty entry in the RamGlobals array to place new */
/* volume controls. */
/*-------------------------------------------------------------------*/
for (i = 0;; ++i)
{
/*-----------------------------------------------------------------*/
/* If no space, set errno and go to exit. */
/*-----------------------------------------------------------------*/
if (i == NUM_RFS_VOLS)
{
set_errno(ENOMEM);
goto RamAddVol_error_exit;
}
if (RamGlobals[i].num_sects == (ui32)-1)
{
vol = &RamGlobals[i];
break;
}
}
/*-------------------------------------------------------------------*/
/* Attempt to allocate memory for the first files table. */
/*-------------------------------------------------------------------*/
vol->files_tbl = GetRamTable();
if (vol->files_tbl == NULL)
goto RamAddVol_error_exit;
/*-------------------------------------------------------------------*/
/* Set the sys node so it can later be added to the mounted list. */
/*-------------------------------------------------------------------*/
vol->sys.volume = vol;
vol->sys.ioctl = RamIoctl;
if (strlen(name) >= FILENAME_MAX)
{
set_errno(ENAMETOOLONG);
goto RamAddVol_error_exit;
}
strcpy(vol->sys.name, name);
/*-------------------------------------------------------------------*/
/* First two entries in the files table are reserved for root. */
/*-------------------------------------------------------------------*/
vol->files_tbl->free -= 1;
/*-------------------------------------------------------------------*/
/* Get pointer to the second entry in the files table. */
/*-------------------------------------------------------------------*/
v_ent = &vol->files_tbl->tbl[1];
/*-------------------------------------------------------------------*/
/* Set second entry in files table to be the file struct associated */
/* with the root directory. */
/*-------------------------------------------------------------------*/
v_ent->type = FCOMMN;
v_ent->entry.comm.open_mode = 0;
v_ent->entry.comm.links = 1;
v_ent->entry.comm.open_links = 0;
v_ent->entry.comm.frst_sect = NULL;
v_ent->entry.comm.last_sect = NULL;
v_ent->entry.comm.mod_time = v_ent->entry.comm.ac_time = OsSecCount;
v_ent->entry.comm.fileno = vol->fileno_gen++;
v_ent->entry.comm.one_past_last = 0;
v_ent->entry.comm.addr = v_ent;
/*-------------------------------------------------------------------*/
/* Get pointer to the first entry in the files table. */
/*-------------------------------------------------------------------*/
v_ent = &vol->files_tbl->tbl[0];
/*-------------------------------------------------------------------*/
/* Set the first entry in files table to be root dir. */
/*-------------------------------------------------------------------*/
v_ent->type = FDIREN;
v_ent->entry.dir.cwds = 0;
v_ent->entry.dir.next = NULL;
v_ent->entry.dir.prev = NULL;
v_ent->entry.dir.comm = &vol->files_tbl->tbl[1].entry.comm;
v_ent->entry.dir.parent_dir = NULL;
v_ent->entry.dir.first = NULL;
strncpy(v_ent->entry.dir.name, vol->sys.name, FILENAME_MAX);
/*-------------------------------------------------------------------*/
/* Set the other variables for this volume. */
/*-------------------------------------------------------------------*/
vol->total_free = FNUM_ENT - 2;
vol->num_sects = 0;
/*-------------------------------------------------------------------*/
/* Set the permissions for the root directory. */
/*-------------------------------------------------------------------*/
SetPerm((void *)v_ent->entry.dir.comm, S_IROTH | S_IWOTH | S_IXOTH);
/*-------------------------------------------------------------------*/
/* Release exclusive access to TargetRFS and return success. */
/*-------------------------------------------------------------------*/
semPost(RamSem);
return 0;
/*-------------------------------------------------------------------*/
/* In case of error, clean exit. */
/*-------------------------------------------------------------------*/
RamAddVol_error_exit:
if (vol)
{
if (vol->files_tbl)
{
free(vol->files_tbl);
vol->files_tbl = NULL;
}
vol->num_sects = vol->total_free = 0;
}
semPost(RamSem);
return -1;
}
#endif /* NUM_RFS_VOLS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -