español - ¿Argumento no válido para mmap de lectura-escritura?
qgis español (2)
Su statbuf.st_size
es 0
. mmap()
fallará si el parámetro de longitud es 0
.
Hay 3 razones enumeradas para el error EINVAL
mmap()
:
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
...
- No nos gusta
addr
,length
ooffset
(por ejemplo, son demasiado grandes o no están alineados en el límite de una página).- (Desde Linux 2.6.12) la
length
era 0.flags
no conteníanMAP_PRIVATE
niMAP_SHARED
, o contenían ambos valores.
Estoy recibiendo -EINVAL
por alguna razón, y no tengo claro por qué. Aquí es donde abro e intento mmap
el archivo:
if ((fd = open(argv[1], O_RDWR)) < 0)
{
fprintf(stderr, "Failed to open %s: %s/n", argv[1], strerror(errno));
return 1;
}
struct stat statbuf;
if (fstat(fd, &statbuf))
{
fprintf(stderr, "stat filed: %s/n", strerror(errno));
return 1;
}
char* fbase = mmap(NULL, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (fbase == MAP_FAILED)
{
fprintf(stderr, "mmap failed: %s/n", strerror(errno));
return 1;
}
EDITAR: Debería agregar, el error está ocurriendo en el mmap
.
Resulta que cambiar el MAP_SHARED
a MAP_PRIVATE
permite que esto MAP_PRIVATE
éxito.
Esta razón por la que falló fue sutil: mi código se ejecuta dentro de una VM VirtualBox, y el archivo que intentaba hacer mmap
estaba en un directorio compartido en mi máquina host. El sistema de archivos virtual VirtualBox aparentemente no implementa mmap
con la opción MAP_SHARED
través del límite del hipervisor.
Si lees los útiles comentarios de jxh tanto en mi pregunta como en su respuesta, resulta que este código estaba funcionando para él porque probablemente estaba intentando mmap
un archivo del sistema de archivos del host en la memoria del host.
Mi observación de que el cambio de MAP_SHARED
a MAP_PRIVATE
también es coherente con esto: dado que la memoria asignada de forma privada es invisible para otros procesos, el controlador del sistema de archivos virtual probablemente no tendrá ninguna objeción en asignar la memoria.
La solución fue mover el archivo que quería mapear en el disco duro del huésped y realizar la manipulación desde allí.