Acerca de
Tutoriales
Comunidad
Actualidad
Enlaces





En MacProgramadores
En Internet

Trucos

HFS+



En este truco se estudian las distintas características de HFS+, el sistema de ficheros de Mac OS X.

El estudio se hace tanto a nivel conceptual como a nivel práctico, utilizando para ello comandos de consola que ayudan a identificar estas características.

Esperamos que conocer estas características le ayude a resolver y entender mejor problemas con los que los desarrolladores y usuarios avanzados se enfrentan a menudo.


Introducción

HFS Plus o HFS+ es el sistema de ficheros desarrollado por Apple para Mac OS X, y que reemplaza el antiguo HFS (Hierarchical File System). El nombre HFS+ es el usado en la documentación para programadores. En la documentación para usuarios suele usarse el nombre Mac OS Extended. Las principales ventajas que incluye HFS+ respecto a HFS son: dispone de un sistema de journaling, permisos al estilo UNIX, y los nombres de fichero se representan en Unicode (y no en Mac OS Roman). Como veremos, a partir de Mac OS X 10.4, además de permisos UNIX, se puede usar una ACL (Access Control List).

Resource fork y data fork

En Mac OS Classic cada fichero está compuesto por dos ficheros que comparten el mismo nombre: El resource fork y el data fork. El resource fork está formado por recursos, cada uno de los cuales se identifica con un código de cuatro letras que indica el tipo del recurso. El data fork es un fichero plano convencional. En Mac OS X se conservan estos dos fork, pero se utiliza con mucha más frecuencia el data fork. Podemos usar la herramienta ResKnife para consultar el resource fork y data fork de un fichero Mac OS X.

También podemos extraer el recurso de un fichero usando el comando /Developer/Tools/DeRez. Por ejemplo, para extraer el recurso de tipo icns del fichero donorfile.jpg, y guardarlo en el fichero tempicns.rsrc hacemos:

$ /Developer/Tools/DeRez -only icns donorfile.jpg > tempicns.rsrc

Si lo que queremos es guardar un recurso en el fichero podemos usar el comando Rez. Por ejemplo, para poner un icono personalizado al fichero donorfile.jpg podemos usar los comandos:

$ /Developer/Tools/Rez -append tempicns.rsrc -o donorfile.jpg
$ /Developer/Tools/SetFile -a C donorfile.jpg

Más adelante veremos que el comando /Developer/Tools/SetFile sirve (entre otras cosas) para activar el atributo de fichero C (custom icon).

Por último podemos consultar el resource fork de un fichero con el comando /Developer/Tools/RezDet. Por ejemplo:

$ RezDet -l donorfile.jpg
"donorfile.jpg": 'icns' (-16455) [52110]
The resource fork of donorfile.jpg appears to be OK.

Desde la línea de comandos podemos acceder al data fork y al resource fork usando como nombre de fichero fichero/..namedfork/data y fichero/..namedfork/rsrc respectivamente. Por ejemplo, si tenemos el fichero cosas.txt con data y resource fork, podemos acceder al data fork de dos formas:

$ cat cosas.txt
Una prueba
$ cat cosas.txt/..namedfork/data
Una prueba

Y para acceder al resource fork usamos:

$ cat cosas.txt/..namedfork/rsrc
99'?T,2BNDL

Muchos comandos UNIX de Mac OS X (p.e. el comando cp) copian sólo el data fork. Si queremos que se copie el resource fork debemos usar el comando /usr/bin/ditto (disponible en cualquier sistema Mac OS X), o el comando /Developer/Tools/CpMac (disponible sólo con las Developer Tools).

Type code, Creator code, y Launch Services

En Mac OS Classic (y después lo heredó Mac OS X) cada fichero HFS tiene asociado un type code que es un código de cuatro letras indicando el tipo del fichero, y un creator code que es otro código de cuatro letras el cual indica qué aplicación creo el fichero. Podemos consultar estos códigos sobre un fichero de ejemplo con el comando:

$ /Developer/Tools/GetFileInfo P1010008.JPG
file: "/Volumes/Autor/home/Desktop/P1010008.JPG"
type: "JPEG"
creator: "Bwv2"
attributes: avbstclinmedz
created: 01/01/1904 00:00:00
modified: 03/18/2007 08:40:08

En el ejemplo el type code es JPEG, y el creator code es Bwv2 (Goldberg). También podemos usar el comando /Developer/Tools/SetFile para modificar estos valores.

Launch Services es el servicio de Mac OS X que se encarga de abrir un fichero o programa cuando hacemos doble click sobre él. Este servicio primero consulta el creator code, y si la aplicación con este creator code está disponible lanza esta aplicación. Si no usa alguna aplicación que se haya registrado como capaz de abrir el type code. En el ejemplo anterior, esto significa que, de estar disponible Goldberg (cuyo creator code es Bwv2), se usará esta aplicación para abrir el fichero, y en caso contrario se usará cualquier aplicación que pueda abrir ficheros de tipo JPEG.

La Tabla 1 muestra ejemplo de type code y creator code comunes.

Type code Descripción Creator code Descripción
TEXT Fichero de texto plano ttxt Text Edit
JPEG Imagen JPEG adrb Address Book
TIFF Imagen TIFF wrbt iCal
PDF Fichero PDF emal Mail
W8BN Microsoft Word MSWD Microsoft Word
XLS8 Microsoft Excel XCEL Microsoft Excel
APPL Aplicación DmWr Dream Weaver
BNDL Bundle MOZB FireFox
Tabla 1: Type code y creator code comunes

En Mac OS X se añadió también la posibilidad de que Launch Services tenga en cuenta la extensión del fichero. Esto permite trabajar con ficheros procedentes de otras plataformas (o de Internet), que no llevan asociado type code ni creator code. En general, las aplicaciones Carbon suelen usar el type code y creator code, mientras que las aplicaciones Cocoa suelen usar la extensión del fichero. Más especificamente, Launch Services sigue las siguientes reglas:

  1. Si el fichero tiene un creator code, y su aplicación está disponible, ésta será la aplicación que se use para abrir el fichero.
  2. Si el usuario ha especificado una aplicación preferida para abrir el fichero (usando el dialogo Get Info), ésta será la aplicación con la que se abrirá.
  3. Si no, Launch Services mira la extensión del fichero y usa la aplicación por defecto para abrir los ficheros con esta extensión. Esta aplicación por defecto también se configura desde el dialogo Get Info.
  4. Si no existe aplicación preferida para esta extensión consulta el type code, y en caso de existir usa la aplicación preferida para este type code.
  5. En caso contrario aparece un diálogo preguntando con qué aplicación abrir el fichero.

En el caso de las aplicaciones, estas siempre tienen el type code APPL, y su creator code no indica con qué aplicación abrirlas, sino qué creator code tienen los ficheros que generan (p.e. MooV para películas QuickTime). Además, en el caso de las aplicaciones el type code y creator code no se consultan con /Developer/Tools/GetFileInfo, sino que está información está dentro del bundle de la aplicación, en concreto puede estar en dos sitios:

  1. Algunas aplicaciones usan el fichero PkgInfo para almacenar ocho bytes correspondientes al type code y creator code de la aplicación.
  2. La forma más moderna es usar el fichero Info.plist para almacenar el type code (en la propiedad CFBundlePackageType), el creator code (en la propiedad CFBundleSignature). Esta segunda forma incorpora la ventaja de permitir indicar a Launch Services tanto las extensiones como los type codes de los ficheros que abre la aplicación (en la propiedad CFBundleDocumentTypes).

Información posicional

Cuando Finder pasa por una carpeta Mac OS X, crea un fichero .DS_Store donde almacena información posicional de los iconos en la carpeta. Este fichero no es visible desde Finder (ya que Finder nunca muestra los ficheros cuyo nombre empieza por punto), pero sí que es visibles desde el terminal.

