-
Notifications
You must be signed in to change notification settings - Fork 22
/
PORTABILITY
132 lines (113 loc) · 4.27 KB
/
PORTABILITY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
Portability guideline
KAME project
$Id: PORTABILITY,v 1.12 1999/10/07 03:24:45 itojun Exp $
Source code in "kame" directory will be shared among operating systems
and hardware platforms. Here are several guidelines to be portable
across those possibilities.
- Developers MUST compile the code on two or more platforms, before committing
it to the repository (trivial changes or comment typos are okay).
- Do not break paren-match.
Always try to keep paren-match correctly, regardless of #ifdef.
The following is WRONG example:
#if foo
if (hoge) {
#else
if (hoge && hage) {
#endif
....
}
It should be written like follows:
#if foo
if (hoge)
#else
if (hoge && hage)
#endif
{
....
}
It is also advised to add extra comment to help paren match,
if you need to write widow paren in string. For example:
printf("("); /* ) */
- Follow NetBSD KNF.
They are the most strict guys about source code formatting.
If you obey NetBSD KNF, other platforms are happy.
- Pointer can be 64bit (for example, on alpha).
When taking integer from pointer, use u_long, or long.
This is WRONG:
void *p;
/* alignment check */
if ((1 & (int)p) == 0) {
...
}
This is correct (but actually is not future-proven - fail on 128bit arch):
void *p;
/* alignment check */
if ((1 & (u_long)p) == 0) {
...
}
- size_t can be 64bit, and may not be of same size as int.
When doing printf(), cast size_t to u_long and print it as %lu.
size_t siz;
printf("%lu", (u_long)siz);
- tv.tv_sec is not typed as time_t.
If you want time_t, explicitly copy the value.
- Packed structs must be used with care.
Unaligned structure can cause problem on certain architectures.
You'll need to copy the return value to aligned structure before accessing.
Structure returned by SIOCGIFCONF falls into this category.
- 2nd arg to ioctl() must be u_long, not int, on non-FreeBSD2 platforms.
- If you define multi-statement #define, define that like:
#define foobaa (x, y) \
do { \
/*something*/ \
} while (0)
Without this wrapper nasty mistakes can happen.
- Compiler options needs to be configured differently into Makefile.
For NetBSD and OpenBSD, CFLAGS and CPPFLAGS are defined separately:
CPPFLAGS+=-I/usr/local/include
CFLAGS+=-g
For FreeBSD and BSDI, there's no distinction.
CFLAGS+=-I/usr/local/include
CFLAGS+=-g
- To refer objects and machine-generated source code, FreeBSD needs to use
${.OBJDIR} This is because because FreeBSD completely separates "obj" tree
and "src" tree and has no symlink from ${.CURDIR}/obj to /usr/obj/foobaa.
On other platforms, ${.CURDIR}/obj should do.
- On manpage installation.
for BSDI3, you need to set MAN[0-9] in Makefile like below. MANDIR must
point to "catN" directory, not "manN", without "N":
MANDIR= /usr/local/v6/man/cat
MAN5= foo.0
MAN8= baz.0
MLINKS= foo.5 baa.5
For NetBSD, you need to set MAN (not MAN[0-9]). MANDIR needs to point to
"man" directory right above "catN" or "manN" directory:
MANDIR= /usr/local/v6/man
MAN= foo.5 baz.8
MLINKS= foo.5 baa.5
MKPIC= # if you do not want shlib, make it empty
For OpenBSD, you need to set MAN (not MAN[0-9]). MANDIR needs to point to
"catN" directory, without "N":
MANDIR= /usr/local/v6/man/cat
MAN= foo.5 baz.8
MLINKS= foo.5 baa.5
NOPIC= yes # if you do not want shlib, define it
For FreeBSD, you need to set MAN[0-9] like below. MANDIR needs to point
to "manN" directory, without "N":
MANDIR= /usr/local/v6/man/man
MAN5= foo.5
MAN8= baz.8
MLINKS= foo.5 baa.5
# if you do not want shlib, do not define SHLIB_{MAJOR,MINOR}
- BSDI3 /usr/bin/cc is gcc 1.42, and it does not support __FUNCTION__.
If you need to use __FUNCTION__, you need to set CC to "gcc", or "shlicc2"
explicitly.
__FUNCTION__ macro is not included in ANSI standard, so it is best to
avoid __FUNCTION__, or make it optional, for portability.
- sys/queue.h are very different in each of *BSDs. Most of macros found in
FreeBSD3 are not available in other systems. Simply avoid those, make sure
your code compile on non-FreeBSD3 systems.
Avoid xx_FOREACH(), which is only available in FreeBSD3. Just use
for (x = xx_FIRST(); x; x = xx_NEXT(x))
and do not try to do #ifdef (FreeBSD3). More #ifdef introduces more bugs.
- For portability in networking code, look at kame/sys/net/net_osdep.h.