Linux 4.2.0
link, linkat - make a new name for a file
在之前的章节,我们知道一个文件可以有多个dirctory entries指向它的i-node。我们可以使用link , linkat来创建已经存在文件的链接(link)
原型如下:
#include <unistd.h>
int link(const char *oldpath, const char *newpath);
#include <fcntl.h> /* Definition of AT_* constants */
#include <unistd.h>
int linkat(int olddirfd, const char *oldpath,
int newdirfd, const char *newpath, int flags);
//Return: 0 if OK, -1 on error
link
link() creates a new link (also known as a hard link) to an existing file.
If newpath exists, it will not be overwritten.
This new name may be used exactly as the old one for any operation;both names refer to the same file (and so have the same permissions and ownership) and it is impossible to tell which name was the “original”.
linkat
Thelinkat() system call operates in exactly the same way as link(), except for the differences described here.:
If the pathname given in
oldpathis relative, then it is interpreted relative to the directory referred to by the file descriptorolddirfd(rather than relative to the current working directory of the calling process, as is done by link() for a relative pathname).If oldpath is relative and olddirfd is the special value AT_FDCWD, then oldpath is interpreted relative to the current working directory of the calling process (
like link()).If oldpath is absolute, then olddirfd is ignored.
The interpretation of
newpathis as foroldpath, except that a relative pathname is interpreted relative to the directory referred to by the file descriptornewdirfd.
flags argument
如果flag是AT_SYMLINK_FOLLOW,创建的link是用于symbolic link指向的目标。如果flag被清除,则link用于symblic link本身。
Besides
directory entry的新建和link count的增加必须是原子操作。
大部分实现都需要路径名在同一个文件系统上,尽管POSIX.1允许实现支持link能跨越文件系统。支持创建directories的hard link(硬链接)的实现,都只能让超级用户进行该项操作。这条限制(constraint)是因为hard link可能在文件系统中造成循环(loops),这是文件系统不法处理的。(在4.17节我们会展示symbolic link的loop实例)。因此,许多文件系统不允许(目录)directories的硬链接(hard link)。
unlink, unlinkat - delete a name and possibly the file it refers to
原型:
#include <unistd.h>
int unlink(const char *pathname);
#include <fcntl.h> /* Definition of AT_* constants */
#include <unistd.h>
int unlinkat(int dirfd, const char *pathname, int flags);
//both Return: 0 if OK, -1 on error
这些系统调用会移除目录条目(directory entry)并且减少pathename引用的文件的链接数目link count。如果文件还有其他的链接(link),文件的内容还可以通过其他链接访问。如果产生error,文件不会发生变化。
As mentioned earlier, to unlink a file, we must have write permission and execute permission in the directory containing the directory entry, as it is the directory entry that we will be removing. Also, as mentioned in Section 4.10, if the sticky bit is set in this directory we must have write permission for the directory and meet one of the following criteria:
• Own the file
• Own the directory
• Have superuser privileges
仅仅当link count达到0,文件的内容才会被删除。另一种阻止文件内容被删除的条件就是,一些进程open了该文件,文件的内容也不会被删除。当某文件被关闭了(closed),内核会先确定打开(open)该文件的进程数量,如果为0,此时内核会继续确定link count,如果还为0,文件内容被删除。
unlinat
pathname为相对路径,unlinkat会将其看做fd开的目录的相对路径。
如果fd值为AT_FDCWD时,pathname就是相对路径,相对于调用进程的当前工作目录。如果pathname是绝对路径,fd直接被忽略。
flag
用于改变unlinkat默认行为。
1. AT_REMOVEDIR: 用于删除目录,类似于使用rmdir命令。
2. clear: unlinkat操作和unlink一致。
Example
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
int main()
{
if(open("tempfile", O_RDWR|O_CREAT, S_IRWXO) < 0)
{
fprintf(stderr, "open file error %s\n", strerror(errno));
exit(-1);
}
if(unlink("tempfile") < 0)
{
fprintf(stderr, "unlink file error %s\n", strerror(errno));
exit(-1);
}
printf("file unlinked\n");
sleep(15);
printf("done\n");
return 0;
}
sleep(15),用于睡眠15s,定义在unistd中。
This property of unlink is often used by a program to ensure that a temporary file it creates won’t be left around in case the program crashes. The process creates a file using either open or creat and then immediately calls unlink. The file is not deleted, however, because it is still open. Only when the process either closes the file or terminates, which causes the kernel to close all its open files, is the file deleted.
If pathname is a symbolic link, unlink removes the symbolic link, not the file referenced by the link. There is no function to remove the file referenced by a symbolic link given the name of the link.
The superuser can call unlink with pathname specifying a directory if the file system supports it, but the function rmdir should be used instead to unlink a directory. We describe the rmdir function in Section 4.21.
remove
We can also unlink a file or a directory with the remove function. For a file, remove is identical to unlink. For a directory, remove is identical to rmdir.
remove - remove a file or directory
#include <stdio.h>
int remove(const char *pathname);
//Returns: 0 if OK, -1 on error
本文深入探讨Linux中文件的链接操作(link和linkat)与删除操作(unlink和unlinkat),包括其作用原理、参数解释及实例演示。重点阐述了如何通过链接创建文件的硬链接与符号链接,以及在不同场景下使用unlink和unlinkat删除文件或目录的详细步骤。
573

被折叠的 条评论
为什么被折叠?



