Tutoriales. Explican en profundidad un área de conocimiento.
Reportajes. Informan al lector sobre una tecnología.
Trucos. Describen alguna pequeña funcionalidad o consejo.
Videocursos. Vídeos sobre programación Mac/iOS
Bibliografía. Las fuentes de información que utilizamos.Animamos a otros sitios web a poner enlaces a nuestros tutoriales, pero por favor no hagan copias de ellos en otros servidores, ya que si actualizamos los tutoriales seguirá habiendo copias antiguas en circulación durante mucho tiempo. Esto va en perjuicio de los lectores que cojan la copia antigua. Lo que sí recomendamos es poner enlaces directos los permalink de esta página.
Mac OS X 10.6 y iOS 4 han introducido en el lenguaje los bloques (blocks), una construcción sintáctica que simplifica la programación de tareas. Su implementación es de código abierto, forma parte de GCC y Apple la ha enviado al comité de estandarización de ISO. Actualmente el compilador de GCC de Apple permite utilizar bloques tanto en lenguaje C como en el lenguaje C++ y Objective-C. En este tutorial se explica qué son los bloques, qué ventajas ofrecen y cómo se programan.
Este tutorial asume que el lector conoce el lenguaje C, y los conceptos de lenguaje y de programación que se explican en el tutorial Compilar y depurar aplicaciones con las herramientas de programación de GNU.
| Download | [enlace alternativo] | [permalink] |
En este tutorial pretendemos mostrar el manejo de las herramientas de programación que GNU ha puesto a disposición de los usuarios en multitud de sistemas, y que Apple ha elegido como base para sus herramientas de programación. Estas herramientas incluyen los conocidos comandos gcc y gdb. Sin embargo, las herramientas de programación de GNU son mucho más completas, e incluyen multitud de comandos que vamos a ir comentando a lo largo de este tutorial.
Al acabar este tutorial el lector debería de haber aprendido a compilar y depurar sus aplicaciones, crear librerías, medir el rendimiento, e incluso a combinar aplicaciones escritas en distintos lenguajes.
| Download | [enlace alternativo] | [permalink] |
Este tutorial pretende recoger toda la información necesaria para poder escribir ficheros Makefile usados para controlar la construcción de un programa con el comando make.
El documento empieza explicando las opciones más básicas para ir profundizando en ellas poco a poco. En los apartados 6 y 7 se acaban dando una serie de reglas prácticas que simplifican mucho el desarrollo de estos ficheros, con lo que aunque el lector no desee leer todo el documento le recomendamos que por lo sí que consulte estos apartados.
| Download | [enlace alternativo] | [permalink] |
El uso de un gestor de versiones se vuelve imprescindible para evitar la tediosa tarea de intercambiar entre los programadores los ficheros de código fuente que componen un proyecto según estos ficheros se van actualizando. Este documento intenta recopilar los conocimientos necesarios para usar y administrar los gestores de versiones CVS y Subversion.
La primera parte de este documento recopila los elementos generales que incorporan los gestores de versiones. La segunda y tercera parte del documento se centra en estudiar CVS y Subversion, respectivamente.
| Download | [enlace alternativo] | [permalink] |
En este tutorial pretendemos enseñar el manejo de Bash, el Bourne Again Shell de GNU. Este shell es el que proporcionan por defecto muchos sistemas UNIX entre ellos Mac OS X o Linux.
Los ejemplos se explicarán sobre Mac OS X, pero debido a la interoperatividad que caracteriza a Bash, estos ejemplos deberían ser exactamente igual de útiles en otros sistemas UNIX. Cuando existan diferencias las indicaremos para que usuarios de otros sistemas puedan seguir correctamente este documento.
Al acabar este tutorial el lector debería de haber aprendido a usar las principales teclas rápidas, personalizar mucho más su terminal para hacerlo más manejable, y modificar o crear los scripts que configuran su sistema.
| Download | [enlace alternativo] | [permalink] |
GNU ha definido un mecanismo estándar para construir paquetes software que puedan compilar en distintas plataformas. Una vez construido el paquete de acuerdo a las reglas que vamos a ver, podemos usar los conocidos comandos configure y make para compilar e instalar el software. Este documento pretende definir cuáles son estas recomendaciones.
Aunque los ejemplos se realizan sobre Mac OS X, la interoperatividad de este mecanismo de empaquetamiento debería permitir aplicar estas mismas reglas en otros sistemas con facilidad.
Al acabar este documento el lector deberá ser capaz de crear sus propios paquetes GNU de forma que se configuren, compilen, e instalen correctamente en distintas plataformas.
| Download | [enlace alternativo] | [permalink] |
Este tutorial nos enseña a programar en ensamblador del PowerPC de Mac OS X.
El tutorial empieza enseñando a manejar la herramienta de compilación que se distribuye con las herramientas de programación de Mac OS X y rápidamente se mete a estudiar la sistaxis del lenguaje con ejemplo aclaratorios.
| Download | [enlace alternativo] | [permalink] |
Este tutorial pretende recopilar los conceptos y tecnologías que se usan para conseguir crear sistemas informáticos seguros.
Muchos tutoriales de seguridad se centran en el uso de las herramientas administrativas. En este tutorial, aunque se evalúan bastantes herramientas desde el punto de vista administrativo, pretendemos llevar este estudio hasta el punto de vista del programador de estas herramientas. Con este fin hemos elegido las librerías criptográficas de Java, ya que creemos que son unas librerías completas, homogéneas, y que abarcan todos los aspectos de la criptografía moderna. Aunque el estudio se hace sobre Mac OS X, la interoperatividad del lenguaje Java permite llevar estos conceptos a otros sistemas operativos sin problemas.
| Download | [enlace alternativo] | [permalink] |
Este documento es un tutorial de JNI (Java Native Interface), el mecanismo que permite ejecutar funciones C y C++ desde Java.
El tutorial supone que el lector conoce tanto los lenguajes Java como C, no es necesario saber C++, aunque el saber siempre ayuda. También supone que el lector esta familiarizado con el uso de herramientas de programación como gcc, java o javac
El tutorial trata cómo realizar estas operaciones en varios sistemas operativos aunque se centra sobre todo en dos: Mac OS X y Win32.
| Download | [enlace alternativo] | [permalink] |
Animamos a otros sitios web a poner enlaces a nuestros tutoriales, pero por favor no hagan copias de ellos en otros servidores, ya que si actualizamos los tutoriales seguirá habiendo copias antiguas en circulación durante mucho tiempo. Esto va en perjuicio de los lectores que cojan la copia antigua. Lo que sí recomendamos es poner enlaces directos los permalink de esta página.
En este reportaje tenemos un resumen claro y rápido sobre las principales características, lenguajes y herramientas que existen para programar en Mac OS X.
El documento está claramente dirigido a programadores de otros entornos que quieran conocer cómo se programa en OS X.
| Download | [enlace alternativo] | [permalink] |
Muchas aplicaciones fallan de forma impredecible debido a que se corrompe la memoria, o simplemente acaban agotando toda la memoria del sistema tras un periodo prolongado de uso debido a pérdidas de memoria. Este reportaje explica cómo podemos detectar los problemas de corrupción y pérdida de memoria en nuestras aplicaciones usando una serie de herramientas que existen en Mac OS X para tal fin.
| Download | [enlace alternativo] | [permalink] |
En muchas ocasiones es útil para una aplicación saber cuándo otra aplicación modifica algún fichero del sistema de ficheros. Ejemplo de aplicaciones que pueden necesitar esta información serian un antivirus o una aplicación que necesita conocer cuándo han sido modificado externamente alguno de los múltiples ficheros que componen un proyecto. Este reportaje explica las APIs que proporciona Mac OS X para detectar estos eventos y actuar el consecuencia.
| Download | [enlace alternativo] | [permalink] |
Las aplicaciones ejecutan en el espacio de usuario ateniéndose a una serie de restricciones impuestas por el kernel. Sin embargo, el código que ejecuta en el kernel no tiene restricciones y puede cambiar cualquier aspecto del funcionamiento del sistema operativo. Un rootkit es un programa que se instala en el kernel del sistema operativo. Los rootkits son frecuentemente usados como malware ya que permite al atacante ocultar ficheros, procesos y conexiones de red, para ser transparente a las herramientas de administración. Esto hace que los rootkits sean extremadamente difíciles de detectar y de eliminar. Los rootkits también suelen habilitar un mecanismo de acceso (backdoor) así como sniffers de teclado y ratón. Este documento explica cómo se crea un rootkit.
| Download | [enlace alternativo] | [permalink] |
La ingeniería inversa (reversing) son un conjunto de técnicas que nos permiten descubrir cómo funcionan las aplicaciones cuando no disponemos de su código fuente. Estas técnicas se utilizan frecuentemente para modificar el comportamiento de programas que incluyen funcionalidades no deseadas. Este reportaje describe estas técnicas en el entorno de Mac OS X.
| Download | [enlace alternativo] | [permalink] |
En este reportaje se estudia el proceso de arranque que sigue Mac OS X, y cómo podemos configurar servicios de Mac OS X para que se ejecutan automáticamente al arrancar la máquina.
Este documento está escrito para Mac OS X 10.4 o posteriores. Si quiere configurar una versión anterior debe consultar este otro reportaje.
| Download | [enlace alternativo] | [permalink] |
En este reportaje se estudia cómo podemos configurar servicios de Mac OS X para que se ejecutan automáticamente al arrancar la máquina.
Este documento está escrito para Mac OS X 10.3 o anteriores. Debido a los cambios introducidos por Apple en el proceso de arranque de Mac OS X 10.4, si lo que quiere es configurar Mac OS X 10.4 o posterior debe consultar el reportaje Configuración del sistema de arranque de Mac OS X.
| Download | [enlace alternativo] | [permalink] |
En este reportaje se explica que es y cómo funciona ColorSync, el sistema de corrección de color de Mac OS X.
Este sistema de corrección de color permite obtener representaciones más precisas del color de las imágenes con las que estamos trabajando de forma transparente para el usuario. Antes de esto se describe detalladamente qué es la luz y el color, y cómo percibimos las personas los colores, así como técnicas de representación y corrección del color, como por ejemplo el soft-proofing.
| Download | [enlace alternativo] | [permalink] |
En este reportaje se explica que es Quartz Extreme y que ventajas aporta.
Quartz Extreme no es más que el nombre que Apple da a su nuevo gestor de ventanas acelerado por hardware que incorpora desde Mac OS X 10.2.
| Download | [enlace alternativo] | [permalink] |
La librería gettext permite traducir un programa a muchas configuraciones del usuario: lenguajes, países y juegos de caracteres. Este truco revisa cómo configurar nuestro Mac usando la herramienta locale.
La librería gettext permite internacionalizar el código fuente de nuestros programas. Para ello, sentencias como esta:
printf("Hello %s.\n", name);
Deben de indicar el texto a internacionalizar usando el macro _():
printf(_("Hello %s.\n"), name);
El comando xgettext permite extraer estas cadenas en fichero .pot. el traductor traduce las cadenas del fichero .pot a distintos idiomas, y nos entrega el fichero renombrado a la extensión .po
El programador usar msgfmt para compilar el fichero .po para generar un fichero .mo. el fichero .mo se distribuye junto con el programa, y es la forma de que el programa pueda mostrar mensajes en el la configuración del usuario.
La librería gettext la usan la mayoría de las aplicaciones GNU, y especialmente las de terminal. Para que un programa de terminal muestre mensajes adaptados a la configuración de usuario, es necesario que este configure locale. A Continuación vamos a ver cómo se haría.
Para empezar podemos consultar nuestra configuración actual:
$ locale
LANG=
LC_COLLATE="C"
LC_CTYPE="C"
LC_MESSAGES="C"
LC_MONETARY="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_ALL=
El valor "C" en las variables de configuración de locale indica que se use el valor hardcoded (por defecto) con el que se compiló el programa. Se llama "C" porque la mayoría de los programas están escritos en lenguaje C.
Además del valor "C", las variables de configuración de locale pueden tomar valores de la forma "en_US" donde las 2 primeras letras indican el idioma y las 2 segundas el país. Por ejemplo, para español de España se usaría "es_ES".
El valor de las variables de configuración también pueden incluir opcionalmente el juego de caracteres a usar. Por ejemplo, "es_ES.UTF-8" indica que queremos usar el juego de caracteres UTF-8.
Podemos obtener un listado de todos los posibles valores locale con el comando:
$ locale -a
La librería gettext consulta las variables de configuración en este orden:
LANG LC_xxx, (LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES, ...)LC_ALLLANGUAGEPor ejemplo, si LANG tiene un valor asignado, ya no consulta las demás. Sino consulta LC_xxx, etc.
El usuario sólo debería de configurar en su script de arranque (p.e. .profile) las variables de tipo LC_xxx. LC_ALL se reserva para scripts como configure o autoconf con el fin de sobrescribir la configuración del usuario.
LC_MESSAGES indica el lenguaje para los mensajes. Por ejemplo:
$ LC_MESSAGES="en_US" bison
bison: missing operand after `bison'
Try `bison --help' for more information.
$ LC_MESSAGES="es_ES" bison
bison: falta un operando después de `bison'
Pruebe `bison --help' para más información.
LC_CTYPE indica la configuraciones para funciones C como tolower(), toupper() and isalpha(), etc. LC_COLLATE se usa para indicar la configuración para ordenar caracteres. Por ejemplo, el siguiente comando muestra el path de los ficheros usando LC_CTYPE=C:
$ svn status
? content/files/Parc_Gu?\204?\136ell.jpg
Vemos que el nombre del fichero no representa bien símbolos UTF-8. Para resolverlo podemos hacer:
$ export LC_CTYPE=UTF-8
$ svn status
? content/files/Parc_Güell.jpg
El propósito de otras variables como LC_NUMERIC, LC_TIME, LC_MONETARY es más evidente.
Los paquetes Mac OS X son ficheros con la extensión .pkg que básicamente contienen ficheros a instalar junto con una descripción de la ruta de los ficheros a instalar y sus permisos. Mac OS X utiliza los paquetes Mac OS X para instalar aplicaciones. Este truco clarifica cómo son y cómo usar estos paquetes.
Para instalar un paquete basta con hacer doble click sobre él, pero también podemos usar el comando installer para instalarlo. Por ejemplo el siguiente comando instalaría el paquete iTunes.pkg en la raíz de nuestro sistema de ficheros:
$ installer -pkg iTunes.pkg -target /
Una ventaja de los paquetes es que Mac OS X lleva la cuenta de los paquetes instalados. Podemos consultar los paquetes instalados con el comando:
$ pkgutil --packages
apache.tomcat.6.0.26
com.adobe.pkg.FlashPlayer
com.apple.darwinstreamingserver
com.apple.MacOSX.lang.es
com.apple.pkg.AdditionalEssentials
com.apple.pkg.AdditionalFonts
com.apple.pkg.iTunesX
················
El comando devuelve el ID de cada paquete instalado. A partir de este ID podemos saber los ficheros que componen el paquete con el comando. Por ejemplo:
$ pkgutil --files org.virtualbox.pkg.vboxstartupitems
Library
Library/StartupItems
Library/StartupItems/VirtualBox
Library/StartupItems/VirtualBox/Resources
Library/StartupItems/VirtualBox/Resources/English.lproj
Library/StartupItems/VirtualBox/Resources/English.lproj/Localizable.strings
Library/StartupItems/VirtualBox/StartupParameters.plist
Library/StartupItems/VirtualBox/VirtualBox
Y también podemos desinstalar el paquete con el comando:
$ pkgutil --unlink org.virtualbox.pkg.vboxstartupitems
Formato de los paquetes
Hasta Mac OS X 10.4 los paquetes eran bundles estándar de Mac OS X, que son directorios especiales con los ficheros del paquete. La Figura 1 muestra el contenido de un paquete antiguo.

