link, linkat, unlink, unlinkat, and remove Functions

Linux 4.2.0

在之前的章节,我们知道一个文件可以有多个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() 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.:

  1. If the pathname given in oldpath is relative, then it is interpreted relative to the directory referred to by the file descriptor olddirfd (rather than relative to the current working directory of the calling process, as is done by link() for a relative pathname).

  2. 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()).

  3. If oldpath is absolute, then olddirfd is ignored.

  4. The interpretation of newpath is as for oldpath, except that a relative pathname is interpreted relative to the directory referred to by the file descriptor newdirfd.

flags argument

如果flag是AT_SYMLINK_FOLLOW,创建的link是用于symbolic link指向的目标。如果flag被清除,则link用于symblic link本身。

Besides

directory entry的新建和link count的增加必须是原子操作。

大部分实现都需要路径名在同一个文件系统上,尽管POSIX.1允许实现支持link能跨越文件系统。支持创建directorieshard link(硬链接)的实现,都只能让超级用户进行该项操作。这条限制(constraint)是因为hard link可能在文件系统中造成循环(loops),这是文件系统不法处理的。(在4.17节我们会展示symbolic link的loop实例)。因此,许多文件系统不允许(目录)directories的硬链接(hard link)。

原型:

#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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猎羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值