我编写此代码,如果从与要删除的文件相同的目录调用文件,它将不会取消链接文件,它将取消链接其他目录中的文件
.section .data
fpath:
.asciz "/home/user/filename" # path to file to delete
.section .text
.globl _start
_start:
movl $10, %eax # unlink syscall
movl $fpath, %ebx # path to file to delete
int $0x80
movl %eax, %ebx # put syscall ret value in ebx
movl $1, %eax # exit syscall
int $0x80
我想要的是取消所有文件(包括其自身)在其运行目录中的链接。
答案 0 :(得分:1)
您需要以递归方式删除目录内容,然后才能删除目录本身。以下是C语言,但不使用标准库函数,只使用syscalls:
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
#include <dirent.h>
#include <fcntl.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
struct linux_dirent64 {
ino64_t d_ino;
off64_t d_off;
unsigned short d_reclen;
unsigned char d_type;
char d_name[];
};
static void rmrf(int dfd, const char *name) {
unsigned char buffer[16384];
struct linux_dirent64 *dirent;
int fd, off, size;
fd = syscall(SYS_openat, dfd, name, O_RDONLY | O_DIRECTORY);
if (fd == -1) {
syscall(SYS_exit, 1);
}
do {
size = syscall(SYS_getdents64, fd, buffer, sizeof(buffer));
if (size < 0) {
syscall(SYS_exit, 1);
}
for (off = 0; off < size; off += dirent->d_reclen) {
dirent = (struct linux_dirent64 *)&buffer[off];
if (dirent->d_name[0] == '.' &&
(dirent->d_name[1] == '\0' ||
(dirent->d_name[1] == '.' &&
(dirent->d_name[2] == '\0')))) {
continue;
}
if (dirent->d_type != DT_DIR) {
if (!syscall(SYS_unlinkat, fd, dirent->d_name, 0)) {
continue;
}
if (dirent->d_type != DT_UNKNOWN) {
syscall(SYS_exit, 1);
}
}
rmrf(fd, dirent->d_name);
}
} while (off);
syscall(SYS_close, fd);
if (syscall(SYS_unlinkat, dfd, name, AT_REMOVEDIR)) {
syscall(SYS_exit, -1);
}
}
int main() {
const char fpath[] = "/home/user/filename";
if (syscall(SYS_unlink, fpath)) {
rmrf(0, fpath);
}
syscall(SYS_exit, 0);
}