Osbs
No hay una distinción clara entre el software del sistema operativo y el software que se ejecuta sobre él. Jim Allchin
Funciones
uint32_t | (*FPtr_thread_main (...)) |
void | osbs_start (void) |
void | osbs_finish (void) |
platform_t | osbs_platform (void) |
win_t | osbs_windows (void) |
endian_t | osbs_endian (void) |
Tipos y Constantes
enum | platform_t |
enum | device_t |
enum | win_t |
enum | endian_t |
enum | week_day_t |
enum | month_t |
enum | file_type_t |
enum | file_mode_t |
enum | ferror_t |
enum | perror_t |
enum | serror_t |
struct | Date |
struct | Dir |
struct | File |
struct | Mutex |
struct | Proc |
struct | ProcOpt |
struct | Thread |
struct | Socket |
struct | SockOpt |
osbs (Operating System Basic Services) es un wrapper portable que permite a las aplicaciones la comunicación con el núcleo del sistema operativo a nivel de procesos, memoria, archivos, redes, relojes, etc. Esta comunicación se lleva a cabo a través de una serie de llamadas al sistema (Figura 1) que varían según el sistema operativo para el que estemos programando. Es el API no gráfico de más bajo nivel para comunicarse con dispositivos de hardware y acceder a los recursos de la máquina. Por debajo se encuentran los controladores de dispositivos (drivers) administrados directamente por el kernel, a los que las aplicaciones tienen vetado el acceso.

Darwin, el kernel de macOS, y Linux son sistemas tipo-Unix, por tanto, comparten el mismo conjunto de llamadas al sistema (con pequeñas diferencias). Pero Windows presenta una arquitectura y juego de funciones radicalmente diferente. La librería osbs de NAppGUI no es más que una pequeña envoltura que internamente maneja estas diferencias y provee una vía común para acceder a los mismos recursos en diferentes plataformas (Figura 2). Solo depende de Sewer y sus funcionalidades se han dividido en diferentes módulos:
- Procesos, Hebras, Exclusión mutua.
- Memoria.
- Archivos y directorios.
- Sockets.
- E/S Estándar.
- Tiempo.
- Matemáticas.
- Log.

1. Librería estándar de C
La librería estándar de C (cstdlib) no forma parte del lenguaje C, pero implementa funciones de gran utilidad para el desarrollador que resuelven problemas típicos de programación. Cualquier programador de C las ha utilizado en mayor o menor medida y su estudio va normalmente ligado con el aprendizaje del propio lenguaje (Figura 3).

Esta librería se sitúa a medio camino entre la aplicación y las llamadas al sistema y proporciona un API portable para acceso a archivos, memoria dinámica, E/S, tiempo, etc (Figura 4). También implementa funciones matemáticas, de conversión, búsqueda, manejo de cadenas, etc. De una forma o de otra, NAppGUI integra su funcionalidad dentro de osbs, por lo que no es necesario (ni recomendable) utilizar cstdlib directamente en la capa de aplicación. Las razones que han motivado esta decisión de diseño las podemos resumir en:

- Pequeñas diferencias: Los sistemas tipo-Unix no soportan las versiones seguras del cstdlib implementadas por Microsoft (
strcpy_s()
y otras). El uso de las funciones clásicas (sin el sufijo_s
) es inseguro y activarán molestos warnings en Visual Studio. - Seguridad: Relacionada con la anterior, osbs evita vulnerabilidades del tipo buffer overflow en el tratamiento de cadenas y bloques de memoria.
- Duplicidad: Mucha de la funcionalidad de cstdlib ya se implementa en osbs utilizando directamente llamadas al sistema (archivos, memoria dinámica, E/S, tiempo, etc).
- Completo: Las funciones de cstdlib relacionadas con archivos (
fopen()
y demás) no incorporan soporte para el manejo de directorios. Archivos y directorios presenta un API completo basado en llamadas al sistema. - Rendimiento: En ciertos casos, sobre todo en funciones matemáticas y gestión de memoria, puede ser interesante cambiar la implementación de cstdlib por otra mejorada. Todas las aplicaciones se beneficiarán del cambio, sin tener que modificar su código.
- Claridad: El comportamiento de algunas funciones del cstdlib no es del todo claro y puede llevar a confusión. Por ejemplo,
strtoul
tiene un funcionamiento muy particular que debemos recordar cada vez que la utilicemos. - Estilo: El uso de funciones osbs no rompe la estética de una aplicación escrita con NAppGUI.
- Independencia: NAppGUI utiliza internamente un subconjunto muy pequeño de funciones cstdlib. Es posible que en un futuro realicemos nuestras propias implementaciones y desvinculemos completamente el soporte de la librería estándar.
1 2 3 4 5 6 7 |
1 2 3 4 5 6 7 |
real32_t a1 = 1.43f; real64_t a2 = .38; real32_t c = (real32_t)cosf((float)a1); real64_t t = (real64_t)tan((double)a2); ... real32_t c = bmath_cosf(a1); real64_t t = bmath_tand(a2); |
enum platform_t
Sistemas operativos soportados por NAppGUI.
enum platform_t
{
ekWINDOWS,
ekMACOS,
ekLINUX,
ekIOS
};
ekWINDOWS | Microsoft Windows. |
ekMACOS | Apple macOS. |
ekLINUX | GNU/Linux. |
ekIOS | Apple iOS. |
enum device_t
Tipo de dispositivo.
enum device_t
{
ekDESKTOP,
ekPHONE,
ekTABLET
};
ekDESKTOP | Ordenador de escritorio o portátil. |
ekPHONE | Teléfono. |
ekTABLET | Tableta. |
enum win_t
Versiones de Microsoft Windows.
enum win_t
{
ekWIN_9x,
ekWIN_NT4,
ekWIN_2K,
ekWIN_XP,
ekWIN_XP1,
ekWIN_XP2,
ekWIN_XP3,
ekWIN_VI,
ekWIN_VI1,
ekWIN_VI2,
ekWIN_7,
ekWIN_71,
ekWIN_8,
ekWIN_81,
ekWIN_10,
ekWIN_NO
};
ekWIN_9x | Windows 95, 98 or ME. |
ekWIN_NT4 | Windows NT4. |
ekWIN_2K | Windows 2000. |
ekWIN_XP | Windows XP. |
ekWIN_XP1 | Windows XP Service Pack 1. |
ekWIN_XP2 | Windows XP Service Pack 2. |
ekWIN_XP3 | Windows XP Service Pack 3. |
ekWIN_VI | Windows Vista. |
ekWIN_VI1 | Windows Vista Service Pack 1. |
ekWIN_VI2 | Windows Vista Service Pack 2. |
ekWIN_7 | Windows 7. |
ekWIN_71 | Windows 7 Service Pack 1. |
ekWIN_8 | Windows 8. |
ekWIN_81 | Windows 8 Service Pack 1. |
ekWIN_10 | Windows 10. |
ekWIN_NO | El sistema no es Windows. |
enum endian_t
Representa el Orden de bytes, o como los datos multi-byte son almacenados en memoria.
enum endian_t
{
ekLITEND,
ekBIGEND
};
ekLITEND | Little endian. El byte más bajo primero. |
ekBIGEND | Big endian. El byte más alto primero. |
enum week_day_t
Día de la semana.
enum week_day_t
{
ekSUNDAY,
ekMONDAY,
ekTUESDAY,
ekWEDNESDAY,
ekTHURSDAY,
ekFRIDAY,
ekSATURDAY
};
ekSUNDAY | Domingo. |
ekMONDAY | Lunes. |
ekTUESDAY | Martes. |
ekWEDNESDAY | Miércoles. |
ekTHURSDAY | Jueves. |
ekFRIDAY | Viernes. |
ekSATURDAY | Sábado. |
enum month_t
Mes.
enum month_t
{
ekJANUARY,
ekFEBRUARY,
ekMARCH,
ekAPRIL,
ekMAY,
ekJUNE,
ekJULY,
ekAUGUST,
ekSEPTEMBER,
ekOCTOBER,
ekNOVEMBER,
ekDECEMBER
};
ekJANUARY | Enero. |
ekFEBRUARY | Febrero. |
ekMARCH | Marzo. |
ekAPRIL | Abril. |
ekMAY | Mayo. |
ekJUNE | Junio. |
ekJULY | Julio. |
ekAUGUST | Agosto. |
ekSEPTEMBER | Septiembre. |
ekOCTOBER | Octubre. |
ekNOVEMBER | Noviembre. |
ekDECEMBER | Diciembre. |
enum file_type_t
Tipo de archivo.
enum file_type_t
{
ekARCHIVE,
ekDIRECTORY,
ekOTHERFILE
};
ekARCHIVE | Archivo ordinario. |
ekDIRECTORY | Directorio. |
ekOTHERFILE | Otro tipo de archivo reservado para el sistema operativo (dispositivos, tuberías, etc). |
enum file_mode_t
Diferentes modos de abrir un archivo.
enum file_mode_t
{
ekREAD,
ekWRITE,
ekAPPEND
};
ekREAD | Solo lectura. |
ekWRITE | Lectura y escritura. |
ekAPPEND | Escritura al final del archivo. |
enum ferror_t
Códigos de error manipulando archivos.
enum ferror_t
{
ekFEXISTS,
ekFNOPATH,
ekFNOFILE,
ekFBIGNAME,
ekFNOFILES,
ekFNOEMPTY,
ekFNOACCESS,
ekFLOCK,
ekFBIG,
ekFUNDEF,
ekFOK
};
ekFEXISTS | El archivo ya existe. |
ekFNOPATH | El directorio no existe. |
ekFNOFILE | El archivo no existe. |
ekFBIGNAME | El nombre del archivo excede la capacidad del buffer para almacenarlo. |
ekFNOFILES | No hay más archivos cuando recorremos un directorio. bfile_dir_get. |
ekFNOEMPTY | Se está tratando de eliminar un directorio no vacío. hfile_dir_destroy. |
ekFNOACCESS | No se puede acceder al archivo (posiblemente por falta de permisos). |
ekFLOCK | El archivo está siendo utilizado por otro proceso. |
ekFBIG | El archivo es muy grande. Puede aparecer en funciones que no puedan manejar archivos de más de 4Gb. |
ekFUNDEF | No hay más información acerca del error. |
ekFOK | No hay error. |
enum perror_t
Códigos de error trabajando con procesos.
enum perror_t
{
ekPPIPE,
ekPEXEC,
ekPOK
};
ekPPIPE | Error en el canal de E/S estándar. |
ekPEXEC | Error al lanzar el proceso. Seguramente el comando es inválido. |
ekPOK | No hay error. |
enum serror_t
Código de error en comunicaciones de red.
enum serror_t
{
ekSNONET,
ekSNOHOST,
ekSTIMEOUT,
ekSSTREAM,
ekSUNDEF,
ekSOK
};
ekSNONET | No hay conexión a Internet en el dispositivo. |
ekSNOHOST | No se puede conectar con el servidor remoto. |
ekSTIMEOUT | Se ha excedido el tiempo máximo de espera por la conexión. |
ekSSTREAM | Error en el canal E/S al leer o escribir. |
ekSUNDEF | No hay más información acerca del error. |
ekSOK | No hay error. |
struct Date
Estructura pública que contiene los campos de una marca temporal (fecha + hora) para su acceso de forma directa.
struct Date { int16_t year; uint8_t month; uint8_t wday; uint8_t mday; uint8_t hour; uint8_t minute; uint8_t second; };
year | El año. |
month | El mes (1-12). month_t. |
wday | El día de la semana (0-6). week_day_t. |
mday | El día del mes (1-31). |
hour | La hora (0-23). |
minute | El minuto (0-59). |
second | El segundo (0-59). |
struct Dir
Representa un directorio abierto, por el que se puede navegar. bfile_dir_open.
struct Dir;
struct File
Manejador de fichero en disco. bfile_open.
struct File;
struct Mutex
Mecanismo de exclusión mutua (mutex) utilizado para controlar el acceso concurrente a un recurso. Cerrojos.
struct Mutex;
struct Proc
Representa un proceso en ejecución, con el que el programa principal puede comunicarse utilizando los canales E/S estándar. bproc_exec.
struct Proc;
struct ProcOpt
Opciones de ejecución de un proceso.
struct ProcOpt { uint32_t unused; };
unused | Para requerimientos futuros. |
struct Thread
Representa un hilo de ejecución, lanzado desde el proceso principal. bthread_create.
struct Thread;
struct Socket
Manejador de un socket o conexión en red. bsocket_connect.
struct Socket;
struct SockOpt
Opciones de creación de un socket.
struct SockOpt { uint32_t rcvtimeo_ms; uint32_t sndtimeo_ms; };
rcvtimeo_ms | Tiempo de espera máximo por una conexión (timeout), en el lado del receptor. |
sndtimeo_ms | timeout, en el lado del emisor. |
FPtr_thread_main
Prototipo de function de inicio de una hebra de ejecución (thread main). bthread_create.
uint32_t (*FPtr_thread_main)(type *data);
data | Datos pasados a la función main de la hebra. |
Retorna
El valor de retorno de la hebra.
osbs_start ()
Inicia la librería osbs, reservando espacio para las estructuras internas globales.
void
osbs_start(void);
osbs_finish ()
Finaliza la librería osbs, liberando el espacio de las estructuras internas globales.
void
osbs_finish(void);
osbs_platform ()
Obtiene el sistema operativo en el que está corriendo la aplicación.
platform_t osbs_platform(void);
Retorna
La plataforma.
osbs_windows ()
Obtiene la versión de Windows.
win_t osbs_windows(void);
Retorna
La versión de Microsoft Windows.
osbs_endian ()
Obtiene el Orden de bytes de la plataforma.
endian_t osbs_endian(void);
Retorna
El orden de bytes en tipos de datos multi-byte.