A partir de Mac OS X 10.5 su formato cambio a formato nuevo plano que es un formato de fichero comprimido con el comando xar. Podemos usar el comando xar para ver o extraer el contenido del paquete. Por ejemplo, para ver el contenido de un paquete nuevo hacemos:
$ xar -t -f iTunes.pkg
También tenemos la herramienta gráfica SuspiciousPackage para poder inspeccionar el contenido de un paquete (antiguo o nuevo) desde Finder. La Figura 2 muestra el contenido de un fichero de paquete plano.

Mac OS X utiliza el término bill of materials (bom) para determinar los ficheros de paquete a instalar, actualizar o eliminar. Básicamente se trata de un log de ficheros instalados que después permite a Mac OS X desinstalarlos.
En el formato de paquetes antiguos este log se almacenaba en el directorio /Library/Receipts/boms. Con el formato de paquetes nuevos este log se ha pasado a almacenar en el directorio /var/db/receipts. Podemos usar el comando lsbom para ver el contenido de uno de estos ficheros.
$ lsbom /var/db/receipts/com.apple.pkg.CoreFP.bom
. 41775 0/80
./System 40755 0/0
./System/Library 40755 0/0
./System/Library/PrivateFrameworks 40755 0/0
./System/Library/PrivateFrameworks/CoreFP.framework 40755 0/0
./System/Library/PrivateFrameworks/CoreFP.framework/CodeResources
Tenga en cuenta que los paquetes (tanto en formato antiguo como nuevo) también contienen un fichero .bom, porque está es la forma de almacenar información sobre los permisos de los ficheros a instalar. Si por alguna razón se modifican los permisos de los ficheros del paquete podemos restaurarlos con el comando:
$ /usr/libexec/repair_packages --pkg com.birdstep.ZTEDataCardDriver --repair
Una vez que el paquete se instala, el fichero .bom se copia a Mac OS X para llevar un registro de los ficheros instalados y poder así desinstalarlos. Antes vimos que podemos desinstalar un paquete proporcionando su ID. Por ejemplo:
$ pkgutil --unlink com.birdstep.ZTEDataCardDriver
Este comando borra los ficheros pero no elimina el registro en el fichero bom. Podemos eliminar su registro en el fichero bom de Mac OS X usando el comando:
$ pkgutil --forget com.birdstep.ZTEDataCardDriver
Software Update se basa en los ficheros bom y en los paquetes Mac OS X para llevar la cuenta del software que tenemos instalado. Este software compara los ficheros bom de nuestra máquina con los ficheros bom de un servidor de Apple para determinar si tiene que instalar nuevos paquetes en nuestro sistema.
Para determinar si hay actualizaciones disponibles podemos usar el comando:
$ softwareupdate -l
El comando softwareupdate también permite instalar un paquete con la opción -i, o bajarlo pero no instalarlo con la opción -d.
Mac OS X 10.6 no tiene en cuenta clásico fichero /etc/group para determinar los usuarios de un grupo. Este fichero sólo se tiene en cuenta cuando se arranca en modo monousuario. Este truco explica cómo configurar los grupos a los que pertenecen los usuarios.
Podemos obtener los usuarios del sistema (y su uid) asociado con el comando:
$ dscl . list /Users uid
Podemos obtener los grupos del sistema (y su gid asociado) con el comando:
$ sudo dscl . list groups gid
Podemos conocer los grupos a los que nuestro usuario está asignado con el comando groups:
$ groups
staff com.apple.access_screensharing _developer _lpoperator _lpadmin _appserveradm admin _appserverusr localaccounts everyone
Para añadir o eliminar usuarios a grupos Mac OS X proporciona el comando dseditgroup. Este comando maneja los Directory Services y tiene la opción -o (operation) para indicar qué operación ejecutar (read, create, delete, edit, checkmember).
Para consultar los usuarios de un grupo tenemos la operacion read:
$ dseditgroup -o read admin
dsAttrTypeStandard:GroupMembers -
FFFFEEEE-DDDD-CCCC-BBBB-AAAA00000000
140D1472-7F93-472D-B221-D65A427F6FAA
561812D4-6182-46BC-A8CE-931BD77D5C0A
dsAttrTypeStandard:GroupMembership -
root
flh
fernando
Esta operación nos dice que hay tres usuarios en el grupo admin y nos da tanto su nombre como sus UUID.
Si queremos añadir un usuario a un grupo debemos usar la operación edit junto con la opción -a para indicar el registro que queremos añadir y -t para indicar que este registro es de tipo usuario. Por ejemplo, para añadir el usuario fernando al grupo wheel haríamos:
$ sudo dseditgroup -o edit -a fernando -t user wheel
Y para quitarlo del grupo:
$ sudo dseditgroup -o edit -d fernando -t user wheel
Apple proporciona gratuitamente las Server Admin Tools. Dentro de estas herramientas encontramos Workgroup Manager. Para administrar usuario y grupos visualmente debemos:
/Applications/Server/Workgroup Managerlocalhost.View | Show System Users and Groups.Este truco explica qué son y cómo se usan los servicios que aparecen en el menú de sistema de las aplicaciones Mac OS X.
Los servicios del menú de sistema de las aplicaciones permiten a los usuarios acceder a la funcionalidad de una aplicación desde otra aplicación cliente. Las aplicaciones anuncian los servicios que proporcionan sobre uno o más tipos de datos. Las aplicaciones cliente (las que usan los servicios) no necesitan conocer por adelantado qué servicios existen en el sistema. La aplicación cliente simplemente necesita indicar los tipos de datos que usa. El menú de servicios se encarga de indicar qué servicios se pueden realizar sobre el tipo de dato que se está usando.
Ejemplos de servicios serían la encriptación de un texto, el reconocimiento de caracteres en un bitmap, o generar un mensaje del día. Cuando el usuario está manipulando un tipo de dato (p.e., escribiendo en una caja de texto), el usuario puede ejecutar los servicios que manipulan ese tipo de dato.
Existen dos tipos de servicios: procesadores y proveedores.
Procesadores. Este tipo de servicios reciben datos y realizan una operación sobre ellos. Por ejemplo, si en una aplicación cliente seleccionamos un texto podemos enviárselo a alguien usando Mail como procesador. Si en la aplicación cliente seleccionamos una palabra podemos usar Dictionary para buscar la palabra, tal como muestra la siguiente figura:

Tras ejecutarse el servicio obtenemos la palabra resuelta en el procesaror (Dictionary):

Proveedores. Estos servicios devuelven datos a la aplicación cliente que les llama. Por ejemplo, podemos ejecutar desde TextEdit el servicio que captura parte de la pantalla:

Al terminar de ejecutarse el servicio obtenemos la captura de pantalla incrustada en la posición del cursor en TextEdit:

La aplicación cliente y el servicio se ejecutan en procesos independientes. La forma de compartir datos es que las aplicaciones transportan datos a los servicios a través de un portapapeles privado. En caso de tratarse de un servicio proveedor, éste devuelve los datos usando el mismo portapapeles.
En concreto el proceso es el siguiente:
Si el servicio es un proveedor:
Un servicio se puede ofrecer de dos formas:
.app y se suele guardar en la carpeta /Applications..service y se guardan en la carpeta /Library/Services (puede ser que tengamos que crear esta carpeta).Un ejemplo de servicio standalone es SymbolycLinker, una aplicación que extiende Finder para crear enlaces simbólicos blandos UNIX.
No todos los servicios existentes están habilitados. Algunos se habilitan por defecto y otros tenemos que habilitarlos en System Preferences | Keyboard Shortcuts | Services. Como muestra la siguiente figura, estos servicios se agrupan por tipo.

Las aplicaciones que proporcionan un servicio pueden estar instaladas en cualquier lugar del disco duro. Launch Services se encarga de identificar que una aplicación proporciona servicios consultando su fichero Info.plist. En base a esta información Mac OS X rellena el menú de servicios de las aplicaciones clientes. La siguiente figura muestra la entrada NSServices de la aplicación Dictionary. Esta es la entrada que usan las aplicaciones para indicar los servicios que prestan a otras aplicaciones clientes. Básicamente la entrada NSServices es un array de objetos NSDictionary. Cada servicio se describe en un objeto NSDictionary mediante una serie de claves y valores.

Este truco explica cómo utilizar SSH para hacer X11 forwarding. X11 forwarding permite ejecutar aplicaciones X11 situadas en un servidor remoto. Aunque el truco se centra en Mac OS X, los principios son los mismos en otros sistemas UNIX.
Se llama servidor X al gestor de ventanas X11. Se llama cliente X a una aplicación gráfica X11 (p.e. xclock). Tenga cuidado, es muy frecuente liarse al interpretar estos términos al revés. Recuerde que el servidor X siempre se ejecuta en su máquina local y necesita de un teclado y una pantalla. Por su parte el cliente X es una aplicación que se puede estar ejecutando en su máquina local o en remoto. En Mac OS X el servidor X es la aplicación X11.app situada en la carpeta Utilities.
Las aplicaciones necesitan saber dónde está el servidor X, para ello usan la variable de entorno DISPLAY. Tres valores similares, pero no equivalentes, de esta variable son:
localhost:0 -> Conectar al puerto 6000 de localhost :0 -> Connectar al socket de dominio UNIX /tmp/.X11-unix/:0/tmp/launchd-xxxxxx/:0 -> Conectar al socket de dominio UNIX /tmp/launchd-xxxxxx/:0La última opción es la que utiliza por defecto Mac OS X 10.5 y permite que no haga falta ejecutar X11.app. Cuando launchd detecta una conexión a este socket, lanza X11. Por ejemplo, en mi máquina obtengo el valor:
$ echo $DISPLAY
/tmp/launch-v6IuEo/:0
Una vez entendidos los principios básicos, vamos a ver cómo se configura el cliente X y el servidor X.
En la máquina remota podemos ejecutar fácilmente aplicaciones de consola a través de SSH. En este apartado vamos a explicar cómo configurar la máquina remota para poder ejecutar aplicaciones X11 (clientes X) cuyas ventanas se muestren en la máquina local (servidor X). Para ello tenemos habilitar X11 forwarding editando el fichero /etc/ssh/sshd_config, y reemplazando la entrada:
#X11Forwarding no
Por la entrada:
X11Forwarding yes
La otra cosa que tenemos que hacer es reiniciar el acceso remoto (sshd). Para ello podemos usar la opción Enable Remote Login del panel Sharing de System Preferences. Alternativamente podemos ejecutar el comando:
$ kill -HUP `cat /var/run/sshd.pid`
En la máquina local primero conviene comprobar que podamos conectarnos a la máquina remota:
$ ssh flh@dymas.ii.uam.es
En este caso, para hacer X11 forwarding basta con añadir la opción -X (en mayúsculas, ya que -x en minúsculas deshabilita el X11 forwarding):
$ ssh -X flh@dymas.ii.uam.es
Ahora podemos ejecutar un cliente X en la máquina remota y ver si SSH hace X11 forwarding correctamente, nuestro servidor X (X11.app) deverá mostrar la ventana del cliente X remoto:
$ xclock
Observe que en la sesión SSH en la máquina remota la variable DISPLAY vale algo así como:
$ echo $DISPLAY
localhost:10.0
Esto significa que el servidor X está en el screen 10 del servidor de ventanas 0 de la máquina remota (localhost). El servidor SSH (sshd) se encargará de hacer forwarding al servidor X de nuestra máquina local.
Cuando lanzamos una aplicación desde el terminal, resulta fácil fijar sus variables de entorno. Sin embargo, esta operación se puede complicar cuando es Finder quien debe fijar las variables de entorno. En este truco explicamos cómo fijar variables de entorno en las aplicaciones que ejecuta Finder.
Algunas aplicaciones requieren variables de entorno para funcionar correctamente. En este truco usaremos como ejemplo a NetBeans, y supondremos que queremos de pasarle valores en las variables de entorno PATH y CLASSPATH.
Una primera opción es fijar las variables de entorno en el terminal y ejecutar la aplicación desde el terminal:
$ export CLASSPATH=$CLASSPATH:.:/Library/Java/Home/lib/xjparse-1.0.jar
$ export PATH=$PATH:/usr/local/sw/bin
$ open /Applications/Development/NetBeans.app
Sin embargo, en ocasiones preferimos poder ejecutar la aplicación haciendo doble click en su icono con Finder. En este caso tenemos tres alternativas:
En el primer caso podemos añadir la una línea como la siguiente al fichero /etc/launchd.conf o /etc/launchd-user.conf.
setenv VBOX_USER_HOME /Volumes/autor/storage/VirtualBox
Si añadimos la línea a /etc/launchd.conf la variable de entorno será recibida por todos los procesos del sistema mientras que si la añadimos a /etc/launchd-user.conf la variable de entorno sólo será recibida por los procesos de usuario.
En el segundo caso podemos crear un fichero de propiedades en la ruta $HOME/.MacOSX/environment.plist. Para crearlo podemos usar la herramienta Property List Editor tal como muestra la Figura 1. Podemos usar la utilidad RDEnvironment para configurar estas variables gráficamente.

