Symbian Developer Library

SYMBIAN OS V6.1 EDITION FOR C++

[Index] [Glossary] [Previous] [Next]



Design and implementation of STDLIB


Overview

This is a description of some of the main features of the Symbian software platform's implementation of the C Standard Library (normally referred to as STDLIB). It provides information on how it differs from other such libraries and descriptions of some of its main features. It does not attempt to document the library's entire API. For such documentation, see the following:

[Top]


Design goals

The following are some of the reasons behind the implementation of STDLIB:

The following are not among STDLIB's design goals:

[Top]


Similarities between STDLIB and the ANSI standard

[Top]


Differences between STDLIB and ANSI and POSIX

[Top]


Single-threaded programs

Simple C programs may not need to support file descriptors shared between threads, or the execution of sub-processes. Such programs may use the default implementation of STDLIB, in which the library code opens files, sockets etc. in the context of the calling thread, and provides a per-thread table of open file descriptors.

Multiple threads may still be used, but each thread's resources are private and cannot be shared with other threads. For example, a setenv() call in one thread will not be seen by a getenv() call in another and each thread will have a separate console window (created on demand when the console is first read from or written to).

[Top]


Multi-threaded programs; the CPosixServer

More complex programs may need to use process-wide resources. This is often true of programs which assume the existence of support for multiple threads within a POSIX process. To meet this requirement, STDLIB can operate in a mode in which all shareable resources are owned by a single CPosixServer thread. In this mode, library routines such as open(), read() and write() operate by passing an appropriate request to the CPosixServer.

The program's mode of operation is determined when it first tries to use STDLIB's services. If a CPosixServer is running for the Symbian software platform process, the thread will use it; otherwise the program will operate in the single-threaded mode.

The CPosixServer is a Symbian software platform active object, and can be started either in the context of an existing active scheduler, or by spawning a separate thread to run an active scheduler. The functions for doing this have a C++ interface, defined in estlib.h. For more information on active objects in the Symbian software platform, see active objects.

Communication between CPosixServers is used to establish the POSIX process hierarchy and to communicate resources from parent to child. Programs which require multiple processes must use the multi-threaded mode of operation.

[Top]


Error codes

Most error codes reported by STDLIB functions correspond to the standard C error code values. Some of these are identified within STDLIB, which produces the correct errno value directly; most are reported by translating the Symbian software platform error codes into equivalent errno values using a translation table. Occasionally, a Symbian software platform error code may be reported untranslated. In this case, it will have a negative value. For a list of the Symbian software platform's error codes, see System wide error codes. STDLIB does not usually attempt to detect inputs which will cause an EPOC panic, (for example attempting to accept() on a stream socket which has not been bound). Such a panic will terminate the offending thread, which may in turn result in the termination of the whole process. For more information on panics in the Symbian Software platfrom, see Panics.

[Top]


ECRT0.LIB and the cleanup stack

A normal Symbian executable provides an E32Main() function which is called by the operating system to start the program. The file ecrt0.lib provides an E32Main() function for projects which use STDLIB. This function prepares the traditional argc and argv arguments and passes them to main().

For a simple example demonstrating how to link to ecrt0.lib, see the description of the project specification for "Hello World" in Porting. The user of STDLIB does not need to use ecrt0.lib, and may provide their own E32Main(). In this case, a CTrapCleanup pointer should normally be provided. This pointer is required because although STDLIB does not call Symbian functions which can leave, it does use some functions which require a cleanup stack. Code in ecrt0.lib provides such a cleanup stack ("TheTrapCleanup"), but programs which do not link with ecrt0.lib will need to supply one directly. For more details on the motivation behind Symbian's use of the cleanup stack, see Cleanup support.

[Top]


Handles versus file descriptors

STDLIB provides a POSIX-like abstraction of file descriptors which unifies the different types of resource and permits a single API to be used across all of them. This is a significantly different approach from Win32 and the Symbian software platform, both of which have separate APIs for each distinct type of resource.

STDLIB supports files stored in the file system, sockets, a console, and a /dev/null device. The first time STDLIB initialises its internal file descriptor table it creates an emulated console device and attaches it to descriptors 0, 1 and 2. The emulated console device will appear as a window when it is first used (i.e. when the program writes to or reads from the console).

The open() function recognises the following names:

The number of open files in the file has no explicit limit.

EPOC resources such as RFiles and RSockets are derived from class RSubSessionBase, so are thread specific. This means they cannot be used by any thread other than the one which opened them. In STDLIB however, the CPosixServer, if running, controls the master file descriptor table. In this case, all STDLIB threads in a process may share their resources, because the STDLIB implementation forwards all i/o requests to the resources owned by that process's CPosixServer thread. If no CPosixServer is running, each thread has a separate file descriptor table and the resources are not shareable.

[Top]


Console versus terminals

The STDLIB console (encapsulated by class CTtyDesc, defined in fdesc.h) is a client of the CConsoleBase class implemented by econs.dll. It provides very simple text input and output with no support for embedded control sequences. When STDLIB receives a character from the console it prints it out to the same console, providing a "local echo" facility to make simple command-line interfaces possible.

STDLIB does not provide any sort of terminal driver or line-discipline. In particular there is no support for local processing of backspace, nor any line buffering. Neither does it provide termio or termcap facilities. The Symbian software platform is a graphics-based system and it is recommended that C code be ported into a Symbian program which uses a graphical user interface.

[Top]


Asynchronous i/o vs blocking i/o

All STDLIB i/o operations are blocking; that is they will suspend the calling thread indefinitely until the i/o completes. So in general, STDLIB i/o should not be used in an EPOC active object because it will cause the entire active scheduler to block. A possible way to avoid this problem might be to use fcntl() for individual file descriptors, but STDLIB does not currently implement this function.

