← Fundamentos de Sistemas Operativos Bloque 6 · Tipos y diseños de sistemas operativos · Tema 25 de 34

Tema 25

Unix, Linux, Windows y macOS

Casi todas las computadoras en uso ejecutan un descendiente de dos sistemas diseñados hace décadas. En este tema ordenamos el mapa: qué relación hay entre Unix y Linux, por qué existen cientos de distribuciones, en qué decidió Windows ser distinto, qué hay debajo de macOS, y qué diferencias encuentra quien escribe un programa para más de uno.

1. Dos linajes

En el tema 3 recorrimos la historia de los sistemas operativos como una sucesión de problemas y soluciones. Aquí la miramos como una genealogía, porque explica el presente con muy pocos trazos. De los muchos sistemas que existieron, los que hoy se usan descienden casi todos de dos: Unix, de 1969, y Windows NT, de 1993, que a su vez heredó ideas de un sistema anterior llamado VMS.

Genealogía de los sistemas actuales: de Unix descienden System V, con Solaris, AIX y HP-UX; BSD, con FreeBSD, OpenBSD y NetBSD; y macOS e iOS a través de BSD. Linux reimplementa la interfaz de Unix con código nuevo y da origen a las distribuciones y a Android. Por otro lado, de VMS desciende Windows NT y de él las versiones actuales de Windows Unix · 1969 System V Solaris · AIX · HP-UX BSD FreeBSD · OpenBSD · NetBSD macOS · iOS Linux · 1991 Distribuciones · Android VMS · 1977 NT · 1993 Windows 10 y 11 · Xbox
Las líneas continuas indican herencia de código o de diseñadores. La línea de trazos hacia Linux indica otra cosa: la misma interfaz, escrita de nuevo.

El dibujo adelanta las tres ideas del tema. La rama superior es una familia en sentido estricto, con código que pasó de un sistema a otro. Linux pertenece a ella por adopción: se comporta como Unix sin contener una línea suya. Y la rama inferior es un diseño independiente, que resolvió los mismos problemas con otras decisiones.

2. Unix: una palabra, tres significados

Buena parte de la confusión en este terreno proviene de que «Unix» se usa con tres sentidos distintos, y un mismo sistema puede cumplir uno y no otro:

SentidoSignificaLo cumplen
HistóricoEl sistema original de los Laboratorios Bell y los que derivan de su código fuente.Los sistemas BSD, Solaris, AIX, HP-UX; en parte, macOS.
LegalUNIX es una marca registrada. Puede usarla el sistema que supere las pruebas de conformidad de una especificación oficial.macOS, AIX, HP-UX. Ni Linux ni los BSD están certificados.
De diseñoUn sistema que ofrece la interfaz y sigue las convenciones de Unix: procesos, descriptores, «todo es un archivo», shell, tuberías. Se dice «tipo Unix» o Unix-like.Todos los anteriores, y Linux.

El tercer sentido es el que importa a quien programa, y es el que usamos en este curso. Un sistema tipo Unix es aquel donde copiar.c se compila sin cambios, donde ls | wc -l hace lo esperado y donde los conceptos de los temas anteriores se aplican tal cual.

Linux es el caso más ilustrativo. Torvalds lo escribió desde cero, sin código de Unix, y nadie pagó nunca la certificación. No es Unix en el primer sentido ni en el segundo. Lo es por completo en el tercero, hasta el punto de ser hoy el sistema tipo Unix más usado, con mucha diferencia.

3. Los descendientes directos

La rama histórica sigue viva, aunque con menos presencia que hace treinta años:

SistemaOrigenDónde se lo encuentra hoy
FreeBSDBSDServidores de distribución de video, equipos de red y almacenamiento. Es la base del sistema de las consolas PlayStation.
OpenBSDBSDCortafuegos y equipos donde la seguridad es la prioridad. De este proyecto salió OpenSSH, que usan todos los demás sistemas.
NetBSDBSDEquipos embebidos; su meta es funcionar en la mayor cantidad posible de arquitecturas.
Solaris, AIX, HP-UXSystem VServidores de grandes empresas, en instalaciones heredadas. Casi no hay despliegues nuevos.

Los sistemas BSD se diferencian de Linux en algo que la tabla del tema 10 permite precisar. En Linux, el kernel, la biblioteca de C, la shell y las utilidades son proyectos independientes que una distribución reúne. En un BSD, todo eso lo desarrolla un mismo equipo, en un único repositorio, y se publica junto: FreeBSD es un sistema operativo completo, no un kernel. La otra diferencia es la licencia. La de BSD permite incorporar el código a productos cerrados sin publicar los cambios, y por eso aparece dentro de sistemas comerciales, macOS entre ellos.

4. Linux: un kernel, muchas distribuciones

En el tema 1 distinguimos el kernel de la distribución, y en el tema 10 vimos que una distribución reúne componentes de proyectos distintos. Falta explicar por qué hay cientos y en qué difieren realmente.

Que existan tantas es consecuencia directa de ese modelo. Si las piezas son libres e independientes, cualquiera puede combinarlas a su manera, y cada combinación responde a una prioridad: estabilidad para servidores, software reciente para desarrolladores, tamaño mínimo para contenedores. Las decisiones que distinguen a una distribución de otra son estas:

DecisiónOpciones habituales
Formato y gestor de paquetes.deb con apt; .rpm con dnf o zypper; pacman; apk.
Ritmo de publicaciónVersiones fijas, con años de mantenimiento, o actualización continua.
Qué versiones incluyeProbadas y algo antiguas, o las más recientes.
Biblioteca de C y utilidadesglibc y las herramientas de GNU, o musl y busybox.
Sistema de iniciosystemd en casi todas; alternativas más simples en algunas.
Quién la respaldaUna empresa, con soporte pago, o una comunidad de voluntarios.

Las distribuciones se agrupan en familias, según de cuál derivan y qué gestor de paquetes comparten:

FamiliaMiembros conocidosPaquetesSe caracteriza por
DebianDebian, Ubuntu, Linux Mint.deb, aptLa más extendida en escritorios y en la nube.
Red HatFedora, Red Hat Enterprise Linux, Rocky, AlmaLinux.rpm, dnfPredomina en servidores de empresas.
SUSEopenSUSE, SUSE Linux Enterprise.rpm, zypperFuerte en Europa y en entornos corporativos.
ArchArch Linux, ManjaropacmanActualización continua; el usuario arma el sistema.
AlpineAlpine LinuxapkMínima, con musl y busybox. Muy usada en contenedores.

A lo largo del curso fuimos anotando las diferencias al pasar: apt o dnf, update-grub o grub2-mkconfig, /lib/x86_64-linux-gnu o /lib64. Todas son de este orden. Lo que no cambia de una distribución a otra es lo que estudiamos: el kernel, sus llamadas al sistema, la interfaz POSIX, /proc, el formato ELF. Un programa en C de este curso se compila igual en todas.

Hay una excepción, que ya conocemos del tema 15: la biblioteca de C. Un ejecutable compilado en Ubuntu, contra glibc, no funciona en Alpine, que usa musl. Y Android, que comparte el kernel, está todavía más lejos: como vimos en el tema 10, reemplaza casi todo el espacio de usuario, y no se lo considera una distribución en el sentido habitual.

5. Identificar un sistema

Todas las distribuciones actuales se describen a sí mismas en un archivo de formato común, /etc/os-release, del que vimos dos líneas en el tema 1:

terminal
$ cat /etc/os-release
PRETTY_NAME="Ubuntu 24.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="24.04"
VERSION="24.04.1 LTS (Noble Numbat)"
VERSION_CODENAME=noble
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
…

Las dos líneas resaltadas son las útiles para un programa. ID identifica la distribución, y ID_LIKE, la familia de la que deriva: un script que sabe trabajar con Debian puede reconocer que también sirve para Ubuntu, o para una derivada que nunca oyó nombrar. El archivo tiene además una propiedad conveniente: sus líneas son asignaciones válidas de Bash, de modo que un script puede incorporarlo directamente.

familia.sh
#!/bin/bash
# Informa la distribución, su familia y su gestor de paquetes.

. /etc/os-release                   # define NAME, VERSION_ID, ID, ID_LIKE...

echo "Distribucion: $NAME $VERSION_ID"
echo "Kernel:       $(uname -sr)"

case " $ID $ID_LIKE " in
    *" debian "*)             echo "Familia:      Debian (paquetes .deb, gestor apt)" ;;
    *" fedora "*|*" rhel "*)  echo "Familia:      Red Hat (paquetes .rpm, gestor dnf)" ;;
    *" suse "*)               echo "Familia:      SUSE (paquetes .rpm, gestor zypper)" ;;
    *" arch "*)               echo "Familia:      Arch (gestor pacman)" ;;
    *" alpine "*)             echo "Familia:      Alpine (gestor apk, biblioteca musl)" ;;
    *)                        echo "Familia:      no reconocida ($ID)" ;;
esac
terminal
$ chmod +x familia.sh
$ ./familia.sh
Distribucion: Ubuntu 24.04
Kernel:       Linux 6.8.0-45-generic
Familia:      Debian (paquetes .deb, gestor apt)

La salida tiene dos versiones, y son las dos caras del sistema: la de la distribución, 24.04, y la del kernel, 6.8. Se actualizan por separado. El script reconoce a Ubuntu como miembro de la familia Debian sin que «ubuntu» figure en ninguna de sus comparaciones: lo hace por ID_LIKE.

6. Windows: el otro linaje

Windows NT no desciende de Unix ni intenta parecérsele. Su arquitecto principal, Dave Cutler, había dirigido antes el diseño de VMS, el sistema de las minicomputadoras de Digital, y llevó consigo sus ideas. El resultado es un sistema que resuelve los mismos problemas —procesos, memoria virtual, archivos, protección— con un vocabulario y unas decisiones propias.

AspectoEn Unix y LinuxEn Windows
Idea unificadoraTodo es un archivo: un descriptor sirve para archivos, dispositivos y conexiones.Todo es un objeto: archivos, procesos, hilos y otros recursos se manejan mediante identificadores llamados handles, cada tipo con sus propias funciones.
Interfaz estableLas llamadas al sistema.La API Win32: un conjunto de bibliotecas. Las llamadas al sistema son internas y cambian entre versiones.
Crear un procesoDos pasos: duplicar el proceso y reemplazar su programa.Un paso: una función que crea el proceso con el programa indicado.
ConfiguraciónArchivos de texto, en /etc.El Registro: una base de datos jerárquica.
Nombres de archivoUn único árbol, que empieza en /.Un árbol por unidad: C:\, D:\.
PermisosDueño, grupo y otros.Listas de control de acceso, más detalladas.
Quién arma el sistemaUna distribución, con piezas de muchos proyectos.Un solo fabricante, que entrega todo.

La segunda fila explica una observación del tema 13. En Linux pudimos escribir hola.s, un programa que habla con el kernel por número de llamada, porque esos números son un compromiso público. En Windows, un programa así dejaría de funcionar con la siguiente actualización. Allí el contrato está un nivel más arriba, en las bibliotecas, y es el que Microsoft mantiene compatible desde hace treinta años con un cuidado notable: programas de los años noventa siguen ejecutándose.

La tercera fila la veremos con detalle en el tema 26. En el tema 16 observamos con strace la secuencia de Unix: clone para duplicar el proceso y execve para cargar el programa. Windows no tiene un equivalente del primer paso, y es una de las diferencias que más trabajo dan al llevar programas de un sistema a otro.

NT fue diseñado, además, con la idea de admitir varias «personalidades»: subsistemas que ofrecieran a los programas la interfaz de otros sistemas operativos. De esa idea salió, mucho después, el subsistema de Windows para Linux que presentamos en el tema 4.

7. macOS: un Unix con otra cara

La apariencia de macOS no lo sugiere, pero debajo hay un sistema Unix en los tres sentidos de la sección 2. Su base se llama Darwin, y está formada por el kernel XNU, que estudiamos en el tema 24, y un espacio de usuario tomado en buena parte de FreeBSD. Sobre esa base, Apple construye lo que el usuario reconoce: el entorno gráfico y las bibliotecas con que se escriben las aplicaciones. iOS y los demás sistemas de la empresa comparten el mismo fundamento.

Para quien llega desde Linux, la terminal de macOS resulta familiar: la misma shell, los mismos comandos, gcc y make disponibles. Los programas de este curso que usan solo POSIX se compilan sin cambios. Las diferencias aparecen al salir de ese terreno común:

