我正在编写一个(联合国)归档工具及其设计方式,它首先会在检查特殊属性之前从归档创建一个常规文件,并且可能会确定此项目是符号链接。
注意:在更多人误解我想要制作 文件的符号链接之前。不,我将符号链接数据(即其路径)写入文件,然后我想告诉文件系统这是一个符号链接
我一直在OS X上进行开发,只需相应地设置Type和Creator代码,就可以将常规文件转换为符号链接。
现在我想让这段代码也在Linux上运行。所以我想在那里找到类似的方式。
我知道创建符号链接的正常方法是调用symlink()函数,但我想知道是否还有一种方法可以将常规文件更改为符号链接,就像在OSX的BSD系统中一样,所以我不必过多地重构我的工作代码?
有lstat(),它以st_mode的最高位返回文件类型。现在我想知道这个模式字段是否还有类似的setter函数。
答案 0 :(得分:4)
我不相信Linux中有一种方法可以像你描述的那样去做。 IIRC,文件系统将符号链接信息存储在inode表中而不是常规文件中,因此没有直接的方法将文件转换为链接。
如果符号链接的路径存储在文件中,为什么不读出路径,删除文件,并在其位置创建符号链接?
答案 1 :(得分:3)
证明我写的是对bmarguiles答案的评论,
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char **argv) {
char *buffer = 0, *name = 0;
int i;
for (i = 1; i < argc; i++) {
struct stat st;
int fd = open(argv[i], O_RDONLY);
fstat(fd, &st);
buffer = realloc(buffer, st.st_size + 1);
read(fd, buffer, st.st_size);
close(fd);
buffer[st.st_size] = '\0';
name = realloc(name, strlen(argv[i]) + 2);
sprintf(name, "%s~", argv[i]);
symlink(buffer, name);
rename(name, argv[i]);
}
free(buffer);
free(name);
return 0;
}
$ vi f2s.c ... $ cc -o f2s f2s.c $ echo -n / > test $ ./f2s test $ ls -l test lrwxrwxrwx 1 me me 1 Feb 24 23:17 test -> / $ echo -n / > test2 $ strace ./f2s test2 open("test2", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=1, ...}) = 0 read(3, "/", 1) = 1 close(3) = 0 symlink("/", "test2~") = 0 rename("test2~", "test2") = 0
这只是一个示范;它真的需要更多的错误处理,也许是一个更好的临时文件名。
答案 2 :(得分:1)
不,你不能把一个变成另一个。您必须取消链接以终止文件,然后使用符号链接创建符号链接作为替换。