xref: /openbsd-src/lib/libc/include/README (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1So you want to add an interface to libc...
2
3CASE 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
18CASE 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
98