La creación de este fichero ha sido muy criticada por los usuarios avanzados de Mac OS X. Especialmente se ha criticado que se crea este fichero cuando nos conectamos a un servicio de ficheros compartidos como Samba, AFP o NFS. Para evitar que Finder cree este fichero cuando nos conectamos a un servicio de red podemos cambiar la propiedad:

$ defaults write com.apple.desktopservices DSDontWriteNetworkStores true

Por desgracia no existe forma de evitar su creación en carpetas locales.

Atributos de fichero

La mayoría de los sistemas de ficheros permiten asociar atributos a los ficheros. En este apartado vamos a ver qué atributos pueden tener los ficheros en HFS+, y con qué comandos podemos leer y modificar estos atributos.

La Tabla 2 resume los atributos de fichero que soporta HFS+. Podemos usar el comando /Developer/Tools/GetFileInfo para consultar los atributos de un fichero. Por ejemplo:

$ cd Desktop
$ /Developer/Tools/GetFileInfo Xcode
file: "/Volumes/Autor/home/Desktop/Xcode"
type: "fapa"
creator: "xcde"
attributes: AvbstClinmedz
created: 04/12/2006 21:55:32
modified: 04/12/2006 21:55:32

Los atributos que estén activos aparecen en mayúscula. En el ejemplo anterior Xcode es un fichero colocado en el escritorio con el atributo A (alias) y C (Icono personalizado) activamos. El hecho de ser un alias hace que aparezca una fecha en la parte inferior izquierda como la de la figura.

Atributo Descripción
a
Alias
b
El directorio contiene un bundle
c
Icono personalizado (se permite en carpetas)
d
Fichero localizado en el escritorio (Mac OS Classic 6)
e
Extensión oculta (se permite en carpetas)
i

Inicializado. Finder ha dado una localización a este fichero. Este atributo lo usa sólo Finder. Cuando está activado indica que el fichero contiene recursos de base de datos ('BNDL', 'FREF', 'open', 'kind'...) que no han sido añadidos todavía a la base de datos del escritorio.

l
Bloqueado (locked)
m
Compartido. Si el fichero tiene desactivado este flag indica que puede tener datos en su resource fork, y en consecuencia no se puede compartir en una red. Si el flag está activado indica que está compartido en una red, y en consecuencia no se puede escribir en su resource fork.
n
El fichero no tiene recurso INIT. Indica que el fichero no contiene elementos que modifiquen el arranque de Mac OS Classic.
s
Fichero de sistema
t
Fichero stationery pad
v
Fichero invisible (se permite en carpetas)
z
Fichero ocupado (se permite en carpetas)
Tabla 2: Atributos de fichero

La forma de almacenar el icono personalizado es distinta en el caso de los ficheros que en el de los directorios. En ambos casos se activa el atributo C, pero en el caso de los ficheros se almacena en el resource fork un recurso de tipo icns con el icono (aunque tambien tiene cuatro letras, no debemos confundir el tipo de un recurso situado en el resource fork, con el type code o creator code del fichero). Mientras que en el caso de las carpetas se crea dentro de la carpeta un fichero Icon\n con los atributos C y V (invisible), y en el resource fork de este fichero se almacena un recurso de tipo icns con el icono.

El atributo B (bundle) lo usan las aplicaciones y bundles (add-ons) para que una carpeta sea vista por Finder como un único fichero.

Podemos pedir que no se muestre la extensión de un fichero activando el atributo E (extensión oculta). Para que estas extensiones se oculten es necesario desactivar la opción de Finder de mostrar las extensiones de todos los ficheros (situada en Preferences | Advanced). Algunas extensiones (p.e. .app) se ocultan incluso sin activar el flag E, pero para ello debemos haber indicado a Finder que no muestre las extensiones de todos los ficheros. Este atributo se puede modificar desde el diálogo Get Info.

El atributo L (que también se puede modificar desde el diálogo Get Info) permite crear ficheros cuyo contenido no se puede modificar.

En atributo T (que también se puede modificar desde el diálogo Get Info) permite crear un fichero que sirva como template. Si un fichero tiene este atributo, cuando se abre la aplicación crea una copia de su contenido en otro fichero, y esta copia es la que podemos modificar y guardar.

