📄 sysioctl.c
字号:
/*-------------------------------------------------------------------*/
pivot = *head;
*head = (*head)->entry.dir.next;
(*head)->entry.dir.prev = NULL;
pivot->entry.dir.next = NULL;
/*-------------------------------------------------------------------*/
/* Fill in DirEntry for the pivot. */
/*-------------------------------------------------------------------*/
fill_dir_entry(&pivot->entry.dir, e1);
/*-------------------------------------------------------------------*/
/* Now walk the rest of the list and place each entry into one of the*/
/* two categories (<=, >) based on the comparison function. */
/*-------------------------------------------------------------------*/
while ((curr_ent = *head) != NULL)
{
/*-----------------------------------------------------------------*/
/* Advance head to next entry in list. */
/*-----------------------------------------------------------------*/
*head = (*head)->entry.dir.next;
curr_ent->entry.dir.next = NULL;
/*-----------------------------------------------------------------*/
/* Fill in DirEntry for current entry. */
/*-----------------------------------------------------------------*/
fill_dir_entry(&curr_ent->entry.dir, e2);
/*-----------------------------------------------------------------*/
/* If entry >= pivot, place it in the 'less' list. */
/*-----------------------------------------------------------------*/
if (cmp(e1, e2) >= 0)
{
if (less_tail == NULL)
{
less_head = less_tail = curr_ent;
curr_ent->entry.dir.prev = NULL;
}
else
{
less_tail->entry.dir.next = curr_ent;
curr_ent->entry.dir.prev = less_tail;
less_tail = curr_ent;
}
}
/*-----------------------------------------------------------------*/
/* If entry after pivot, place it in the 'greater' list. */
/*-----------------------------------------------------------------*/
else
{
if (greater_tail == NULL)
{
greater_head = greater_tail = curr_ent;
curr_ent->entry.dir.prev = NULL;
}
else
{
greater_tail->entry.dir.next = curr_ent;
curr_ent->entry.dir.prev = greater_tail;
greater_tail = curr_ent;
}
}
}
/*-------------------------------------------------------------------*/
/* Sort both lists if non-empty. */
/*-------------------------------------------------------------------*/
if (less_head)
QuickSort(&less_head, &less_tail, e1, e2, cmp);
if (greater_head)
QuickSort(&greater_head, &greater_tail, e1, e2, cmp);
/*-------------------------------------------------------------------*/
/* Create sorted list: less->pivot->greater. */
/*-------------------------------------------------------------------*/
if (less_tail)
{
*head = less_head;
less_tail->entry.dir.next = pivot;
}
else
*head = pivot;
pivot->entry.dir.prev = less_tail;
if (greater_head)
{
*tail = greater_tail;
greater_head->entry.dir.prev = pivot;
}
else
*tail = pivot;
pivot->entry.dir.next = greater_head;
}
/***********************************************************************/
/* InitFFS: Initialize the flash */
/* */
/* Returns: 0 on success, -1 on failure */
/* */
/***********************************************************************/
int InitFFS(void)
{
/*-------------------------------------------------------------------*/
/* Set the file system semaphore and global variables. */
/*-------------------------------------------------------------------*/
FileSysSem = semCreate("FSYS_SEM", 1, OS_FIFO);
if (FileSysSem == NULL)
return -1;
FsInitFCB(&Files[ROOT_DIR_INDEX], FCB_DIR);
Files[ROOT_DIR_INDEX].ioctl = root_ioctl;
/*-------------------------------------------------------------------*/
/* Initialize all modules in the list. */
/*-------------------------------------------------------------------*/
return sw_mod_loop(kInitMod);
}
/***********************************************************************/
/* IsLast: Given a string, look to see if it is last entry in the */
/* path for a filename or a directory */
/* */
/* Inputs: name = string to check */
/* incr = pointer to num of chars to increment */
/* */
/* Returns: length of entry if not last, 0 if it is */
/* */
/***********************************************************************/
ui32 IsLast(const char *name, ui32 *incr)
{
ui32 i, inc = 0;
for (;; ++name, ++inc)
{
/*-----------------------------------------------------------------*/
/* If a '/' is encountered, it's not the last entry in the path. */
/*-----------------------------------------------------------------*/
if (*name == '/')
{
/*---------------------------------------------------------------*/
/* If there's nothing pointing past the '/' however, it is the */
/* last entry in the path. */
/*---------------------------------------------------------------*/
for (i = inc;; ++i)
{
++name;
*incr = i + 1;
if (*name == '\0')
return 0;
else if (*name != '/')
return inc;
}
}
/*-----------------------------------------------------------------*/
/* If we've reached the end of the string, it is last entry. */
/*-----------------------------------------------------------------*/
if (*name == '\0')
{
*incr = inc;
return 0;
}
}
}
/***********************************************************************/
/* FSearchFSUID: Search for a filename(or full path) based on FSUID */
/* */
/* Inputs: fsuid = FSUID number to look for */
/* buf = buffer to place filename(path) in if non NULL */
/* size = size of buf when non NULL */
/* lookup = flag to indicate filename or full path */
/* */
/* Returns: filename(path), NULL on error */
/* */
/***********************************************************************/
char *FSearchFSUID(ui32 fsuid, char *buf, size_t size, int lookup)
{
ui32 vid, fid;
FileSys *fsys;
char *r_value = NULL;
/*-------------------------------------------------------------------*/
/* Get the volume id and file id from the FSUID. */
/*-------------------------------------------------------------------*/
vid = get_vid(fsuid);
fid = get_fid(fsuid);
/*-------------------------------------------------------------------*/
/* Scan all the mounted volumes for the entry with FSUID. */
/*-------------------------------------------------------------------*/
for (fsys = MountedList.head; fsys && r_value == NULL;
fsys = fsys->next)
{
r_value = fsys->ioctl(NULL, GET_NAME, fsys->volume, buf, size,
lookup, vid, fid);
if (r_value == (char *)-1)
return NULL;
}
return r_value;
}
/***********************************************************************/
/* FSearch: Search a path to determine if it is valid */
/* */
/* Inputs: handle = handle to either dir or file ctrl block */
/* path = pointer to the path */
/* dir_lookup = flag to indicate up to what level lookup */
/* is performed (actual or parent directory) */
/* */
/* Returns: Pointer to directory that holds entity for which */
/* search was performed, or NULL if no directory exists */
/* */
/***********************************************************************/
void *FSearch(void *handle, const char **path, int dir_lookup)
{
FILE *file = handle;
void *r_value = (void *)-1;
ui32 len, incr, dummy;
FsVolume *volume;
/*-------------------------------------------------------------------*/
/* Set FSPath to point to *path. */
/*-------------------------------------------------------------------*/
FSPath = *path;
/*-------------------------------------------------------------------*/
/* Keep looping until entry found or error. */
/*-------------------------------------------------------------------*/
do
{
/*-----------------------------------------------------------------*/
/* Obtain current directory info. If never set before, set it to */
/* root. */
/*-----------------------------------------------------------------*/
FsReadCWD((void *)&volume, &dummy);
/*-----------------------------------------------------------------*/
/* If it's an absolute path, or current ioctl is root one, figure */
/* out to which file system to direct the search. */
/*-----------------------------------------------------------------*/
if (*FSPath == '/' || volume == NULL || r_value == NULL)
{
/*---------------------------------------------------------------*/
/* Strip off the leading '/' in the path if there are any. */
/*---------------------------------------------------------------*/
while (*FSPath == '/')
++FSPath;
/*---------------------------------------------------------------*/
/* Skip multiple "./" strings. Skip ending ".". */
/*---------------------------------------------------------------*/
while (!strncmp(FSPath, "./", 2))
FSPath += 2;
if (!strcmp(FSPath, "."))
++FSPath;
/*---------------------------------------------------------------*/
/* If pathname is empty, we're in the root directory, stop. */
/*---------------------------------------------------------------*/
if (*FSPath == '\0')
{
file->ioctl = Files[ROOT_DIR_INDEX].ioctl;
file->acquire = file->release = do_nothing;
r_value = &Files[ROOT_DIR_INDEX];
}
/*---------------------------------------------------------------*/
/* Else pathname is valid, check if any file systems are mounted.*/
/*---------------------------------------------------------------*/
else if (MountedList.head)
{
FileSys *fsys;
/*-------------------------------------------------------------*/
/* Check if we're looking at last name in path. */
/*-------------------------------------------------------------*/
len = IsLast(FSPath, &incr);
if (len == 0)
{
/*-----------------------------------------------------------*/
/* If it's directory, strip off trailing '/' if it exists. */
/*-----------------------------------------------------------*/
if (dir_lookup == ACTUAL_DIR || dir_lookup == DIR_FILE)
{
if ((FSPath)[incr - 1] == '/')
{
len = incr - 1;
while (FSPath[len - 1] == '/')
--len;
}
else
len = incr;
/*---------------------------------------------------------*/
/* If path too long, return error if no truncation, else */
/* truncate. */
/*---------------------------------------------------------*/
if (len > PATH_MAX)
{
#if _PATH_NO_TRUNC
set_errno(ENAMETOOLONG);
return NULL;
#else
len = PATH_MAX;
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -