[444] | 1 | @c -*- Texinfo -*- |
---|
| 2 | @node Syscalls |
---|
| 3 | @chapter System Calls |
---|
| 4 | |
---|
| 5 | @cindex linking the C library |
---|
| 6 | The C subroutine library depends on a handful of subroutine calls for |
---|
| 7 | operating system services. If you use the C library on a system that |
---|
| 8 | complies with the POSIX.1 standard (also known as IEEE 1003.1), most of |
---|
| 9 | these subroutines are supplied with your operating system. |
---|
| 10 | |
---|
| 11 | If some of these subroutines are not provided with your system---in |
---|
| 12 | the extreme case, if you are developing software for a ``bare board'' |
---|
| 13 | system, without an OS---you will at least need to provide do-nothing |
---|
| 14 | stubs (or subroutines with minimal functionality) to allow your |
---|
| 15 | programs to link with the subroutines in @code{libc.a}. |
---|
| 16 | |
---|
| 17 | @menu |
---|
| 18 | * Stubs:: Definitions for OS interface |
---|
| 19 | * Reentrant Syscalls:: Reentrant covers for OS subroutines |
---|
| 20 | @end menu |
---|
| 21 | |
---|
| 22 | @node Stubs |
---|
| 23 | @section Definitions for OS interface |
---|
| 24 | @cindex stubs |
---|
| 25 | |
---|
| 26 | @cindex subroutines for OS interface |
---|
| 27 | @cindex OS interface subroutines |
---|
| 28 | This is the complete set of system definitions (primarily subroutines) |
---|
| 29 | required; the examples shown implement the minimal functionality |
---|
| 30 | required to allow @code{libc} to link, and fail gracefully where OS |
---|
| 31 | services are not available. |
---|
| 32 | |
---|
| 33 | Graceful failure is permitted by returning an error code. A minor |
---|
| 34 | complication arises here: the C library must be compatible with |
---|
| 35 | development environments that supply fully functional versions of these |
---|
| 36 | subroutines. Such environments usually return error codes in a global |
---|
| 37 | @code{errno}. However, the Red Hat newlib C library provides a @emph{macro} |
---|
| 38 | definition for @code{errno} in the header file @file{errno.h}, as part |
---|
| 39 | of its support for reentrant routines (@pxref{Reentrancy,,Reentrancy}). |
---|
| 40 | |
---|
| 41 | @cindex @code{errno} global vs macro |
---|
| 42 | The bridge between these two interpretations of @code{errno} is |
---|
| 43 | straightforward: the C library routines with OS interface calls |
---|
| 44 | capture the @code{errno} values returned globally, and record them in |
---|
| 45 | the appropriate field of the reentrancy structure (so that you can query |
---|
| 46 | them using the @code{errno} macro from @file{errno.h}). |
---|
| 47 | |
---|
| 48 | This mechanism becomes visible when you write stub routines for OS |
---|
| 49 | interfaces. You must include @file{errno.h}, then disable the macro, |
---|
| 50 | like this: |
---|
| 51 | |
---|
| 52 | @example |
---|
| 53 | #include <errno.h> |
---|
| 54 | #undef errno |
---|
| 55 | extern int errno; |
---|
| 56 | @end example |
---|
| 57 | |
---|
| 58 | @noindent |
---|
| 59 | The examples in this chapter include this treatment of @code{errno}. |
---|
| 60 | |
---|
| 61 | @ftable @code |
---|
| 62 | @item _exit |
---|
| 63 | Exit a program without cleaning up files. If your system doesn't |
---|
| 64 | provide this, it is best to avoid linking with subroutines that require |
---|
| 65 | it (@code{exit}, @code{system}). |
---|
| 66 | |
---|
| 67 | @item close |
---|
| 68 | Close a file. Minimal implementation: |
---|
| 69 | |
---|
| 70 | @example |
---|
| 71 | int close(int file) @{ |
---|
| 72 | return -1; |
---|
| 73 | @} |
---|
| 74 | @end example |
---|
| 75 | |
---|
| 76 | @item environ |
---|
| 77 | A pointer to a list of environment variables and their values. For a |
---|
| 78 | minimal environment, this empty list is adequate: |
---|
| 79 | |
---|
| 80 | @example |
---|
| 81 | char *__env[1] = @{ 0 @}; |
---|
| 82 | char **environ = __env; |
---|
| 83 | @end example |
---|
| 84 | |
---|
| 85 | @item execve |
---|
| 86 | Transfer control to a new process. Minimal implementation (for a system |
---|
| 87 | without processes): |
---|
| 88 | |
---|
| 89 | @example |
---|
| 90 | #include <errno.h> |
---|
| 91 | #undef errno |
---|
| 92 | extern int errno; |
---|
| 93 | int execve(char *name, char **argv, char **env) @{ |
---|
| 94 | errno = ENOMEM; |
---|
| 95 | return -1; |
---|
| 96 | @} |
---|
| 97 | @end example |
---|
| 98 | |
---|
| 99 | @item fork |
---|
| 100 | Create a new process. Minimal implementation (for a system without processes): |
---|
| 101 | |
---|
| 102 | @example |
---|
| 103 | #include <errno.h> |
---|
| 104 | #undef errno |
---|
| 105 | extern int errno; |
---|
| 106 | int fork(void) @{ |
---|
| 107 | errno = EAGAIN; |
---|
| 108 | return -1; |
---|
| 109 | @} |
---|
| 110 | @end example |
---|
| 111 | |
---|
| 112 | @item fstat |
---|
| 113 | Status of an open file. For consistency with other minimal |
---|
| 114 | implementations in these examples, all files are regarded as character |
---|
| 115 | special devices. The @file{sys/stat.h} header file required is |
---|
| 116 | distributed in the @file{include} subdirectory for this C library. |
---|
| 117 | |
---|
| 118 | @example |
---|
| 119 | #include <sys/stat.h> |
---|
| 120 | int fstat(int file, struct stat *st) @{ |
---|
| 121 | st->st_mode = S_IFCHR; |
---|
| 122 | return 0; |
---|
| 123 | @} |
---|
| 124 | @end example |
---|
| 125 | |
---|
| 126 | @item getpid |
---|
| 127 | Process-ID; this is sometimes used to generate strings unlikely to |
---|
| 128 | conflict with other processes. Minimal implementation, for a system |
---|
| 129 | without processes: |
---|
| 130 | |
---|
| 131 | @example |
---|
| 132 | int getpid(void) @{ |
---|
| 133 | return 1; |
---|
| 134 | @} |
---|
| 135 | @end example |
---|
| 136 | |
---|
| 137 | @item isatty |
---|
| 138 | Query whether output stream is a terminal. For consistency with the |
---|
| 139 | other minimal implementations, which only support output to |
---|
| 140 | @code{stdout}, this minimal implementation is suggested: |
---|
| 141 | |
---|
| 142 | @example |
---|
| 143 | int isatty(int file) @{ |
---|
| 144 | return 1; |
---|
| 145 | @} |
---|
| 146 | @end example |
---|
| 147 | |
---|
| 148 | @item kill |
---|
| 149 | Send a signal. Minimal implementation: |
---|
| 150 | |
---|
| 151 | @example |
---|
| 152 | #include <errno.h> |
---|
| 153 | #undef errno |
---|
| 154 | extern int errno; |
---|
| 155 | int kill(int pid, int sig) @{ |
---|
| 156 | errno = EINVAL; |
---|
| 157 | return -1; |
---|
| 158 | @} |
---|
| 159 | @end example |
---|
| 160 | |
---|
| 161 | @item link |
---|
| 162 | Establish a new name for an existing file. Minimal implementation: |
---|
| 163 | |
---|
| 164 | @example |
---|
| 165 | #include <errno.h> |
---|
| 166 | #undef errno |
---|
| 167 | extern int errno; |
---|
| 168 | int link(char *old, char *new) @{ |
---|
| 169 | errno = EMLINK; |
---|
| 170 | return -1; |
---|
| 171 | @} |
---|
| 172 | @end example |
---|
| 173 | |
---|
| 174 | @item lseek |
---|
| 175 | Set position in a file. Minimal implementation: |
---|
| 176 | |
---|
| 177 | @example |
---|
| 178 | int lseek(int file, int ptr, int dir) @{ |
---|
| 179 | return 0; |
---|
| 180 | @} |
---|
| 181 | @end example |
---|
| 182 | |
---|
| 183 | @item open |
---|
| 184 | Open a file. Minimal implementation: |
---|
| 185 | |
---|
| 186 | @example |
---|
| 187 | int open(const char *name, int flags, int mode) @{ |
---|
| 188 | return -1; |
---|
| 189 | @} |
---|
| 190 | @end example |
---|
| 191 | |
---|
| 192 | @item read |
---|
| 193 | Read from a file. Minimal implementation: |
---|
| 194 | |
---|
| 195 | @example |
---|
| 196 | int read(int file, char *ptr, int len) @{ |
---|
| 197 | return 0; |
---|
| 198 | @} |
---|
| 199 | @end example |
---|
| 200 | |
---|
| 201 | @item sbrk |
---|
| 202 | Increase program data space. As @code{malloc} and related functions |
---|
| 203 | depend on this, it is useful to have a working implementation. The |
---|
| 204 | following suffices for a standalone system; it exploits the symbol |
---|
| 205 | @code{_end} automatically defined by the GNU linker. |
---|
| 206 | |
---|
| 207 | @example |
---|
| 208 | @group |
---|
| 209 | caddr_t sbrk(int incr) @{ |
---|
| 210 | extern char _end; /* @r{Defined by the linker} */ |
---|
| 211 | static char *heap_end; |
---|
| 212 | char *prev_heap_end; |
---|
| 213 | |
---|
| 214 | if (heap_end == 0) @{ |
---|
| 215 | heap_end = &_end; |
---|
| 216 | @} |
---|
| 217 | prev_heap_end = heap_end; |
---|
| 218 | if (heap_end + incr > stack_ptr) @{ |
---|
| 219 | write (1, "Heap and stack collision\n", 25); |
---|
| 220 | abort (); |
---|
| 221 | @} |
---|
| 222 | |
---|
| 223 | heap_end += incr; |
---|
| 224 | return (caddr_t) prev_heap_end; |
---|
| 225 | @} |
---|
| 226 | @end group |
---|
| 227 | @end example |
---|
| 228 | |
---|
| 229 | @item stat |
---|
| 230 | Status of a file (by name). Minimal implementation: |
---|
| 231 | |
---|
| 232 | @example |
---|
| 233 | int stat(char *file, struct stat *st) @{ |
---|
| 234 | st->st_mode = S_IFCHR; |
---|
| 235 | return 0; |
---|
| 236 | @} |
---|
| 237 | @end example |
---|
| 238 | |
---|
| 239 | @item times |
---|
| 240 | Timing information for current process. Minimal implementation: |
---|
| 241 | |
---|
| 242 | @example |
---|
| 243 | int times(struct tms *buf) @{ |
---|
| 244 | return -1; |
---|
| 245 | @} |
---|
| 246 | @end example |
---|
| 247 | |
---|
| 248 | @item unlink |
---|
| 249 | Remove a file's directory entry. Minimal implementation: |
---|
| 250 | |
---|
| 251 | @example |
---|
| 252 | #include <errno.h> |
---|
| 253 | #undef errno |
---|
| 254 | extern int errno; |
---|
| 255 | int unlink(char *name) @{ |
---|
| 256 | errno = ENOENT; |
---|
| 257 | return -1; |
---|
| 258 | @} |
---|
| 259 | @end example |
---|
| 260 | |
---|
| 261 | @item wait |
---|
| 262 | Wait for a child process. Minimal implementation: |
---|
| 263 | @example |
---|
| 264 | #include <errno.h> |
---|
| 265 | #undef errno |
---|
| 266 | extern int errno; |
---|
| 267 | int wait(int *status) @{ |
---|
| 268 | errno = ECHILD; |
---|
| 269 | return -1; |
---|
| 270 | @} |
---|
| 271 | @end example |
---|
| 272 | |
---|
| 273 | @item write |
---|
| 274 | Write to a file. @file{libc} subroutines will use this |
---|
| 275 | system routine for output to all files, @emph{including} |
---|
| 276 | @code{stdout}---so if you need to generate any output, for example to a |
---|
| 277 | serial port for debugging, you should make your minimal @code{write} |
---|
| 278 | capable of doing this. The following minimal implementation is an |
---|
| 279 | incomplete example; it relies on a @code{outbyte} subroutine (not |
---|
| 280 | shown; typically, you must write this in assembler from examples |
---|
| 281 | provided by your hardware manufacturer) to actually perform the output. |
---|
| 282 | |
---|
| 283 | @example |
---|
| 284 | @group |
---|
| 285 | int write(int file, char *ptr, int len) @{ |
---|
| 286 | int todo; |
---|
| 287 | |
---|
| 288 | for (todo = 0; todo < len; todo++) @{ |
---|
| 289 | outbyte (*ptr++); |
---|
| 290 | @} |
---|
| 291 | return len; |
---|
| 292 | @} |
---|
| 293 | @end group |
---|
| 294 | @end example |
---|
| 295 | |
---|
| 296 | @end ftable |
---|
| 297 | |
---|
| 298 | @page |
---|
| 299 | @node Reentrant Syscalls |
---|
| 300 | @section Reentrant covers for OS subroutines |
---|
| 301 | |
---|
| 302 | Since the system subroutines are used by other library routines that |
---|
| 303 | require reentrancy, @file{libc.a} provides cover routines (for example, |
---|
| 304 | the reentrant version of @code{fork} is @code{_fork_r}). These cover |
---|
| 305 | routines are consistent with the other reentrant subroutines in this |
---|
| 306 | library, and achieve reentrancy by using a reserved global data block |
---|
| 307 | (@pxref{Reentrancy,,Reentrancy}). |
---|
| 308 | |
---|
| 309 | @menu |
---|
| 310 | * _close_r:: Reentrant version of close |
---|
| 311 | * _execve_r:: Reentrant version of execve |
---|
| 312 | * _fork_r:: Reentrant version of fork |
---|
| 313 | @ifset STDIO64 |
---|
| 314 | * _fstat64_r:: Reentrant version of fstat64 |
---|
| 315 | @end ifset |
---|
| 316 | * _fstat_r:: Reentrant version of fstat |
---|
| 317 | * _getpid_r:: Reentrant version of getpid |
---|
| 318 | * _kill_r:: Reentrant version of kill |
---|
| 319 | * _link_r:: Reentrant version of link |
---|
| 320 | @ifset STDIO64 |
---|
| 321 | * _lseek64_r:: Reentrant version of lseek64 |
---|
| 322 | @end ifset |
---|
| 323 | * _lseek_r:: Reentrant version of lseek |
---|
| 324 | @ifset STDIO64 |
---|
| 325 | * _open64_r:: Reentrant version of open64 |
---|
| 326 | @end ifset |
---|
| 327 | * _open_r:: Reentrant version of open |
---|
| 328 | * _read_r:: Reentrant version of read |
---|
| 329 | * _sbrk_r:: Reentrant version of sbrk |
---|
| 330 | @ifset STDIO64 |
---|
| 331 | * _stat64_r:: Reentrant version of stat64 |
---|
| 332 | @end ifset |
---|
| 333 | * _stat_r:: Reentrant version of stat |
---|
| 334 | * _times_r:: Reentrant version of times |
---|
| 335 | * _unlink_r:: Reentrant version of unlink |
---|
| 336 | * _wait_r:: Reentrant version of wait |
---|
| 337 | * _write_r:: Reentrant version of write |
---|
| 338 | @end menu |
---|
| 339 | |
---|
| 340 | @lowersections |
---|
| 341 | @page |
---|
| 342 | @include reent/closer.def |
---|
| 343 | |
---|
| 344 | @page |
---|
| 345 | @include reent/execr.def |
---|
| 346 | |
---|
| 347 | @ifset STDIO64 |
---|
| 348 | @page |
---|
| 349 | @include reent/fstat64r.def |
---|
| 350 | @end ifset |
---|
| 351 | |
---|
| 352 | @page |
---|
| 353 | @include reent/fstatr.def |
---|
| 354 | |
---|
| 355 | @page |
---|
| 356 | @include reent/linkr.def |
---|
| 357 | |
---|
| 358 | @ifset STDIO64 |
---|
| 359 | @page |
---|
| 360 | @include reent/lseek64r.def |
---|
| 361 | @end ifset |
---|
| 362 | |
---|
| 363 | @page |
---|
| 364 | @include reent/lseekr.def |
---|
| 365 | |
---|
| 366 | @ifset STDIO64 |
---|
| 367 | @page |
---|
| 368 | @include reent/open64r.def |
---|
| 369 | @end ifset |
---|
| 370 | |
---|
| 371 | @page |
---|
| 372 | @include reent/openr.def |
---|
| 373 | |
---|
| 374 | @page |
---|
| 375 | @include reent/readr.def |
---|
| 376 | |
---|
| 377 | @page |
---|
| 378 | @include reent/sbrkr.def |
---|
| 379 | |
---|
| 380 | @page |
---|
| 381 | @include reent/signalr.def |
---|
| 382 | |
---|
| 383 | @ifset STDIO64 |
---|
| 384 | @page |
---|
| 385 | @include reent/stat64r.def |
---|
| 386 | @end ifset |
---|
| 387 | |
---|
| 388 | @page |
---|
| 389 | @include reent/statr.def |
---|
| 390 | |
---|
| 391 | @page |
---|
| 392 | @include reent/timesr.def |
---|
| 393 | |
---|
| 394 | @page |
---|
| 395 | @include reent/unlinkr.def |
---|
| 396 | |
---|
| 397 | @page |
---|
| 398 | @include reent/writer.def |
---|
| 399 | @raisesections |
---|