2015-03-13 1 views
4

J'ai joué avec des tampons de copie en écriture sur Linux et l'exemple suivant semble fonctionner comme prévu:tampon copie-sur-écriture avec mmap sous Mac OS X

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/mman.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <string.h> 

#define SIZE 4096 

#define SHM_NAME "foobar" 

int main(void) 
{ 
    int fd = shm_open(SHM_NAME, O_RDWR | O_CREAT, 0666); 
    int r = ftruncate(fd, SIZE); 

    char *buf1 = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, 
        MAP_SHARED, fd, 0); 

    strcpy(buf1, "Original buffer"); 

    char *buf2 = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, 
         MAP_PRIVATE, fd, 0); 

    // At this point buf2 is aliased to buf1 

    // Now modifying buf2 should trigger copy-on-write)... 

    strcpy(buf2, "Modified buffer"); 

    // buf1 and buf2 are now two separate buffers 

    strcpy(buf1, "Modified original buffer"); 

    // clean up 

    r = munmap(buf2, SIZE); 
    printf("munmap(buf2): %i\n", r); 
    r = munmap(buf1, SIZE); 
    printf("munmap(buf1): %i\n", r); 
    r = shm_unlink(SHM_NAME); 
    printf("shm_unlink: %i\n", r); 

    return EXIT_SUCCESS; 
} 

Cependant, sous OS X (10.10) le deuxième appel mmap renvoie MAP_FAILED, avec errno = 22 (EINVAL). Le OS X man page for mmap semble suggérer que cela devrait fonctionner (il mentionne même copy-on-write dans la description du drapeau MAP_PRIVATE), et j'ai expérimenté avec différents drapeaux différents pour les appels à mmap, mais rien ne semble fonctionner. Des idées ?

+0

Sur 'OS X' utilisant' MAP_PRIVATE' ne gère pas les descripteurs de fichier de la même manière. –

+0

@ l'L: merci pour l'indice - pouvez-vous me donner plus de détails? –

+0

Jetez un coup d'oeil [ici] (https://gist.github.com/anonymous/256a83cad3dd43895553). –

Répondre

2

Il semble que l'utilisation de shm_open avec MAP_SHARED et MAP_PRIVATE fasse quelque chose d'indésirable avec le descripteur de fichier. L'utilisation open est une solution possible:

int fd = open(SHM_NAME, O_RDWR | O_CREAT, 0666); 
... 

Résultat:

munmap(buf2): 0 
munmap(buf1): 0 
shm_unlink: -1 

utilisant shm_open avec MAP_SHARED et MAP_PRIVATE résultats dans un Invalid file descriptor, bien l'utiliser avec MAP_SHARED et MAP_SHARED par exemple ne fonctionne pas. Ce n'est pas clair pour moi si c'est un bug, ou par conception - le comportement ne semble pas correct cependant.

+1

Merci - le passage de 'shm_open' à' open' avec un fichier normal a résolu mon problème! –