Figura 1: Property List Editor con el fichero environment.plist
La tercera opción es fijar esas variables para una única aplicación. En este caso, usando la opción Show Package Contents podemos editar el fichero Info.plist de la aplicación en cuestión (p.e. NetBeans) y añadir la propiedad LSEnvironment, la cual es un diccionario donde cada entrada representa una variable de entorno. La Figura 2 muestra el resultado de esta edición.

Figura 2: Property List Editor con el fichero Info.plist de NetBeans
Para que Finder vuelva a releer el bundle de la aplicación NetBeans debemos de actualizar su fecha, por ejemplo ejecutando el comando touch sobre la aplicación de la forma:
$ touch /Applications/Development/NetBeans.app
Xcode 3.0 ha introducido un gestor de proyectos alternativo llamado Organizer. Este truco explica cómo usar Organizer para compilar y ejecutar proyectos desde Xcode.
Los proyectos que genera Xcode son proyectos con una estructura cerrada, y en consecuencia no reutilizable desde otras herramientas de programación. Muchos programadores se sienten más cómodos usando ficheros de proyecto abiertos y clásicos como puedan ser make o ant. Además, a muchos programadores les gusta controlar los comandos de terminal que se están ejecutando cuando compilan o ejecutan sus programas. Xcode 3.0 introduce Organizer, una forma de trabajar con una gran variedad de lenguajes de programación como si estuviéramos trabajando en el terminal, pero con las ventajas que aporta el usar un entorno de desarrollo.
Para abrir Organizer ejecute Xcode y, sin crear ningún proyecto, use la opción de menú Window|Organizer para obtener la ventana de la Figura 1 (a). Debajo de la ventana encontramos tres botones: El primero permite añadir ficheros y directorios a Organizer. El segundo permite añadir acciones. El tercero permite editar el fichero seleccionado en el proyecto.
![]() |
![]() |
|
(a)
|
(b)
|
Figura 1: Organizer todavía no hace referencia a ningún proyecto
Como ejemplo vamos a crear un directorio vacío llamado saludos y vamos a añadir este directorio al proyecto usando la opción Add Existing Folder de la Figura 1 (b), o bien arrastrando el fichero desde Finder a Organizer. Después podemos usar la opción New File de la Figura 1 (b) para crear un fichero vacío al que podemos llamar saluda.c. También podemos usar el tercer botón de la Figura 1 (b) para editar su contenido tal como muestra la Figura 2.

Figura 2: Proyecto simple con Organizer
Lo siguiente que tenemos que hacer es compilar el fichero saluda.c. Para ello tenemos que crear una acción en el botón Build de la barra de herramientas. Pinchamos en el botón Build y obtenemos un diálogo como el de la Figura 3.

Figura 3: Crear una acción
Abajo encontramos las opciones del menú:
New Shell Script, permite indicar uno o más comandos a ejecutar. Add Script File, permite indicar un fichero de script a ejecutar. Add Automator Workflow, permite indicar un Workflow de Automator a ejecutar. Usando la opción New Shell Script podemos indicar que queremos ejecutar el siguiente comando de compilación:
gcc *.c -o saluda
En caso de que nuestro proyecto tenga subdirectorios, en Directory de la Figura 3 podemos indicar en qué directorio deberá ejecutarse la acción. En concreto se pueden usar uno de estos valores:
Selection, el directorio seleccionado en Organizer cuando ejecutamos la acción.Top Level Organizer Item, el directorio raíz del proyecto.Defining Organizer Item, el directorio seleccionado en Organizer cuando creamos la acción.Home Directory, el directorio home.File System Root, el directorio raíz (/) del sistema.Observe que también podemos cambiar el nombre de la acción que hemos creado e indicar una shortkey para esta opción.
Análogamente al botón Clean le podemos asignar la siguiente acción que borra todos los ficheros generados durante la compilación:
rm -r build rm saluda
Y al botón Run le podemos asociar la acción:
./saluda
La Figura 4 muestra cómo a las acciones de Run también las podemos asociar argumentos que se pasarán al comando a ejecutar. Por ejemplo, en la Figura 4 pasamos el argumento "Hola mundo". También podemos indicar si al ejecutar el comando lo queremos hacer con depuración.

Figura 4: Crear una acción de ejecución
Por último, el botón Action permite crear acciones adicionales. Por ejemplo, podemos crear acciones para subir o bajar ficheros de un repositorio de código fuente.
Cuando añadimos a Organizer una carpeta que contiene un proyecto, Organizer crea automáticamente acciones para ese proyecto. Si no nos gustan esas acciones siempre podemos modificarlas o borrarlas.
Actualmente Organizer, al menos, reconoce tres tipos de proyectos:
xcodebuild con los parámetros adecuados para cada acción.Makefile, se creará en el botón Build una acción que ejecuta el comando make all, y en el botón Clean otra acción que ejecuta el comando make clean.build.xml, se creará en el botón Build una acción que ejecuta el comando ant."Xcode 3.0 User Guide". Apple Inc.
El comando defaults permite modificar el comportamiento de gran cantidad de aplicaciones de Mac OS X, e incluso del propio sistema operativo. En este truco pretendemos recopilar las preferencias más útiles. Si alguien conoce más preferencias especialmente útiles que no aparezcan aquí, por favor póngase en contacto conmigo.
El comando defaults permite leer y escribir preferencias escritas en ficheros de preferencias de los directorios /Library/Preferences/ y ~/Library/Preferences/.
En la siguiente tabla se resumen las preferencias más útiles que hemos recopilado.
|
defaults write com.apple.appstore ShowDebugMenu -bool true
|
| Añade un menú de depuración a Mac AppStore. |
|
defaults write com.apple.Safari IncludeDebugMenu 1
|
| Tras reiniciar Safari, habilita un menu que permite depurar páginas web, incluida la opción Inspect Element |
|
defaults write com.apple.Safari WebKitDeveloperExtras -bool true
|
| Habilita otro botón de depuración válido para todas las aplicaciones WebKit-based, no solo Safari. Por ejemplo, Google Chrome. |
| defaults write com.apple.Safari WebKitInitialTimedLayoutDelay -float 0.25 |
| Reduce el tiempo que tarda Safari en empezar a renderizar una página de 1 seg a 0.25 seg. |
| defaults write com.apple.finder AppleShowAllFiles -bool true |
| Tras reiniciar Finder se empiezan a mostrar todos los ficheros del disco aunque tengan el atributo V o empiecen por punto (p.e. .profile). Encontrará una mejor descripción de esta preferencia en este otro truco. |
| defaults write com.apple.dock single-app -bool true |
| Tras reiniciar Finder pasa al modo single-app en el que sólo se ve la aplicación activa. |
| defaults write com.apple.LaunchServices LSQuarantine -bool NO |
| Deshabilita el que Finder emita un warning la primera vez que intentamos abrir un fichero bajado de Internet. |
| defaults write com.microsoft.word NSQuitAlwaysKeepsWindows -bool false |
| Evita que los ficheros abiertos al cerrar la sesión se vuelvan a abrir al volver a entrar en la sesión |
| defaults write com.apple.finder _FXShowPosixPathInTitle -bool YES |
| Tras reiniciar Finder, hace que Finder muestre en la barra de título no sólo el nombre de la carpeta donde estamos situados, sino su path. |
| defaults write com.apple.dashboard mcx-disabled -boolean YES killall Dock |
| Deshabilita Dashboard. |
| defaults write -g NSNavPanelExpandedStateForSaveMode -bool true |
| Por defecto el cuadro de diálogo guardar como se muestra sin expandir. Con esta preferencia el cuadro de dialogo se muestra expandido por defecto. |
| defaults write -g PMPrintingExpandedStateForPrint -bool true |
| Por defecto el cuadro de dialogo imprimir se muestra sin expandir. Con esta preferencia el cuadro de di?logo se muestra expandido por defecto. |
| sudo defaults write /System/Library/LaunchDaemons/com.apple.WindowServer EnvironmentVariables -dict-add CI_NO_BACKGROUND_IMAGE 1 sudo plutil -convert xml1 /System/Library/LaunchDaemons/com.apple.WindowServer.plist sudo chmod 644 /System/Library/LaunchDaemons/com.apple.WindowServer.plist |
| En Mac OS X 10.5 elimina la transparencia del menú. Para que tenga efecto es necesario reiniciar el sistema para que se vuelva a cargar el servidor de ventanas. |
| defaults write NSGlobalDomain NSAutomaticWindowAnimationsEnabled -bool NO |
| Elimina el efecto 3D de animación al abrir una ventana introducido en Mac OS X 10.7. |
| defaults write com.apple.dock no-glass -boolean YES killall Dock |
| En Mac OS X 10.5 elimina el efecto 3D que tiene el Dock cuando se sitúa en la parte de abajo. |
| defaults write com.apple.dock mouse-over-hilte-stack -boolean yes killall Dock |
| Crea un efecto que permite trazar la posición del ratón en los stack de Mac OS X 10.5. |
| defaults write com.apple.iTunes AutomaticDeviceBackupsDisabled -bool true |
| Deshabilita el lento backup que iTunes hace cada vez que sincronizados con iPhone |
| defaults write com.apple.iTunes hide-ping-dropdown 1 |
Oculta el botín de Ping en iTunes. Poner a 0 para volver a mostrarlo. |
| defaults write com.stuffit.Expander allowVersionChecking -bool NO |
| Deshabilita la comprobación de versión (llamada a casa) que hace StuffItExpander capa vez que se ejecuta. |
| defaults write com.apple.CrashReporter DialogType none |
| Deshabilita el diálogo de CrashReporter que sale cada vez que una aplicación explota. |
| defaults write com.apple.dashboard devmode YES |
| Permite ejecutar Widgests fuera de Dashboard. |
Este truco enseña cómo asociar un icono a una imagen con su thumbnail. Si para guardar sus imágenes no usa ningún software como iPhoto, sino que guarda sus imágenes directamente en carpetas, quizá este truco le resulte útil. El truco enseña a asociar un icono personalizado (con un thumbnail de la propia imagen) a cada fichero de imagen. De esta forma le resultará más fácil identificar el contenido de cada imagen.
Finder muestra un icono por defecto como el de la Figura 1 (a) por cada imagen que encuentra. Podemos asociar un icono personalizado como el de la Figura 1 (b) a cada imagen con lo que la identificación de su contenido es mucho más fácil.
|
|
|
Figura 1: Icono por defecto e icono personalizado
En este truco veremos cómo crear un script bash que pone y quita iconos personalizados a las imágenes, y cómo crear un plug-in Automator que nos permita poner o quitar iconos personalizados desde Finder.
Podemos usar el comando /usr/bin/sips para poner un icono personalizado a una imágen de la forma:
$ sips -i fichero.jpg
Donde fichero.jpg es el fichero al que ponemos la imagen.
Para borrar el icono a una imagen, basta con borrar su resource fork:
$ echo -n "" > fichero.jpg/..namedfork/rsrc
El Listado 1 muestra un ejemplo de un script bash llamado poniconojpg que pone un icono personalizado a los ficheros recibidos. Para ejecutarlo podemos hacer:
$ poniconojpg fichero.jpg
En caso de recibir un directorio, el script busca los ficheros *.jpg (mayúsculas o minúsculas) que contenga ese directorio, y pone un icono personalizado a cada uno de ellos.
#!/bin/bash
# Este comando es un ejemplo escrito por Fernando Lopez
# para MacProgramadores
# Comprueba que se reciba al menos un argumento
if [ -z $1 ]; then
echo "Indique fichero o directorio como argumento"
exit 1
fi
# Ejecuta sips sobre cada argumento.
# Los argumentos pueden ser un fichero o directorio.
# Si un argumento es un directorio busca los *.jpg que contenga
for arg in "$@"
do
for f in $(find $arg -iname "*.jpg")
do
if [ -a $f ]; then
sips -i $f
fi
done
doneListado 1: Script bash que pone iconos personalizados
El Listado 2 muestra otro script llamado quitaiconojpg. El script es parecido al Listado 1 pero, quita el icono personalizado a los ficheros de imagen recibidos (o a los ficheros de imagen contenidos en el directorio). Por ejemplo, si queremos quitar el icono personalizado a todas la imágenes contenidas en la carpeta album2006, hacemos:
$ quitaiconojpg album2006
#!/bin/bash
# Este comando es un ejemplo escrito por Fernando Lopez
# para MacProgramadores
# Comprueba que se reciba al menos un argumento
if [ -z $1 ]; then
echo "Indique fichero o directorio como argumento"
exit 1
fi
# Borra el resource fork de cada imagen.
# Los argumentos pueden ser un fichero o directorio.
# Si un argumento es un directorio busca los *.jpg que contenga
for arg in "$@"
do
for f in $(find $arg -iname "*.jpg")
do
if [ -a $f ]; then
echo -n > "$f/..namedfork/rsrc"
fi
done
doneListado 2: Script bash que quita iconos personalizados
Automator, es una herramienta de programación (que se distribuye gratuitamente con las Developer Tools) la cual nos permite crear pequeñas aplicaciones en muy poco tiempo.
Podemos construir fácilmente un aplicación Automator, como la de la figura, que ejecute el script del Listado 1 al arrastrar ficheros con las imágenes (o bien una carpeta con las imágenes) sobre el icono de la aplicación.
Para construir esta aplicación ejecute Automator, concatene las acciones Get Selected Finder Items y Run Shell Script, tal como muestra la figura. La acción Get Selected Finder Items permite conocer los ficheros seleccionados en Finder cuando se ejecuta la aplicación Automator, o también, como va a ser nuestro caso, conocer los ficheros arrastrados sobre la aplicación Automator. Los ficheros seleccionados se pasan a la acción Run Shell Script que ejecuta el script sobre ellos. Para que los ficheros seleccionados se pasen como argumento, seleccione la opción Pass input as argument.
![]()
Cuando vaya a guardar la aplicación Automator con la opción File|Save As..., verá que está se puede guardar de dos formas:
Workflow, lo cual le permite editar a posteriori la aplicación. Es decir, sería el equivalente al código fuente de un programa.Application, lo cual crea un ejecutable con un icono.Guárdela como una aplicación con el nombre poniconojpg, para obtener una aplicación como la de la primera figura.
![]()
Un tercera opción es guardar la aplicación con la opción File|Save As Plug-in, en este caso puede generar un Plug-in de Finder como el de la figura que luego se podrá ejecutar sobre las imágenes o carpetas seleccionadas. Por desgracia Apple ha eliminado los Plug-in de Finder en Mac OS X 10.6 con lo que esta opción sólo está disponible en Mac OS X 10.5.
Análogamente puede crear usted otro plug-in automator para quitar los iconos a las imágenes.
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.
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).
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 /Developer/Tools/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).
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 creó 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 ellos. 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 |
| Fichero PDF | emal | ||
| 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:
Get Info), ésta será la aplicación con la que se abrirá.Get Info.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:
PkgInfo para almacenar ocho bytes correspondientes al type code y creator code de la aplicación.Info.plist para almacenar el type code (en la propiedad CFBundlePackageType) y 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).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.
Spotlight permite realizar búsquedas tanto por nombre de fichero como por su contenido. Para poder realizar las búsquedas rápidamente es necesario indexar el contenido de todos los ficheros del sistema. En ocasiones conviene que Spotlight no indexe determinados directorios para lo cual disponemos de dos opciones.
System Preferences | Spotlight | Privacy para indicar directorios del disco que no queremos indexar..metadata_never_index en la raíz de la unidad para indicar que no queremos que ésta se indexe.En este último caso es recomendable ejecutar el comando mdutil con la opción -E para borrar los índices de la unidad que no vamos a indexar. Por ejemplo:
$ mdutil -E /Volumes/FER_PEN
/Volumes/FER_PEN:
Indexing and searching disabled.
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) |

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 el tipo de recurso situado en el resource fork tiene cuatro letras, no debemos confundirlo con el type code o creator code del fichero. 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:
.profile) nunca los muestra Finder.V no se muestran en Finder./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.
En Mac OS X Snow Leopard, Apple ha ocultado la carpeta Library del usuario. Los usuarios avanzados pueden desocultar esta carpeta con el comando:
$ SetFile -a v $HOME/Library
Nota: En Mac OS X Lion, Apple cambió la forma de ocultarlo, y para desocultarlo debemos usar:
$ chflags nohidden $HOME/Library
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. En concreto, para pedir a Finder que muestre todos los ficheros modificamos esta preferencia de usuario, con el comando:
$ defaults write com.apple.finder AppleShowAllFiles TRUE
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.
Cuando se escribió este truco sólo se podía 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. Mac OS X 10.5 añadió la opción -@ al comando ls para poder listar los atributos extendidos. Mac OS X también introdujó el comando xattr que permite ver el contenido de los atributos extendidos. 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. Por ejemplo:
$ make
$ sudo cp setx lsx rmx /usr/local/bin
Ahora podemos crear un fichero de prueba:
$ 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 , ls -l@ o xattr para ver los atributos extendidos:
$ lsx prueba.txt
3 edad 33
9 nombre Fernando
$ ls -@l prueba.txt
-rw-rw-r--@ 1 fernando staff 62 Jan 24 21:59 prueba.txt
edad 3
nombre 9
$ xattr -l prueba.txt
edad:
00000000 33 33 00 |33.|
00000003
nombre:
00000000 46 65 72 6E 61 6E 64 6F 00 |Fernando.|
00000009
El comando lsx nos muestra por cada atributo extendido: la longitud del valor, la clave y el valor. El comando xattr nos muestra el valor tanto en hexadecimal como en ASCII.
Tambien podemos usar rmx para borrar los atributos extendidos:
$ rmx edad prueba.txt
$ lsx prueba.txt
9 nombre Fernando
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
Podemos evitar que se copien estos ficheros (al usar cp) y que se guarden dentro de un .tar al crear el fichero comprimido. Para ello debemos exportar las siguientes variables de entorno:
$ export COPYFILE_DISABLE=true
$ export COPY_EXTENDED_ATTRIBUTES_DISABLED=true
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 |
| hidden | Fichero oculto para Finder |
| nohidden | Fichero visible para Finder |
| 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
Los flags nohidden y hidden aparecen con Mac OS X 10.7 y permiten ocultar y desocultar un fichero para Finder. Estos flags BSD modifican el atributo de fichero V (accesible con GetFileInfo) activándolo o desactivándolo.
En Mac OS X 10.7, Apple ha ocultado la carpeta Library del usuario. Los usuarios avanzados pueden desocultar esta carpeta con el comando:
$ chflags nohidden $HOME/Library
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 un 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.
Los permisos UNIX son una forma tradicional 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.
El comando umask permite consultar o cambiar una máscara de permisos que se restan a 777 para obtener los permisos efectivos con los que por defecto se crea un fichero:
$ umask
0022
Mac OS X viene preinstalado con la mácara 022 (el primer cero se ignora), que significa que los ficheros y directorios se crearán por defecto con los permisos rwxr-xr-x.
Por desgracia el comando umask sólo afecta a los ficheros y directorios creados desde el terminal. A partir de Mac OS X 10.5.3 es posible indicar la máscara de permisos con los que cualquier proceso crea los ficheros y directorios. Esto se consigue asignando una máscara de permisos a launchd (el proceso padre 1 que crea los demás procesos). Para ello debemos indicar los permisos de launchd en el fichero:
$ cat /etc/launchd-user.conf
umask 002
En este ejemplo hemos cambiado la máscara de permisos de 022 a 002 para que todos los usuarios de nuestro mismo grupo tengan permiso de escritura sobre los ficheros que creemos. Esto es muy útil si tenemos varias cuentas de usuario y queremos compartir el permiso de escritura entre las distintas cuentas.
Ojo: En man launchctl se explica el uso de los ficheros launchd.conf y launchd-user.conf. En el caso del comando umask Apple recomienda usarlo en launchd-user.conf. Su uso en launchd.conf implicaría modificar esta máscara en todos los procesos del sistema, lo cual es un riesgo de seguridad.
Muchos usuarios prefieren el modelo de permisos de UNIX porque lo consideran lo suficientemente flexible para sus necesidades, además d e ser más simple que el modelo las Access Control List (ACL) que vamos a ver a continuación. 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:
allow o deny).A cada regla también se la llama Access Control Entry (ACE).
| 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 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.
Los ficheros al crearse sólo tienen permisos UNIX. Esta precedencia de las ACL permite modificar los permisos UNIX sólo cuando definimos una ACE para el fichero. 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.
El que las reglas ACL se comprueben antes que los permisos UNIX tiene la ventaja de que podemos denegar el que una aplicación modifique un fichero. Por ejemplo, si queremos que los usuarios fernando y flh no puedan borrar el fichero de configuración VirtualBox.xml podemos hacer:
$ chmod +a "fernando deny delete" VirtualBox.xml
$ chmod +a "flh deny delete" VirtualBox.xml
Este truco permite que la aplicación VirtualBox no borre su fichero de configuración y lo recree con permisos de sólo escritura para el usuario que está ejecutando VirtualBox.
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.
En Mac OS X 10.4 las ACL están por defecto desactivadas. A partir de Mac OS X 10.5 las ACL están por defecto activadas. Si queremos activar o desactivar 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. En Mac OS X 10.6 las ACL están por defecto activadas y el comando fsaclctl ha sido eliminado.
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 el usuario 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 el usuario 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 al comando 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 sólo 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 que añadimos 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 |
Por ejemplo, si tenemos un subdirectorio datos, podemos asignarle permiso de escritura para carolina, junto con el permiso de herencia para ficheros y subdirectorios haciendo:
$ 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
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, pero 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. Podemos usar la utilidad RDDefaultApp para ver los tipos existentes en la base de datos de Finder. 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:
.doc pueden ser ficheros de Microsoft Word o de texto plano, o los ficheros .conf pueden tener configuraciones de distintos sistemas.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). UTI generaliza la idea de tipos MIME de BeOS. Las principales ventajas de este nuevo sistema de asignación de tipos son:
public.xml hereda de public.text, ya que un fichero XML es un tipo de fichero de texto.Al igual que en BeOS, 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 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.
Muchas veces disponemos de varios ficheros de vídeo que queremos unir. Este truco muestra cómo hacer un pequeño programa Automator que realiza esta tarea.
El comando mencoder es un comando GPL que nos permite codificar los formatos de vídeo MPEG-1/2/4 y AVI. Por desgracia no codifica ni decodifica WMV, el formato de vídeo de Microsoft. Este comando no viene por defecto en Mac OS X, pero puede buscarlo en Internet.
En la web es muy común que los vídeos se distribuyen partidos en trozos más fáciles de bajar. Este comando permite volver a juntar varios vídeos que cumplan la condición de tener la misma resolución y formato.
Si tenemos los ficheros br01.mpg br02.mpg br03.mpg, podemos juntarlos en el fichero br_unido.mpg con el comando:
$ mencoder -oac copy -ovc copy -forceidx -of mpeg -o br_unido.mpg br01.mpg br02.mpg br03.mpg
Donde -oac copy y -ovc copy indican que no queremos transcodificar, sólo copiar los elementary stream de audio y vídeo a la salida. La opción -of indica el formato de salida al que codificar (avi o mpeg), y -o indica el fichero de salida. La opción -forceidx, aunque no suele ser necesaria, es útil porque fuerza a que se reconstruya el índice de sistema.
Para facilitar la ejecución de este comando (y construir el programa del siguiente apartado), podemos crear un script como el siguiente:
#!/bin/bash
# Este comando es un ejemplo escrito por Fernando López
# para MacProgramadores
# Comprueba que se reciba al menos dos ficheros por argumento
if [ -z $2 ]; then
echo "No se recibieron argumentos suficientes"
exit 1
fi
# Obtiene el nombre y extension del primer fichero
# (todos los ficheros deberian tener la misma extension)
# El nombre sirve para crear el nombre del fichero final
# La extension sirve para conocer el formato a que convertir
nombre=${1%.*}
ext=${1##*.}
# Determina el tipo de la extension
case $ext in
mpeg|mpg) ext="mpg";;
avi) ;;
*) echo "Extension $ext no valida"; exit 1;;
esac
# Une los ficheros de video
nombre=${nombre}_unidos.${ext}
comando=/usr/local/bin/mencoder
if [ -x $comando ]; then
$comando -oac copy -ovc copy -forceidx -of $ext -o $nombre $@
else
echo "No se encuentra $comando"
exit 1;
fi
Puede descargar este script de aquí. El comando supone que mencoder se encuentra en la ruta /usr/local/bin/mencoder. Como argumento recibe los ficheros de vídeo a usar, y los une en otro fichero cuyo nombre es el mismo que el del primer fichero pasado, pero con el sufijo _unidos. Por ejemplo, para unir los ficheros de vídeo anteriores, ponga el permiso de ejecución a el fichero de script, y ejecute el script de la forma:
$ chmod +x unirvideos.sh
$ unirvideos.sh br01.mpg br02.mpg br03.mpg
El script generará el fichero br01_unidos.mpg.
Puede colocar este script en algún directorio que esté en el PATH, y ya podrá unir ficheros de vídeo desde la línea de comandos. Pero en el siguiente apartado veremos cómo ejecutar este script desde Finder.
Automator, es una herramienta de programación (que se distribuye gratuitamente con las Developer Tools) la cual nos permite crear pequeñas aplicaciones, de este tipo, en muy poco tiempo.
Podemos construir fácilmente un aplicación Automator, como la de la figura, que al arrastrar sobre ella varios ficheros de vídeo los una, para lo cual se ejecuta el script anterior.
Para ello ejecute Automator, concatene las acciones Get Selected Finder Items y Run Shell Script, tal como muestra la figura. La acción Get Selected Finder Items permite conocer los ficheros seleccionados en Finder cuando se ejecuta la aplicación Automator, o también, como va a ser nuestro caso, conocer los ficheros arrastrados sobre la aplicación Automator. Los ficheros seleccionados se pasan a la acción Run Shell Script que ejecuta el script sobre ellos. Para que los ficheros seleccionados se pasen como argumento, seleccione la opción Pass input as argument.

Cuando vaya a guardar la aplicación Automator con la opción File|Save As..., verá que está se puede guardar de dos formas:
Guárdela como una aplicación con el nombre unirvideos, para obtener una aplicación como la de la primera figura.

Un tercera opción es guardar la aplicación con la opción File|Save As Plug-in, en este caso puede generar un Plug-in de Finder como el de la figura que luego se podrá ejecutar sobre los ficheros de vídeo seleccionados.
Por último comentar existe una aplicación GPL llamada DropScript que también permite crear iconos que, al arrastar sobre ella ficheros, también ejecuta un script. La figura muestra la forma que tienen las aplicaciones generadas por DropScript.
Para crear la aplicación de la última figura basta con que arrastre el fichero unirvideos.sh sobre la aplicación DropScript, para obtener otra aplicación llamada Dropunirvideos.
Este truco muestra cómo hacer un pequeño programa Automator que arranque y pare el servidor de MLDonkey.
Los demonios son programas (generalmente de consola) que quedan ejecutando en background. MLDonkey es un ejemplo de demonio muy utilizado en el mundo de Mac OS X para compartir datos y programas entre la comunidad. Lógicamente sólo se debe compartir datos y programas que no estén licenciados para explotación comercial.
El demonio de MLDonkey lo implementa el comando mlnet, el cual se puede obtener haciendo una sencilla búsqueda en Internet.
Suponiendo que el comando lo guardamos en el directorio /usr/local/bin, podemos ejecutar el comando así:
$ /usr/local/bin/mlnet
2006/09/17 19:39:35 Starting MLDonkey 2.7.7.CVS ...
2006/09/17 19:39:35 Language EN, locale UTF-8, ulimit for open files 256
2006/09/17 19:39:35 MLDonkey is working in /Users/fernando/.mldonkey
2006/09/17 19:39:35 [DNS] Resolving [ferbook] ...
2006/09/17 19:39:35 [DNS] Resolving [www.mldonkey.net] ...
2006/09/17 19:39:35 Logging in /Users/fernando/.mldonkey/mlnet.log
2006/09/17 19:39:36 Core started
El comando crea en $HOME/.mldonkey una carpeta con algunos ficheros de configuración, y carpetas donde depositar los datos y programas compartidos.
Una vez lanzado el demonio podremos acceder a el desde un browser usando la URL:
http://localhost:4080
Para parar el demonio basta con pulsar Ctrl+C sobre el terminal.
Por desgracia, si lo ejecutamos de la forma anterior, el comando no devuelve el control al terminal. Además produce una salida textual que puede, o no, interesarnos. Para evitarlo podemos lanzarlo de la forma:
$ nohup /usr/local/bin/mlnet >/dev/null 2>&1 &
Ahora se nos devuelve el control al terminal inmediatamente, y además no obtendremos mensajes por consola.
Al haber perdido el control del proceso, para pararlo podemos usar el comando:
$ killall mlnet
Tener que entrar en el terminal cada vez que queremos lanzar mlnet se vuelve un dolor. Para evitarlo podemos crear dos pequeñas aplicaciones en el escritorio como las que muestra la figura.

