diff --git a/newlib/ChangeLog b/newlib/ChangeLog index e0034a951..96f3fce66 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,9 @@ +2008-03-27 Patrick Mansfield + + * libc/include/reent.h: Define _func_r functions in this file to + func if REENTRANT_SYSCALLS_PROVIDED and MISSING_SYSCALL_NAMES are + defined. + 2008-03-27 Corinna Vinschen * libc/include/sys/unistd.h: Declare lockf(2) and define lockf diff --git a/newlib/libc/include/reent.h b/newlib/libc/include/reent.h index 4f3d6a9bf..dfd0c9a36 100644 --- a/newlib/libc/include/reent.h +++ b/newlib/libc/include/reent.h @@ -10,7 +10,7 @@ be declared here. It documents them all in one place. All library access to the system is via some form of these functions. - There are three ways a target may provide the needed syscalls. + The target may provide the needed syscalls by any of the following: 1) Define the reentrant versions of the syscalls directly. (eg: _open_r, _close_r, etc.). Please keep the namespace clean. @@ -29,11 +29,56 @@ When you do this, add -DMISSING_SYSCALL_NAMES to newlib_cflags in configure.host. + 4) Define or otherwise provide the regular versions of the syscalls, + and do not supply functional interfaces for any of the reentrant + calls. With this method, the reentrant syscalls are redefined to + directly call the regular system call without the reentrancy argument. + When you do this, specify both -DREENTRANT_SYSCALLS_PROVIDED and + -DMISSING_SYSCALL_NAMES via newlib_cflags in configure.host and do + not specify "syscall_dir". + Stubs of the reentrant versions of the syscalls exist in the libc/reent - source directory and are used if REENTRANT_SYSCALLS_PROVIDED isn't defined. - They use the native system calls: _open, _close, etc. if they're available - (MISSING_SYSCALL_NAMES is *not* defined), otherwise open, close, etc. - (MISSING_SYSCALL_NAMES *is* defined). */ + source directory and are provided if REENTRANT_SYSCALLS_PROVIDED isn't + defined. These stubs call the native system calls: _open, _close, etc. + if MISSING_SYSCALL_NAMES is *not* defined, otherwise they call the + non-underscored versions: open, close, etc. when MISSING_SYSCALL_NAMES + *is* defined. + + By default, newlib functions call the reentrant syscalls internally, + passing a reentrancy structure as an argument. This reentrancy structure + contains data that is thread-specific. For example, the errno value is + kept in the reentrancy structure. If multiple threads exist, each will + keep a separate errno value which is intuitive since the application flow + cannot check for failure reliably otherwise. + + The reentrant syscalls are either provided by the platform, by the + libc/reent stubs, or in the case of both MISSING_SYSCALL_NAMES and + REENTRANT_SYSCALLS_PROVIDED being defined, the calls are redefined to + simply call the regular syscalls with no reentrancy struct argument. + + A single-threaded application does not need to worry about the reentrancy + structure. It is used internally. + + A multi-threaded application needs either to manually manage reentrancy + structures or use dynamic reentrancy. + + Manually managing reentrancy structures entails calling special reentrant + versions of newlib functions that have an additional reentrancy argument. + For example, _printf_r. By convention, the first argument is the + reentrancy structure. By default, the normal version of the function + uses the default reentrancy structure: _REENT. The reentrancy structure + is passed internally, eventually to the reentrant syscalls themselves. + How the structures are stored and accessed in this model is up to the + application. + + Dynamic reentrancy is specified by the __DYNAMIC_REENT__ flag. This + flag denotes setting up a macro to replace _REENT with a function call + to __getreent(). This function needs to be implemented by the platform + and it is meant to return the reentrancy structure for the current + thread. When the regular C functions (e.g. printf) go to call internal + routines with the default _REENT structure, they end up calling with + the reentrancy structure for the thread. Thus, application code does not + need to call the _r routines nor worry about reentrancy structures. */ /* WARNING: All identifiers here must begin with an underscore. This file is included by stdio.h and others and we therefore must only use identifiers @@ -59,6 +104,35 @@ struct tms; struct timeval; struct timezone; +#if defined(REENTRANT_SYSCALLS_PROVIDED) && defined(MISSING_SYSCALL_NAMES) + +#define _close_r(__reent, __fd) close(__fd) +#define _execve_r(__reent, __f, __arg, __env) execve(__f, __arg, __env) +#define _fcntl_r(__reent, __fd, __cmd, __arg) fcntl(__fd, __cmd, __arg) +#define _fork_r(__reent) fork() +#define _fstat_r(__reent, __fdes, __stat) fstat(__fdes, __stat) +#define _getpid_r(__reent) getpid() +#define _isatty_r(__reent, __desc) isatty(__desc) +#define _kill_r(__reent, __pid, __signal) kill(__pid, __signal) +#define _link_r(__reent, __oldpath, __newpath) link(__oldpath, __newpath) +#define _lseek_r(__reent, __fdes, __off, __w) lseek(__fdes, __off, __w) +#define _open_r(__reent, __path, __flag, __m) open(__path, __flag, __m) +#define _read_r(__reent, __fd, __buff, __cnt) read(__fd, __buff, __cnt) +#define _sbrk_r(__reent, __incr) sbrk(__incr) +#define _stat_r(__reent, __path, __buff) stat(__path, __buff) +#define _times_r(__reent, __time) times(__time) +#define _unlink_r(__reent, __path) unlink(__path) +#define _wait_r(__reent, __status) wait(__status) +#define _write_r(__reent, __fd, __buff, __cnt) write(__fd, __buff, __cnt) +#define _gettimeofday_r(__reent, __tp, __tzp) gettimeofday(__tp, __tzp) + +#ifdef __LARGE64_FILES +#define _lseek64_r(__reent, __fd, __off, __w) lseek64(__fd, __off, __w) +#define _fstat64_r(__reent, __fd, __buff) fstat64(__fd, __buff) +#define _open64_r(__reent, __path, __flag, __m) open64(__path, __flag, __m) +#endif + +#else /* Reentrant versions of system calls. */ extern int _close_r _PARAMS ((struct _reent *, int)); @@ -96,6 +170,8 @@ extern int _fstat64_r _PARAMS ((struct _reent *, int, struct stat64 *)); extern int _open64_r _PARAMS ((struct _reent *, const char *, int, int)); #endif +#endif + #ifdef __cplusplus } #endif