AspectoLinuxmacOS
Formato de ejecutableELFMach-O
Interfaz estableLas llamadas al sistemaLa biblioteca del sistema; los números de llamada no están garantizados
Información del kernel/proc y /sysNo existen; se usa la función sysctl
UtilidadesLas de GNULas de BSD: mismos nombres, opciones a veces distintas
Inicio y serviciossystemdlaunchd
Trazar llamadas al sistemastracedtruss, con restricciones
Mayúsculas en nombres de archivoSe distinguenPor defecto, no

La cuarta fila es una fuente clásica de sorpresas. Un script que usa una opción de sed o de date propia de las versiones de GNU funciona en Linux y falla en una Mac, aunque el comando exista en los dos. Es el mismo problema de portabilidad del tema 15, trasladado de las funciones de C a los comandos: lo que garantiza el estándar es un subconjunto, y las extensiones de cada familia no coinciden.

8. POSIX, en la práctica

En el tema 15 vimos qué es POSIX y qué define. Ahora podemos decir qué significa en concreto para lo que hicimos en este curso. La tabla clasifica lo que usamos según dónde funciona:

Lo que usamosLinuxmacOS y BSDWindows
printf, fopen, malloc, strlenSíSíSí: son del estándar de C
open, read, write, getpid, nanosleep, getrusageSíSí: son de POSIXNo de forma nativa
Bash, ls, grep, tuberíasSíSí, con diferencias en las opcionesNo de forma nativa
syscall(), gettidSíNoNo
/proc/interrupts, /proc/cmdline, /proc/PID/statusSíNoNo
strace, lsmod, dmesgSíOtras herramientasOtras herramientas
Ensamblador con números de llamadaSíNo convieneNo conviene

La tabla se lee de dos maneras. Para escribir programas, marca tres niveles de portabilidad: lo que funciona en todas partes, lo que funciona en la familia Unix y lo que es exclusivo de Linux. Para aprender, explica la elección del curso: las filas inferiores, las menos portables, son justamente las que permiten ver el sistema operativo trabajando. Ningún otro sistema de uso general expone tanto de sí mismo.

Y hay que separar las herramientas de los conceptos. /proc/interrupts no existe en una Mac, pero las interrupciones sí, y funcionan como describimos. Lo que aprendiste mirando Linux vale para los demás; lo que cambia es dónde mirar.

9. Qué cambia para quien programa

Esta es la tabla de consulta del tema. Reúne las diferencias con que se encuentra, tarde o temprano, quien escribe un programa que debe funcionar en más de un sistema:

AspectoLinuxmacOSWindows
Formato de ejecutableELFMach-OPE (.exe)
Bibliotecas compartidas.so.dylib.dll
Interfaz de programaciónPOSIXPOSIXWin32
Crear un procesofork y execfork y execCreateProcess
Separador de rutas//\; acepta también /
Datos.txt y datos.txtDos archivosEl mismo, por defectoEl mismo
Fin de línea en archivos de texto\n\n\r\n
Codificación de texto del sistemaUTF-8UTF-8UTF-16 en la interfaz nativa
Tamaño de long en 64 bits8 bytes8 bytes4 bytes
Borrar un archivo que está abiertoPermitidoPermitidoRechazado, por defecto
Aviso asíncrono a un procesoSeñalesSeñalesUn mecanismo distinto y más limitado

Varias filas tienen consecuencias que no se adivinan a primera vista:

10. Experimento: el mismo código, otro sistema

El compilador define unas macros que indican para qué sistema está compilando. Con ellas, un mismo archivo fuente puede adaptarse en el momento de compilar:

plataforma.c
#include <stdio.h>

#if defined(_WIN32)
#  define SISTEMA "Windows"
#elif defined(__APPLE__)
#  define SISTEMA "macOS"
#elif defined(__linux__)
#  define SISTEMA "Linux"
#else
#  define SISTEMA "otro"
#endif

#if defined(__unix__) || defined(__APPLE__)
#  include <unistd.h>                  /* existe solo en los sistemas tipo Unix */
#  define HAY_POSIX 1
#else
#  define HAY_POSIX 0
#endif