Existen tres situaciones en las que Finder no muestra algunos de los ficheros de la jerarquía de ficheros:

  • Los ficheros cuyo nombre empieza por punto (p.e. .profile) nunca los muestra Finder.
  • Los fichero que tiene el atributo V no se muestran en Finder.
  • Por último existen ciertos ficheros que están cableados dentro de Finder para que nunca se muestren (p.e. /automount).

Podemos desactivar el atributo V en algunos directorios de la raíz para que sí que los muestre Finder. Por ejemplo, los directorios /bin, /sbin y /usr tienen activo este atributo. Podemos desactivar este atributo ejecutando:

$ sudo SetFile -a V /bin /sbin /usr

Ahora (tras cerrar y volver a lanzar Finder), estos directorios serán accesibles desde Finder.

También es posible indicar a Finder que queremos ver todos los ficheros (aunque cumplan las reglas de ocultación anteriores) modifiando las preferencias de usuario, que no son más que ficheros de propiedades (de los cuales suele existir uno por cada aplicación) almacenados en la carpeta ~/Library/Preferences.

Podemos pedir a Finder que muestre todos los ficheros modificando la siguiente preferencia de usuario, con el comando:

$ defaults write com.apple.finder AppleShowAllFiles TRUE

Atributos extendidos

A partir de Mac OS X 10.4 se han introducido los atributos extendidos, que son pares clave-valor que se pueden asociar a cualquier objeto del sistema de ficheros (ficheros, directorios, enlaces simbólicos, ...). La clave es una cadena UTF-8 acabada en NULL que puede tener hasta 128 bytes. El valor es un puntero a un buffer (textual o binario) cuya longitud no está limitada.

En Mac OS X 10.4 sólo se puede acceder a los atributos extendidos a través de la capa BSD, en concreto con la familia de funciones getxattr(), setxattr(), removexattr() y listxattr(). Es de esperar que en un futuro se permita el acceso a estos atributos desde Carbon y Cocoa.

Apple proporciona unos comandos de ejemplo de uso de estos atributos aquí, que vamos a estudiar. Para usar estos comandos, lo primero que tenemos que hacer es descomprimir este fichero, compilarlo, e instalar los comandos setx, lsx y rmx en algún directorio dentro del PATH:

$ make
$ sudo cp setx lsx rmx /usr/local/bin

Ahora podemos crear un fichero:

$ cat > prueba.txt
Este fichero sirve para probar los atributos extendidos
^D
$ cat prueba.txt
Este fichero sirve para probar los atributos extendidos

A continuación podemos usar setx para añadir atributos al fichero:

$ setx nombre Fernando prueba.txt
$ setx edad 33 prueba.txt

Y ahora podemos usar lsx y rmx para listar y borrar atributos:

$ lsx prueba.txt
3 edad 33
9 nombre Fernando
$ rmx edad prueba.txt
$ lsx prueba.txt
9 nombre Fernando

El comando lsx nos muestra por cada atributo extendido: la longitud del valor, la clave y el valor.

Los atributos extendidos forman parte del sistema de ficheros, con lo que no se crear ficheros adicionales:

$ ls -la
drwxr-xr-x 49 fernando admin 1666 Apr 1 .
drwxrwxr-x 11 root     admin  476 Sep 2 ..
-rw-r--r--  1 fernando admin   62 Apr 1 prueba.txt

Ni entradas en el resource fork:

$ ls -l prueba.txt/..namedfork/rsrc
-rw-r--r-- 1 fernando admin 0 Apr 1 prueba.txt/..namedfork/rsrc

Además, los comandos UNIX preservan los atributos extendidos al copiar un fichero:

$ cp prueba.txt prueba2.txt
$ lsx prueba2.txt
9 nombre Fernando

En sistemas de ficheros anteriores o distintos a HFS+, los metadatos (resource forks, flags, atributos de fichero), y ahora también los atributos extendidos se guardan en ficheros con el prefijo "._". Pero en HFS+, todos estos metadatos se guardan en el propio sistema de ficheros. Por ejemplo, si creamos atributos extendidos en una unidad MS-DOS:

