我正在编写一个(取消)存档工具,它的设计方式是首先从存档中创建一个常规文件,然后再检查特殊属性,并可能决定该项目实际上是一个符号链接。
注意:在更多人误解我想要为文件创建符号链接之前。不,我将符号链接数据(即它的路径)写入文件中,然后我想告诉文件系统这是一个符号链接 我一直在 OS X 上开发这个,只需相应地设置其类型和创建者代码,就可以将常规文件转换为符号链接。
现在我想让这段代码也能在 Linux 上运行。所以我喜欢在那里找到类似的方式。
我知道创建符号链接的正常方法是调用 symlink() 函数,但我想知道是否还有一种方法可以将常规文件更改为符号链接,就像在 OSX 的 BSD 系统中一样,这样我不必过多重构我的工作代码?
lstat(),返回st_mode最高位的文件类型。现在我想知道这个模式字段是否也有一个类似的设置函数。
如果符号链接的路径存储在文件内,为什么不读出该路径,删除该文件,然后在其位置创建一个符号链接?
#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 /> 测试 $ ./f2s 测试 $ ls -l 测试 lrwxrwxrwx 1 me me 2 月 1 日 23:17 测试 -> / $ echo -n /> test2 $ strace ./f2s test2 打开(“测试2”,O_RDONLY)= 3 fstat(3, {st_mode=S_IFREG|0644, st_size=1, ...}) = 0 读取(3,“/”,1)= 1 关闭(3) = 0 符号链接(“/”,“test2〜”)= 0 重命名("test2~", "test2") = 0
这只是一个演示;它确实需要更多的错误处理,也许还需要一个更好的临时文件名。