int main(void)
{
    printf("Sistema:           %s\n", SISTEMA);
    printf("Tamano de long:    %d bytes\n", (int)sizeof(long));
    printf("Tamano de puntero: %d bytes\n", (int)sizeof(void *));

#if HAY_POSIX
    printf("POSIX:             version %ld, PID %d\n", (long)_POSIX_VERSION, (int)getpid());
#else
    printf("POSIX:             no disponible\n");
#endif
    return 0;
}

Para obtener un ejecutable de Windows no hace falta Windows. Un compilador cruzado se ejecuta en un sistema y produce programas para otro; el paquete gcc-mingw-w64-x86-64 instala uno. Compilamos el mismo archivo dos veces:

terminal
$ gcc -Wall -Wextra -g plataforma.c -o plataforma
$ ./plataforma
Sistema:           Linux
Tamano de long:    8 bytes
Tamano de puntero: 8 bytes
POSIX:             version 200809, PID 7412

$ sudo apt install gcc-mingw-w64-x86-64
$ x86_64-w64-mingw32-gcc -Wall -Wextra plataforma.c -o plataforma.exe
$ file plataforma plataforma.exe
plataforma:     ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, …
plataforma.exe: PE32+ executable (console) x86-64, for MS Windows

$ ./plataforma.exe
bash: ./plataforma.exe: cannot execute binary file: Exec format error

Los dos archivos contienen instrucciones para el mismo procesador, traducidas del mismo código fuente. El kernel de Linux rechaza el segundo en la llamada execve: lee sus primeros bytes, no encuentra el número mágico de ELF que conocimos en el tema 9, y devuelve un error. No llega a ejecutar una sola instrucción. Copiado a un equipo con Windows, ese archivo produce esto:

en Windows
Sistema:           Windows
Tamano de long:    4 bytes
Tamano de puntero: 8 bytes
POSIX:             no disponible

Tres de las cuatro líneas cambiaron, y cada una corresponde a una fila de la tabla anterior: el sistema, el tamaño de long y la ausencia de unistd.h. El código fuente es portable porque prevé las diferencias; el ejecutable no lo es en ningún caso.

En WSL ocurre otra cosa

Si haces este experimento en WSL, ./plataforma.exe no da error: se ejecuta y muestra la salida de Windows. WSL reconoce los ejecutables de Windows y se los entrega al sistema anfitrión. Es una comodidad de ese entorno, y no contradice lo dicho: el kernel de Linux sigue sin saber cargar ese archivo.

11. Capas de compatibilidad

Existen muchas herramientas para usar los programas de un sistema en otro. Parecen un conjunto heterogéneo, y se ordenan con una sola pregunta: ¿qué interfaz reemplazan? En el tema 10 distinguimos tres, y hay técnicas para cada una, además de la del hardware.

Se reimplementaCómoEjemplos
La interfaz de programaciónSe escriben de nuevo las bibliotecas de un sistema sobre las llamadas de otro. El programa original se ejecuta sin modificar.Wine ofrece la API de Windows sobre Linux y macOS. Cygwin ofrece la de POSIX sobre Windows; requiere recompilar.
Las llamadas al sistemaEl kernel anfitrión atiende las llamadas del otro sistema, traduciéndolas.La primera versión de WSL: el kernel de Windows respondía a las llamadas de Linux.
El hardwareSe ejecuta el otro sistema operativo completo, con su kernel, en una máquina virtual.VirtualBox, y la versión actual de WSL.
El procesadorSe traducen las instrucciones de una arquitectura a otra.Rosetta, que ejecuta en las Mac con procesador ARM los programas hechos para Intel.

La historia de WSL recorre dos filas de la tabla, y enseña algo. La primera versión traducía llamadas al sistema: era liviana, y nunca logró reproducir con fidelidad todos los comportamientos del kernel de Linux. La segunda abandonó ese camino y ejecuta un kernel de Linux real en una máquina virtual. Imitar una interfaz tan amplia resultó más difícil que ejecutar el original.

La última fila resuelve un problema distinto de los otros tres, y se confunde con ellos a menudo. Rosetta no cambia de sistema operativo, sino de procesador: el programa sigue siendo de macOS. Las dos barreras son independientes, y un ejecutable solo funciona donde coinciden ambas, el sistema y la arquitectura.

