最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c - adding a new syscall for copying file to linux-6.9.8 but "Failed to stat source file" - Stack Overflow

programmeradmin2浏览0评论

edited kernel: linux 6.9.8

machine for building: AMD 9950X, debian 12, linux 6.1.0

Codes

kernel/sys.c

# codes above are omitted.

#endif /* CONFIG_COMPAT */

SYSCALL_DEFINE0(mycall) {
        printk(KERN_INFO "Hello Linux 6.9.8 by Konrad\n");
        return 0;
}

SYSCALL_DEFINE2(mycopy, const char __user *, s_file, const char __user *, t_file) {
    struct kstat k_buf;
    char copy_buf[1024];
    char s_filename[256], t_filename[256];
    struct file *read_file = NULL, *write_file = NULL;
    long read_num;

    /* Get source and target file name */
    read_num = strncpy_from_user(s_filename, s_file, sizeof(s_filename));
    if (read_num < 0 || read_num >= sizeof(s_filename)) {
        printk(KERN_ERR "Failed to copy source filename from user space\n");
        return read_num < 0 ? read_num : -ENAMETOOLONG;
    }
    read_num = strncpy_from_user(t_filename, t_file, sizeof(t_filename));
    if (read_num < 0 || read_num >= sizeof(t_filename)) {
        printk(KERN_ERR "Failed to copy target filename from user space\n");
        return read_num < 0 ? read_num : -ENAMETOOLONG;
    }

    /* Print file paths */
    printk(KERN_INFO "Source file: %s\n", s_filename);
    printk(KERN_INFO "Target file: %s\n", t_filename);

    /* Get source file mode */
    if (vfs_stat(s_filename, &k_buf) != 0) {
        printk(KERN_ERR "Failed to stat source file: %s\n", s_filename);
        return -ENOENT;
    }

    /* Open files */
    read_file = filp_open(s_filename, O_RDONLY, 0);
    if (IS_ERR(read_file)) {
        printk(KERN_ERR "Failed to open source file: %ld\n", PTR_ERR(read_file));
        return PTR_ERR(read_file);
    }
    write_file = filp_open(t_filename, O_WRONLY | O_CREAT | O_TRUNC, k_buf.mode);
    if (IS_ERR(write_file)) {
        printk(KERN_ERR "Failed to open target file: %ld\n", PTR_ERR(write_file));
        filp_close(read_file, NULL);
        return PTR_ERR(write_file);
    }

    /* Do copy */
    for (;;) {
        read_num = kernel_read(read_file, copy_buf, sizeof(copy_buf), &read_file->f_pos);
        if (read_num < 0) {
            printk(KERN_ERR "Failed to read from source file: %ld\n", read_num);
            filp_close(read_file, NULL);
            filp_close(write_file, NULL);
            return read_num;
        } else if (read_num == 0)
            break;
        kernel_write(write_file, copy_buf, read_num, &write_file->f_pos);
    }

    filp_close(read_file, NULL);
    filp_close(write_file, NULL);

    return 0;
}

arch/x86/entry/syscalls/syscall_64.tbl

Error

The first syscall mycall(462) works well, but the second mycopy(463) for copying files did not work with testing codes below:

#include <stdio.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <errno.h>

#define MYCOPY_SYSCALL 463

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <source_file> <destination_file>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    if (chdir("/usr/src/syscall") != 0) {
        perror("Failed to change directory");
        exit(EXIT_FAILURE);
    }

    const char *src_file = argv[1];
    const char *dest_file = argv[2];

    printf("Source file: %s\n", src_file);
    printf("Destination file: %s\n", dest_file);

    long result = syscall(MYCOPY_SYSCALL, src_file, dest_file);

    if (result == -1) {
        printf("Error: errno=%d\n", errno);
        perror("Error in mycopy syscall");
        exit(EXIT_FAILURE);
    } else {
        printf("File copied successfully from %s to %s\n", src_file, dest_file);
    }

    return 0;
}

more running info is listed in the img:

and run with abs path and the permissions for /usr are 777 recursively.

according to the error info, it might be vfs_stat() in kernel/sys.c, but i do not know the reason, anyone can help ?

    /* Get source file mode */
    if (vfs_stat(s_filename, &k_buf) != 0) {
        printk(KERN_ERR "Failed to stat source file: %s\n", s_filename);
        return -ENOENT;
    }
发布评论

评论列表(0)

  1. 暂无评论