$ hdiutil create -size 50K -fs MS-DOS -volname DOS dos.dmg
$ hdiutil attach dos.dmg
/dev/disk1    /Volumes/DOS
$ cd /Volumes/DOS/
$ touch prueba.txt
$ setx autor "Fernando Lopez" prueba.txt
$ lsx prueba.txt
15 autor Fernando Lopez

Vemos que se ha creado un fichero ._prueba.txt para almacenar el atributo extendido:

$ ls -la
drwxrwxrwx 1 fernando fernando 16384 Apr 1 .
drwxrwxrwt 6 root     admin      204 Apr 1 ..
-rwxrwxrwx 1 fernando fernando  4096 Apr 1 ._prueba.txt
-rwxrwxrwx 1 fernando fernando     0 Apr 1 prueba.txt

Flags BSD

Además de los atributos de fichero y de los atributos extendidos, HFS+ soporta otro tipo de atributos heredados del mundo de BSD llamados flags de fichero. Estos flags de fichero se fijan con el comando chflags, y se resumen en la Tabla 3.

Flags Descripción
arch Fichero archivado
opaque Sólo es útil al usar la opción union al montar un sistema de ficheros.
nodump Sólo es útil en combinación con el comando dump
uchg Fichero inmutable por parte del usuario
uappnd Fichero en el que el usuario sólo puede añadir datos al final
schg Fichero inmutable por parte del superusuario
sappnd Fichero en el que el superusuario sólo puede añadir datos al final
Tabla 3: Flags de fichero

El flag uchg es equivalente al atributo de fichero L (Lock), y de hecho activando uno se activa el otro. Su finalidad es evitar que el usuario pueda modificar un fichero con este flag activado. Para activarlo sobre el fichero documento.txt hacemos:

$ chflags uchg documento.txt

Podemos ver los flags BSD activos con el comando ls y la opción -lo:

$ ls -alo
drwxr-xr-x 51 fernando admin -   1734 Apr 2 .
drwxrwxr-x 11 root     admin -    476 Sep 2 ..
-rw-r--r-- 1 fernando  admin uchg   0 Apr 2 documento.txt

Para desactivar un flag ponemos un no delante del flag:

$ chflags nouchg documento.txt

El flag schg es similar a uchg, pero sólo puede ser fijado por root o por un usuario que ejecute sudo. Sin embargo es mucho más difícil desactivar este flags, ya que para hacerlo deberemos reiniciar la máquina en modo monousuario.

Si lo que queremos es que a un fichero (p.e. fichero de log) sólo se le puedan añadir datos al final, pero no modificar lo ya escrito podemos activar el flag de usuario uappnd o de sistema sappnd.

ACL (Access Control List)

Las ACL son una forma de indicar los permisos de acceso sobre un fichero que permite mayor grado de personalización que el modelo de permisos tradicional de UNIX: r (read), w (write), x (execute), a nivel de usuario, grupo y todos.

Muchos usuarios prefieren el modelo de permisos de UNIX porque lo consideran lo suficientemente flexible para sus necesidades, y mucho más simple que el modelo las ACL. Uno de los motivos por los que se introdujeron las ACL en Mac OS X 10.4 fue para poder usar el modelo de permisos de Active Directory implementado en Microsoft Windows.

Una ACL es una lista ordenada de reglas que controlan el acceso a un fichero. Cada regla especifica tres cosas: Un actor (usuario o grupo), un permiso (las posibles permisos se resumen en la Tabla 4), y si el permiso se activa o se deniega. A cada regla también se la llama ACE (Access control Entry).