12. Dónde se usa cada uno

La pregunta por «el sistema operativo más usado» no tiene una respuesta única, porque depende del tipo de equipo. Cada ámbito tiene su reparto, y son muy distintos entre sí:

ÁmbitoPredominaTambién presentes
Computadoras personalesWindowsmacOS; Linux, sobre todo entre desarrolladores
TeléfonosAndroid, es decir, LinuxiOS
Servidores y nubeLinuxWindows Server; sistemas BSD
SupercomputadoresLinux, en todos—
Sistemas embebidosLinux y los RTOSQNX, VxWorks
Consolas de videojuegosRepartidoUn derivado de FreeBSD, uno de Windows y un sistema propio

Contando todos los equipos, el kernel más extendido del mundo es Linux, por los teléfonos y los servidores, aunque su presencia en los escritorios sea pequeña. Y si se agrupa por linaje, la familia de Unix —con Linux, Android, macOS e iOS— abarca la gran mayoría de las computadoras en uso. El sistema que Thompson y Ritchie escribieron para una máquina que nadie quería dejó la descendencia más numerosa de la historia del software.

13. Lo que no cambia

Este tema estuvo dedicado a las diferencias, y conviene cerrarlo con la proporción correcta. Las diferencias están en la superficie: en los nombres, los formatos y las interfaces. Por debajo, los cuatro sistemas del título son el mismo tipo de objeto.

FundamentoLo vimos en¿Vale para Linux, Windows y macOS?
Un kernel en modo privilegiado, y programas en modo usuarioTema 12Sí
Llamadas al sistema como única entrada voluntaria al kernelTema 13Sí
Una biblioteca entre el programa y el kernelTema 15Sí
Interrupciones y excepciones atendidas mediante una tabla de vectoresTemas 17 y 18Sí
Multitarea apropiativa gobernada por un temporizadorTema 19Sí
Arranque por etapas: firmware, cargador, kernel, primer procesoTemas 20 a 22Sí
Procesos, memoria virtual, archivos y permisosBloque 7Sí

No es una coincidencia. Todos se ejecutan sobre los mismos procesadores, que ofrecen los mismos mecanismos, y todos heredaron las ideas de los mismos sistemas de los años sesenta y setenta. Quien entiende uno a fondo tiene hecho la mayor parte del camino para entender los otros: le falta aprender los nombres.

Con esto termina el bloque sobre tipos y diseños. El siguiente, el último antes de la integración final, recorre uno por uno los servicios que todo sistema operativo ofrece, empezando por el que apareció en casi todos los temas sin que lo definiéramos del todo: el proceso.

14. Resumen

15. Preguntas de repaso

Intenta responder cada una antes de abrir la respuesta.

1. ¿Es Linux un Unix?

Depende del sentido. No deriva del código de Unix ni tiene la certificación que permite usar la marca. Sí lo es por diseño: ofrece la misma interfaz y sigue las mismas convenciones. Se lo llama un sistema «tipo Unix».

2. ¿En qué se diferencia el modo de desarrollo de FreeBSD del de una distribución de Linux?

FreeBSD desarrolla el kernel, la biblioteca de C y las utilidades en un mismo proyecto, y los publica juntos como un sistema completo. Una distribución de Linux reúne piezas de proyectos independientes: el kernel por un lado, glibc, Bash y las utilidades por otro.

3. ¿Por qué existen tantas distribuciones de Linux?

Porque los componentes son libres e independientes, y cualquiera puede combinarlos según una prioridad distinta: estabilidad, novedad, tamaño, soporte comercial. Cada combinación es una distribución.

4. ¿Qué comparten Ubuntu y Fedora, y qué no?

Comparten el kernel, sus llamadas al sistema, la interfaz POSIX, glibc y la mayor parte de las utilidades. Difieren en el formato y el gestor de paquetes, las versiones que incluyen, la ubicación de algunos archivos y los comandos de administración.

5. ¿Para qué sirve el campo ID_LIKE de /etc/os-release?

Indica de qué distribución deriva la actual. Permite que un programa preparado para una familia reconozca a todas sus derivadas, sin necesidad de conocer el nombre de cada una.

