feat: support link/symlink/readlink
新增link/symlink/readlink接口的系统调用及内核实现,当前仅支持jffs2文件系统。具体接口说明如下: 一、hard link 接口原型: int link(const char *oldpath, const char *newpath); int linkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, int flags); 作用: 创建oldpath的硬链接,名为newpath。 功能说明: 1、newpath与oldpath必须在同一挂载分区内。 2、若newpath已存在,不会覆盖,错误码EEXIST。 3、oldpath必须为普通文件或者软链接文件。 4、如果oldpath是一个软链接文件,那么: 若调用link接口或者linkat(flags=0),创建出软链接文件的硬链接; 若调用linkat(flags = AT_SYMLINK_FOLLOW),创建出软链接所指向源文件的硬链接。 5、oldpath与newpath对应同一个文件,对oldpath与newpath任一名字的操作都是直接操作文件,没有“原始文件”的说法。 6、使用cp命令拷贝一个硬链接文件,生成文件的拷贝,新文件的nlink数为1。 7、删除oldpath或newpath,底层文件仍存在,可以通过另一个path访问。只有当两个path都删除之后,才会真正将文件删除,空间释放。 二、symbol link 接口原型: int symlink(const char *target, const char *linkpath); int symlinkat(const char *target, int newdirfd, const char *linkpath); 作用: 创建一个软链接文件linkpath,存储字符串target。 功能说明: 1、target可以为任意字符串(长度小于PATH_MAX)。 2、若linkpath文件名已存在,不会覆盖,错误码EEXIST。 3、用readlink函数可读取软链接的target内容。 4、软链接文件本身大小为target长度。 5、ls时软链接文件类型显示为 'l'。 6、symlink最大循环次数为CONFIG_FS_MAX_LNK_CNT(目前为40),超出则返回错误,错误码ELOOP。 7、使用cp命令拷贝一个软链接文件: 若target是一个文件:创建一个源文件的拷贝,类型为普通文件; 若target非文件:拷贝失败。 三、readlink 接口原型: ssize_t readlink(const char *pathname, char *buf, size_t bufsiz); ssize_t readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz); 作用: 读取软链接文件存放的的target内容。 功能说明: 1、pathname必须为软链接文件,否则错误码EINVAL。 2、如果bufsiz小于target长度,则截断target。 close #I3Q0OD Change-Id: I3864d6069b627b705a369e8e32dc1eb922dc0157 Signed-off-by: chenjing <chenjing139@huawei.com>
This commit is contained in:
@@ -832,7 +832,7 @@ static int os_shell_cmd_do_rmdir(const char *pathname)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (S_ISREG(stat_info.st_mode))
|
||||
if (S_ISREG(stat_info.st_mode) || S_ISLNK(stat_info.st_mode))
|
||||
{
|
||||
return remove(pathname);
|
||||
}
|
||||
@@ -1050,7 +1050,7 @@ static int os_wildcard_extract_directory(char *fullpath, void *dst, wildcard_typ
|
||||
else if (mark == CP_COUNT)
|
||||
{
|
||||
ret = stat(fullpath, &stat_buf);
|
||||
if (ret == 0 && S_ISREG(stat_buf.st_mode))
|
||||
if (ret == 0 && (S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode)))
|
||||
{
|
||||
(*(int *)dst)++;
|
||||
}
|
||||
@@ -1106,7 +1106,7 @@ static int os_wildcard_extract_directory(char *fullpath, void *dst, wildcard_typ
|
||||
else if (mark == CP_COUNT)
|
||||
{
|
||||
ret = stat(src, &stat_buf);
|
||||
if (ret == 0 && S_ISREG(stat_buf.st_mode))
|
||||
if (ret == 0 && (S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode)))
|
||||
{
|
||||
(*(int *)dst)++;
|
||||
if ((*(int *)dst) > 1)
|
||||
@@ -1216,7 +1216,7 @@ int osShellCmdCp(int argc, const char **argv)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (S_ISREG(stat_buf.st_mode) && dst[strlen(dst) - 1] == '/')
|
||||
if ((S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode)) && dst[strlen(dst) - 1] == '/')
|
||||
{
|
||||
PRINTK("cp error: %s is not a directory.\n", dst_fullpath);
|
||||
goto errout_with_path;
|
||||
@@ -1225,7 +1225,7 @@ int osShellCmdCp(int argc, const char **argv)
|
||||
|
||||
if (os_is_containers_wildcard(src_fullpath))
|
||||
{
|
||||
if (ret < 0 || S_ISREG(stat_buf.st_mode))
|
||||
if (ret < 0 || S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode))
|
||||
{
|
||||
char *src_copy = strdup(src_fullpath);
|
||||
if (src_copy == NULL)
|
||||
|
||||
Reference in New Issue
Block a user