C 中的目录问题

发布于 2024-10-29 01:42:46 字数 2329 浏览 6 评论 0原文

我正在用 C 语言为 Linux 编写一个程序,它接收一个目录作为参数,然后对于该目录中的每个文件及其每个子目录,调用一个名为 monfile 的程序。代码如下:

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <fcntl.h>

#define DIR_ARG 1
#define DUR_ARG 2
#define SEC_ARG 3
#define LOG_ARG 4
#define OP1_ARG 5
#define OP2_ARG 6

int main(int argc, char** argv)
{
    // Teste aos argumentos
    if (argc < 5) {
        printf("Erro! Argumentos insuficientes!\n");
        return -1;
    }

    // Declaração de variáveis
    DIR *dir;
    struct dirent *dentry;
    struct stat stat_entry;

    int fork_result;


    // Testa se o directório passado como argumento é válido
    if ((dir = opendir( argv[DIR_ARG])) == NULL)
    {
        perror(argv[DIR_ARG]);
        exit(2);
    }

    chdir(argv[DIR_ARG]);
    // Ciclo de propagação
    while ((dentry = readdir(dir)) != NULL) {

        stat(dentry->d_name, &stat_entry);
        // Se for ficheiro regular
        if (S_ISREG(stat_entry.st_mode)) {
            fork_result = fork();
            if (fork_result == -1) {
                printf("file fork error!\n");
                exit(1);
            }
            if (fork_result == 0) {
                execlp("monfile", "monfile", argv[SEC_ARG], dentry->d_name, filedes, (char *)NULL);
                printf("Erro no exec!\n");
                exit(1);
            }
        }
        // Se for directório vai criar um novo processo e passar dir para esse directório 
        if (S_ISDIR (stat_entry.st_mode)) {
            fork_result = fork();
            if (fork_result == -1) {
                printf ("dir fork error!\n");
                exit(1);
            }
            if (fork_result == 0) {
                chdir(dentry->d_name);
                dir = opendir (dentry->d_name);
            }
        }
    }



    return 0;
}

现在,结果是......大量的 exec 错误消息,然后是一堆 fork 错误消息,即使我只是为带有文件和子目录的目录调用它。这给我带来了两个问题: a) cicle 是如何进行如此多次迭代的? b) exec 出了什么问题,看看 monfile 是如何构建的并且与 mondir 位于同一文件夹中?

因此,我决定通过在 cicle 的开头添加来找出程序正在查看的目录

printf("%s\n", dentry->d_name);

,并且它以某种方式扫描每个目录,即使它的调用方式如下: mondir Subfolder1 ...(其他参数), Subfolder1 与 mondir 位于同一目录中。我在这里做错了什么,无论是目录问题还是执行问题?

I'm making a program for Linux in C that recieves a directory as an argument, then for each file in that directory and each of it's sub-directories, calls a program called monfile. Here's the code:

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <fcntl.h>

#define DIR_ARG 1
#define DUR_ARG 2
#define SEC_ARG 3
#define LOG_ARG 4
#define OP1_ARG 5
#define OP2_ARG 6

int main(int argc, char** argv)
{
    // Teste aos argumentos
    if (argc < 5) {
        printf("Erro! Argumentos insuficientes!\n");
        return -1;
    }

    // Declaração de variáveis
    DIR *dir;
    struct dirent *dentry;
    struct stat stat_entry;

    int fork_result;


    // Testa se o directório passado como argumento é válido
    if ((dir = opendir( argv[DIR_ARG])) == NULL)
    {
        perror(argv[DIR_ARG]);
        exit(2);
    }

    chdir(argv[DIR_ARG]);
    // Ciclo de propagação
    while ((dentry = readdir(dir)) != NULL) {

        stat(dentry->d_name, &stat_entry);
        // Se for ficheiro regular
        if (S_ISREG(stat_entry.st_mode)) {
            fork_result = fork();
            if (fork_result == -1) {
                printf("file fork error!\n");
                exit(1);
            }
            if (fork_result == 0) {
                execlp("monfile", "monfile", argv[SEC_ARG], dentry->d_name, filedes, (char *)NULL);
                printf("Erro no exec!\n");
                exit(1);
            }
        }
        // Se for directório vai criar um novo processo e passar dir para esse directório 
        if (S_ISDIR (stat_entry.st_mode)) {
            fork_result = fork();
            if (fork_result == -1) {
                printf ("dir fork error!\n");
                exit(1);
            }
            if (fork_result == 0) {
                chdir(dentry->d_name);
                dir = opendir (dentry->d_name);
            }
        }
    }



    return 0;
}

Now, the result of this was...a ton of exec error messages and then a bunch of fork error messages, even though I was just calling this for a directory with a file and a sub-directory. This brought me 2 questions:
a) How was the cicle doing so many iterations?
b) What was wrong with the exec, seeing how monfile is built and in the same folder as mondir?

So, I decided to figure out what directory the program was looking at by adding

printf("%s\n", dentry->d_name);

at the beggining of the cicle, and it was somehow scanning every directory, even though it was called like this: mondir Subfolder1 ...(other args), being Subfolder1 in the same directory as mondir. What am I doing wrong here, both with the directory problem and the exec problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

任性一次 2024-11-05 01:42:47

readdir 将返回“.”和“..”,这样你的代码就会沿着目录树向上走,并永远重复每个目录——fork/exec 轰炸你的机器。

另外,如前所述,find -exec 似乎是一个合理的替代方案?

readdir will return "." and ".." so you code will walk up the directory tree, as well as repeating every directory forever - fork/exec bombing your machine.

Also, as mentioned, find -exec would seem a reasonable alternative?

冷了相思 2024-11-05 01:42:47

您的代码不能很好地处理子目录。您停止处理当前目录(但在进程中泄漏了 DIR 指针,因为您在用新目录覆盖之前没有对旧目录执行 closedir() 操作),然后 chdir()< /code> 进入新目录。

您也不会避免目录条目 ...;您可能不想处理它们,但 readdir() 会忠实地将它们作为每个目录中的前两个条目返回。这就是进程泛滥的原因。

您应该查找 POSIX 函数 nftw() 并使用它 - 或者在代码运行之前不要尝试处理目录。

Your code is not handling sub-directories very well. You stop processing the current directory (but leak a DIR pointer in the process since you do not do closedir() on the old one before overwriting with the new one) and then chdir() into the new directory.

You also don't avoid directory entries . and ..; you probably do not want to process them, but readdir() will faithfully return them as the first two entries in each directory. This accounts for the flood of processes.

You should look up the POSIX function nftw() and use that - or not try handling directories until after your code is working.

寄人书 2024-11-05 01:42:47

您正在绊倒一个非常常见的错误:readdir()返回的名称没有源名称名称,因此您必须自己将其放在那里。

You're tripping over a very common mistake: the names returned by readdir() don't have the source directory name prepended, so you have to put it there yourself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文