(Difference between revisions)
Jump to: navigation, search

Revision as of 06:11, 29 January 2006

Unixlib is essentially a Unix interface for RISC OS. It is a set of C libraries which can be used instead of the SharedCLibrary in instances where SharedCLibrary lacks functions, or more Unix-like behaviour is required. It is also the default C library for GCC for RISC OS.

This document doesn't describe how to use Unixlib in the general case - that is extensively discussed elsewhere. Nor does it discuss the general Unix functionality of Unixlib. As Unixlib attempts to be a full Unix interface, its public functions should be described in the man pages on your favourite real Unix machines. Any deviation from those is probably a bug.

What isn't documented elsewhere (or all together in an obvious place) is the extra functionality in Unixlib required for interaction with RISC OS, which is what this document presents. Filename Translation

If you've used any filename handling in Unixlib, you may know that by default, Unixlib translates any filenames to functions like fopen(), stat(), etc, from Unix format to RISC OS format. The most obvious effect of this is for '/' to be swapped with '.' e.g.:

  ../file.c -> ^.c.file

But there are also a large number of other details that are taken care for you too, such are the complexities of RISC OS filenames. The point of all this is for Unix ports which expect to be able to deal directly with Unix filenames. Some programs can be made to use RISCS OS filenames all the way through, but often it's a lot of work.

Sometimes it's preferrable not to have this translation happen. To disable this, or change the behaviour of the translation, include the file <unixlib/local.h>. Set the variable __riscosify_control to values specified in this header for other actions. e.g.:

 __riscosify_control = __RISCOSIFY_NO_PROCESS;

Often, implicit filename translation isn't enough, and the program will need to do explicit translation. You can achieve this with the __riscosify() and __riscosify_std() functions. You can translate in the other direction with __unixify() and __unixify_std(). In older versions of Unixlib, the function was __uname(), but this is now deprecated and should be avoided. The parameters to these functions are also described in the header file.

Memory Usage

Instead of using the stack for its heap, Unixlib programs can use a dynamic area for their heap. The traditional way is to set program$heap to any value. e.g:

  *set gcc$heap ""

There is another way, however. If you create the variable __dynamic_da_name, your program will automatically use dynamic areas, and use a more sensible name. e.g.:

  const char *__dynamic_da_name = "Nettle Heap";


Unixlib aims to be as compatible with SharedCLibrary as possible. This means it implements all the same C library calls (as required by ANSI C), and also the RISC OS functions such as _swix(), _kernel_swi(), etc. but there are a few differences worth noting:

If you use socket functions (built into Unixlib, and with TCPIPLibs or NetLib when using SCL) the socket number you get back has a different meaning. Unixlib gives you an opaque file descriptor, as you'd expect in Unix, but TCPIPLib/Netlib gives you a raw RISC OS socket handle.

This almost never matters, except when you need raw handles such as when using the SocketWatch module. This is the solution employed in Nettle:

 #include <stdio.h>
 #include <unixlib/unix.h>
 void socketwatch_register(int socket)
   socket = (int)__u->fd[socket].handle;

A further difference is that the size of the FILE structure differs between Unixlib and SCL, as Unixlib has to hold more information per file to implement full Unix functionality. Again, this normally doesn't matter. The situation where it does is when you mix object files compiled against the two libraries. The solution is not to mix libraries in general.

One instance where it does matter is the use of getc() or getchar(), as these can be (and are, in SharedCLibrary headers) defined as macros which poke with the internals of a file pointer. If you have a library which uses these functions, and which you want to be compatible with both Unixlib and SharedCLibrary, then place:

 #undef getc
 #undef getchar
 #undef feof
 #undef ferror
 #undef putc
 #undef putchar

after any #includes in your source file. Desklib, for example, uses this. Of course, you only need to undefine the functions that you use.

Image Filing Systems

Under RISC OS image files can be treated as either directories or files. Sometimes this can cause programs to get upset, or misbehave if they aren't expecting it. By default, Unixlib treats image files as diretories. To change this at runtime:

 #include <unixlib/features.h>
 __feature_imagefs_is_file = 1;
Personal tools