1.创建一个硬链接
#include<unistd.h>
定义函数 int link (const char * oldpath,const char * newpath);
函数说明 link()以参数newpath指定的名称来建立一个新的连接(硬连接)到参数oldpath所指定的已存在文件。如果参数newpath指定的名称为一已存在的文件则不会建立连接。
返回值 成功则返回0,失败返回-1,错误原因存于errno。
附加说明 link()所建立的硬连接无法跨越不同文件系统,如果需要请改用symlink()。
错误代码
EXDEV 参数oldpath与newpath不是建立在同一文件系统。
EPERM 参数oldpath与newpath所指的文件系统不支持硬连接
EROFS 文件存在于只读文件系统内
EFAULT 参数oldpath或newpath 指针超出可存取内存空间。
ENAMETOLLONG 参数oldpath或newpath太长
ENOMEM 核心内存不足
EEXIST 参数newpath所指的文件名已存在。
EMLINK 参数oldpath所指的文件已达最大连接数目。
ELOOP 参数pathname有过多符号连接问题
ENOSPC 文件系统的剩余空间不足。
EIO I/O 存取错误。
#include<unistd.h>
定义函数 int symlink( const char * oldpath,const char * newpath);
函数说明 symlink()以参数newpath指定的名称来建立一个新的连接(符号连接)到参数oldpath所指定的已存在文件。参数oldpath指定的文件不一定要存在,如果参数newpath指定的名称为一已存在的文件则不会建立连接。
返回值 成功则返回0,失败返回-1,错误原因存于errno。
错误代码 EPERM 参数oldpath与newpath所指的文件系统不支持符号连接
EROFS 欲测试写入权限的文件存在于只读文件系统内
EFAULT 参数oldpath或newpath指针超出可存取内存空间。
ENAMETOOLONG 参数oldpath或newpath太长
ENOMEM 核心内存不足
EEXIST 参数newpath所指的文件名已存在。
EMLINK 参数oldpath所指的文件已达到最大连接数目
ELOOP 参数pathname有过多符号连接问题
ENOSPC 文件系统的剩余空间不足
EIO I/O 存取错误
2.删除一个硬链接
#include<unistd.h>
定义函数 int unlink(const char * pathname);
函数说明 unlink()会删除参数pathname指定的文件。如果该文件名为最后连接点,但有其他进程打开了此文件,则在所有关于此文件的文件描述词皆关闭后才会删除。如果参数pathname为一符号连接,则此连接会被删除。
返回值 成功则返回0,失败返回-1,错误原因存于errno
错误代码 EROFS 文件存在于只读文件系统内
EFAULT 参数pathname指针超出可存取内存空间
ENAMETOOLONG 参数pathname太长
ENOMEM 核心内存不足
ELOOP 参数pathname 有过多符号连接问题
EIO I/O 存取错误
3.范例
//hardlink.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
/* 缓冲区的大小 */
#define MAX 1024
int main(void)
{
int fd;
struct stat statbuf;
char buf[MAX];
int n;
if(stat("test.txt", &statbuf) == -1){ /* 得到目标文件的状态 */
perror("fail to get status");
exit(1);
}
/* 打印文件的链接数 */
printf("test.txt, the number of links is : %d/n", statbuf.st_nlink);
/* 当前目录下创建一个叫做test2.txt的文件,该文件和test.txt共用一个i结点 */
if(link("test.txt", "test2.txt") == -1){
perror("fail to link");
exit(1);
}
/* 再次取得test.txt文件的状态,其链接数已经更新 */
if(stat("test.txt", &statbuf) == -1){
perror("fail to get status");
exit(1);
}
printf("test.txt, the number of links is : %d/n", statbuf.st_nlink);
/* 得到test2.txt文件的状态,这个状态结构实际上是文件test.txt的 */
if(stat("test2.txt", &statbuf) == -1){
perror("fail to get status");
exit(1);
}
printf("test2.txt, the number of links is : %d/n", statbuf.st_nlink);
printf("/n");
if((fd = open("test.txt", O_RDWR)) == -1){ /* 打开文件test.txt */
perror("fail to open");
exit(1);
}
strcpy(buf, "hello world"); /* 复制字符串 */
if((n = write(fd, buf, strlen(buf))) == -1){ /* 向文件中输出字符串"hello world" */
perror("fail to write");
exit(1);
}
close(fd); /* 关闭文件,输出的字符串写入到磁盘文件中 */
if((fd = open("test2.txt", O_RDWR)) == -1){ /* 打开test2.txt文件 */
perror("fail to open");
exit(1);
}
if((n = read(fd, buf, n)) == -1){ /* 读该文件的内容 */
perror("fail to read");
exit(1);
}
buf[n] = '/0'; /* 添加字符串结束标志,便于打印 */
printf("content of test2.txt is : %s/n", buf); /* 输出test2.txt文件中的内容 */
close(fd);
/* 删除test2.txt的目录项,但是其磁盘文件没有受到影响,
* 仍可以通过另一个链接test.txt引用该文件
*/
if(unlink("test2.txt") == -1){
perror("fail to unlink");
exit(1);
}
if(stat("test.txt", &statbuf) == -1){ /* 得到test.txt文件的状态 */
perror("fail to get status");
exit(1);
}
printf("test.txt, the number of links is : %d/n", statbuf.st_nlink); /* 打印该文件链接计数 */
/* 打开test.txt文件,这样做可以避免该文件被系统删除 */
if((fd = open("test.txt", O_RDWR)) == -1){
perror("fail to open");
exit(1);
}
if(unlink("test.txt") == -1){ /* 现在该文件的引用计数为0了 */
perror("fail to unlink");
exit(1);
}
if(fstat(fd, &statbuf) == -1){ /* 得到文件的状态 */
perror("fail to get status");
exit(1);
}
printf("test.txt, the number of links is : %d/n", statbuf.st_nlink);
printf("/n");
/* 由于文件仍然打开,所有该文件仍可以应用 */
if((n = read(fd, buf, n)) == -1){
perror("fail to read");
exit(1);
}
buf[n] = '/0';
printf("content of test.txt is : %s/n", buf); /* 输出结果 */
close(fd); /* 关闭文件 */
return 0;
}
该例子同时说明,即使一个文件的链接数已经为0,但是只要该文件打开,程序仍可以引用该文件。包括对文件的读和写,但此时的读写操作实际上是对内存中缓冲区进行操作的。当文件被关闭时,内存中的缓冲区消失,文件也消失。