NOMBRE¶
mmap, munmap - ubica o elimina ficheros o dispositivos en memoria
SINOPSIS¶
#include <sys/mman.h>
 
caddr_t mmap(void *start, size_t length, int
  prot , int flags, int fd, off_t
  offset);
 
int munmap(void *start, size_t length);
DESCRIPCIÓN¶
La función 
mmap intenta ubicar 
length bytes comenzando en el
  desplazamiento 
offset desde el fichero (u otro objeto) especificado por
  el descriptor de fichero 
fd en memoria, preferiblemente en la
  dirección 
start. Esta última dirección es una sugerencia
  y normalmente se especifica como 0. El lugar donde es ubicado el objeto es
  devuelto por 
mmap, y nunca vale 0. El argumento 
prot describe la
  protección de memoria deseada. (y no debe entrar en conflicto con el modo
  de apertura del fichero). Puede valer 
PROT_NONE o ser la
  combinación mediante la operación OR de una o más de las otras
  banderas PROT_*.
  - PROT_EXEC
 
  - Las páginas deben ser ejecutadas.
 
  - PROT_READ
 
  - Las páginas deben ser leídas.
 
  - PROT_WRITE
 
  - Las páginas deben ser escritas.
 
  - PROT_NONE
 
  - Las páginas no pueden ser accedidas.
 
El parámetro 
flags especifica el tipo de objeto insertado, las
  opciones de asociación y si las modificaciones hechas a la copia
  insertada en memoria son privadas al proceso o son compartidas por otras
  referencias. Tiene los bits:
  - MAP_FIXED
 
  - No seleccionar una dirección diferente a la
      especificada. Si la dirección especificada no puede ser utilizada,
      mmap fallará. Si MAP_FIXED es especificado, start debe
      ser un múltiplo del tamaño de página. Utilizar esta
      opción es desaconsejable.
 
  - MAP_SHARED
 
  - Comparte este área con todos los otros objetos que
      señalan a este objeto. Almacenar en la región es equivalente a
      escribir en el fichero. El fichero puede no actualizarse hasta que se
      llame a msync(2) o munmap(2).
 
  - MAP_PRIVATE
 
  - Crear un área privada "copy-on-write".
      Almacenar en la región no afecta al fichero original. Es indefinido
      si los cambios hechos al fichero después de la llamada a mmap
      son visibles en la región mapeada.
 
Debe especificarse exactamente uno de los parámetros MAP_SHARED o
  MAP_PRIVATE.
Los tres parámetros anteriores están descritos en POSIX.1b
  (formalmente POSIX.4) y Linux también reconoce los siguientes
  parámetros no estándares:
  - MAP_DENYWRITE
 
  - Este parámetro es ignorado. (Anteriormente, indicaba
      que los intentos de escritura al fichero subyacente deberían fallar
      con ETXTBUSY. Pero ésto era fuente de ataques de denegación
      -de-servicio.)
 
  - MAP_EXECUTABLE
 
  - Este parámetro es ignorado.
 
  - MAP_NORESERVE
 
  - (Usado junto con MAP_PRIVATE.) No reserva páginas del
      espacio de intercambio para esta correspondencia. Cuando se reserva
      espacio de intercambio, se tiene la garantía de que es posible
      modificar esta región privada. Cuando no se reserva puede obtenerse
      una violación de segmento al escribir si no hay memoria
    disponible.
 
  - MAP_LOCKED
 
  - Este parámetro es ignorado.
 
  - MAP_GROWSDOWN
 
  - Usado para pilas. Indica al sistema VM del núcleo que
      la correspondencia podría extenderse hacia abajo en memoria.
 
  - MAP_ANONYMOUS
 
  - La correspondencia no está respaldada por ningún
      fichero; los argumentos fd y offset son ignorados. Este
      parámetro conjuntamente con MAP_SHARED está implementado desde
      Linux 2.4.
 
  - MAP_ANON
 
  - Sinónimo para MAP_ANONYMOUS. Desaconsejado.
 
  - MAP_FILE
 
  - Parámetro de compatibilidad. Ignorado.
 
  - MAP_32BIT
 
  - Ubica la correspondencia dentro de los primeros 2 GB del
      espacio de direcciones del proceso. Es ignorado cuando MAP_FIXED
      está activo. Este parámetro está soportado actualmente
      sólo sobre x86-64 para programas de 64 bits.
 
Algunos sistemas documentan los parámetros adicionales MAP_AUTOGROW,
  MAP_AUTORESRV, MAP_COPY, y MAP_LOCAL.
fd debe ser un descriptor de fichero válido, a menos que
  MAP_ANONYMOUS esté activo, en cuyo caso el argumento es ignorado.
