diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libc/include/README | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/lib/libc/include/README b/src/lib/libc/include/README new file mode 100644 index 0000000000..6410072c96 --- /dev/null +++ b/src/lib/libc/include/README | |||
| @@ -0,0 +1,97 @@ | |||
| 1 | So you want to add an interface to libc... | ||
| 2 | |||
| 3 | CASE I: internal symbols | ||
| 4 | |||
| 5 | A) used in a single file | ||
| 6 | Duh: use whatever name you want and make it static | ||
| 7 | |||
| 8 | B) used in multiple files | ||
| 9 | Give it a name in the implementation namespace (leading underbar) | ||
| 10 | and declare it in a __{BEGIN,END}_HIDDEN_DECLS block in a .h | ||
| 11 | file inside libc. If it's used in just a single subdir of | ||
| 12 | libc *and* that subdir has an appropriate .h file in it, then | ||
| 13 | declare it there. | ||
| 14 | Example: stdio/local.h. | ||
| 15 | Otherwise, declare it in one of the hidden/* files. | ||
| 16 | Example: _mktemp() in hidden/stdio.h | ||
| 17 | |||
| 18 | CASE II: external symbols | ||
| 19 | |||
| 20 | First of all, add your symbol to Symbols.list. MD symbols go in | ||
| 21 | arch/*/Symbols.list (shock, I know) | ||
| 22 | |||
| 23 | Declare your function in the appropriate header. It almost certainly | ||
| 24 | should be in a public header installed under /usr/include/. Exceptions | ||
| 25 | are symbols that are just shared between libc and libpthread/csu/ld.so | ||
| 26 | which are only declared in libc/include/* or just in each .c file. | ||
| 27 | |||
| 28 | A) objects (variables) | ||
| 29 | That's it, you're done. | ||
| 30 | |||
| 31 | B) plain C functions (not syscalls) | ||
| 32 | 1) functions that are *not* called from inside libc | ||
| 33 | |||
| 34 | If this function is specified in the ISO C standard or its | ||
| 35 | name begins with an underbar, then in the hidden/* version | ||
| 36 | of the header where you declared the function, add this line: | ||
| 37 | PROTO_STD_DEPRECATED(your_function_name); | ||
| 38 | |||
| 39 | Otherwise, this is *not* a function specified in the ISO C | ||
| 40 | standard and its name begins with a letter. In the hidden/* | ||
| 41 | version of the header where you declared the function, add | ||
| 42 | this line: | ||
| 43 | PROTO_DEPRECATED(your_function_name); | ||
| 44 | |||
| 45 | 2) functions that are called from inside libc | ||
| 46 | |||
| 47 | In the hidden/* version of the header where you declared | ||
| 48 | the function, add this line: | ||
| 49 | PROTO_NORMAL(your_function_name); | ||
| 50 | |||
| 51 | Then, in the .c file(s) where the function is defined: | ||
| 52 | - if the function is specified in the ISO C standard or | ||
| 53 | its name begins with an underbar, add | ||
| 54 | DEF_STRONG(your_function_name); | ||
| 55 | |||
| 56 | - otherwise, add: | ||
| 57 | DEF_WEAK(your_function_name); | ||
| 58 | |||
| 59 | C) syscalls that require cancellation or other libpthread wrappers | ||
| 60 | You're done in libc, but go to libpthread and add the wrapper there. | ||
| 61 | |||
| 62 | D) syscalls that require libc wrappers for other reasons | ||
| 63 | First of all, make sure this really is the Right Thing. Talk | ||
| 64 | with kettenis, deraadt, miod, and guenther. | ||
| 65 | |||
| 66 | 1) If the actual syscall doesn't have the same calling convention | ||
| 67 | as the C interface, then maybe it shouldn't be exported at | ||
| 68 | all and you should just have an ASM stub, like SYS___tfork | ||
| 69 | --> __tfork_thread() or SYS_break --> brk() and sbrk(). If | ||
| 70 | it _could_ be called from C, then give the syscall a name | ||
| 71 | different from the C API. Syscalls that fail this for | ||
| 72 | historical reasons (e.g., getlogin) are generated with | ||
| 73 | PSEUDO in libc/sys/Makefile.inc, so the ASM stub has a | ||
| 74 | leading underbar. Go read gen/getlogin.c for an example | ||
| 75 | of how to do this. | ||
| 76 | |||
| 77 | 2) Otherwise, you're sane and have a syscall like sigaction() | ||
| 78 | which requires a wrapper but whose syscall API is the same | ||
| 79 | as the C API. Then: | ||
| 80 | - generate the ASM stub with HIDDEN in libc/sys/Makefile.inc | ||
| 81 | - in the proper hidden/*.h file add | ||
| 82 | PROTO_WRAP(your_function_name) | ||
| 83 | - the wrapper function should be defined in | ||
| 84 | libc/sys/w_your_function_name.c | ||
| 85 | which should define WRAP(your_function_name) and | ||
| 86 | follow it with DEF_WRAP(your_function_name). Look at | ||
| 87 | libc/sys/w_sigaction.c for an example. | ||
| 88 | - by default, libc code that calls your_function_name() | ||
| 89 | will get the real syscall and *not* the wrapper. libc | ||
| 90 | calls that needd to go through the wrapper should invoke | ||
| 91 | WRAP(your_function_name) | ||
| 92 | |||
| 93 | E) syscalls that don't require any wrapping | ||
| 94 | In the hidden/* version of the header where you declared the | ||
| 95 | function, add this line: | ||
| 96 | PROTO_NORMAL(your_function_name); | ||
| 97 | |||
