4

我想关闭一个用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 的情况下关闭文件描述符?这是一种方法:

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;
}

好的,直到你之后,第二个才起作用exec。那好吧...

多一个:

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 回答