Automator, es una herramienta de programación (que se distribuye gratuitamente con las Developer Tools) la cual nos permite crear pequeñas aplicaciones, de este tipo, en muy poco tiempo.
Nosotros vamos a crear dos aplicaciones llamadas lanza y para que ejecuten las operaciones de lanzar y parar el demonio mlnet.
Para ello ejecute Automator, elija la acción Run Shell Script, y cree un script como el de la figura, el cual ejecutará el comando nohup /usr/local/bin/mlnet >/dev/null 2>&1 &.

Cuando vaya a guardar la aplicación Automator (p.e. con el nombre lanza), verá que está se puede guardar de dos formas:
Análogamente puede crear otra aplicación Automator con el nombre para que ejecute el comando killall mlnet.
Los sistemas de control de versiones usan el modelo cliente/servidor donde un servidor almacena los ficheros de uno o más proyectos, y varios clientes se conectan a él para bajar los ficheros (check out), modificarlos, y subir los cambios (check in).
Actualmente Xcode proporciona acceso a varias herramientas de gestión de versiones (Perforce, Subversions y CVS), en este truco sólo veremos como utilizar Xcode en CVS, que actualmente es la herramienta de control de versiones más utilizada en todo el mundo. Xcode no proporciona una interfaz para el servidor de CVS, sólo actúa como una interfaz gráfica de acceso a los comandos cliente de CVS.
En este truco supondremos que el lector sabe manejar la interfaz de comandos de CVS (en caso contrario le recomendamos leer primero el tutorial sobre Gestión de versiones con CVS y Subversion). Aun así a lo largo de este documento vamos a ir detallando los pasos para crear un repositorio CVS de ejemplo (usando la línea de comandos). De esta forma, un lector que no conozca (o que no recuerde) la interfaz de comandos de CVS debería poder seguir este truco.
Para empezar necesitamos disponer de un repositorio donde aprender a manejar CVS desde Xcode. Aunque si el lector forma parte de una organización es posible que ya tenga uno configurado, en este truco vamos a crear un pequeño repositorio donde realizar nuestras pruebas.
Un repositorio puede estar en la misma máquina o en otra máquina, en ambos casos la ubicación del servidor CVS se indica en la variable de entorno CVSROOT1. Para nuestros ejemplos bastará con disponer de un repositorio local.
Una vez tomada esta decisión vamos a proceder a crear un repositorio. En nuestro caso hemos decidido crear el directorio llamado repositorio directamente en el directorio home del usuario fernando. Ahora debemos exportar la variable de entorno CVSROOT con la ubicación del repositorio:
$ export CVSROOT=/Users/fernando/repositorio/
E inicializamos el repositorio:
$ cvs init
En el directorio repositorio deberá de haberse creado el subdirectorio CVSROOT con metainformación sobre el recién creado repositorio:
$ ls repositorio
CVSROOT
El siguiente paso es crearnos una carpeta para el proyecto que queremos exportar. Debido a que CVS es independiente del lenguaje de programación podríamos crear un proyecto en cualquier lenguaje, pero en este caso hemos elegido el lenguaje Java para nuestros ejemplos. En concreto hemos creado un directorio llamado Mate con un sólo fichero Aritmetica.java donde vamos a implementar varias operaciones aritméticas:
$ cd Mate
$ cat Aritmetica.java
public class Aritmetica {
public static double suma(int a, int b) {
return a+b;
}
}
Una vez tenemos nuestro proyecto de ejemplo debemos de exportarlo al repositorio, para lo cual desde el directorio Mate ejecutamos el comando:
$ cvs import Matematicas rama_principal version_inicial
N Matematicas/Aritmetica.java
No conflicts created by this import
El comando import importa todos los ficheros del directorio actual y sus subdirectorios al repositorio creando en el repositorio un proyecto con el nombre Matematicas. Observe que el nombre del proyecto en el repositorio no tiene porque coincidir con el nombre de la carpeta donde tenemos guardado el proyecto. Además al comando debemos pasarle dos tag, el primero rama_principal es el nombre de la rama dentro del proyecto, el segundo version_inicial es el nombre de un tag que ponemos a los ficheros exportados.
Una vez tengamos exportado el proyecto hemos acabado nuestro trabajo como administrador, ahora pasamos a ejecutar el role de un programador que se baja el repositorio a su máquina para trabajar con él.
El lugar donde un programador se baja un proyecto del repositorio es una carpeta que se suele conocer como sandbox. Auque no es necesario que así sea, lo normal es que el nombre del directorio del sandbox coincida con el nombre que puso el comando import al proyecto del repositorio cuando lo creó.
Vamos a bajarnos el repositorio directamente al directorio home con los comandos:
$ cd
$ cvs checkout Matematicas
cvs checkout: Updating Matematicas
U Matematicas/Aritmetica.java
El comando checkout recibe como argumento el nombre del proyecto en el repositorio y lo baja a un directorio con el mismo nombre:
$ ls -l Matematicas
-rw-r--r-- 1 fernando admin 109 Apr 22 18:19 Aritmetica.java
drwxr-xr-x 5 fernando admin 170 Apr 22 18:34 CVS
En cada directorio del sandbox siempre existirá un subdirectorio con el nombre CVS donde se almacena metainformación sobre el sandbox.
Ya tenemos en el sandbox el proyecto, ahora debemos de crear un proyecto con Xcode que debe crearse sobre la carpeta del sandbox. Esto es así porque el subdirectorio CVS es el que le sirve a Xcode para poder conectarse al sandbox. Actualmente Xcode no es capaz de crear un sandbox haciendo algo equivalente a lo que el comando checkout ha hecho.
Para proceder a crear el proyecto desde Xcode, use la opción de menú File|New Project...|Java Tool, y cree un proyecto llamado igual que el sandbox para que se cree en la misma carpeta (véase Figura 1).

Una vez tengamos creado el proyecto Xcode en el sandbox, lo siguiente que debemos hacer, antes de poder acceder a las opciones de repositorio desde Xcode, es configurar el SCM (Source Code Managenment). Para acceder a las opciones de SCM desde Xcode tiene una persiana de menú llamada SCM.
Antes de estar configurado el SCM la única opción de menú que tenemos es SCM|Configure SCM... Usando esta opción debemos de activar la opción Enable SCM e indicar el tipo de sistema de SCM en el campo SCM System. La Figura 2 muestra estas opciones.
También muchas veces resulta útil apartar los ficheros intermedios y los ficheros finales del sandbox, en este caso puede usar las opciones Place Build Product In y Place Intermediate Build Files para indicar otra ruta donde depositar estos ficheros.

Si está trabajando en un lugar donde no tiene red quizá le convenga desactivar temporalmente el SCM usando la opción de menú SCM|Go Offline. Cuando vuelva a tener acceso al repositorio puede volver a activar el SCM con SCM|Go Online.
El smart group SCM (véase Figura 3) nos muestra el estado de los ficheros usando una sola letra para indicar su estado de acuerdo a la nomenclatura común de CVS (blanco actualizado, ? desconocido, A listo para añadir, U hay una versión más moderna en el repositorio, M ha sido modificado en local y puede subirse al repositorio, C conflicto debido a que ha sido modificado en local y por alguien más en el repositorio, R Listo para ser borrado del repositorio). De momento todos los ficheros aparecen marcados con ? porque ninguno de ellos forma parte del repositorio (el subdirectorio CVS le sirve a Xcode para conocer esto).

Como muestra la Figura 4, también podemos ver la información de SCM de un fichero en las columnas de detalle del fichero. Pero en este caso la columna que da esta información no aparece visible por defecto y debemos usar la opción de menú View|Detail View Columns|SCM para que aparezca.

Nota: Puede que Xcode no le actualice correctamente la vista del estado de los ficheros, en ese caso puede usar la opción de menú SCM|Refresh Entire Project.
En este momento el repositorio está activo, pero el único fichero que ha generado el proyecto de Xcode (el fichero Matematicas.java) no está en el repositorio. Para añadirlo podemos seleccionar el fichero y usar la opción de menú SCM|Add to Repository. En este momento el fichero aparecerá marcado con una A, que significa que el fichero está listo para ser añadido al repositorio la próxima vez que hagamos un commit.
A continuación puede seleccionar el fichero y usar la opción de menú SCM|Commit Changes... para subir el fichero al repositorio. Se le pedirá que introduzca un comentario de commit que describa los cambios. Este comentario se almacena junto a la versión inicial del fichero. Más abajo veremos como consultar estos comentarios.
Una vez añadido el fichero al repositorio el campo de detalle de SCM aparecerá banco indicando que el fichero está actualizado y el fichero habrá desaparecido del SCM smart group. Si se pregunta por qué Apple ha implementado el extraño comportamiento de que los ficheros actualizados desaparecen del smart group SCM, la razón procede de que el comando cvs -n update no devuelve información sobre los ficheros actualizados, es decir en nuestro ejemplo el comando devuelve1:
$ cvs -n update
? Manifest
? Matematicas.1
? Matematicas.xcodeproj
Recuerde que en el repositorio inicial que creamos al principio de este documento creamos un fichero llamado Aritmetica.java que actualmente no forma parte del proyecto. Para que pase a formar parte del proyecto podemos usar la opción de menú Project|Add to project... El fichero debería aparecer marcado como actualizado ya que estaba correctamente subido al repositorio.
Cuando un fichero de nuestro proyecto aparece marcado con U significa que otro programador ha modificado el fichero y en este caso necesitamos actualizar los cambios en nuestro sandbox. Podemos actualizar el fichero de dos formas:
SCM|Update To|Latest...SCM|Update Entire Project que actualiza todos los ficheros del proyecto existentes en el CVS.Podemos usar la opción de menú SCM|SCM Results para ver las operaciones a nivel de interfaz de comandos que Xcode ha realizado sobre el CVS (véase Figura 5). Para obtener una vista detallada de los comandos ejecutados puede necesitar tener que usar el botón que aparece abajo a la derecha. Observe que el comando que Xcode ejecuta no es cvs sino ocvs. El comando ocvs se creó cuando CVS no soportaba wrappers, los cuales permitían tratar una carpeta marcada con el atributo de paquete como un sólo fichero. Actualmente CVS soporta esta opción con lo que ocvs y cvs son equivalentes.

Puede consultar las revisiones de un fichero del repositorio seleccionándolo y usando la combinación de teclas Command+I, o bien con la opción de menú SCM|SCM Info (véase Figura 7). En el panel de SCM aparecerá para cada revisión información sobre el número de revisión, autor, fecha y mensaje de commit. Si selecciona una determinada revisión debajo obtendrá una información más detallada.
Vamos a ver cómo se suben cambios a un fichero del proyecto. Para ello, tal como aparece en la Figura 6, vamos a eliminar los comentarios del fichero Matematicas.java, que por defecto introdujo Xcode cuando creó el proyecto.
Luego podemos subir los cambios al repositorio con la opción de menú SCM|Commit Changes...

Si ahora volvemos a ver las revisiones del fichero Matematicas.java (con Command+I), la Figura 7 muestra el resultado, donde apreciamos que existen dos revisiones.

Xcode nos permite ver las diferencias entre dos revisiones de un fichero. Para ello podemos usar dos herramientas: O bien la opción SCM|Compare With..., o bien la opción SCM|Diff With... Ambas opciones de comparación se pueden ejecutar también desde el panel de propiedades de la Figura 7. En ambos casos la forma de comparar es la misma, seleccionamos un fichero y pedimos comparar la versión actual del sandbox con otra revisión.
La opción de comparar es la más visual (véase Figura 8). Por defecto se ejecuta una herramienta visual que viene con Xcode llamada FileMerge. También podemos modificar la herramienta de comparación a usar en las preferencias de Xcode, por ejemplo para usar BBedit.

La otra forma de comparar es obteniendo el resultado del comando cvs diff1, tal como muestra la Figura 9.

Si pedimos borrar un fichero del proyecto (usando la opción Edit|Delete) aparecerá un diálogo como el de la Figura 10 (a), entonces tenemos dos opciones:
Delete References nos permite borrar sólo la referencia que hace el proyecto al fichero, pero no borra el fichero del disco.Delete References & Files borraría tanto la referencia que hace el proyecto al fichero como el propio fichero.En este segundo caso, si el fichero está bajo control de un SCM aparecerá un segundo diálogo como el de la Figura 10 (b) donde se nos preguntará si queremos borrar también el fichero del repositorio.
Si pedimos borrar el fichero del repositorio el fichero quedará marcado con una R y sombreado en gris, como muestra la Figura 10 (c), de forma que para borrarlo definitivamente del repositorio deberemos hacer un commit (con la opción SCM|Commit Changes...), o bien podremos cancelar el borrado y recuperar el fichero con la opción SCM|Add to repository.


(b)

