4

で開いたFDを閉じたいshm_open

コードは次のとおりです。

 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>             
 #include <sys/file.h>           
 #include <sys/mman.h>          
 #include <sys/wait.h>

 void errorAndExit(const char *msg)
 {
     perror(msg);
     exit(EXIT_FAILURE);
 }

 int main(int argc, char *argv[])
 {
      /* shm_open recommends using a leading '/' in
      the region name for portability, but Linux
      doesn't require it. */

      const char *memname = "/myMkfifo.txt";

      // Use one page for this example

      const size_t region_size = sysconf(_SC_PAGE_SIZE);

     /* Create the shared memory region.
      Notice the args are identical to open(2).*/

     int fd = shm_open(memname, O_CREAT | O_TRUNC | O_RDWR, 0666);
     if (fd == -1)
         errorAndExit("shm_open");

    /* Allocate some memory in the region. We use ftruncate, but
     write(2) would work just as well. */

     int r = ftruncate(fd, region_size);
     if (r != 0)
         errorAndExit("ftruncate");

    // Map the region into memory.

     void *ptr =
         mmap(0, region_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
              0);
     if (ptr == MAP_FAILED)
         errorAndExit("mmap");

     // Don't need the fd after the mmmap call.

     close(fd);
     pid_t pid = fork();

     if (pid == 0)   // son
     {
         // Child process inherits the shared memory mapping.

         u_long *d = (u_long *) ptr;
         *d = 200;
         printf("I'm the child process and I wrote: %#lx\n", *(u_long *) d);
         exit(0);
     }


     else    
     {   /* child
          Synchronize with the child process. */

         int status;
         waitpid(pid, &status, 0);

         // Parent process sees the same memory.

         printf("I'm the father process , and my child wrote: %#lx\n", *(u_long *) ptr);

     }

     // errorAndExit with the memory, umap it.

     r = munmap(ptr, region_size);
     if (r != 0)
         errorAndExit("munmap");

     // Remove the shared memory region.

     r = shm_unlink(memname);
     if (r != 0)
         errorAndExit("shm_unlink");

    return 0;
}

fdなしで閉じるにはどうすればよいclose()ですか?

ありがとう

4

2 に答える 2

4

私にはパズルのように聞こえます.fdでcloseを呼び出さずにファイル記述子を閉じるにはどうすればよいですか? 1 つの方法を次に示します。

int close_without_close (int fd) {
    if (dup2(!fd, fd) < 0) return -1; // assumes 0 and 1 are open
    return close(!fd);
}

ここに別のものがあります:

int close_without_close2 (int fd) {
    if (fcntl(fd, fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) return -1;
    switch (fork()) {
    case -1: return -1;
    case 0:  break;
    default: exit(EXIT_SUCCESS);
    }
    return 0;
}

わかりました、2番目はあなたの後まで機能しませんexec. しかたがない...

もう1つ:

int close_without_close3 (int fd) {
    return syscall(SYS_close, fd);
}
于 2012-07-18T08:22:49.990 に答える
2

これは、close() を回避するための (コストのかかる...) 方法です ...

#include <unistd.h>
#include <fcntl.h>

int main (int argc, char **argv)
{
int val;
int fd = -1;

val = fcntl(fd, F_GETFD, 0);
val |= FD_CLOEXEC;
fcntl(fd, F_SETFD, val);

execve(argv[0], argv, NULL);
return 0; /* not reached */
}
于 2012-07-18T09:06:09.187 に答える