offset debe ser un múltiplo del tamaño de página como lo
  devuelve 
getpagesize(2).
La memoria asociada con 
mmap es conservada después de
  
fork(2), con los mismos atributos.
Un fichero es ubicado en múltiplos del tamaño de página. Para un
  fichero que no sea múltiplo del tamaño de página, la memoria
  restante es puesta a cero cuando se ubica, y las escrituras a esa región
  no son llevadas al fichero. El efecto de cambiar el tamaño del fichero
  subyacente a una correspondencia en aquellas páginas que correspondan a
  regiones añadidas o eliminadas del fichero es indefinido.
 
La llamada al sistema 
munmap borra las ubicaciones para el rango de
  direcciones especificado, y produce referencias a las direcciones dentro del
  rango a fin de generar referencias a memoria inválidas. La región es
  también desubicada automáticamente cuando el proceso termina. Por
  otra parte, cerrar el descriptor de fichero no desubica la región.
La dirección 
start debe ser un múltiplo del tamaño de
  página. Todas las páginas que contengan una parte del rango indicado
  son desubicadas, y referencias posteriores a estas páginas generarán
  una violación de segmento. No se considera un error si el rango indicado
  no contiene páginas con correspondencia.
 
Para correspondencias respaldadas por fichero, el campo 
st_atime para el
  fichero ubicado puede ser actualizado en cualquier instante entre la llamada
  
mmap() y la desubicación correspondiente; la primera referencia a
  una página con correspondencia actualizará el campo si no lo ha sido
  ya.
Los campos 
st_ctime y 
st_mtime para un fichero ubicado con
  PROT_WRITE y MAP_SHARED serán actualizados después de una escritura
  a la región ubicada, y antes de una llamada posterior a 
msync()
  con la opción MS_SYNC o MS_ASYNC, si alguna procede.
VALOR DEVUELTO¶
Si ha funcionado 
mmap devuelve un puntero al área reservada. En caso
  de error, es devuelto -1, y 
errno es modificado apropiadamente. Si ha
  funcionado 
munmap devuelve 0, si hay error -1, y 
errno es fijada
  (probablemente a EINVAL).
OBSERVACIONES¶
Es dependiente de la arquitectura si 
PROT_READ incluye a 
PROT_EXEC
  o no. Los programas portables deberían siempre activar 
PROT_EXEC
  si intentan ejecutar código en la nueva región ubicada.
ERRORES¶
  - EBADF
 
  - fd no es un descriptor de fichero válido (y
      MAP_ANONYMOUS no ha sido fijado).
 
  - EACCES
 
  - Un descriptor de fichero hace referencia a un fichero no
      regular. O bien se solicitó MAP_PRIVATE, pero fd no está
      abierto para lectura. O bien se solicitó MAP_SHARED y PROT_WRITE
      está activo, pero fd no está abierto en modo
      lectura/escritura (O_RDWR). O bien PROT_WRITE está activo, pero el
      fichero es sólo para añadir.
 
  - EINVAL
 
  - No es correcto start o length o
      offset. (E.g., son demasiado grandes, o no están alineados en
      los limites de un valor múltiplo de PAGESIZE).
 
  - ETXTBSY
 
  - MAP_DENYWRITE fue fijado pero el objeto especificado por
      fd está abierto para escritura.
 
  - EAGAIN
 
  - El fichero ha sido bloqueado, o se ha bloqueado una
      cantidad excesiva de memoria.
 
  - ENOMEM
 
  - No hay memoria disponible, o el número máximo de
      correspondencias del proceso habría sido excedido.
 
  - ENODEV
 
  - El sistema de ficheros subyacente del fichero especificado
      no soporta la correspondencia de memoria.
 
El uso de una región ubicada puede resultar en estas señales:
  - SIGSEGV
 
  - Intento de escritura en una región especificada a mmap
      como solo-lectura.
 
  - SIGBUS
 
  - Intento de acceso a una porción del buffer que no se
      corresponde con el fichero (por ejemplo, más allá del fin del
      fichero, incluyendo el caso en el que otro proceso ha truncado el
      fichero).
 
SVr4, POSIX.1b (formalmente POSIX.4), 4.4BSD, SUSv2. SVr4 documenta los
  códigos de error ENXIO y ENODEV. SUSv2 documenta ls códigos de error
  adicionales EMFILE y EOVERFLOW.
 
MAP_32BIT es una extensión de Linux.
VÉASE TAMBIÉN¶
getpagesize(2), 
mmap2(2), 
mremap(2), 
msync(2),
  
shm_open(2), B.O. Gallmeister, POSIX.4, O'Reilly, pp. 128-129 and
  389-391.