]>
Commit | Line | Data |
---|---|---|
7a938933 ILT |
1 | #!/bin/sh |
2 | ||
3 | # Copyright 2009 The Go Authors. All rights reserved. | |
4 | # Use of this source code is governed by a BSD-style | |
5 | # license that can be found in the LICENSE file. | |
6 | ||
7 | # Create sysinfo.go. | |
8 | ||
9 | # This shell script creates the sysinfo.go file which holds types and | |
10 | # constants extracted from the system header files. This relies on a | |
11 | # hook in gcc: the -ggo option will generate debugging information in | |
12 | # Go syntax. | |
13 | ||
14 | # We currently #include all the files at once, which works, but leads | |
15 | # to exposing some names which ideally should not be exposed, as they | |
16 | # match grep patterns. E.g., WCHAR_MIN gets exposed because it starts | |
17 | # with W, like the wait flags. | |
18 | ||
19 | CC=${CC:-gcc} | |
20 | OUT=tmp-sysinfo.go | |
21 | ||
22 | set -e | |
23 | ||
24 | rm -f sysinfo.go | |
25 | ||
26 | rm -f sysinfo.c | |
27 | cat > sysinfo.c <<EOF | |
28 | #include "config.h" | |
29 | #include <sys/types.h> | |
30 | #include <dirent.h> | |
31 | #include <errno.h> | |
32 | #include <fcntl.h> | |
33 | #include <netinet/in.h> | |
34 | #include <netinet/tcp.h> | |
35 | #include <signal.h> | |
36 | #if defined(HAVE_SYSCALL_H) | |
37 | #include <syscall.h> | |
38 | #endif | |
39 | #if defined(HAVE_SYS_EPOLL_H) | |
40 | #include <sys/epoll.h> | |
41 | #endif | |
42 | #if defined(HAVE_SYS_PTRACE_H) | |
43 | #include <sys/ptrace.h> | |
44 | #endif | |
45 | #include <sys/resource.h> | |
46 | #include <sys/socket.h> | |
47 | #include <sys/stat.h> | |
48 | #include <sys/time.h> | |
49 | #include <sys/wait.h> | |
50 | #include <sys/un.h> | |
51 | #if defined(HAVE_SYS_USER_H) | |
52 | #include <sys/user.h> | |
53 | #endif | |
54 | #if defined(HAVE_SYS_UTSNAME_H) | |
55 | #include <sys/utsname.h> | |
56 | #endif | |
57 | #include <unistd.h> | |
58 | EOF | |
59 | ||
60 | ${CC} -D_GNU_SOURCE -fdump-go-spec=gen-sysinfo.go -S -o sysinfo.s sysinfo.c | |
61 | ||
62 | echo 'package syscall' > ${OUT} | |
63 | ||
64 | # Get all the consts and types, skipping ones which could not be | |
65 | # represented in Go and ones which we need to rewrite. We also skip | |
66 | # function declarations, as we don't need them here. All the symbols | |
67 | # will all have a leading underscore. | |
68 | grep -v '^// ' gen-sysinfo.go | \ | |
69 | grep -v '^func' | \ | |
70 | grep -v '^type _timeval ' | \ | |
71 | grep -v '^type _timespec ' | \ | |
72 | grep -v '^type _epoll_' | \ | |
73 | grep -v 'in6_addr' | \ | |
74 | grep -v 'sockaddr_in6' | \ | |
75 | sed -e 's/\([^a-zA-Z0-9_]\)_timeval\([^a-zA-Z0-9_]\)/\1Timeval\2/g' \ | |
76 | -e 's/\([^a-zA-Z0-9_]\)_timespec\([^a-zA-Z0-9_]\)/\1Timespec\2/g' \ | |
77 | >> ${OUT} | |
78 | ||
79 | # The errno constants. | |
80 | grep '^const _E' gen-sysinfo.go | \ | |
81 | sed -e 's/^\(const \)_\(E[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} | |
82 | ||
83 | # The O_xxx flags. | |
84 | grep '^const _\(O\|F\|FD\)_' gen-sysinfo.go | \ | |
85 | sed -e 's/^\(const \)_\([^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} | |
86 | if ! grep '^const O_CLOEXEC' ${OUT} >/dev/null 2>&1; then | |
87 | echo "const O_CLOEXEC = 0" >> ${OUT} | |
88 | fi | |
89 | ||
90 | # The signal numbers. | |
91 | grep '^const _SIG[^_]' gen-sysinfo.go | \ | |
92 | grep -v '^const _SIGEV_' | \ | |
93 | sed -e 's/^\(const \)_\(SIG[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} | |
94 | ||
95 | # The syscall numbers. We force the names to upper case. | |
96 | grep '^const _SYS_' gen-sysinfo.go | \ | |
97 | sed -e 's/const _\(SYS_[^= ]*\).*$/\1/' | \ | |
98 | while read sys; do | |
99 | sup=`echo $sys | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` | |
100 | echo "const $sup = _$sys" >> ${OUT} | |
101 | done | |
102 | ||
103 | # Stat constants. | |
104 | grep '^const _S_' gen-sysinfo.go | \ | |
105 | sed -e 's/^\(const \)_\(S_[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} | |
106 | ||
107 | # Process status constants. | |
108 | grep '^const _W' gen-sysinfo.go | | |
109 | sed -e 's/^\(const \)_\(W[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} | |
110 | # WSTOPPED was introduced in glibc 2.3.4. | |
111 | if ! grep '^const _WSTOPPED = ' gen-sysinfo.go >/dev/null 2>&1; then | |
112 | if grep '^const _WUNTRACED = ' gen-sysinfo.go > /dev/null 2>&1; then | |
113 | echo 'const WSTOPPED = _WUNTRACED' >> ${OUT} | |
114 | else | |
115 | echo 'const WSTOPPED = 2' >> ${OUT} | |
116 | fi | |
117 | fi | |
118 | if grep '^const ___WALL = ' gen-sysinfo.go >/dev/null 2>&1 \ | |
119 | && ! grep '^const _WALL = ' gen-sysinfo.go >/dev/null 2>&1; then | |
120 | echo 'const WALL = ___WALL' >> ${OUT} | |
121 | fi | |
122 | ||
123 | # Networking constants. | |
124 | grep '^const _\(AF\|SOCK\|SOL\|SO\|IPPROTO\|TCP\|IP\|IPV6\)_' gen-sysinfo.go | | |
125 | sed -e 's/^\(const \)_\([^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} | |
126 | grep '^const _SOMAXCONN' gen-sysinfo.go | | |
127 | sed -e 's/^\(const \)_\(SOMAXCONN[^= ]*\)\(.*\)$/\1\2 = _\2/' \ | |
128 | >> ${OUT} | |
129 | grep '^const _SHUT_' gen-sysinfo.go | | |
130 | sed -e 's/^\(const \)_\(SHUT[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} | |
131 | ||
132 | # pathconf constants. | |
133 | grep '^const __PC' gen-sysinfo.go | | |
134 | sed -e 's/^\(const \)__\(PC[^= ]*\)\(.*\)$/\1\2 = __\2/' >> ${OUT} | |
135 | ||
136 | # The epoll constants were picked up by the errno constants, but we | |
137 | # need to be sure the EPOLLRDHUP is defined. | |
138 | if ! grep '^const EPOLLRDHUP' ${OUT} >/dev/null 2>&1; then | |
139 | echo "const EPOLLRDHUP = 0x2000" >> ${OUT} | |
140 | fi | |
141 | ||
142 | # Ptrace constants. We don't expose all the PTRACE flags, just the | |
143 | # PTRACE_O_xxx and PTRACE_EVENT_xxx ones. | |
144 | grep '^const _PTRACE_O' gen-sysinfo.go | | |
145 | sed -e 's/^\(const \)_\(PTRACE_O[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} | |
146 | grep '^const _PTRACE_EVENT' gen-sysinfo.go | | |
147 | sed -e 's/^\(const \)_\(PTRACE_EVENT[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT} | |
148 | # We need PTRACE_SETOPTIONS and PTRACE_GETEVENTMSG, but they are not | |
149 | # defined in older versions of glibc. | |
150 | if ! grep '^const _PTRACE_SETOPTIONS' ${OUT} > /dev/null 2>&1; then | |
151 | echo "const _PTRACE_SETOPTIONS = 0x4200" >> ${OUT} | |
152 | fi | |
153 | if ! grep '^const PTRACE_O_TRACESYSGOOD' ${OUT} > /dev/null 2>&1; then | |
154 | echo "const PTRACE_O_TRACESYSGOOD = 0x1" >> ${OUT} | |
155 | fi | |
156 | if ! grep '^const PTRACE_O_TRACEFORK' ${OUT} > /dev/null 2>&1; then | |
157 | echo "const PTRACE_O_TRACEFORK = 0x2" >> ${OUT} | |
158 | fi | |
159 | if ! grep '^const PTRACE_O_TRACEVFORK' ${OUT} > /dev/null 2>&1; then | |
160 | echo "const PTRACE_O_TRACEVFORK = 0x4" >> ${OUT} | |
161 | fi | |
162 | if ! grep '^const PTRACE_O_TRACECLONE' ${OUT} > /dev/null 2>&1; then | |
163 | echo "const PTRACE_O_TRACECLONE = 0x8" >> ${OUT} | |
164 | fi | |
165 | if ! grep '^const PTRACE_O_TRACEEXEC' ${OUT} > /dev/null 2>&1; then | |
166 | echo "const PTRACE_O_TRACEEXEC = 0x10" >> ${OUT} | |
167 | fi | |
168 | if ! grep '^const PTRACE_O_TRACEVFORKDONE' ${OUT} > /dev/null 2>&1; then | |
169 | echo "const PTRACE_O_TRACEVFORKDONE = 0x20" >> ${OUT} | |
170 | fi | |
171 | if ! grep '^const PTRACE_O_TRACEEXIT' ${OUT} > /dev/null 2>&1; then | |
172 | echo "const PTRACE_O_TRACEEXIT = 0x40" >> ${OUT} | |
173 | fi | |
174 | if ! grep '^const PTRACE_O_MASK' ${OUT} > /dev/null 2>&1; then | |
175 | echo "const PTRACE_O_MASK = 0x7f" >> ${OUT} | |
176 | fi | |
177 | if ! grep '^const _PTRACE_GETEVENTMSG' ${OUT} > /dev/null 2>&1; then | |
178 | echo "const _PTRACE_GETEVENTMSG = 0x4201" >> ${OUT} | |
179 | fi | |
180 | if ! grep '^const PTRACE_EVENT_FORK' ${OUT} > /dev/null 2>&1; then | |
181 | echo "const PTRACE_EVENT_FORK = 1" >> ${OUT} | |
182 | fi | |
183 | if ! grep '^const PTRACE_EVENT_VFORK' ${OUT} > /dev/null 2>&1; then | |
184 | echo "const PTRACE_EVENT_VFORK = 2" >> ${OUT} | |
185 | fi | |
186 | if ! grep '^const PTRACE_EVENT_CLONE' ${OUT} > /dev/null 2>&1; then | |
187 | echo "const PTRACE_EVENT_CLONE = 3" >> ${OUT} | |
188 | fi | |
189 | if ! grep '^const PTRACE_EVENT_EXEC' ${OUT} > /dev/null 2>&1; then | |
190 | echo "const PTRACE_EVENT_EXEC = 4" >> ${OUT} | |
191 | fi | |
192 | if ! grep '^const PTRACE_EVENT_VFORK_DONE' ${OUT} > /dev/null 2>&1; then | |
193 | echo "const PTRACE_EVENT_VFORK_DONE = 5" >> ${OUT} | |
194 | fi | |
195 | if ! grep '^const PTRACE_EVENT_EXIT' ${OUT} > /dev/null 2>&1; then | |
196 | echo "const PTRACE_EVENT_EXIT = 6" >> ${OUT} | |
197 | fi | |
198 | ||
199 | # The registers returned by PTRACE_GETREGS. This is probably | |
200 | # GNU/Linux specific. | |
201 | regs=`grep '^type _user_regs_struct struct' gen-sysinfo.go` | |
202 | if test "$regs" != ""; then | |
203 | regs=`echo $regs | sed -e 's/type _user_regs_struct struct //' -e 's/[{}]//g'` | |
204 | regs=`echo $regs | sed -e s'/^ *//'` | |
205 | nregs= | |
206 | while test -n "$regs"; do | |
207 | field=`echo $regs | sed -e 's/^\([^;]*\);.*$/\1/'` | |
208 | regs=`echo $regs | sed -e 's/^[^;]*; *\(.*\)$/\1/'` | |
209 | # Capitalize the first character of the field. | |
210 | f=`echo $field | sed -e 's/^\(.\).*$/\1/'` | |
211 | r=`echo $field | sed -e 's/^.\(.*\)$/\1/'` | |
212 | f=`echo $f | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` | |
213 | field="$f$r" | |
214 | nregs="$nregs $field;" | |
215 | done | |
216 | echo "type PtraceRegs struct {$nregs }" >> ${OUT} | |
217 | fi | |
218 | ||
219 | # Some basic types. | |
220 | echo 'type Size_t _size_t' >> ${OUT} | |
221 | echo "type Ssize_t _ssize_t" >> ${OUT} | |
222 | if grep '^const _HAVE_OFF64_T = ' gen-sysinfo.go > /dev/null 2>&1; then | |
223 | echo "type Offset_t _off64_t" >> ${OUT} | |
224 | else | |
225 | echo "type Offset_t _off_t" >> ${OUT} | |
226 | fi | |
227 | echo "type Mode_t _mode_t" >> ${OUT} | |
228 | echo "type Pid_t _pid_t" >> ${OUT} | |
229 | echo "type Uid_t _uid_t" >> ${OUT} | |
230 | echo "type Gid_t _gid_t" >> ${OUT} | |
231 | echo "type Socklen_t _socklen_t" >> ${OUT} | |
232 | ||
233 | # The long type, needed because that is the type that ptrace returns. | |
234 | sizeof_long=`grep '^const ___SIZEOF_LONG__ = ' gen-sysinfo.go | sed -e 's/.*= //'` | |
235 | if test "$sizeof_long" = "4"; then | |
236 | echo "type _C_long int32" >> ${OUT} | |
237 | elif test "$sizeof_long" = "8"; then | |
238 | echo "type _C_long int64" >> ${OUT} | |
239 | else | |
240 | echo 1>&2 "mksysinfo.sh: could not determine size of long (got $sizeof_long)" | |
241 | exit 1 | |
242 | fi | |
243 | ||
244 | # The time structures need special handling: we need to name the | |
245 | # types, so that we can cast integers to the right types when | |
246 | # assigning to the structures. | |
247 | timeval=`grep '^type _timeval ' gen-sysinfo.go` | |
248 | timeval_sec=`echo $timeval | sed -n -e 's/^.*tv_sec \([^ ]*\);.*$/\1/p'` | |
249 | timeval_usec=`echo $timeval | sed -n -e 's/^.*tv_usec \([^ ]*\);.*$/\1/p'` | |
250 | echo "type Timeval_sec_t $timeval_sec" >> ${OUT} | |
251 | echo "type Timeval_usec_t $timeval_usec" >> ${OUT} | |
252 | echo $timeval | \ | |
253 | sed -e 's/type _timeval /type Timeval /' \ | |
254 | -e 's/tv_sec *[a-zA-Z0-9_]*/Sec Timeval_sec_t/' \ | |
255 | -e 's/tv_usec *[a-zA-Z0-9_]*/Usec Timeval_usec_t/' >> ${OUT} | |
256 | timespec=`grep '^type _timespec ' gen-sysinfo.go` | |
257 | timespec_sec=`echo $timespec | sed -n -e 's/^.*tv_sec \([^ ]*\);.*$/\1/p'` | |
258 | timespec_nsec=`echo $timespec | sed -n -e 's/^.*tv_nsec \([^ ]*\);.*$/\1/p'` | |
259 | echo "type Timespec_sec_t $timespec_sec" >> ${OUT} | |
260 | echo "type Timespec_nsec_t $timespec_nsec" >> ${OUT} | |
261 | echo $timespec | \ | |
262 | sed -e 's/^type _timespec /type Timespec /' \ | |
263 | -e 's/tv_sec *[a-zA-Z0-9_]*/Sec Timespec_sec_t/' \ | |
264 | -e 's/tv_nsec *[a-zA-Z0-9_]*/Nsec Timespec_nsec_t/' >> ${OUT} | |
265 | ||
266 | # The stat type. | |
267 | grep 'type _stat ' gen-sysinfo.go | \ | |
268 | sed -e 's/type _stat/type Stat_t/' \ | |
269 | -e 's/st_dev/Dev/' \ | |
270 | -e 's/st_ino/Ino/' \ | |
271 | -e 's/st_nlink/Nlink/' \ | |
272 | -e 's/st_mode/Mode/' \ | |
273 | -e 's/st_uid/Uid/' \ | |
274 | -e 's/st_gid/Gid/' \ | |
275 | -e 's/st_rdev/Rdev/' \ | |
276 | -e 's/st_size/Size/' \ | |
277 | -e 's/st_blksize/Blksize/' \ | |
278 | -e 's/st_blocks/Blocks/' \ | |
279 | -e 's/st_atim/Atime/' \ | |
280 | -e 's/st_mtim/Mtime/' \ | |
281 | -e 's/st_ctim/Ctime/' \ | |
282 | -e 's/\([^a-zA-Z0-9_]\)_timeval\([^a-zA-Z0-9_]\)/\1Timeval\2/g' \ | |
283 | -e 's/\([^a-zA-Z0-9_]\)_timespec\([^a-zA-Z0-9_]\)/\1Timespec\2/g' \ | |
284 | >> ${OUT} | |
285 | ||
286 | # The directory searching types. | |
287 | grep '^type _dirent ' gen-sysinfo.go | \ | |
288 | sed -e 's/type _dirent/type Dirent/' \ | |
289 | -e 's/d_name/Name/' \ | |
290 | -e 's/]int8/]byte/' \ | |
291 | -e 's/d_ino/Ino/' \ | |
292 | -e 's/d_off/Off/' \ | |
293 | -e 's/d_reclen/Reclen/' \ | |
294 | -e 's/d_type/Type/' \ | |
295 | >> ${OUT} | |
296 | echo "type DIR _DIR" >> ${OUT} | |
297 | ||
298 | # The rusage struct. | |
299 | rusage=`grep '^type _rusage struct' gen-sysinfo.go` | |
300 | if test "$rusage" != ""; then | |
301 | rusage=`echo $rusage | sed -e 's/type _rusage struct //' -e 's/[{}]//g'` | |
302 | rusage=`echo $rusage | sed -e 's/^ *//'` | |
303 | nrusage= | |
304 | while test -n "$rusage"; do | |
305 | field=`echo $rusage | sed -e 's/^\([^;]*\);.*$/\1/'` | |
306 | rusage=`echo $rusage | sed -e 's/^[^;]*; *\(.*\)$/\1/'` | |
307 | # Drop the leading ru_, capitalize the next character. | |
308 | field=`echo $field | sed -e 's/^ru_//'` | |
309 | f=`echo $field | sed -e 's/^\(.\).*$/\1/'` | |
310 | r=`echo $field | sed -e 's/^.\(.*\)$/\1/'` | |
311 | f=`echo $f | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` | |
312 | # Fix _timeval and _timespec. | |
313 | r=`echo $r | sed -e s'/ _timeval$/ Timeval/'` | |
314 | r=`echo $r | sed -e s'/ _timespec$/ Timespec/'` | |
315 | field="$f$r" | |
316 | nrusage="$nrusage $field;" | |
317 | done | |
318 | echo "type Rusage struct {$nrusage }" >> ${OUT} | |
319 | fi | |
320 | ||
321 | # The utsname struct. | |
322 | grep '^type _utsname ' gen-sysinfo.go | \ | |
323 | sed -e 's/_utsname/Utsname/' \ | |
324 | -e 's/sysname/Sysname/' \ | |
325 | -e 's/nodename/Nodename/' \ | |
326 | -e 's/release/Release/' \ | |
327 | -e 's/version/Version/' \ | |
328 | -e 's/machine/Machine/' \ | |
329 | -e 's/domainname/Domainname/' \ | |
330 | >> ${OUT} | |
331 | ||
332 | mv -f ${OUT} sysinfo.go | |
333 | exit $? |