(c)
Figura 10: Borrar ficheros del repositorio
Cuando renombramos un fichero bajo control de CVS, el fichero original es marcado con R indicando que será borrado del repositorio y el fichero nuevo será marcado con A indicando que el fichero será añadido al repositorio. Además renombrar un fichero inevitablemente hace que se pierda la información de log del fichero antiguo.
Para renombrar un fichero del proyecto puede usar la opción de menú File|Rename. En esta caso un mensaje de advertencia como el de la Figura 11 (a) le indicará que el fichero está bajo control de un SCM y que si renombra el fichero inevitablemente la información histórica de revisiones del fichero se perderá. Si aceptamos, y por ejemplo cambiamos el nombre de Aritmetica.java por Algebra.java, obtendremos el fichero antiguo marcado con R y el nuevo marcado con A, tal como muestra la Figura 11 (b). Después podemos usar la opción de menú SCM|Commit changes... para que los cambios se ejecuten definitivamente en el repositorio.


(b)
Figura 11: Renombrar un fichero bajo control de CVS
No sólo es posible subir los ficheros de código fuente a un repositorio, sino que otros ficheros como los de documentación también es muy común tenerlos en el repositorio.
Si usted trabaja en un proyecto donde algunos programadores usan Xcode y otros usan otra herramienta quizá no convenga que coloque el proyecto en el repositorio, pero si todos los programadores trabajan con Xcode sí que puede resultar útil compartir el proyecto. De esta forma cuando un programador añade un fichero al proyecto o cambia una opción de éste, todos los programadores se beneficiarán automáticamente del cambio. Debido a que los proyectos de Xcode (ficheros del bundle .xcodeproj) están escritos en texto plano, CVS gestiona bien los cambios cuando más de un programador cambia el proyecto a la vez. En este último apartado vamos a ver cómo se comparten los ficheros de proyecto en el repositorio.
Xcode guarda metainformación sobre el proyecto en un directorio con el atributo de paquete con la extensión .xcodeproj2. Por ejemplo, en nuestro ejemplo el proyecto Matematicas.xcodeproj tiene los ficheros que muestra la Figura 123.

Este paquete contiene dos ficheros a los que debemos prestar especial atención si queremos colocar un proyecto en el repositorio4: El fichero de proyecto y el fichero de usuario.
project.pbxproj) almacena información referente al proyecto como los ficheros que le componen, los targets, y opciones de compilación. Este fichero puede ser compartido por todos los programadores, y normalmente sí que se deberá poner en el repositorio si queremos compartir el proyecto.fernando.pbxuser) almacena información de personalización del usuario, como por ejemplo sus bookmarks, su target activo, o sus preferencias de edición. Cuando creamos un proyecto Xcode crea un fichero como éste con el nombre de la cuenta del usuario. Este fichero no debe ser compartido por los programadores, aunque opcionalmente se puede colocar en el repositorio si queremos poder trabajar con el mismo proyecto desde varias máquinas. Al existir uno por cada nombre de usuario no deberían de producirse conflictos."Xcode User Guide". Apple Inc.
1 Puede consultar el tutorial sobre Gestión de versiones con CVS y Subversion para ver cómo se hace esto.
2 En versiones anteriores estos ficheros tuvieron las extensiones .xcode, .pbproj, .pbxproj.
3 Puede abrir un directorio con el atributo de paquete desde Finder pulsando con el botón derecho y eligiendo la opción Show Package Contents.
4 Todos estos ficheros pueden ser editados con la herramienta Property List Editor.
Los compiladores de C y C++ actualmente pasan la mayoría de su tiempo compilando una y otra vez cabeceras mucho más grandes que el código fuente del fichero .c o .cpp en sí. El compilador gcc de GNU a partir de la versión 3.3 incluye la posibilidad de usar cabeceras precompiladas, lo cual acelera mucho la compilación de programas C y C++. En este truco se explica cómo aprovechar esta nueva característica
Durante la explicación de este truco vamos a suponer que nuestros ficheros fuente incluyen en su mayoría el fichero <iostream> con las operaciones típicas de entrada/salida C++, y el fichero <math.h> con las operaciones matemáticas más normales.
En consecuencia hemos decidido crear un fichero precompilado con estos ficheros de cabecera con el fin de acelerar la compilación de nuestro proyecto.
El fichero de cabecera en general deberá incluir sólo ficheros de cabecera que cambien poco, preferiblemente sólo los que vienen con el compilador (los que se invluyen de la forma #include <...>), y no los ficheros de cabecera de nuestro programa (que se incluyen de la forma #include "..."), ya que si no tendría que recompilarse el fichero de caberera cada vez que modificáramos uno de nuestros ficheros .h
Los ficheros de cabecera precompilados tienen el mismo nombre que el fichero .h correspondiente, pero con el sufijo .gch Por ejemplo si creamos el fichero precompiled.h con las cabeceras comunes que incluye nuestro proyecto el fichero de cabecera precompilado se llamará precompiled.h.gch
El fichero que nosotros hemos creado como ejemplo es el siguiente:
$ cat precompiled.h
#include <iostream>
#include <math.h>
using namespace std;
Lo siguiente que tenemos que hacer es precompilar este fichero para lo cual ejecutamos:
$ g++ -c precompiled.h -o precompiled.h.gch
Lo cual nos crea el fichero precompiled.h.gch con todos los ficheros incluidos por precompiled.h precompilados.
Ahora si, por ejemplo, el fichero encuadre.cpp incluye el fichero precompiled.h cuando ejecutemos:
$ g++ -c encuadre.cpp -o encuadre.o
El compilador de GNU buscará en el directorio actual un fichero llamado precompiled.h.gch. Si lo encuentra lo usará, y sólo si no lo encuentra incluirá precompiled.h
Aquí conviene hacer varias apreciaciones: La primera es que para que el compilador de GNU use el fichero .gch que encuentre, éste deberá estar compilando exactamente con las mismas opciones con las que hemos lanzado la compilación de encuadre.cpp, es decir basta con que hubiéramos hecho:
$ g++ -O1 -c encuadre.cpp -o encuadre.o
Para que no nos acepte el fichero precompilado y use el fichero de cabecera sin precompilar.
La segunda es que el compilador de GNU requiere un fichero precompilado para cada dialecto de C (C, C++, Objective-C). Si quisiésemos que un fichero precompilado se usase por distintos dialectos de C necesitaríamos crear uno distinto para cada dialecto (usando la opción -x c-header, -x c++-header y -x objective-c-header, respectivamente). En este caso la forma de proceder es crear un directorio con el nombre precompiled.h.gch y dentro de él meter todos los ficheros precompilados para todos los dialectos que estemos usando (da lo mismo el nombre que demos a estos ficheros, gcc examina todos los ficheros del directorio en busca del que necesite).
La tercera apreciación es que si vamos a usar ficheros precompilados en un fichero Makefile conviene crear una regla que actualice los ficheros de cabecera como la siguiente:
encuadre.o: encuadre.cpp encuadre.h Matriz.h Punto.h precompiled.h.gch
precompiled.h.gch: precompiled.h
$(CXX) $^ $(CXXFLAGS) -o $@
Desgraciadamente actualmente make no soporta el uso de reglas implícitas para los ficheros precompilados.

Por último conviene comentar que Xcode también soporta el designar a un fichero como fichero que actúe como cabecera precompilada, para ello debemos de activar dos opciones del proyecto o del target que son:
GCC_PRIFIX_HEADER) Indica que fichero de cabecera es el que debe precompilarse (en principio sólo soporta uno por proyecto que de hecho es lo normal). Por ejemplo aquí pondríamos precompiled.h. Esta opción no aparece por defecto en las opciones de Xcode con lo que debemos de usar el botón de añadir nueva opción y añadir la opción con clave GCC_PREFIX_HEADER y con valor precompiled.hGCC_PRECOMPILE_PREFIX_HEADER) Debemos de activar esta opción para que funcionen las cabeceras precompiladas dentro del proyecto o del target.Aquí se explica un truco que aprovecha un error en la configuración del PATH, por parte del administrador de una máquina UNIX, para apoderarse de su sistema. Este truco es válido para cualquier máquina UNIX incluida, como no, Mac OS X.
Nota: Este truco se explica con el fin de que los administradores de una máquina eviten que un usuario hostil viole la seguridad de su máquina, y nunca con el fin de que los usuarios aprendan a violar la seguridad de un sistema. En cualquier caso MacProgramadores no se hace responsable del mal uso que se pueda hacer de la información aquí suministrada.
Es muy típico que los administradores de las máquinas UNIX añadan al PATH de su máquina un "." con le fin de poder ejecutar los ficheros del directorio actual donde se encuentran. Si es este su caso recuerde que debe de hacerlo siempre al final del PATH y nunca al principio, es decir, en sus ficheros de configuración del shell (p.e. /etc/profile) debe de poner:
export PATH=/usr/local/bin:/usr/local/lib:/bin:/usr/local/sbin:/usr/sbin:/sbin:.
Y nunca:
export PATH=.:/usr/local/bin:/usr/local/lib:/bin:/usr/local/sbin:/usr/sbin:/sbin
Vamos a poner un ejemplo de como un usuario llamado judas se apodera del control de una máquina UNIX en la que su administrador no tuvo en cuenta este consejo.
En primer lugar al entrar judas en su nueva cuenta en la universidad se da cuenta de que le han asignado una cuenta de usuario en la que el primer campo del PATH es el directorio ".", como judas conoce este truco se dirige al fichero /etc/profile (del cual sólo tiene permiso de lectura) y comprueba eufórico que el administrador ha colocado de la forma no recomendada el PATH de la máquina.
Lo siguiente que hace judas es preparar una trampa al administrador para lo cual coloca en le directorio /tmp (en le que tiene permiso de lectura y escritura) un fichero con permiso de ejecución al que llama ls como el que sigue:
#!/bin/sh
if cp /bin/sh /usr/bin/.superdude >/dev/null 2>/dev/null
then
chmod 4555 /usr/bin/.superdude
rm -f $0
fi
exec /bin/ls ${1+$@}Y finalmente modifica el permiso de ejecución de este script para que todo el mundo lo pueda ejecutar:
$ chmod a+x /tmp/ls
En este momento la trampa esta tendida. Ahora lo único que tiene que tiene que hacer judas es esperar a que el ingenuo administrador pase por el directorio /tmp y ejecute el comando ls. Si algún usuario se pasea por estos lares al estar el "." como primer campo del PATH se ejecutara el script de judas y no el verdadero /bin/ls, el comando cp fallará (ya que los usuarios no tienen permiso para escribir en el directorio /usr/bin) y simplemente ese usuario obtendrá el resultado de un ls en pantalla. Pero cuando el administrador pase por ahí y ejecute este comando ls, el comando cp funcionará, lo cual permitirá que se ejecute el cuerpo del bloque if y al fichero .supersede se le activará el bit de setuid, se borrará el malvado script de judas y el administrador obtendrá el resultado de un ls como normalmente.
Cuando judas descubra la existencia del nuevo fichero /usr/bin/.superdude lo único que tiene que hacer es ejecutarlo y boala, acaba de logarse como superusuario en la máquina.
Multitud de paquetes del mundo de GNU se están portando a Mac OS X. Un problema con el que se puede encontrar el usuario es el de buscar, compilar e instalar estos paquetes en su sistema, problema que se puede solucionar fácilmente usando el gestión de paquetes Fink.
El proyecto Fink es un proyecto que encontramos en la web:
Se trata de un gestor de paquetes que se encarga de todo el proceso de búsqueda, compilación, configuración, instalación y desinstalación de paquetes directamente de Internet.
De esta forma el usuario nunca tiene que preocuparse de buscar e instalarse el mismo manualmente estos paquetes.
Internamente Fink se basa en los gestores de paquetes de Debian dselect, dpkg y apt-get, aunque el usuario Mac OS X, si quiere, el único comando que tiene que usar es el comando fink.
Una vez que nos bajamos el fichero fink-0.4.0a-installer.dmg lo único que tenemos que hacer es doble click en el para montarlo como una unidad. Una vez montado, dentro de él encontramos el fichero FinkInstaller.pkg que al hacer doble click sobre él, ejecuta un asistente que instala fink y todos sus ficheros en el directorio /sw de nuestro disco.
Lo otro que tenemos que hacer es configurar las variables de entorno de Fink, para lo cual si usamos lal shell bash debemos añadir al fichero de configuración ~/.profile la entrada:
. /sw/bin/init.sh
Que llama a este script el cual carga todas las variables de entorno que necesita Fink. Una vez reiniciamos el terminal, el entorno de Fink está ya configurado.
Si por contra usamos tcsh debemos de añadir al fichero ~/.tcsh la entrada:
source /sw/bin/init.csh
Una vez Fink está operativo podemos empezar usando el comando fink list para sacar un listado de todos los paquetes con que cuenta Fink.
$ fink list
Reading package info...
Information about 427 packages read in 2 seconds.
a2ps 4.12-4 Any to PostScript filter.
aalib 1.4rc4-5 Ascii art library
aalib-bin 1.4rc4-5 Ascii art library
aalib-shlibs 1.4rc4-5 Ascii art library
agqt 0.9.1-1 6's Spiffy AudioGalaxy Query Tool
amaya 5.3-2 W3C's Editor/Browser
·······················
·······················
Después podemos instalar o desinstalar paquetes usando los comandos fink install [paquete] y fink remove [paquete].
Por ejemplo podemos hacer:
$ fink install lynx
Y ya Fink se encarga de buscar el paquete en la red, bajárselo e instalarlo.
El lector puede usar man fink para ver que más opciones trae el comando fink.
Una última observación, para actualizar Fink no debemos de bajarnos y instalar el programa de instalación de la última versión. los pasos correctos son:
1) Comprobar la versión de Fink que tenemos instalada con:
$ sudo fink --version
Package manager version: 0.10.0
Distribution version: 0.4.1
2) Si queremos instalar la última versión podemos usar el comando:
$ fink selfupdate
Si no tenemos la última versión de Fink, el la buscará en Internet y nos la instalará.
Por último comentar que existe una buena herramienta freeware llamada FinkCommander que nos permite acceder a Fink desde una interfaz gráfica. Lo único que necesitamos para poder usar esta herramienta es haber instalado previamente Fink.

Podemos bajar FinkCommander de:
Existen multitud de combinaciones de teclas que podemos usar durante el arranque de la máquina para cambiar su comportamiento. Por desgracia estas combinaciones están mal documentadas, con lo que hemos decidido reunir aquí todas las que encontremos. Si alguien conoce más combinaciones de teclas que no aparezcan aquí, por favor póngase en contacto con nostros
Esta tabla resume las combinaciones de teclas que hemos encontrado, algunas de las cuales son especialmente útiles:
| Combinación de teclas | Descripción |
| C | Arrancar desde CD-ROM. Esta tecla se usa cuando por ejemplo queremos instalar o reinstalar el sistema operativo |
| H | Arrancar desde disco duro. La opción por defecto si no se pulsa ninguna tecla |
| N | Arrancar desde una unidad de red. Open Firmware debe de haber sido configurado correctamente para que funcione esta opción |
| T | Modo "Target". Al hacerlo veréis el logo de firewire saltando por la pantalla, no es mas que nuestra máquina convertida en un disco Firewire. Estando en este modo, le enchufamos un cable desde otro ordenador y veremos un disco externo. |
| Z | Arrancar desde la unidad Zip. Útil si estamos haciendo nuestro propio sistema operativo en esta unidad |
| Expulsar CD | Si se mantiene pulsada durante el arranque expulsa el CD-ROM de la unidad de CD. Esto es especialmente útil cuando un CD-ROM se atasca y no hay forma de sacarlo. Alternativamente se puede dejar el botón del ratón pulsado mientras arranca la máquina |
| Shift | Permite arrancar en modo a prueba de fallos. La tecla debe pulsarse justo después del campanazo inicial y hasta que sale el spin giratorio en pantalla. Deshabilita los login items y las extensiones del kernel no esenciales |
| Option | Se nos muestra una lista de los sistemas operativos instalados, y nosotros podemos indicar con cuál arrancar. Útil si tenemos instalados otros sistemas operativos como Darwin o Linux |
| Command+V | Muestra mensajes descriptivos de todo el proceso de arranque de Mac OS X (modo "verbose"). Se recomienda probarlo al menos una vez para ver como arranca Mac OS X "al estilo UNIX" |
| Command+S | "Single User Mode". Arranca en modo consola monousuario. Especialmente útil para ejecutar comandos que sólo se puedan ejecutar en este modo como fsck |
| Command+Option+ Shift+Delete |
Elude el arranque con el disco duro y arranca con CD o unidad de disco externa |
| Command+Option+ O+F |
Nos permite acceder al Open Firmware de nuestra máquina. Después podemos usar el comando printenv para ver las variables de la configuración. Usando el comando setenv podemos cambiarlas. |
| "6"+"4" "3"+"2" |
Válidas para Mac OS X 10.6 en adelante. Permiten arrancar respectivamente el kernel en 64 bits y 32 bits. Por defecto Mac OS X 10.6 arranca en 32 bits (excepto Xserve). |
Con el fin de simplificar el uso de Mac OS X, Finder oculta los ficheros y directorios en los que normalmente el usuario no está interesado.
En este truco veremos como se pueden ver estos ficheros "ocultos".
Finder suele ocultar los ficheros más "UNIX" como puedan ser los directorios /etc, /bin, /lib, /usr, /var, etc, o bien los ficheros que empiezan por . (punto), y en general oculta todos los ficheros que considera no necesarios para el usuario. En concreto hay tres formas de que un fichero se oculte al Finder: Listarlo dentro del fichero /.hidden, que el nombre de fichero empiece por punto (p.e. .profile), o que el fichero tenga el atributo HFS+ de oculto activado.
Los usuarios avanzados pueden querer ver todos los ficheros en Finder, para lo cual simplemente hay que modificar el fichero de configuración com.apple.Finder.plist que se encuentra en el directorio ~/Library/Preferences. Este fichero es un fichero de configuración .plist (XML Property List) que se puede editar o bien a mano desde un editor de texto, o bien desde el Property List Editor, un programa que viene con las herramientas de desarrollo de Mac OS X, que sirve para editar estos ficheros.
En concreto debemos de poner la propiedad AppleShowAllFiles a true:

Otra posible forma de modificar esta propiedad es con el comando /usr/bin/defaults, un comando que permite modificar los ficheros de configuración que tiene el usuario en ~/Library/Preferences.
Podemos ejecutar este comando así:
$ defaults write com.apple.Finder AppleShowAllFiles -bool true
Una vez modificada esta propiedad debemos de reiniciar Finder, o bien volviéndonos a logar, o bien reiniciando Finder desde Command+Alt+Esc
Y ya podremos ver todos los ficheros y directorios de nuestro disco duro:

Como seguramente ya conozca el lector, las aplicaciones en Mac OS X, también son directorios (con la extensión .app) que aparecen en Finder al usuario como si fueran un único fichero.
Este truco que hemos comentado no permite que veamos el contenido de estos directorios, pero sí podemos verlo si pulsamos sobre la aplicación con el botón derecho del ratón con la tecla Ctrl apretada. Entonces aparecerá una opción llamada Show Package Contents que nos permite ver los ficheros de este directorio.

También hay otras formas de poder ver los directorios ocultos sin necesidad de cambiar esta opción de Finder. Una de ellas consiste en usar la opción de ménu de Finder Go|Go to Folder... que nos pregunta por el directorio que queremos abrir en Finder, y nos los abre aunque sea oculto:

Por último, comentar que tambien podemos usar el comando /usr/bin/open que en caso de que le pasemos el directorio de una aplicación lo que hace es ejecutarla:
$ open Applications/Internet/Internet\ Explorer.app
Pero si le pasamos un directorio nos los lo abre en Finder.
$ open /usr/include
En este truco se trata como podemos generar ficheros PDF con Mac OS X sin necesidad de más software que el propio Mac OS X.
Mac OS X utiliza un motor gráfico llamado Quartz, que renderiza todas las salidas a pantalla e impresora en formato PDF (Portable Data Format), una evolución de PostScript.
Podemos aprovechar esta característica para capturar una salida de impresora y mandarla a un fichero PDF. A continuación se indica como hacer esto.
En Mac OS X todos los cuadros de dialogo de imprimir tienen un botón Preview que permite mostrar el documento a imprimir en Preview, la aplicación Mac OS X que nos permite visualizar documentos PDF, además de otros formatos como JPG, GIF, PNG PICT y TIFF.
Preview tiene la opción de menú File|Save as PDF que nos permite guardar el documento en formato PDF.

Aunque programas como PDF Writer de Adobe tienen características adicionales, como firma digital de documentos o marcas de agua, este truco es suficiente para la mayoría de los usuarios.
Nota: Las Aplicaciones Classic no pueden aprovechar esta característica, pero si las aplicaciones Carbon.
Mac OS X tiene la posibilidad de acceder al sistema de ficheros e impresoras compartidas de Windows. En este artículo se explica cómo realizar la interconexión del mejor sistema operativo del mundo con el ... vamos, con Windows.
El protocolo que utiliza Windows para compartir archivos e impresoras se llama SMB (Server Message Block), y ha sido implementado ya desde hace tiempo en los sistemas UNIX por el proyecto de código fuente abierto Samba. Actualmente Samba permite compartir ficheros y impresoras, dar servicio de nombres WINS, y actuar como primary domain controler de Windows NT. Recientemente Microsoft ha cambiado el nombre de SMB por el de CIFS (Common Internet File System). Cosas de que esté de moda Internet, porque este protocolo sólo funciona medio bien en redes locales, así que a través de Internet mejor ni intentarlo.
Nota: Windows XP en adelante utilizar un protocolo de envío de password firmado completo que da problemas con Mac OS X. Para conectar Windows a Mac OS X recomendamos deshabilitar esta opción como se explica aquí.
Antes de empezar a describir como usar Samba, vamos a presentar algunos términos importantes:
Workgroup. Es la forma en que Windows agrupa a sus usuarios en grupos de trabajos o dominios.
Nombre NetBIOS. Es un nombre que pone Windows a cada máquina conectada a través del protocolo NetBIOS de Microsoft.
Servidor WINS: Es un ordenador que actúa resolviendo nombres NetBIOS. En caso de no existir un servidor WINS los nombres se resuelven haciendo broadcast por la red local. El broadcast puede incrementar el tiempo que se tarda en encontrar otra máquina, si la segunda máquina tarda en responder a la consulta. Para evitarlo es útil disponer de un servidor WINS.
Recurso. Es una carpeta o impresora compartida.
Vamos a empezar viendo cómo conectarse a una carpeta compartida, para luego ver cómo configurar el servidor Samba. Para conectarse a una carpeta compartida en Windows tenemos dos formas: Usar Finder, o usar el terminal.
Esta es la forma más fácil. Simplemente desde Finder usamos la opción Go|Connect to server..., o bien la tecla Command+K.

Esto abre un diálogo como el de la figura donde indicamos la URL del recurso al que queremos conectarnos que tiene la forma:
Esto abre un diálogo como el de la figura donde indicamos la URL del recurso al que queremos conectarnos que tiene la forma:
smb://workgroup;usuario@nombrenetbios/recurso
workgroup es el grupo de trabajo Windows, en mi caso es GTI
usuario a de ser un nombre de usuario válido en Windows. Por ejemplo yo uso el usuario FERNANDO
nombrenetbios es el nombre de la máquina. Por ejemplo mi PC se llama WINBOX
recurso Es la carpeta compartida en Windows a la que queremos acceder. En mi caso es AUTOR
Con lo que la URL que usaré es:
smb://GTI;FERNANDO@WINBOX/AUTOR
Windows no diferencia mayúsculas de minúsculas en los nombres SMB, pero en este documento vamos a escribir los nombres siempre en mayúsculas.
Después aparece otro diálogo que nos pide el password, y si todo va bien en la raíz de Finder aparecerá una nueva unidad, que representa la unidad de red.
Antes de conectarnos a una máquina conviene empezar comprobando que la máquina es alcanzable por la red haciéndola un ping:
$ ping 192.168.1.3
Si no conocemos la IP de un nombre NetBIOS podemos usar el comando:
$ smbutil lookup WINBOX
Got response from 192.168.1.3
IP address of WINBOX: 192.168.1.3
Podemos descubrir el nombre NetBIOS y workgroup usando el comando smbutil status así:
$ smbutil status 192.168.1.3
Workgroup: GTI
Server: WINBOX
Podemos comprobar los recursos compartidos en una máquina usando el comando smbutil view:
$ smbutil view '//GTI;FERNANDO@192.168.1.3'
Password: *****
Share Type Comment
-------------------------------
AUTOR disk
IPC$ pipe Comunicación remota entre procesos
Obsérvese que hemos usado la dirección IP de la máquina y no su nombre NetBIOS (lo cual evita el problema que se produce cuando no se resuelve bien el nombre NetBIOS). El comando nos informa de que en la máquina hay una carpeta compartida llamada AUTOR.
Desde el terminal podemos montar la unidad de red usando el comando mount. Para ello primero nos hemos creardo un directorio llamado autor donde montar la unidad. Para poder montar la unidad de red en el directorio autor debemos de estar logados como root (para ello debemos de usar el comando su). Después montamos la unidad con el comando:
# mount_smbfs -W GTI //FERNANDO@WINBOX/AUTOR ./autor
-W sirve para especificar el workgroup, y después va el recurso al que nos queremos conectar.
Tras ejecutar estos comandos, el directorio autor pasará a ser una unidad de red montada, y podremos acceder a ella desde Finder o desde el terminal.
Para desmontar la unidad tenemos el comando:
# umount ./autor
Dentro de System Preferences|Sharing disponemos de la opción File Sharing, la cual debemos de activar para que nuestra máquina actúe como servidor de ficheros. En el botón Options debemos activar la opción SMB.

Como muestra la figura, en la parte superior aparece el nombre de la máquina, que será el nombre NetBIOS que usará nuestra máquina. En Shared Folders indicamos las carpetas a compartir y los usuarios que pueden acceder a ellas. Necesitaremos conocer el usuario y password de alguna de estas cuentas para acceder a los recursos compartidos por Samba.
Por defecto es servidor Samba usa el nombre de workgroup WORKGROUP. A partir deMac OS X 10.5, dentro de System Preferences|Network|Advanced tenemos un cuadro de diálogo que nos permite configurar el nombre del workgroup y el servidor WINS.

En Mac OS X 10.4, para configurar el nombre del workgroup y el servidor WINS, necesitamos usar la utilidad Directory Service.app, situada en la carpeta /Applications/Utilities.

Si desea que los usuarios puedan conectarse a un recurso compartido sin identificarse, deberá indicarlo en System Preferences|Accounts tal como muestra la siguiente figura.

