hal_file.c
来自「基于ARM和uC/OS-II实现的串口控制台」· C语言 代码 · 共 134 行
C
134 行
#include "../../inc/dev/hal_file.h"
#include "../../inc/pub/hal_errno.h"
#include "../../inc/pub/hal_types.h"
#include "../../inc/inf/hal_unistd_inf.h"
#include "../../inc/dev/hal_fcntl.h"
#include <stdio.h>
#include <string.h>
/*
* hal_get_fd() 用于从文件描述符表中分配一个新的描述符,如果成功分配
* 则配置该描述符中的dev元素指向dev参数所指定的器件
*/
int hal_get_fd (hal_dev* dev)
{
hal_32 i;
int rc = -EMFILE;
/*
* 使用信号量hal_fd_list_lock来避免使用hal_fd_list表的冲突
*/
HAL_SEM_PEND(hal_fd_list_lock, 0);
/*
* 在文件描述符的数组中查找没用的单元,如果搜索到第一个没用的单元,则
* 根据具体的情况更新变量"hal_max_fd", 这个变量用于指出现在所用的描述符
* 中索引最大值,这样每次搜索的时候则可以知道从那个索引值以下是已用的,
* 只在已用的描述符中搜索便可以实现提高效率之目的。
*/
for (i = 0; i < HAL_MAX_FD; i++)
{
if (!hal_fd_list[i].dev)
{
hal_fd_list[i].dev = dev;
if (i > hal_max_fd)
{
hal_max_fd = i;
}
rc = i;
goto hal_get_fd_exit;
}
}
hal_get_fd_exit:
HAL_SEM_POST(hal_fd_list_lock);
return rc;
}
/*
* hal_open_fd() 与 open()函数类似。但与open()函数不同,本函数不重新分配一个
* 文件描述符,而是使用参数中传入的文件描述符。本函数主要由hal_io_redirect()
* 函数调用,用于重定向stdin stdout stderr。在这里调用了open()函数的目的是
* 防止无法打开设备时,不破害原来的文件描述符内容。
*/
static void hal_open_fd(hal_fd* fd, const char* name, int flags, int mode)
{
int old;
old = open(name, flags, mode);
if (old >= 0)
{
fd->dev = hal_fd_list[old].dev;
fd->priv = hal_fd_list[old].priv;
fd->fd_flags = hal_fd_list[old].fd_flags;
hal_release_fd (old);
}
}
/*
* hal_io_redirect() 函数用于重定向stdout,stdin和stderr到指定的设备。
*
* 在没调用本函数之前,stdin stdout stderr默认是指向/dev/null的。
* 如果本函数没调用成功,同样保持原来的指向。
*/
void hal_io_redirect(const char* stdout_dev,
const char* stdin_dev,
const char* stderr_dev)
{
/* 重定向各个通道 */
hal_open_fd (&hal_fd_list[STDOUT_FILENO], stdout_dev, O_WRONLY, 0777);
hal_open_fd (&hal_fd_list[STDIN_FILENO], stdin_dev, O_RDONLY, 0777);
hal_open_fd (&hal_fd_list[STDERR_FILENO], stderr_dev, O_WRONLY, 0777);
}
/*
* hal_find_dev() 由open()函数调用,用于在已经注册的设备链表中根据名字查找
* 相应的设备。参数llist是一个指向设备链表的头的指针。
*
* 没有匹配的设备,返回NULL,成功匹配返回对应设备的指针
*/
hal_dev* hal_find_dev(const char* name, hal_llist* llist)
{
hal_dev* next = (hal_dev*) llist->next;
hal_32 len;
len = strlen(name) + 1;
while (next != (hal_dev*) llist)
{
if (!memcmp (next->name, name, len))
{
return next; /*找到匹配的设备*/
}
next = (hal_dev*) next->llist.next;
}
/* 没有发现匹配 */
return NULL;
}
/*
* hal_release_fd() 用于释放一个文件描述符。注意为什么要fd>2才执行的原因是
* 0 1 2所对应的文件描述符保留给stdin stdout stderr,不应该能释放。
*/
void hal_release_fd (int fd)
{
if (fd > 2)
{
hal_fd_list[fd].fd_flags = 0;
hal_fd_list[fd].dev = 0;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?