1 /* This header file provides the reentrancy. */ 2 3 /* The reentrant system calls here serve two purposes: 4 5 1) Provide reentrant versions of the system calls the ANSI C library 6 requires. 7 2) Provide these system calls in a namespace clean way. 8 9 It is intended that *all* system calls that the ANSI C library needs 10 be declared here. It documents them all in one place. All library access 11 to the system is via some form of these functions. 12 13 The target may provide the needed syscalls by any of the following: 14 15 1) Define the reentrant versions of the syscalls directly. 16 (eg: _open_r, _close_r, etc.). Please keep the namespace clean. 17 When you do this, set "syscall_dir" to "syscalls" and add 18 -DREENTRANT_SYSCALLS_PROVIDED to newlib_cflags in configure.host. 19 20 2) Define namespace clean versions of the system calls by prefixing 21 them with '_' (eg: _open, _close, etc.). Technically, there won't be 22 true reentrancy at the syscall level, but the library will be namespace 23 clean. 24 When you do this, set "syscall_dir" to "syscalls" in configure.host. 25 26 3) Define or otherwise provide the regular versions of the syscalls 27 (eg: open, close, etc.). The library won't be reentrant nor namespace 28 clean, but at least it will work. 29 When you do this, add -DMISSING_SYSCALL_NAMES to newlib_cflags in 30 configure.host. 31 32 4) Define or otherwise provide the regular versions of the syscalls, 33 and do not supply functional interfaces for any of the reentrant 34 calls. With this method, the reentrant syscalls are redefined to 35 directly call the regular system call without the reentrancy argument. 36 When you do this, specify both -DREENTRANT_SYSCALLS_PROVIDED and 37 -DMISSING_SYSCALL_NAMES via newlib_cflags in configure.host and do 38 not specify "syscall_dir". 39 40 Stubs of the reentrant versions of the syscalls exist in the libc/reent 41 source directory and are provided if REENTRANT_SYSCALLS_PROVIDED isn't 42 defined. These stubs call the native system calls: _open, _close, etc. 43 if MISSING_SYSCALL_NAMES is *not* defined, otherwise they call the 44 non-underscored versions: open, close, etc. when MISSING_SYSCALL_NAMES 45 *is* defined. 46 47 By default, newlib functions call the reentrant syscalls internally, 48 passing a reentrancy structure as an argument. This reentrancy structure 49 contains data that is thread-specific. For example, the errno value is 50 kept in the reentrancy structure. If multiple threads exist, each will 51 keep a separate errno value which is intuitive since the application flow 52 cannot check for failure reliably otherwise. 53 54 The reentrant syscalls are either provided by the platform, by the 55 libc/reent stubs, or in the case of both MISSING_SYSCALL_NAMES and 56 REENTRANT_SYSCALLS_PROVIDED being defined, the calls are redefined to 57 simply call the regular syscalls with no reentrancy struct argument. 58 59 A single-threaded application does not need to worry about the reentrancy 60 structure. It is used internally. 61 62 A multi-threaded application needs either to manually manage reentrancy 63 structures or use dynamic reentrancy. 64 65 Manually managing reentrancy structures entails calling special reentrant 66 versions of newlib functions that have an additional reentrancy argument. 67 For example, _printf_r. By convention, the first argument is the 68 reentrancy structure. By default, the normal version of the function 69 uses the default reentrancy structure: _REENT. The reentrancy structure 70 is passed internally, eventually to the reentrant syscalls themselves. 71 How the structures are stored and accessed in this model is up to the 72 application. 73 74 Dynamic reentrancy is specified by the __DYNAMIC_REENT__ flag. This 75 flag denotes setting up a macro to replace _REENT with a function call 76 to __getreent(). This function needs to be implemented by the platform 77 and it is meant to return the reentrancy structure for the current 78 thread. When the regular C functions (e.g. printf) go to call internal 79 routines with the default _REENT structure, they end up calling with 80 the reentrancy structure for the thread. Thus, application code does not 81 need to call the _r routines nor worry about reentrancy structures. */ 82 83 /* WARNING: All identifiers here must begin with an underscore. This file is 84 included by stdio.h and others and we therefore must only use identifiers 85 in the namespace allotted to us. */ 86 87 #ifndef _REENT_H_ 88 #ifdef __cplusplus 89 extern "C" { 90 #endif 91 #define _REENT_H_ 92 93 #include <sys/reent.h> 94 #include <sys/_types.h> 95 #include <machine/types.h> 96 97 #define __need_size_t 98 #define __need_ptrdiff_t 99 #include <stddef.h> 100 101 /* FIXME: not namespace clean */ 102 struct stat; 103 struct tms; 104 struct timeval; 105 struct timezone; 106 107 #if defined(REENTRANT_SYSCALLS_PROVIDED) && defined(MISSING_SYSCALL_NAMES) 108 109 #define _close_r(__reent, __fd) close(__fd) 110 #define _execve_r(__reent, __f, __arg, __env) execve(__f, __arg, __env) 111 #define _fcntl_r(__reent, __fd, __cmd, __arg) fcntl(__fd, __cmd, __arg) 112 #define _fork_r(__reent) fork() 113 #define _fstat_r(__reent, __fdes, __stat) fstat(__fdes, __stat) 114 #define _getpid_r(__reent) getpid() 115 #define _isatty_r(__reent, __desc) isatty(__desc) 116 #define _kill_r(__reent, __pid, __signal) kill(__pid, __signal) 117 #define _link_r(__reent, __oldpath, __newpath) link(__oldpath, __newpath) 118 #define _lseek_r(__reent, __fdes, __off, __w) lseek(__fdes, __off, __w) 119 #define _mkdir_r(__reent, __path, __m) mkdir(__path, __m) 120 #define _open_r(__reent, __path, __flag, __m) open(__path, __flag, __m) 121 #define _read_r(__reent, __fd, __buff, __cnt) read(__fd, __buff, __cnt) 122 #define _rename_r(__reent, __old, __new) rename(__old, __new) 123 #define _sbrk_r(__reent, __incr) sbrk(__incr) 124 #define _stat_r(__reent, __path, __buff) stat(__path, __buff) 125 #define _times_r(__reent, __time) times(__time) 126 #define _unlink_r(__reent, __path) unlink(__path) 127 #define _wait_r(__reent, __status) wait(__status) 128 #define _write_r(__reent, __fd, __buff, __cnt) write(__fd, __buff, __cnt) 129 #define _gettimeofday_r(__reent, __tp, __tzp) gettimeofday(__tp, __tzp) 130 131 #ifdef __LARGE64_FILES 132 #define _lseek64_r(__reent, __fd, __off, __w) lseek64(__fd, __off, __w) 133 #define _fstat64_r(__reent, __fd, __buff) fstat64(__fd, __buff) 134 #define _open64_r(__reent, __path, __flag, __m) open64(__path, __flag, __m) 135 #endif 136 137 #else 138 /* Reentrant versions of system calls. */ 139 140 extern int _close_r _PARAMS ((struct _reent *, int)); 141 extern int _execve_r _PARAMS ((struct _reent *, const char *, char *const *, char *const *)); 142 extern int _fcntl_r _PARAMS ((struct _reent *, int, int, int)); 143 extern int _fork_r _PARAMS ((struct _reent *)); 144 extern int _fstat_r _PARAMS ((struct _reent *, int, struct stat *)); 145 extern int _getpid_r _PARAMS ((struct _reent *)); 146 extern int _isatty_r _PARAMS ((struct _reent *, int)); 147 extern int _kill_r _PARAMS ((struct _reent *, int, int)); 148 extern int _link_r _PARAMS ((struct _reent *, const char *, const char *)); 149 extern _off_t _lseek_r _PARAMS ((struct _reent *, int, _off_t, int)); 150 extern int _mkdir_r _PARAMS ((struct _reent *, const char *, int)); 151 extern int _open_r _PARAMS ((struct _reent *, const char *, int, int)); 152 extern _ssize_t _read_r _PARAMS ((struct _reent *, int, void *, size_t)); 153 extern int _rename_r _PARAMS ((struct _reent *, const char *, const char *)); 154 extern void *_sbrk_r _PARAMS ((struct _reent *, ptrdiff_t)); 155 extern int _stat_r _PARAMS ((struct _reent *, const char *, struct stat *)); 156 extern _CLOCK_T_ _times_r _PARAMS ((struct _reent *, struct tms *)); 157 extern int _unlink_r _PARAMS ((struct _reent *, const char *)); 158 extern int _wait_r _PARAMS ((struct _reent *, int *)); 159 extern _ssize_t _write_r _PARAMS ((struct _reent *, int, const void *, size_t)); 160 161 /* This one is not guaranteed to be available on all targets. */ 162 extern int _gettimeofday_r _PARAMS ((struct _reent *, struct timeval *__tp, void *__tzp)); 163 164 #ifdef __LARGE64_FILES 165 166 167 #if defined(__CYGWIN__) 168 #define stat64 stat 169 #endif 170 struct stat64; 171 172 extern _off64_t _lseek64_r _PARAMS ((struct _reent *, int, _off64_t, int)); 173 extern int _fstat64_r _PARAMS ((struct _reent *, int, struct stat64 *)); 174 extern int _open64_r _PARAMS ((struct _reent *, const char *, int, int)); 175 extern int _stat64_r _PARAMS ((struct _reent *, const char *, struct stat64 *)); 176 177 /* Don't pollute namespace if not building newlib. */ 178 #if defined (__CYGWIN__) && !defined (_COMPILING_NEWLIB) 179 #undef stat64 180 #endif 181 182 #endif 183 184 #endif 185 186 #ifdef __cplusplus 187 } 188 #endif 189 #endif /* _REENT_H_ */ 190