From 8a0efa53e44919bcf5ccb1d3353618a82afdf8bc Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Thu, 17 Feb 2000 19:39:52 +0000 Subject: import newlib-2000-02-17 snapshot --- newlib/libc/sys.tex | 436 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 436 insertions(+) create mode 100644 newlib/libc/sys.tex (limited to 'newlib/libc/sys.tex') diff --git a/newlib/libc/sys.tex b/newlib/libc/sys.tex new file mode 100644 index 000000000..44b608b9c --- /dev/null +++ b/newlib/libc/sys.tex @@ -0,0 +1,436 @@ +@c -*- Texinfo -*- +@node Syscalls +@chapter System Calls + +@cindex linking the C library +The C subroutine library depends on a handful of subroutine calls for +operating system services. If you use the C library on a system that +complies with the POSIX.1 standard (also known as IEEE 1003.1), most of +these subroutines are supplied with your operating system. + +If some of these subroutines are not provided with your system---in +the extreme case, if you are developing software for a ``bare board'' +system, without an OS---you will at least need to provide do-nothing +stubs (or subroutines with minimal functionality) to allow your +programs to link with the subroutines in @code{libc.a}. + +@menu +* Stubs:: Definitions for OS interface +* Reentrant Syscalls:: Reentrant covers for OS subroutines +@end menu + +@node Stubs +@section Definitions for OS interface +@cindex stubs + +@cindex subroutines for OS interface +@cindex OS interface subroutines +This is the complete set of system definitions (primarily subroutines) +required; the examples shown implement the minimal functionality +required to allow @code{libc} to link, and fail gracefully where OS +services are not available. + +Graceful failure is permitted by returning an error code. A minor +complication arises here: the C library must be compatible with +development environments that supply fully functional versions of these +subroutines. Such environments usually return error codes in a global +@code{errno}. However, the Cygnus C library provides a @emph{macro} +definition for @code{errno} in the header file @file{errno.h}, as part +of its support for reentrant routines (@pxref{Reentrancy,,Reentrancy}). + +@cindex @code{errno} global vs macro +The bridge between these two interpretations of @code{errno} is +straightforward: the C library routines with OS interface calls +capture the @code{errno} values returned globally, and record them in +the appropriate field of the reentrancy structure (so that you can query +them using the @code{errno} macro from @file{errno.h}). + +This mechanism becomes visible when you write stub routines for OS +interfaces. You must include @file{errno.h}, then disable the macro, +like this: + +@example +#include +#undef errno +extern int errno; +@end example + +@noindent +The examples in this chapter include this treatment of @code{errno}. + +@ftable @code +@item _exit +Exit a program without cleaning up files. If your system doesn't +provide this, it is best to avoid linking with subroutines that require +it (@code{exit}, @code{system}). + +@item close +Close a file. Minimal implementation: + +@example +int close(int file)@{ + return -1; +@} +@end example + +@item environ +A pointer to a list of environment variables and their values. For a +minimal environment, this empty list is adequate: + +@example +char *__env[1] = @{ 0 @}; +char **environ = __env; +@end example + +@item execve +Transfer control to a new process. Minimal implementation (for a system +without processes): + +@example +#include +#undef errno +extern int errno; +int execve(char *name, char **argv, char **env)@{ + errno=ENOMEM; + return -1; +@} +@end example + +@item fork +Create a new process. Minimal implementation (for a system without processes): + +@example +#include +#undef errno +extern int errno; +int fork() @{ + errno=EAGAIN; + return -1; +@} +@end example + +@item fstat +Status of an open file. For consistency with other minimal +implementations in these examples, all files are regarded as character +special devices. The @file{sys/stat.h} header file required is +distributed in the @file{include} subdirectory for this C library. + +@example +#include +int fstat(int file, struct stat *st) @{ + st->st_mode = S_IFCHR; + return 0; +@} +@end example + +@item getpid +Process-ID; this is sometimes used to generate strings unlikely to +conflict with other processes. Minimal implementation, for a system +without processes: + +@example +int getpid() @{ + return 1; +@} +@end example + +@item isatty +Query whether output stream is a terminal. For consistency with the +other minimal implementations, which only support output to +@code{stdout}, this minimal implementation is suggested: + +@example +int isatty(int file)@{ + return 1; +@} +@end example + +@item kill +Send a signal. Minimal implementation: + +@example +#include +#undef errno +extern int errno; +int kill(int pid, int sig)@{ + errno=EINVAL; + return(-1); +@} +@end example + +@item link +Establish a new name for an existing file. Minimal implementation: + +@example +#include +#undef errno +extern int errno; +int link(char *old, char *new)@{ + errno=EMLINK; + return -1; +@} +@end example + +@item lseek +Set position in a file. Minimal implementation: + +@example +int lseek(int file, int ptr, int dir)@{ + return 0; +@} +@end example + +@c FIXME! Why no stub for open? + +@item read +Read from a file. Minimal implementation: + +@example +int read(int file, char *ptr, int len)@{ + return 0; +@} +@end example + +@item sbrk +Increase program data space. As @code{malloc} and related functions +depend on this, it is useful to have a working implementation. The +following suffices for a standalone system; it exploits the symbol +@code{end} automatically defined by the GNU linker. + +@example +@group +caddr_t sbrk(int incr)@{ + extern char end; /* @r{Defined by the linker} */ + static char *heap_end; + char *prev_heap_end; + + if (heap_end == 0) @{ + heap_end = &end; + @} + prev_heap_end = heap_end; + if (heap_end + incr > stack_ptr) + @{ + _write (1, "Heap and stack collision\n", 25); + abort (); + @} + + heap_end += incr; + return (caddr_t) prev_heap_end; +@} +@end group +@end example + +@item stat +Status of a file (by name). Minimal implementation: + +@example +int stat(char *file, struct stat *st) @{ + st->st_mode = S_IFCHR; + return 0; +@} +@end example + +@item times +Timing information for current process. Minimal implementation: + +@example +int times(struct tms *buf)@{ + return -1; +@} +@end example + +@item unlink +Remove a file's directory entry. Minimal implementation: + +@example +#include +#undef errno +extern int errno; +int unlink(char *name)@{ + errno=ENOENT; + return -1; +@} +@end example + +@item wait +Wait for a child process. Minimal implementation: +@example +#include +#undef errno +extern int errno; +int wait(int *status) @{ + errno=ECHILD; + return -1; +@} +@end example + +@item write +Write a character to a file. @file{libc} subroutines will use this +system routine for output to all files, @emph{including} +@code{stdout}---so if you need to generate any output, for example to a +serial port for debugging, you should make your minimal @code{write} +capable of doing this. The following minimal implementation is an +incomplete example; it relies on a @code{writechar} subroutine (not +shown; typically, you must write this in assembler from examples +provided by your hardware manufacturer) to actually perform the output. + +@example +@group +int write(int file, char *ptr, int len)@{ + int todo; + + for (todo = 0; todo < len; todo++) @{ + writechar(*ptr++); + @} + return len; +@} +@end group +@end example + +@end ftable + +@page +@node Reentrant Syscalls +@section Reentrant covers for OS subroutines + +Since the system subroutines are used by other library routines that +require reentrancy, @file{libc.a} provides cover routines (for example, +the reentrant version of @code{fork} is @code{_fork_r}). These cover +routines are consistent with the other reentrant subroutines in this +library, and achieve reentrancy by using a reserved global data block +(@pxref{Reentrancy,,Reentrancy}). + +@c FIXME!!! The following ignored text specifies how this section ought +@c to work; however, both standalone info and Emacs info mode fail when +@c confronted with nodes beginning `_' as of 24may93. Restore when Info +@c readers fixed! +@ignore +@menu +* _open_r:: Reentrant version of open +* _close_r:: Reentrant version of close +* _lseek_r:: Reentrant version of lseek +* _read_r:: Reentrant version of read +* _write_r:: Reentrant version of write +* _link_r:: Reentrant version of link +* _unlink_r:: Reentrant version of unlink +* _stat_r:: Reentrant version of stat +* _fstat_r:: Reentrant version of fstat +* _sbrk_r:: Reentrant version of sbrk +* _fork_r:: Reentrant version of fork +* _wait_r:: Reentrant version of wait +@end menu + +@down +@include reent/filer.def +@include reent/execr.def +@include reent/statr.def +@include reent/fstatr.def +@include reent/linkr.def +@include reent/sbrkr.def +@up +@end ignore + +@ftable @code +@item _open_r +A reentrant version of @code{open}. It takes a pointer +to the global data block, which holds @code{errno}. + +@example +int _open_r(void *@var{reent}, + const char *@var{file}, int @var{flags}, int @var{mode}); +@end example + +@item _close_r +A reentrant version of @code{close}. It takes a pointer to the global +data block, which holds @code{errno}. + +@example +int _close_r(void *@var{reent}, int @var{fd}); +@end example + +@item _lseek_r +A reentrant version of @code{lseek}. It takes a pointer to the global +data block, which holds @code{errno}. + +@example +off_t _lseek_r(void *@var{reent}, + int @var{fd}, off_t @var{pos}, int @var{whence}); +@end example + +@item _read_r +A reentrant version of @code{read}. It takes a pointer to the global +data block, which holds @code{errno}. + +@example +long _read_r(void *@var{reent}, + int @var{fd}, void *@var{buf}, size_t @var{cnt}); +@end example + +@item _write_r +A reentrant version of @code{write}. It takes a pointer to the global +data block, which holds @code{errno}. + +@example +long _write_r(void *@var{reent}, + int @var{fd}, const void *@var{buf}, size_t @var{cnt}); +@end example + +@item _fork_r +A reentrant version of @code{fork}. It takes a pointer to the global +data block, which holds @code{errno}. + +@example +int _fork_r(void *@var{reent}); +@end example + +@item _wait_r +A reentrant version of @code{wait}. It takes a pointer to the global +data block, which holds @code{errno}. + +@example +int _wait_r(void *@var{reent}, int *@var{status}); +@end example + +@item _stat_r +A reentrant version of @code{stat}. It takes a pointer to the global +data block, which holds @code{errno}. + +@example +int _stat_r(void *@var{reent}, + const char *@var{file}, struct stat *@var{pstat}); +@end example + +@item _fstat_r +A reentrant version of @code{fstat}. It takes a pointer to the global +data block, which holds @code{errno}. + +@example +int _fstat_r(void *@var{reent}, + int @var{fd}, struct stat *@var{pstat}); +@end example + +@item _link_r +A reentrant version of @code{link}. It takes a pointer to the global +data block, which holds @code{errno}. + +@example +int _link_r(void *@var{reent}, + const char *@var{old}, const char *@var{new}); +@end example + +@item _unlink_r +A reentrant version of @code{unlink}. It takes a pointer to the global +data block, which holds @code{errno}. + +@example +int _unlink_r(void *@var{reent}, const char *@var{file}); +@end example + +@item _sbrk_r +A reentrant version of @code{sbrk}. It takes a pointer to the global +data block, which holds @code{errno}. + +@example +char *_sbrk_r(void *@var{reent}, size_t @var{incr}); +@end example +@end ftable -- cgit v1.2.3