Permiso Descripción Objetos
read Abrir para lectura Todos excepto directorios
write Abrir para escritura Todos excepto directorios
append Abrir para escritura al final Todos excepto directorios
execute Ejecutar script o programa Todos excepto directorios
delete Borrar el objeto del sistema de ficheros Todos
chown Cambiar los permisos del fichero Todos
readattr Leer atributos de fichero Todos
writeattr Escribir atributos de fichero Todos
readextattr Leer atributos extendidos Todos
writeextattr Escribir atributos extendidos Todos
readsecurity Leer la ACL Todos
writesecurity Escribir la ACL Todos
list Listar el contenido del directorio Directorios
search Buscar un fichero por nombre en el directorio Directorios
add_file Añadir un fichero al directorio Directorios
add_subdirectory Añadir un subdirectorio al directorio Directorios
delete_child Borrar un fichero o subdirectorio del directorio Directorios
Tabla 4: Tipos de permisos de acceso de una ACE

Las reglas se evalúan en orden hasta que la regla se puede aplicar (es decir, el actor y el permiso coinciden). La primera regla que es aplicable determina la decisión. Si ninguna regla se puede aplicar, entonces se usan los permisos tradicionales de UNIX para decidir el acceso.

Téngase en cuenta que los permisos de UNIX no se tienen en cuenta a no ser que ninguna regla de la ACL se cumpla. Esto puede confundir al usuario ya que los permisos UNIX son ignorados si una regla de la ACL se cumple. Para evitar problemas a los usuarios que desconocen las ACL, las ACL están por defecto desactivadas en el sistema de fichero de Mac OS X. Si queremos activar las ACL tenemos que ejecutar el comando fsaclctl sobre el sistema de ficheros en el que queramos activarlas. Por ejemplo, para activar las ACL sobre la raíz de nuestro disco hacemos:

$ sudo /usr/sbin/fsaclctl -p / -e

La opción -p indica el directorio donde está montada la unidad en la que queremos activar las ACL. La opción -e activa las ACL, y la opción -d desactivaría las ACL.

Para estudiar el uso de las ACL, podemos crearnos un sistema de ficheros de prueba, y activar sobre este sistema de ficheros las ACL:

$ hdiutil create -size 1024K -fs HFS+ -volname ACLable acl.dmg
$ hdiutil attach acl.dmg
/dev/disk1s2 Apple_HFS /Volumes/ACLable
$ sudo /usr/sbin/fsaclctl -p /Volumes/ACLable/ -e

Después creamos un fichero en este sistema de ficheros, y vemos que el único que tiene permiso de escritura es fernando, aunque todos pueden leerlo:

$ cd /Volumes/ACLable/
$ touch documento.txt
$ ls -la
drwxr-xr-x 4 fernando fernando 170 Apr 1 .
drwxrwxrwt 6     root    admin 204 Apr 1 ..
-rw-r--r-- 1 fernando fernando   0 Apr 1 documento.txt

Podemos usar el comando chmod con la opción +a para añadir ACEs al fichero. Por ejemplo, si queremos que carolina pueda escribir en el fichero documento.txt podemos crear la regla:

$ chmod +a "carolina allow write" documento.txt

Podemos listar las reglas de un fichero pasando a ls la opción -le:

$ ls -le documento.txt
-rw-r--r-- + 1 fernando fernando 4 Apr 2 documento.txt
0: user:carolina allow write

Obsérvese que no hace falta crear una ACE para que fernando pueda escribir en el fichero, ya que fernando es el dueño del fichero, y los permisos de UNIX (que se ejecutan cuando no se cumple ningún ACE) le conceden este permiso.

En este momento carolina puede escribir en el fichero, pero no puede borrar o añadir datos al fichero. Podemos añadir ACEs para que tenga también estos permisos:

$ chmod +a "carolina allow delete,append" documento.txt
$ ls -le documento.txt
-rw-r--r-- + 1 fernando fernando 44 Apr 2 documento.txt
0: user:carolina allow write,delete,append

Obsérvese que no necesitamos añadir un ACE que dé permiso de borrar ni añadir a fernando, ya que el permiso de escritura UNIX también implica poder borrar y añadir al final del fichero. Tampoco necesitamos dar permiso de lectura a carolina ya que los permisos UNIX se lo dan.

Un problema que tienen las ACL es que no existe un usuario comodín, con lo que si queremos crear una regla que a todos los demás usuarios no les permita leer el fichero tenemos un problema. Una solución sería denegar este permiso a los usuarios del grupo staff, pero un usuario podría salirse de este grupo, y poder así leer el fichero. Una solución mejor, que además es la recomendada, es usar las ACL sólo para conceder permisos, y denegar permisos desactivando los permisos de UNIX:

$ chmod -wr documento.txt

Ahora también deberíamos crear ACEs para que fernando y carolina puedan leerlo y escribirlo:

$ chmod +a "fernando allow read,write,append,delete" documento.txt
$ chmod +a "carolina allow read" documento.txt
$ ls -le documento.txt
---------- + 1 fernando fernando 44 Apr 2 documento.txt
0: user:fernando allow read,write,delete,append
1: user:carolina allow read,write,delete,append

Para borrar una regla podemos usar la opción -a. Por ejemplo, si queremos quitar el permiso de lectura a fernando y carolina, y dárselo a todos los usuarios del grupo staff podemos hacer:

$ chmod -a "fernando allow read" documento.txt
$ chmod -a "carolina allow read" documento.txt
$ chmod +a "staff allow read" documento.txt
$ ls -le documento.txt
---------- + 1 fernando fernando 44 Apr 2 documento.txt
0: group:staff allow read
1: user:fernando allow write,delete,append
2: user:carolina allow write,delete,append

Obsérvese que las reglas se apilan, es decir, la última en añadir es la primera en aplicarse.

También podemos indicar la posición de la regla a añadir con +a# n_regla, y de la regla a borrar con -a# n_regla. Por ejemplo, para borrar las tres reglas anteriores podemos hacer:

$ chmod -a# 2 documento.txt
$ chmod -a# 1 documento.txt
$ chmod -a# 0 documento.txt

Pero como las reglas se "mueven hacia arriba" cuando se borran, también podemos hacer:

$ chmod -a# 0 documento.txt
$ chmod -a# 0 documento.txt
$ chmod -a# 0 documento.txt

ACL soporta la herencia estática, que significa que cuando creamos un fichero en un directorio, éste hereda los ACEs del directorio. Si luego cambiamos los ACEs del directorio, no cambian los ACEs de los ficheros contenidos. La heréncia dinámica haría que al cambiar los ACEs del directorio cambiaran los ACEs de sus ficheros contenidos.

Para que los ficheros y subdirectorios contenidos en un directorio hereden los ACEs del directorio debemos de activan sobre el directorio alguno de los permisos de la Tabla 5.

Permiso Descripción Objetos
file_inherit Los pemisos del directorio los heredan los ficheros Directorios
directory_inherit Los permisos del directorio los heredan los subdirectorios Directorios
limit_inherit Los ACEs del directorio los heredan los ficheros y subdirectorios contenidos en el directorio, pero con el flag de herencia desactivado. Esto hace que si creamos un subdirectorio dentro de un subdirectorio, éste ya no herede el flag de herencia. Directorios
only_inherit Los permisos son heredados por los ficheros y subdirectorios contenidos en el directorio, pero no se aplican al propio directorio. Directorios
Tabla 5: Permisos de herencia (sólo aplicables a directorios)

Por ejemplo, podemos crear un subdirectorio con permiso de escritura para carolina, y con el permiso de herencia para ficheros y subdirectorios haciendo:

$ mkdir datos
$ chmod -rw datos
$ chmod +a "carolina allow write,file_inherit,directory_inherit" datos
$ ls -dle datos
d--x--x--x + 2 fernando fernando 68 Apr 2 datos/
0: user:carolina allow add_file,file_inherit,directory_inherit

Universal Type Identifiers (UTIs)

Mac OS Classic usa una combinación de dos enteros de 32 bits (representados como cuatro símbolos ASCII) para representar el tipo de un fichero: en concreto el type code y creator code del fichero.

Mac OS X mantiene el type code y creator code de un fichero. Desde el año 2001 Apple empezó a recomendar el uso de la extensión de un fichero para identificar el tipo de un fichero. Esto permite trabajar con ficheros procedentes de otras plataformas (o de Internet), que no llevan asociado type code ni creator code, pero el uso de la extensión de un fichero para determinar su tipo presenta dos importantes inconvenientes:

  • La asignación de extensiones no está centralizada, y en consecuencia una misma extensión se puede usar para representar varios tipos de ficheros (ambigüedad). Por ejemplo los ficheros .doc pueden ser ficheros de Microsoft Word o de texto plano, o los ficheros .conf pueden tener configuraciones de distintos sistemas.
  • Al igual que ocurre con el type code y creator code, los tipos no tienen una organización jerárquica.

BeOS fue el pionero en introducir los tipos MIME para representar el tipo de los ficheros. MIME permitió organizar los tipos de los ficheros de forma estandarizada y jerárquica en dos niveles. Por ejemplo image/jpeg indica que se trata de un fichero JPEG. La organización jerárquica permite que una aplicación declare que es capaz de abrir todos los ficheros del primer nivel (p.e. image/*), o bién sólo determinados tipos (p.e. image/gif).

A partir de Mac OS X 10.3 Apple empezó a introducir lentamente un nuevo sistema de asignación de tipos llamado Uniform Type Identifiers (UTIs). Las principales ventajas de este nuevo sistema de asignación de tipos son:

  • Es un sistema centralizado de asignación de tipos controlado por Apple, aunque extensible bajo solicitud a Apple, de forma parecida a como se hacía para definir nuevos type codes y creator codes.
  • Permite la organización jerárquica de tipos mediante relaciones de herencia (conforms to). Por ejemplo el tipo public.xml hereda de public.text, ya que un fichero XML es un tipo de fichero de texto.
  • Los tipos UTI no se aplican sólo a ficheros, sino a cualquier elemento del SO como puedan ser objetos en el portapapeles, unidades de disco, mensajes de correo, tarjetas vCard, etc.

La organización jerárquica permite que, por ejemplo, si una aplicación puede abrir ficheros de tipo public.text, también pueda abrir ficheros de tipo derivado public.xml. El SO siempre elige la aplicación cuyo tipo es más específico para abrir un fichero. Por ejemplo, si un editor de texto es capaz de abrir ficheros public.text, y un editor de XML es capaz de abrir ficheros de tipo public.xml, lo ficheros XML se abrirán con la segunda aplicación.

La Figura 3 muestra un trozo de esta jerarquía de tipos en la que vemos que la jerarquía de tipos no coincide con la jerarquía de namespaces. Por ejemplo com.apple.quicktime.movie hereda de public.audiovisual.content. De hecho, no existe una única raíz en la jerarquía, sino que todo tipo que no hereda de otro tipo es en sí mismo una raíz.


Figura 3: Jerarquía de tipos UTI

Apple ha definido una lista bastante amplia de tipos UTI. Aquellos que empiezan por public representan estándares abiertos, en caso contrarío se usa el sistemas de namespaces inversos. Apple también ha definido tipos UTI para formatos de otras empresas como por ejemplo com.microsoft.windows-executable para ejecutables Windows, com.microsoft.word.doc para ficheros de Microsoft Word, o com.real.realmedia para vídeos de Real Media.

Además, un tipo puede heredar de varios tipos. Por ejemplo, en la Figura 4, el tipo de una aplicación Mac OS X es a su vez un bundle y un paquete.


Figura 4: Herencia múltiple en tipos UTI

Suponiendo que tenemos un fichero con el nombre carta.rtf, podemos consultar su tipo UTI preguntándoselo a Spotlight, el sistema de metadatos de Mac OS X, ejecutando el comando:

$ mdls -name kMDItemContentType carta.rtf
kMDItemContentType = "public.rtf"

Cuando creamos o copiamos un fichero en Mac OS X, Spotlight le asigna automáticamente un tipo UTI. En caso de que la extensión del fichero no sea conocida, Spotlight crea un nuevo tipo UTI con el prefijo dyn. De esta forma Spotlight garantiza que todos los ficheros tienen un tipo UTI.