在循环中打开文件时如何避免分段错误?

时间:2019-03-07 16:18:55

标签: c file loops

当尝试打开文件(由event-> name定义)时,我一直遇到分段错误(核心转储)。我要防止此问题的最接近方法是将“ rb”更改为“ r”,并删除其下方的哈希函数-包括“ fclose(ftest)”-但是我不认为这一进展...

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/inotify.h>
#include <openssl/sha.h>

int main (int argc, char *argv[])
{
        int fd;
        int wd;
        unsigned char c[SHA512_DIGEST_LENGTH];
        int i;
        SHA512_CTX mdContext;
        int bytes;
        unsigned char data[1024];
        const int event_size = sizeof(struct inotify_event);
        const int buf_len = 1024 * (event_size + FILENAME_MAX);
        FILE *ftest;

        fd = inotify_init();

        if (fd < 0) {
          perror("inotify_init");
        }

        wd = inotify_add_watch(fd, "/home/joe/Documents", IN_CREATE);

        while (1) {
          char buff[buf_len];
          int no_of_events, count = 0;

          no_of_events = read (fd, buff, buf_len);
          while (count < no_of_events) {
            struct inotify_event *event = (struct inotify_event *)&buff[count];
            if (event->len) {
              if (event->mask & IN_CREATE)
              if(!(event->mask & IN_ISDIR)) {
                printf("The file %s has been created\n", event->name);

                ftest=fopen(event->name, "rb");  //segmentation fault 
                                                 //occurs here
                SHA512_Init (&mdContext);        
                while ((bytes = fread (data, 1, 1024, ftest)) != 0)
                    SHA512_Update (&mdContext, data, bytes);
                SHA512_Final (c,&mdContext);
                for(i = 0; i < SHA512_DIGEST_LENGTH; i++) printf("%02x", c[i]);
                printf (" %s\n", ftest);
                fclose (ftest);
                fflush(stdout);
              }
            }
            count += event_size + event->len;
          }
        }
        return 0;
}

通过Valgrind进行此操作后,它不会在细分错误之前提供任何错误的详细信息,并且一旦发生错误,此后就不会提供详细信息。

1 个答案:

答案 0 :(得分:3)

您的问题是您没有检查任何返回值。每个返回某些内容的函数调用都必须进行检查和处理。特别是,您不检查以下内容的返回值:

ftest=fopen(event->name, "rb");  //segmentation fault 

如果它返回空值(例如,因为event->name包含文件名,而不是完整路径,并且您不在要监视的目录中运行),则会收到错误消息。

您也没有选中此

wd = inotify_add_watch(fd, "/home/joe/Documents", IN_CREATE);

可能还有其他人。

另一个问题是您要在此处将文件句柄打印为字符串:

printf (" %s\n", ftest);

此外,为了在调试器和valgrind中获得有用的信息,您还需要使用调试信息(gcc -g)进行构建