Asynchronous i/o may be achieved using a set of C++ functions provided by STDLIB which implement a per-file-descriptor equivalent of the POSIX select() function. These functions provide a form of the ioctl() function which takes a TRequestStatus& as a parameter, together with functions for completing the ioctl() operation once the status has been signaled or canceling the pending ioctl. This scheme can be used within an active object to wait for a socket to become ready for reading or writing, so that the subsequent i/o does not block the whole active scheduler. See estlib.h for the interface to these functions. For more information on active objects and the active scheduler in EPOC, see active objects.

Note that there are no such blocking problems with i/o to local files, which is essentially a synchronous operation.

[Top]


Threads

The POSIX interface is designed for a single thread of execution within a process. Many aspects of this interface do not apply to a typical Symbian program in which multiple threads of execution share the same address space. For information about threads and processes, see Threads and processes.

STDLIB allows for multiple threads, but each thread owns its own instance of the _reent structure which contains private data such as the thread's errno variable. Each thread's STDIO FILE structures are completely separate from other threads', even if those structures eventually share the same underlying file descriptor. A consequence of this is that different threads will buffer their output to stdout separately, even though the eventual output will be combined together when the STDIO layer flushes the buffers out to the corresponding file descriptor.

It is unclear how some POSIX functions should be used in a multiple thread environment. An example is the exit() function. Although each thread should have separate atexit() processing, which should include closing all open STDIO files, it is unclear whether closing the STDIO file should also close the underlying descriptor. STDLIB's current implementation is to close the files, as would be expected to happen in a normal POSIX process. However, this implementation may be changed. Note that exit() does not attempt to free memory which was obtained by malloc().

The user of STDLIB can take control over thread termination by implementing exit(), _exit(), abort() and _assert() in their own program, so that all of the user's own code which calls these functions will invoke the user's routines instead of the STDLIB versions. A helper function, _atexit_processing_r(), can be called from the user's version of exit() to do the normal atexit processing, if desired. See stdlib_r.h for details.

[Top]


Files and directories

The Symbian software platform file system APIs require all filenames to be fully specified, possibly by using default components in the session path. For more information, see the documentation on the file server (File server). In particular, the file system does not support the notion of a "relative path" which uses "." and ".." to navigate relative to a "current working directory". STDLIB does support this and does not require fully qualified paths, with the constraint that any pathname beginning with "<letter> :" will be treated as an absolute path from the root of the specified drive. STDLIB allows the drive letter '?' to mean "any drive". This can be useful when a file or directory is known to exist but it could be on any drive. STDLIB allows both "/" and "\" as directory separators, unlike the underlying Symbian file system which recognises only "\".

The current working directory is a process-wide resource (similar to the file descriptor table), so the CPosixServer will provide a single process-wide current working directory. However, when using the "single-threaded" mode of operation, each thread will have a separate current working directory.

The following table gives some examples, all based on a working directory of c:\documents\stdlib

Pathname

in the Symbian software platform

In STDLIB

c:\documents\stdlib\

current directory

current directory

c:\documents\stdlib

illegal (not a file)

current directory

.

illegal

current directory

..

illegal

c:\documents

examples

filename

c:\documents\stdlib\examples

..\examples

illegal

c:\documents\examples

d:examples

illegal

d:\examples

?:\system\data\

illegal

c:\system\data (if file exists on c) or d:\system\data (if it exists on d but not on c) or z:\system\data (if it exists in the ROM).

In summary, the POSIX and STDLIB handling of pathnames is DOS-like, with the exception that there is not a separate working directory per drive.

The Symbian file system supports DOS-like attributes, rather than POSIX-like permissions. STDLIB cannot therefore provide the full POSIX-like handling of file attributes and implements only "user read permission".

[Top]


Unicode support

The Unicode changes for Standard Library come in two groups:


Impact on existing interfaces:

The Symbian platform is a Unicode-based operating system, so all operating system services which use text require that text to be presented in the 16-bit Unicode character encoding known as UCS-2. For the Standard Library on the Symbian platform, this is most significant in dealing with the names of files and directories, all of which are now Unicode sequences.

To minimise the impact of this change on existing narrow C code, the Standard Library has adopted the policy that all such names in char* interfaces will be interpreted using the UTF-8 standard for encoding Unicode strings as 8-byte sequences. UTF-8 is a no surprises encoding and matches the 7-bit ASCII encoding for character codes 0 to 127, so existing string handling code will work without modification.


New interfaces

The wchar_t type is defined and ISO-C standard wide character constants are supported. The wchar_t definition chosen is unsigned short to match the use of UCS-2, and a range of relevant functions now have wide character analogues which use wchar_t* in place of char*, for example:

FILE *    fopen     (const char *_name, const char *_type);

FILE *    wfopen (const wchar_t *_name, const wchar_t *_type);

and

DIR *    opendir (const char *);

WDIR *    wopendir (const wchar_t *);

Where such a pair of functions exists, the char* interface is implemented by converting the UTF-8 parameters to Unicode and calling the matching wchar_t* interface.

The mbtowc family of conversion functions is provided to convert between UTF8 and Unicode, but there is no additional support for locales or other forms of multibyte encoding; to convert from encodings such as Shift-JIS, programmers are recommended to use the CHARCONV conversion routines via C++ wrapper functions callable from C.

There are no implementations of wchar_t* versions of STDIO functions such as fputc.

[Top]


Exclusions

Symbian has no plans to provide the following in the Symbian software platform C Standard Library: