返回fprintf的值

时间:2015-04-28 22:24:11

标签: c printf fwrite

#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main(void)
{
    FILE *fh = fopen ("file.txt", "w");
    if (fh != NULL) {
        int i = 0;
        while(i < 5){
            if (fprintf (fh, "%s", "hello") < 0)
            {
                fprintf (stderr, "err=%d: %s\n", errno, strerror (errno));
            }
            if(ferror(fh))
            {
                printf("wrong\n");
            }
            sleep(10);
        }
    }  
    return(0);
}

当我删除文件&#34; file.txt&#34;在程序运行期间,我希望fprintf返回小于0的值以打印错误消息。但是fprintf总是返回&#34;你好&#34;的大小。字符串是5。

注意:由于有10秒的睡眠调用,我在程序终止之前删除了该文件。

如果fprintf / fwrite写入不再存在的文件(由文件描述符指向),请说明如何生成错误消息。

2 个答案:

答案 0 :(得分:5)

在类UNIX系统上,&#34;删除&#34;文件不会物理删除磁盘上的文件。它只是将链接数减少1.文件实际上不会被删除,直到它的最后一个链接消失。这就是调用rm命令调用的系统调用unlink的原因。 man 2 unlink了解更多信息。

如果您创建指向文件的硬链接,则可以看到其中一个结果:

echo "hello" > file0
ln file0 file1
rm file0

rm file0命令表示该名称不再显示该文件,但通过其他名称file1仍然可以看到该文件。如果你然后rm file1,实际文件将最终消失。

阻止文件被删除的另一种方法是让进程打开它。您的程序创建一个文件,并创建一个名为"file.txt"的目录条目。在程序外键入rm file.txt时,将删除目录条目,而不是文件。您的程序仍然可以写入该文件。它甚至可以回到文件的开头并再次阅读。

如果您的程序调用{​​{1}},或者它终止(隐式关闭所有打开的文件),那么对磁盘文件的最后一次引用将会消失,并且磁盘上的实际文件将被删除。

非UNIX系统(如Windows)可能表现不同。

答案 1 :(得分:0)

还有一种方法可以检查目录是否被删除而不从磁盘读取。

inotify系统调用执行监视目录的工作,如果删除了目录,则会向创建了inotify实例的主程序发送回调。

一个简单的例子 - 这是从inotify的手册页复制的。 link

+/* demo_inotify.c
+
+   Demonstrate the use of the inotify API.
+
+   Usage: demo_inotify pathname...
+
+   The program monitors each of the files specified on the command line for all
+   possible file events.
+
+   This program is Linux-specific. The inotify API is available in Linux 2.6.13
+   and later.
+*/
 #include <sys/inotify.h>
 #include <limits.h>
 #include "tlpi_hdr.h"

 static void             /* Display information from inotify_event structure */
 displayInotifyEvent(struct inotify_event *i)
 {
     printf("    wd =%2d; ", i->wd);
     if (i->cookie > 0)
         printf("cookie =%4d; ", i->cookie);

     printf("mask = ");
     if (i->mask & IN_ACCESS)        printf("IN_ACCESS ");
     if (i->mask & IN_ATTRIB)        printf("IN_ATTRIB ");
     if (i->mask & IN_CLOSE_NOWRITE) printf("IN_CLOSE_NOWRITE ");
     if (i->mask & IN_CLOSE_WRITE)   printf("IN_CLOSE_WRITE ");
     if (i->mask & IN_CREATE)        printf("IN_CREATE ");
     if (i->mask & IN_DELETE)        printf("IN_DELETE ");
     if (i->mask & IN_DELETE_SELF)   printf("IN_DELETE_SELF ");
     if (i->mask & IN_IGNORED)       printf("IN_IGNORED ");
     if (i->mask & IN_ISDIR)         printf("IN_ISDIR ");
     if (i->mask & IN_MODIFY)        printf("IN_MODIFY ");
     if (i->mask & IN_MOVE_SELF)     printf("IN_MOVE_SELF ");
     if (i->mask & IN_MOVED_FROM)    printf("IN_MOVED_FROM ");
     if (i->mask & IN_MOVED_TO)      printf("IN_MOVED_TO ");
     if (i->mask & IN_OPEN)          printf("IN_OPEN ");
     if (i->mask & IN_Q_OVERFLOW)    printf("IN_Q_OVERFLOW ");
     if (i->mask & IN_UNMOUNT)       printf("IN_UNMOUNT ");
     printf("\n");

     if (i->len > 0)
         printf("        name = %s\n", i->name);
 }

 #define BUF_LEN (10 * (sizeof(struct inotify_event) + NAME_MAX + 1))

 int
 main(int argc, char *argv[])
 {
     int inotifyFd, wd, j;
     char buf[BUF_LEN] __attribute__ ((aligned(8)));
     ssize_t numRead;
     char *p;
     struct inotify_event *event;

     if (argc < 2 || strcmp(argv[1], "--help") == 0)
         usageErr("%s pathname...\n", argv[0]);

     inotifyFd = inotify_init();                 /* Create inotify instance */
     if (inotifyFd == -1)
         errExit("inotify_init");

+    /* For each command-line argument, add a watch for all events */
+
     for (j = 1; j < argc; j++) {
         wd = inotify_add_watch(inotifyFd, argv[j], IN_ALL_EVENTS);
         if (wd == -1)
             errExit("inotify_add_watch");

         printf("Watching %s using wd %d\n", argv[j], wd);
     }

     for (;;) {                                  /* Read events forever */
         numRead = read(inotifyFd, buf, BUF_LEN);
         if (numRead == 0)
             fatal("read() from inotify fd returned 0!");

         if (numRead == -1)
             errExit("read");

         printf("Read %ld bytes from inotify fd\n", (long) numRead);

         /* Process all of the events in buffer returned by read() */

         for (p = buf; p < buf + numRead; ) {
             event = (struct inotify_event *) p;
             displayInotifyEvent(event);

             p += sizeof(struct inotify_event) + event->len;
         }
     }

     exit(EXIT_SUCCESS);
 }