Close a FD (file descriptor) that was opened with shm_open() , without using close()?

c, file-descriptor

Solution

It sounds like a puzzle to me: How do you close a file descriptor without calling close on the fd? Here's one way:

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

Here's another:

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

Okay, the second doesn't work until after you `exec`. Oh well...

One more:

int close_without_close3 (int fd) {
    return syscall(SYS_close, fd);
}

Problem

I want to close a FD that was opened with `shm_open` . Here's the code : ``` #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; } ``` How can I close the `fd` without `close()` ? Thanks

Original source