lib Legato

The Legato Application Framework provide a set of APIs to simplify common C programming tasks. lib Legato adds object oriented functions to simplify and enhance the safety and reliability of your systems.

These APIs are available automatically to your applications by including legato.h into your code.

It is also good practice to include interfaces.h. interfaces.h is a C header file that automatically includes all client and server interface definition that your client imports and exports. If you need to import or export any other API you will need to explicitly include interfaces.h into your C or C++ code.

 #include "legato.h"
 #include "interfaces.h"
API Guide API Reference File Name Description
Command Line Arguments API le_args.h le_args.h Provides the ability to add arguments from the command line
Atomic File Operation API le_atomFile.h le_atomFile.h Provides atomic file access mechanism that can be used to perform file operation (specially file write) in atomic fashion
Basic Type and Constant Definitions le_basics.h le_basics.h Provides error codes, portable integer types, and helpful macros that make things easier to use
System Clock API le_clock.h le_clock.h Gets/sets date and/or time values, and performs conversions between these values.
CRC32 API le_crc.h le_crc.h Provides the ability to compute the CRC of a binary buffer
Directory API le_dir.h le_dir.h Provides functions to control directories
Doubly Linked List API le_doublyLinkedList.h le_doublyLinkedList.h Provides a data structure that consists of data elements with links to the next node and previous nodes
Event Loop API le_eventLoop.h le_eventLoop.h Provides event loop functions to support the event-driven programming model
File Descriptor Monitor API le_fdMonitor.h le_fdMonitor.h Provides monitoring of file descriptors, reporting, and related events
File Locking API le_fileLock.h le_fileLock.h Provides file locking, a form of IPC used to synchronize multiple processes' access to common files
File System service le_fs.h le_fs.h Provides a way to access the file system across different platforms
HashMap API le_hashmap.h le_hashmap.h Provides creating, iterating and tracing functions for a hashmap
Hex string API le_hex.h le_hex.h Provides conversion between Hex and Binary strings
JSON Parsing API le_json.h le_json.h Provides fast parsing of a JSON data stream with very little memory required
Logging API le_log.h le_log.h Provides a toolkit allowing code to be instrumented with error, warning, informational, and debugging messages
Dynamic Memory Allocation API le_mem.h le_mem.h Provides functions to create, allocate and release data from a memory pool
Low-level Messaging API le_messaging.h le_messaging.h Provides support to low level messaging within Legato
Mutex API le_mutex.h le_mutex.h Provides standard mutex functionality with added diagnostics capabilities
Low-level Pack/Unpack API le_pack.h le_pack.h Provides low-level pack/unpack functions to support the higher level IPC messaging system
Path API le_path.h le_path.h Provides support for UTF-8 null-terminated strings and multi-character separators
Path Iterator API le_pathIter.h le_pathIter.h Iterate over paths, traverse the path node-by-node, or create and combine paths together
Random Number API le_rand.h le_rand.h Used for cryptographic purposes such as encryption keys, initialization vectors, etc.
Safe References API le_safeRef.h le_safeRef.h Protect from damaged or stale references being used by clients
Semaphore API le_semaphore.h le_semaphore.h Provides standard semaphore functionality, but with added diagnostic capabilities
Signals API le_signals.h le_signals.h Provides software interrupts for running processes or threads
Singly Linked List API le_singlyLinkedList.h le_singlyLinkedList.h Provides a data structure consisting of a group of nodes linked together linearly
Unit Testing API le_test.h le_test.h Provides macros that are used to simplify unit testing
Thread Control API le_thread.h le_thread.h Provides controls for creating, ending and joining threads
Timer API le_timer.h le_timer.h Provides functions for managing and using timers
tty API le_tty.h le_tty.h Provides routines to configure serial ports
UTF-8 String Handling API le_utf8.h le_utf8.h Provides safe and easy to use string handling functions for null-terminated strings with UTF-8 encoding

Overview

Here is some background info on Legato's C Language APIs.

Object-Oriented Design

The Legato framework is constructed in an object-oriented manner.

The C programming language was created before object-oriented programming was popular so it doesn't have native support for OOP features like inheritance, private object members, member functions, and overloading. But object-oriented designs can still be implemented in C.

In the Legato C APIs, classes are hidden behind opaque "reference" data types. You can get references to objects created behind the scenes in Legato, but you can never see the structure of those objects. The implementation is hidden from view. Access to object properties is made available through accessor functions.

Opaque Types

The basic "opaque data type" offered by the C programming language is the "void pointer" (void *). The idea is that a pointer to an object of type T can be cast to point to a void type before being passed outside of the module that implements T.

This makes it impossible for anyone outside of the module that implements T to dereference the pointer or access anything about the implementation of T. This way, the module that implements T is free to change the implementation of T in any way needed without worrying about breaking code outside of that module.

The problem with the void pointer type is that it throws away type information. At compile time, this makes it impossible to detect that a variable with opaque type T has been passed into a function with some other pointer type P.

To overcome this, Legato uses "incomplete types" to implement its opaque types. For example, there are declarations similar to the following in Legato C API header files:

// Declare a reference type for referring to Foo objects.
typedef struct le_foo* le_foo_Ref_t;

But "struct le_foo" would not be defined in the API header or anywhere outside of the hypothetical "Foo" API's implementation files. This makes "struct le_foo" an "incomplete type" for all code outside of the Foo API implementation files. Incomplete types can't be used because the compiler doesn't have enough information about them to generate any code that uses them. But pointers to incomplete types can be passed around because the compiler always knows the pointer size. The compiler knows that one incomplete type is not necessarily interchangeable with another, and it won't allow a pointer to an incomplete type to be used where a pointer to another non-void type is expected.

Handlers and Event-Driven Programs

"Handler" is an alias for "callback function". Many APIs in the Legato world use callback functions to notify their clients of asynchronous events. For example, to register a function called "SigTermHandler" for notification of receipt of a TERM signal,

le_sig_SetEventHandler(SIGTERM, SigTermHandler);

Instead of using "CallbackFunction", "CallbackFunc", or some abbreviation like "CbFn" (Cub fun? Cubs fan? What?) that is difficult to read and/or remember, "Handler" is used.

The term "handler" also fits with the event-driven programming style that is favoured in the Legato world. These callback functions are essentially event handler functions. That is, the function is called when an event occurs to "handle" that event.