Además de estos diálogos, en el fichero /etc/smb.conf permite configurar otras opciones del servidor Samba. El fichero tiene un grupo [global] con opciones globales de configuración de Samba y un grupo para cada recurso compartido (directorios o impresoras).
En este fichero es donde el panel de preferencias escribe la configuración de Samba y los recursos compartidos. Pero para evitar interferir con las modificaciones que nosotros hagamos al fichero /etc/smb.conf, este fichero incluye los ficheros que el panel de preferencias modifica:
; Pull in system-wide preference settings. These are managed ; by smb-sync-preferences. include = /var/db/smb.conf ; Pull in system share configuration. These are managed ; by smb-sync-shares. include = /var/db/samba/smb.shares
Estas inclusiones aparecen al final del fichero /etc/smb.conf, con lo que sobrescriben las preferencias que nosotros hagamos antes de su aparición. Si no queremos que una opción pueda ser modificada por el panel de preferencias debemos ponerla después de la inclusión de estos ficheros.
http://freax.be/files/osxsmb.html
http://www.macdevcenter.com/pub/a/mac/2003/03/18/samba.html
http://www.samba.org
Mac OS X no nos permite modificar todos los ficheros del sistema a pesar de ser administradores de nuestro ordenador. En este truco se comenta como poder tener permiso a esas partes que Apple nos ha "prohibido" tocar.
Para evitar que dañemos ficheros que podrían echar abajo todo el sistema, Apple a reservado el acceso a determinados ficheros y operaciones a un usuario root, que es distinto al usuario que nos asigna Mac OS X al instalar Mac OS X.
Advertimos ya aquí de los daños que podemos causar desde la cuenta de root, con lo que debe usarse sólo sabiendo bien lo que hacemos. P.e. basta con cambiar el permiso de directorio del grupo others del directorio raíz:
$ chmod o-x /
Para que Mac OS X se caiga y no vuelva a levantarse nunca más hasta que formateemos el disco (con la consiguiente perdida de datos). Esto es así porque los procesos que arrancan Mac OS X pierden el permiso de acceso al directorio raíz, y en consecuencia al resto de los directorios del disco duro.
Dicho esto vamos a empezar intentando entrar como root en el sistema usando:
$ su
Password: ********
Sorry
Vamos que el sistema nos dice que no podemos ser root de nuestro ordenador por muy nuestro que sea.
En Mac OS X 10.5 y siguientes, para habilitar el usuario root basta con ejecutar el comando:
$ dsenableroot -u fernando
user password: ********
root password: ********
verify root password:
dsenableroot:: ***Successfully enabled root user.
Donde fernando es el nombre de un usuario con permisos de administración.
Apple tiene más información sobre cómo configurar el usuario root aquí.
Ahora podemos ir al usuario root y borrar el * que hay en el campo de password, lo cual nos permite entrar como root con sólo ejecutar el comando su:
$ su
root#
Ya está, ya tenemos el control de todo nuestro ordenador, ahora lo mejor que podemos hacer es poner un password a root para evitar que otros usuarios puedan entrar como root, para ello ejecutamos el comando:
root# passwd
New password: *******
Reype password: *******
Esta bibliografía está clasificada por las tecnologías que consideramos necesarias para dominar la programación del sistema operativo Mac OS X.
Para dominar OS X se hace imprescindible saber usar el terminal UNIX que trae. Aquí encontrará información útil de como aprender a manejar a fondo este terminal.
Mac OS X, como un tipo de UNIX que es también dispone de un terminal. El shell es el programa que controla el terminal y que permite ejecutar otros programas.
En los sistemas UNIX no hay un shell, sino muchos. Los shells más conocidos son:
| Shell | Descripción |
| sh | (bourne SHell) Es el shell original de UNIX, es el más simple de todos, con lo que casi nadie lo utiliza. Sin embargo si que lo utilizan muchas veces los programas de instalación, ya que por ser el mínimo común divisor de todos los shells, sus comandos ejecutan bien en todos los shells. |
| bash | (Bourne Again SHell) El shell de GNU. Es el que utiliza por defecto Mac OS X y Linux. |
| csh | (C SHell) Es un shell desarrollado en la Universidad de Berkeley con una sintaxis más parecida a la de el lenguaje C. |
| tcsh | (Tenex C SHell) es un csh mejorado. Fue usado por Mac OS X hasta la versión 10.2 |
| chs | (Ch Shell) Posiblemente el shell más completo y potente que existe. Tiene un lenguaje de script con sintaxis muy parecida a la de C++. Por desgracia está poco extendido. |
| ksh | (Korn SHell) Un shell usado en sistemas UNIX como AIX de IBM. |
El shell que ejecuta Mac OS X por defecto es bash.
En MacProgramadores disponemos de un buen tutorial:
Si quiere aprender el shell bash sin centrarse en las peculiaridades de Mac OS X puede leer este libro:
|
Learning the bash Shell, Third Edition Cameron Newham Ed. O'Reilly |
Si por el contrario quiere aprender muchos trucos propios del terminal de Mac OS X puede elegir mejor este otro libro:
|
Mac OS X for Unix Geeks (Leopard), Fourth Edition Ernest E. Rothman, Brian Jepson, Rich Rosen Ed. O'Reilly |
A continuación se indican cuales son las principales herramientas de desarrollo de Mac OS X y iOS
La principal herramienta de desarrollo para Mac OS X y iOS es este kit, que proporciona de forma gratuita Apple a los miembros del ADC. Si quiere conseguir estas herramientas regístrese como usuario del ADC aquí.
Este kit incluye las siguientes herramientas:
Xcode. Un IDE desde el que podemos realizar aplicaciones C, C++, Java y Objective-C para Mac OS X y iOS.
Interface Builder. Herramienta que nos permite realizar la interfaz gráfica de las aplicaciones cómodamente. A partir de Xcode 4.0 está integrado con Xcode. La interfaz gráfica de las aplicaciones, además de poder crearse programáticamente, se puede crear en un fichero XML con la extensión .xib que se compila en un .nib. Cuando se ejecuta una aplicación se carga en memoria este fichero en base al cual se crea la interfaz gráfica. Esto es mucho más cómodo que tener que hacer llamadas al API, y para crear este fichero se usa esta herramienta.
Instruments. Una herramienta que nos permite perfilar nuestras aplicaciones y encontrar errores en tiempo de ejecución.
Package Maker. Una herramienta que nos permite hacer instaladores de aplicaciones Mac OS X de forma rápida y con una interfaz homogénea para todas las aplicaciones. Esta herramienta nos permite crear ficheros .pkg, que al hacer el usuario doble click sobre ellos se ejecuta el instalador.
Dashcode. Es una herramienta que nos permite crear fácilmente widgets para Dashboard.
PropertyListEditor. En Mac OS X muchos ficheros de configuración usan el formato XML, para poder visualizar de forma cómoda (jerárquicamente) estos ficheros tenemos esta herramienta.
Icon Composer. Estas herramientas nos permiten crear y visualizar ficheros .icns de forma cómoda.
Documentación. La gran mayoría de la documentación y tutoriales que encontramos en la web de Apple, la podemos encontrar también aquí.
Ejemplos. Cuando tenemos dudas sobre como se hace "exactamente" algo de lo que nos habla la ayuda, lo mejor es buscar en estos ejemplos.
Un muy buen artículo que resume el funcionamiento de Xcode es el siguiente:
Para profundizar mucho más podemos leer este otro documento:
Terceras partes están desarrollando excelentes herramientas de desarrollo que recomendamos evaluar.
gcc o javac con una combinación de teclas. O bien podemos crear ficheros Makefile o Ant y ejecutarlos. Además consume poca memoria. No es gratuito pero tiene un precio muy asequible.Objective-C es un lenguaje orientado a objetos creado como un superconjunto de C con un estilo muy parecido al de Smalltalk. Originalmente fue escrito por Brad Cox y la corporación StepStone en 1980. En 1988 fue adoptado como lenguaje de programación de NeXTSTEP y en 1992 fue liberado bajo licencia GNU para el compilador gcc. Actualmente se usa como lenguaje principal de programación en Mac OS X y GNUStep.
Podemos obtener un compilador de Objective-C en:
Para aprender Objective-C, básicamente hay tres pasos:
Para ello se puede usar uno de los miles de libros que hay sobre la materia. También se puede consultar esta web con buenos manuales gratuitos en castellano sobre C.
Para aprender Objective-C recomendamos el siguiente libro:
![]() |
Objective-C. Curso práctico para Programadores Mac OS X, iPhone y iPad Autor: Fernando López Hernández Editorial: RC Libros lSBN: 978-84-938312-7-1 560 páginas. |
libobjects son las librerías de clases de GNU para Objective-C. En concreto se trata de librerías de uso general no gráfica. Se puede decir que libobjects son para GNU's Objective-C lo que libc++ para GNU's C++. En un futuro se pretende cambiar el nombre de estas librerías por el de "GNUStep Base Library". Estas librerías están todavía sin acabar.
Objective-C++ es un lenguaje que surgió en los tiempos de NeXTSTEP. Este lenguaje permite mezclar código fuente C++ y Objective-C en el mismo fichero fuente, así como llamar a objetos C++ desde Objective-C y viceversa. Lo cual permite al programador Objective-C utilizar todas las librerías de C++ existentes, y al programador C++ acceder a toda la libraría de Cocoa. Los ficheros Objective-C++ llevan las extensión .mm ó .M (extensión antigua que se mantiene por compatibilidad).
Cocoa es la nueva API de programación de aplicaciones de Mac OS X. Existe otra API llamada Carbon que permite la compatibilidad con las aplicaciones de Mac OS Classic, que no vamos a tratar en esta web. En el caso de iOS la API se llama Cocoa Touch.
Cocoa es una API totalmente orientada a objetos a la que principalmente se accede desde Objective-C. Apple ha creado Cocoa Brigdges para poder acceder a Cocoa desde otros lenguajes como AppleScript, Java, Python o Ruby.
La principal fuente de referencia sobre esta API es la documentación publicada por Apple en:
Los programadores Windows pueden consultar esta guía que tiene publicada Apple sobre como migrar desde Win32 a Mac OS X:
Porting to Mac OS X from Win32 API
Por desgracia esta documentación más que un tutorial es un manual de referencia, con lo que es útil como fuente de consulta, pero no tanto para aprender a programar. Por esta razón proponemos los siguientes libros.
|
Cocoa(R) Programming for Mac(R) OS X (3rd Edition) Aaron Hillegass Ed. Addison-Wesley Professional |
|
Learn Cocoa on the Mac Jack Nutting, David Mark, Jeff LaMarche Ed. Apress |
iOS es un sistema operativo para PDAs y teléfonos móviles desarrollado por Apple. iOS está basado en el sistema operativo Mac OS X y sus herramientas de programación son similares a las de Mac OS X. En concreto ambos sistemas operativos comparten el mismo núcleo Mach/FreeBSD, y utilizan como lenguajes de programación principales C y Objective-C.
Distintos dispositivos utilizan iOS. iPhone es un teléfono móvil con capacidades multimedia desarrollado por Apple. iPod Touch es la versión reducida de iPhone que no tiene teléfono. iPad es un dispositivo con el mismo sistema operativo y arquitectura hardware que iPhone, pero al que se ha quitado las características propias de teléfono móvil y se le ha añadido una pantalla más grande.
Para la programación de iOS, Apple proporciona una API de programación llamada Cocoa Touch. Esta API comparte muchas similitudes con Cocoa de Mac OS X y también tiene diferencias. La las clases base de Foundation Framework son comunes entre Mac OS X y iOS. Las principales diferencias se encuentran la UIKit, que son las clases de programación de interfaz de usuario de iOS . El equivalente a UIKit en Mac OS X es Application Kit.
Actualmente existe bastante bibliografía para aprender a programar iOS. En el sitio web de Apple dedicado a iOS encontramos guías de programación como:
Además existen ya bastantes libros destinados a programar con iOS. Entre ellos destacamos los siguientes:
|
Beginning iPhone Development: Exploring the iPhone SDK Dave Mark, Jeff LaMarche Ed. Apress |
![]() Phone SDK Application Development: Building Applications for the AppStore Jonathan Zdziarski Ed. O'Reilly |
Darwin es la parte open source de Mac OS X que han desarrollado los ingenieros de Apple. Darwin consta de multitud de paquetes (Compiler Tools, Kerberos, Open Directory, X11, CUPS, XNU...).
Un paquete importante de Darwin es el núcleo de Mac OS X, el cual se llama XNU (XNU is not UNIX). Dentro de Darwin encontramos el paquete XNU con el código fuente tanto para x86 como para PowerPC y ARM.
Las principales partes que componen XNU son básicamente dos: Mach 3.0, un microkernel desarrollado en la Universidad de Carnegie Mellon, y el núcleo BSD 4.4 (Berkeley Software Distribution) de FreeBSD.
XNU consta de seis componentes principales:
Mach El "núcleo del núcleo" XNU. Realiza las operaciones críticas de un microkernel, como son la gestión de procesador, la gestión de memoria, la gestión de procesos y hilos (protección de memoria, scheduling), soporte para el reloj real-time (p.e. usado por las aplicaciones multimedia) y el soporte para depuración del kernel.
Aunque el microkernel Mach 3.0 fue el núcleo en el que se basaron los ingenieros de Apple, XNU no es en si un microkernel puro, ya que su espacio de memoria está compartido con una parte de BSD y con las Kernel Extensions.
BSD Una capa por encima de Mach que permite a los programadores usar las conocidas llamadas al sistema POSIX de los sistemas UNIX. Estas funciones nos permiten entre otras cosas la gestión de procesos por ID, dar permisos a estos procesos, gestión de señales, o el uso de sockets BSD. La principal ventaja que aporta BSD es que permite migrar fácilmente aplicaciones UNIX a Mac OS X.
Kernel Extensions (también llamados kexts) Son bundles que extienden la funcionalidad del núcleo de Mac OS X y que se pueden cargar y descargar dinámicamente. Dentro del bundle encontramos el kernel módule (también llamado kmod) que es una imagen binaria Mach que se instala en el kernel. Los kext se programan en C. Para aprender a desarrollar Kernel Extensions, puede consultar:
I/O Kit Proporciona un framework C++ para el desarrollo de drivers de dispositivos mediante kexts. En concreto, usa un subconjunto del lenguaje C++ llamado Embedded C++. Un I/O Kit driver es una kext que, en vez de estar programada en C, está programada en Embeded C++. El I/O Kit está formado por tres componentes principales:
Si vamos a trabajar con el I/O Kit conviene leerse:
File System El sistema de ficheros de XNU se basa en el diseño de VFS (Virtual File System), el cual se caracteriza porque nos permite añadir fácilmente nuevos sistemas de ficheros, así como añadir capas a un sistema de ficheros existentes (p.e. compresión, encriptación). Mac OS X viene con los sistemas de ficheros HFS, HFS+, UFS (Universal File System) y ISO 9660
Networking Mac OS X lleva implementada la pila de red en el núcleo, la cual también tiene un sistema extensible que nos permite añadir nuevos protocolos llamado NKE (Network Kernel Extensions).
Apple tiene un repositorio open source destinados a almacenar el código fuente de Darwin en:
Este es un repositorio del que se saca directamente el código fuente que lleva Mac OS X, con lo que su contenido debe de ser de calidad. Por eso para que un programador pueda modificar este repositorio debe superar unos controles de calidad que establece Apple (en su mayoría acceden a el sólo los empleados de Apple), aunque todo el mundo puede bajarse el código fuente de este repositorio a través de CVS.
Todo aquel que quiera programar en el kernel, debería empezar leyéndose este documento:
Should You Program in the Kernel?
Después podemos bajarnos el código fuente de XNU de aquí:
Para iniciarse en la programación del kernel es recomendable empezar leyéndose:
El mejor libro que conocemos para aprender a programar en el kernel de Mac OS X es:
|
Mac OS X Internals: A Systems Approach Amit Singh Ed. Addison-Wesley Professional |
Otro buen libro con multitud de trucos es:
|
The Mac Hacker's Handbook Charles Miller, Dino Dai Zovi Ed. Wiley |