link、unlink、remove和rename

来源:互联网 发布:局域网管控软件 编辑:程序博客网 时间:2024/06/05 11:06
/*
              如上节所述,任何一个文件可以有多个目录项指向其i节点,创建一个指向现有文件的链接的方法是使用link函数
              
              #include <unistd.h>
              int link(const char *existingpath,const char *newpath);
                返回值:若成功则返回0,若出粗则返回-1
              次函数创建一个新目录项newpath,它引用现有的文件existingpath.如果newpath已经存在,则返回出错,只创建newpath中的最后一个分量,路径中的其
              他部分应当已经存在,创建新目录项以及增加链接计数应当是个原子操作,最然posix.1允许实现支持文件系统的链接,但是大多数实现要求这两个路径名
              在同一个文件系统中。如果实现支持创建指向一个目录的硬链接,那么也仅限于超级用户可以这么做。其理由是这样做可能在文件系统中形成循环,大多数
              处理文件系统的实用程序都不能处理这种情况。因此很多文件系统实现不允许对于目录的硬链接
              
                   为了删除一个现有的目录项,可以调用unlink函数
              #include <unistd.h>
              int unlink(const char *pathname);
              若成功则返回0,若出错则返回-1,此函数删除目录项,并将由pathname所引用文件的链接计数-1,如果还有指向该文件的其他链接,则仍可通过其他链接访
              问该文件的数据。如果出错,则不对该文件做任何更改。
              我们在前面已经提到,为了解除对文件的链接,必须对包含该目录项的目录具有写和执行权限,如果对该目录设置了粘住位,则对该目录必须具有写权限,
              并且具备下列三个条件之一。
                  ×  拥有该文件
                  ×  拥有该目录
                  ×  具有超级用户特权
              只有当链接计数达到0时,该文件的内容才可被删除。另一个条件也会阻止删除文件内容——只要有进程打开了该文件,其内容也是不能删除的
              关闭一个文件时,内核首先检查打开该文件的进程数。如果该数达到0,然后内核检查其链接数,如果这个数也是0,那么就删除该文件的内容
              
              
              unlink的这种性质经常被程序用来确保即使在该程序崩溃时,它所创建的临时文件也不会保留下来,进程用open或creat创建一个文件,然后立即调用unl
              ink.因为该文件仍旧是打开的,所以不会将其删除。只有当进程关闭该文件或终止时(在这种情况下,内核会关闭该进程打开的全部文件),该文件的内
              容才会被删除,如果pathname是符号链接,那么unlink删除该符号链接,而不会删除由该链接所引用的文件。给出符号链接名情况下,没有一个函数能删
              除由该链接所引用的文件
              我们也可以用remove函数解除对一个文件或目录的链接,对于文件remove的功能和unlinke相同。对于目录,remove的功能与rmdir相同。
              #include  <stdio.h>
              int remove(const char *pathname);
                        返回值:若成功则返回0,若出错则返回-1
                        
                                              对文件或目录进行更名。
              #include <stdio.h>
              int rename(const char *oldname,const char *newname);
                           若成功则返回0,若错误则返回-1
                           
              根据oldname是指文件还是指目录,有几种情况要加以说明,我们应说明如果newname已经存在将会发生什么
              (1) 如果oldname指的是一个文件而不是一个目录,那么为该符号或链接更名,在这种情况下,如果newname已经存在,则它不能引用一个目录,如果ne
              wname已经存在,而且不是一个目录,则先将该目录项删除然后将oldname更名为newname,对包含oldname的目录以及包含newname的目录,调用进程必须具
              有写权限,因为将更改这两个目录。
*/
#include "apue.h"
#include <fcntl.h>
#include <stdarg.h>
#include <errno.h>

// print a message and return to caller.caller specifies "errnoflag"
static void err_doit(int errnoflag,int error,const char *fmt,va_list ap)
{
    char  buf[MAXLINE];
    vsnprintf(buf,MAXLINE,fmt,ap);
    if(errnoflag)
    snprintf(buf+strlen(buf),MAXLINE-strlen(buf),": %s",strerror(error));
    strcat(buf,"\n");
    fflush(stdout);
    fputs(buf,stderr);
    fflush(NULL);
}

void err_sys(const char *fmt,...)
{
   va_list  ap;
   va_start(ap,fmt);
   err_doit(1,errno,fmt,ap);
   va_end(ap);
   exit(1);
}
int main(void)
{
    if(open("tempfile",O_RDWR) < 0)
        err_sys("open error");
    if(unlink("tempfile") < 0)
        err_sys("file unliked");
    printf("file unlinked\n");
    sleep(15);
    printf("done\n");
    exit(0);
}
0 0
原创粉丝点击