6. En Windows, ¿cuál es la interfaz que el fabricante mantiene estable? ¿Y en Linux?

En Windows, la API Win32, que es un conjunto de bibliotecas; las llamadas al sistema son internas y pueden cambiar. En Linux, la estabilidad se garantiza en las propias llamadas al sistema.

7. ¿Qué es Darwin?

La base de macOS e iOS: el kernel XNU junto con un espacio de usuario derivado en buena parte de FreeBSD. Sobre ella Apple añade el entorno gráfico y las bibliotecas de aplicación.

8. Un script funciona en Ubuntu y falla en una Mac, aunque todos los comandos existen. ¿Qué pudo ocurrir?

Que use una opción propia de las utilidades de GNU. macOS trae las versiones de BSD de los mismos comandos, que comparten el nombre y las opciones del estándar, pero no las extensiones.

9. Clasifica según su portabilidad: strlen, getpid, /proc/cmdline.

strlen pertenece al estándar de C y existe en todos los sistemas. getpid es de POSIX y existe en los sistemas tipo Unix. /proc/cmdline es propio de Linux.

10. Un programa guarda el tamaño de un archivo en una variable long. ¿Qué riesgo corre?

En Windows de 64 bits, long mide 4 bytes y no puede representar tamaños de más de 2 GB. En Linux y macOS mide 8 y el programa funciona, lo que oculta el problema hasta que se lo lleva a Windows.

11. ¿Por qué Linux rechaza plataforma.exe, si contiene instrucciones para el mismo procesador?

Porque el archivo tiene formato PE, y el kernel de Linux solo sabe cargar ejecutables ELF. Lo rechaza al examinar sus primeros bytes, antes de ejecutar nada. Aunque lograra cargarlo, el programa pediría bibliotecas de Windows que no existen.

12. ¿En qué se diferencian Wine y una máquina virtual?

Wine reimplementa la interfaz de programación de Windows sobre otro sistema: no hay kernel de Windows. Una máquina virtual reimplementa el hardware y ejecuta un Windows completo, con su kernel.

13. ¿Por qué Linux puede actualizar una biblioteca en uso sin reiniciar y Windows suele pedir un reinicio?

En Linux, un archivo abierto puede borrarse o reemplazarse: los programas que lo tenían abierto siguen usando el contenido anterior hasta cerrarlo. Windows rechaza por defecto esa operación, de modo que el reemplazo debe esperar a que nadie use el archivo.

Para practicar

  1. Ejecuta familia.sh en tu sistema. Si tienes acceso a otra distribución —una máquina virtual o un contenedor—, ejecútalo allí y compara.
  2. Amplía familia.sh para que informe también la biblioteca de C, con getconf GNU_LIBC_VERSION, y trate el caso en que ese comando falle.
  3. Averigua a qué paquete pertenecen /bin/ls, /bin/bash y /usr/bin/gcc con el gestor de tu distribución, como hicimos en el tema 10.
  4. Compila plataforma.c con la opción -m32, si tu sistema lo permite, y compara los tamaños. Después añade al programa sizeof(int) y sizeof(long long).
  5. Crea un archivo de texto con dos líneas y examínalo con xxd. Conviértelo con unix2dos, o con sed 's/$/\r/', y vuelve a mirarlo. ¿Cuántos bytes ganó, y cuáles son?
  6. Prueba la última observación de la sección 9: abre un archivo con less en una terminal, bórralo desde otra con rm y comprueba que less sigue mostrándolo. Busca el archivo en ls -l /proc/PID/fd.
  7. Crea dos archivos llamados Datos.txt y datos.txt en un mismo directorio. ¿Lo permite tu sistema? ¿Qué pasaría al copiar ese directorio a una memoria USB con formato FAT?
  8. Para cada elemento de esta lista, indica en cuál de los tres niveles de portabilidad de la sección 8 está: fork, qsort, /sys/firmware/efi, sysconf, fprintf, efibootmgr.
  9. Elige un programa que uses a diario y que exista para varios sistemas. Averigua si se distribuye como código fuente, como un ejecutable distinto por sistema, o sobre una máquina virtual o un intérprete.