POSIX

POSIX (Portable Operative System Interface) es un conjunto de estándares para APIs y lineas de comando de sistemas operativos de forma que los programas hechos para un sistema operativo que cumpla el estándar puedan portarse a otro sistema operativo. La portabilidad que garantizan estos estándares es a nivel de código fuente no ejecutables binarios, es decir, puede hacer falta recompilar el código.

POSIX está fuertemente inspirado en UNIX y sus versiones.

Esta página lista algunas de las exigencias y recomendaciones de POSIX para programar.

## Argumentos de un programa

La cabecera del programa principal debe tener el siguiente formato:

```
int main(int argc, char *argv[])

```

donde \*argv[] es equivalente a \*\*argv.

argc es el numero de argumentos proporcionados contando con el nombre del propio programa, que será el primer argumento, por esto argc > 0 siempre. argv es un vector de strings con los argumentos que tiene argc+1 elementos, el último de los cuales está a NULL. Estos argumentos son el resultado de separar la linea de comando con el que se ha ejecutado el programa por los espacios en blanco.

POSIX recomienda una serie de convenciones para los argumentos y proporciona la función getopt(3) para gestionarlos cómodamente:

* Los argumentos que empiezan por guión '-' (y no son exactamente el guión simple '-' o doble '--') son elementos de opciones y cada uno de los caracteres que siguen al guión inicial son opciones.
* Las opciones que requieren un argumento tienen que ser la última del elemento de opciones y van seguidas de su argumento, con o sin espacio intermedio.
* Las opciones se pueden repetir y proporcionar en cualquier orden.
* A partir de la aparición del argumento doble guión '--' ningún otro argumento se trata como elemento de opciones.
* El argumento guión '-' se suele usar para indicar la entrada o salida estándar.
* Las opciones deben ir antes de los argumentos que no son opciones. La versión de getopt(3) de GNU no exige esto, pero reordena los argumentos para que lo cumpla.

## API

Para usar cierta función de la API de POSIX hay que tener en cuenta una serie de cosas que se pueden consultar en la página man de la función:

* Hay que incluir (**#include**) uno o varios fichero de cabecera para poder usar la función. Estos ficheros vienen listados al principio de la sección SYNOPSIS de la página man.
* Que datos **retorna** la función. El valor que devuelve puede ser la información pedida, un puntero a la información pedida, cierta información relativa a la acción pedida (nº de bytes copiados) o el código de error. Esto viene especificado en la sección RETURN VALUE.
* Que **argumentos** necesita la función. Esto se especifica en la sección SYNOPSIS. Tanto el tipo, como si se pasan por valor o referencia. La sección DESCRIPTION explica que información espera la función que tengan los argumentos. Algunos de estos argumentos pueden ser de salida, es decir, punteros a una posición de memoria donde la función tiene que guardar cierta información.
* El **comportamiento** de la función se explica en DESCRIPTION. Cualquier desviación de POSIX que tenga la implementación estará explicada, habitualmente también se explica como forzarla función a seguir POSIX.

El comando **strace** ejecuta un comando dado y muestra por pantalla todas las llamadas al sistema que va realizando. No es necesario tener el código fuente del comando para usar strace.

## Errores

Cuando una llamada a una función de la API tiene un error guarda el código de ese error en la variable **errno** y, por convenio, retorna el valor -1.

Para obtener una descripción del código de error POSIX proporciona una función que devuelve un string con la descripción (strerror(3)) y una función que muestra un mensaje por pantalla (perror(3)).

## Información del sistema

Para acceder a la información del sistema POSIX proporciona varias funciones y comandos:

* **uname**(2) proporciona información como el nombre del sistema operativo, su versión, un identificador de la maquina... El comando uname(1) también proporciona esta información.
* **sysconf**(3) proporciona información acerca de los "limites" del sistema: máximo nº de procesos por identificador de usuario, máximo nº de archivos que un proceso puede tener abiertos, el tamaño de página, la frecuencia de reloj...
* **pathconf**(3) proporciona información sobre los limites en el numero de enlaces que puede tener un archivo, el tamaño que puede tener un nombre de archivo, la longitud que puede tener un path relativo...

## Información del usuario

POSIX proporciona funciones para acceder a la información de los usuarios:

* **getuid**(2), **getgid**(2), **geteuid**(2) y **getegid**(2) devuelven el identificador del usuario o grupo efectivo o no del proceso.
* **getpwnam**(3) permite consultar el nombre, contraseña, identificadores de usuario y grupo, directorio... de un usuario dado.

## Información de la hora y fecha

Para consultar la fecha y hora y formatearlas POSIX proporciona muchas funciones:

* **time**(2)
* **gettimeofday**(2) y **settimeofday**(2)
* **gmtime**(3) y **localtime**(3) para averiguar la hora GMT o la local.
* **strftime**(3) para formatear la fecha y hora.

## Referencias

1. ↑ Tutorial POSIX

http://leo.ugr.es/elvira/devel/Tutorial/Java/essential/attributes/\_posix.html
2. ↑ Open Group

http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1\_chap12.html
3. ↑ man geopt(3)
http://man7.org/linux/man-pages/man3/getopt.3.html
4. ↑ GNU

https://www.gnu.org/software/libc/manual/html\_node/Argument-Syntax.html
5. ↑ man strace

http://man7.org/linux/man-pages/man1/strace.1.html
6. ↑ man strerror

http://man7.org/linux/man-pages/man3/strerror.3.html
7. ↑ man perror

http://man7.org/linux/man-pages/man3/perror.3.html
8. ↑ man **uname(2)**http://man7.org/linux/man-pages/man2/uname.2.html
9. ↑ man uname(1)

http://man7.org/linux/man-pages/man1/uname.1.html
10. ↑ man sysconf

http://man7.org/linux/man-pages/man3/sysconf.3.html
11. ↑ man pathconf

http://man7.org/linux/man-pages/man3/pathconf.3.html
12. ↑ man getuid

http://man7.org/linux/man-pages/man2/getuid.2.html
13. ↑ man getpwnam

http://man7.org/linux/man-pages/man3/getpwnam.3.html