1#! /bin/sh - 2# 3# @(#)makesyscalls.sh 8.2 (Berkeley) 02/14/95 4 5set -e 6 7case $# in 8 2) ;; 9 *) echo "Usage: $0 config-file input-file" 1>&2 10 exit 1 11 ;; 12esac 13 14# source the config file. 15. $1 16 17# the config file sets the following variables: 18# sysnames the syscall names file 19# sysnumhdr the syscall numbers file 20# syssw the syscall switch file 21# sysarghdr the syscall argument struct definitions 22# compatopts those syscall types that are for 'compat' syscalls 23# switchname the name for the 'struct sysent' we define 24# namesname the name for the 'char *[]' we define 25# constprefix the prefix for the system call constants 26# 27# NOTE THAT THIS makesyscalls.sh DOES NOT SUPPORT 'LIBCOMPAT'. 28 29# tmp files: 30sysdcl="sysent.dcl" 31syscompat_pref="sysent." 32sysent="sysent.switch" 33 34syscompat_files="" 35for file in $compatopts; do 36 syscompat_files="$syscompat_files $syscompat_pref$file" 37done 38 39trap "rm $sysdcl $syscompat_files $sysent" 0 40 41# Awk program (must support nawk extensions) 42# Use "awk" at Berkeley, "nawk" or "gawk" elsewhere. 43awk=${AWK:-awk} 44 45# Does this awk have a "toupper" function? (i.e. is it GNU awk) 46isgawk=`$awk 'BEGIN { print toupper("true"); exit; }' 2>/dev/null` 47 48# If this awk does not define "toupper" then define our own. 49if [ "$isgawk" = TRUE ] ; then 50 # GNU awk provides it. 51 toupper= 52else 53 # Provide our own toupper() 54 toupper=' 55function toupper(str) { 56 _toupper_cmd = "echo "str" |tr a-z A-Z" 57 _toupper_cmd | getline _toupper_str; 58 close(_toupper_cmd); 59 return _toupper_str; 60}' 61fi 62 63# before handing it off to awk, make a few adjustments: 64# (1) insert spaces around {, }, (, ), *, and commas. 65# (2) get rid of any and all dollar signs (so that rcs id use safe) 66# 67# The awk script will deal with blank lines and lines that 68# start with the comment character (';'). 69 70sed -e ' 71s/\$//g 72:join 73 /\\$/{a\ 74 75 N 76 s/\\\n// 77 b join 78 } 792,${ 80 /^#/!s/\([{}()*,]\)/ \1 /g 81} 82' < $2 | $awk " 83$toupper 84BEGIN { 85 sysnames = \"$sysnames\" 86 sysnumhdr = \"$sysnumhdr\" 87 sysarghdr = \"$sysarghdr\" 88 switchname = \"$switchname\" 89 namesname = \"$namesname\" 90 constprefix = \"$constprefix\" 91 92 sysdcl = \"$sysdcl\" 93 syscompat_pref = \"$syscompat_pref\" 94 sysent = \"$sysent\" 95 infile = \"$2\" 96 97 compatopts = \"$compatopts\" 98 "' 99 100 printf "/*\n * System call switch table.\n *\n" > sysdcl 101 printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysdcl 102 103 ncompat = split(compatopts,compat) 104 for (i = 1; i <= ncompat; i++) { 105 compat_upper[i] = toupper(compat[i]) 106 compat_file[i] = sprintf("%s%s", syscompat_pref, compat[i]) 107 108 printf "\n#ifdef %s\n", compat_upper[i] > compat_file[i] 109 printf "#define %s(func) __CONCAT(%s_,func)\n\n", \ 110 compat[i], compat[i] > compat_file[i] 111 } 112 113 printf "/*\n * System call names.\n *\n" > sysnames 114 printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnames 115 116 printf "/*\n * System call numbers.\n *\n" > sysnumhdr 117 printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnumhdr 118 119 printf "/*\n * System call argument lists.\n *\n" > sysarghdr 120 printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysarghdr 121} 122NR == 1 { 123 printf " * created from%s\n */\n\n", $0 > sysdcl 124 125 printf "#define\ts(type)\tsizeof(type)\n\n" > sysent 126 printf "struct sysent %s[] = {\n",switchname > sysent 127 128 printf " * created from%s\n */\n\n", $0 > sysnames 129 printf "char *%s[] = {\n",namesname > sysnames 130 131 printf " * created from%s\n */\n\n", $0 > sysnumhdr 132 133 printf " * created from%s\n */\n\n", $0 > sysarghdr 134 printf "#define\tsyscallarg(x)\tunion { x datum; register_t pad; }\n" \ 135 > sysarghdr 136 next 137} 138NF == 0 || $1 ~ /^;/ { 139 next 140} 141$1 ~ /^#[ ]*include/ { 142 print > sysdcl 143 next 144} 145$1 ~ /^#[ ]*if/ { 146 print > sysent 147 print > sysdcl 148 for (i = 1; i <= ncompat; i++) 149 print > compat_file[i] 150 print > sysnames 151 savesyscall = syscall 152 next 153} 154$1 ~ /^#[ ]*else/ { 155 print > sysent 156 print > sysdcl 157 for (i = 1; i <= ncompat; i++) 158 print > compat_file[i] 159 print > sysnames 160 syscall = savesyscall 161 next 162} 163$1 ~ /^#/ { 164 print > sysent 165 print > sysdcl 166 for (i = 1; i <= ncompat; i++) 167 print > compat_file[i] 168 print > sysnames 169 next 170} 171syscall != $1 { 172 printf "%s: line %d: syscall number out of sync at %d\n", \ 173 infile, NR, syscall 174 printf "line is:\n" 175 print 176 exit 1 177} 178function parserr(was, wanted) { 179 printf "%s: line %d: unexpected %s (expected %s)\n", \ 180 infile, NR, was, wanted 181 exit 1 182} 183function parseline() { 184 f=3 # toss number and type 185 if ($NF != "}") { 186 funcalias=$NF 187 end=NF-1 188 } else { 189 funcalias="" 190 end=NF 191 } 192 if ($f != "{") 193 parserr($f, "{") 194 f++ 195 if ($end != "}") 196 parserr($end, "}") 197 end-- 198 if ($end != ";") 199 parserr($end, ";") 200 end-- 201 if ($end != ")") 202 parserr($end, ")") 203 end-- 204 205 f++ # toss return type 206 207 funcname=$f 208 if (funcalias == "") 209 funcalias=funcname 210 f++ 211 212 if ($f != "(") 213 parserr($f, ")") 214 f++ 215 216 argc= 0; 217 if (f == end) { 218 if ($f != "void") 219 parserr($f, "argument definition") 220 return 221 } 222 223 while (f <= end) { 224 argc++ 225 argtype[argc]="" 226 oldf="" 227 while (f < end && $(f+1) != ",") { 228 if (argtype[argc] != "" && oldf != "*") 229 argtype[argc] = argtype[argc]" "; 230 argtype[argc] = argtype[argc]$f; 231 oldf = $f; 232 f++ 233 } 234 if (argtype[argc] == "") 235 parserr($f, "argument definition") 236 argname[argc]=$f; 237 f += 2; # skip name, and any comma 238 } 239} 240function putent(nodefs, declfile, compatwrap) { 241 # output syscall declaration for switch table 242 if (compatwrap == "") 243 printf("int\t%s();\n", funcname) > declfile 244 else 245 printf("int\t%s(%s)();\n", compatwrap, funcname) > declfile 246 247 # output syscall switch entry 248# printf("\t{ { %d", argc) > sysent 249# for (i = 1; i <= argc; i++) { 250# if (i == 5) # wrap the line 251# printf(",\n\t ") > sysent 252# else 253# printf(", ") > sysent 254# printf("s(%s)", argtypenospc[i]) > sysent 255# } 256 printf("\t{ %d, ", argc) > sysent 257 if (argc == 0) 258 printf("0") > sysent 259 else if (compatwrap == "") 260 printf("s(struct %s_args)", funcname) > sysent 261 else 262 printf("s(struct %s_%s_args)", compatwrap, funcname) > sysent 263 if (compatwrap == "") 264 wfn = sprintf("%s", funcname); 265 else 266 wfn = sprintf("%s(%s)", compatwrap, funcname); 267 printf(",\n\t %s },", wfn) > sysent 268 for (i = 0; i < (33 - length(wfn)) / 8; i++) 269 printf("\t") > sysent 270 if (compatwrap == "") 271 printf("/* %d = %s */\n", syscall, funcalias) > sysent 272 else 273 printf("/* %d = %s %s */\n", syscall, compatwrap, 274 funcalias) > sysent 275 276 # output syscall name for names table 277 if (compatwrap == "") 278 printf("\t\"%s\",\t\t\t/* %d = %s */\n", funcalias, syscall, 279 funcalias) > sysnames 280 else 281 printf("\t\"%s_%s\",\t/* %d = %s %s */\n", compatwrap, 282 funcalias, syscall, compatwrap, funcalias) > sysnames 283 284 # output syscall number of header, if appropriate 285 if (nodefs == "" || nodefs == "NOARGS") 286 printf("#define\t%s%s\t%d\n", constprefix, funcalias, 287 syscall) > sysnumhdr 288 else if (nodefs != "NODEF") 289 printf("\t\t\t\t/* %d is %s %s */\n", syscall, 290 compatwrap, funcalias) > sysnumhdr 291 292 # output syscall argument structure, if it has arguments 293 if (argc != 0 && nodefs != "NOARGS") { 294 if (compatwrap == "") 295 printf("\nstruct %s_args {\n", funcname) > sysarghdr 296 else 297 printf("\nstruct %s_%s_args {\n", compatwrap, 298 funcname) > sysarghdr 299 for (i = 1; i <= argc; i++) 300 printf("\tsyscallarg(%s) %s;\n", argtype[i], 301 argname[i]) > sysarghdr 302 printf("};\n") > sysarghdr 303 } 304} 305$2 == "STD" { 306 parseline() 307 putent("", sysdcl, "") 308 syscall++ 309 next 310} 311$2 == "NODEF" || $2 == "NOARGS" { 312 parseline() 313 putent($2, sysdcl, "") 314 syscall++ 315 next 316} 317$2 == "OBSOL" || $2 == "UNIMPL" { 318 if ($2 == "OBSOL") 319 comment="obsolete" 320 else 321 comment="unimplemented" 322 for (i = 3; i <= NF; i++) 323 comment=comment " " $i 324 325 printf("\t{ 0, 0,\n\t nosys },\t\t\t\t/* %d = %s */\n", \ 326 syscall, comment) > sysent 327 printf("\t\"#%d (%s)\",\t\t/* %d = %s */\n", \ 328 syscall, comment, syscall, comment) > sysnames 329 if ($2 != "UNIMPL") 330 printf("\t\t\t\t/* %d is %s */\n", syscall, comment) > sysnumhdr 331 syscall++ 332 next 333} 334{ 335 for (i = 1; i <= ncompat; i++) { 336 if ($2 == compat_upper[i]) { 337 parseline(); 338 putent("COMMENT", compat_file[i], compat[i]) 339 syscall++ 340 next 341 } 342 } 343 printf "%s: line %d: unrecognized keyword %s\n", infile, NR, $2 344 exit 1 345} 346END { 347 printf "\n#undef\tsyscallarg\n" > sysarghdr 348 349 for (i = 1; i <= ncompat; i++) { 350 printf("\n#else /* %s */\n", compat_upper[i]) > compat_file[i] 351 printf("#define %s(func) nosys\n", compat[i]) > \ 352 compat_file[i] 353 printf("#endif /* %s */\n\n", compat_upper[i]) > compat_file[i] 354 } 355 356 printf("};\n\n") > sysent 357 printf("int\tn%s= sizeof(%s) / sizeof(%s[0]);\n", switchname, 358 switchname, switchname) > sysent 359 360 printf("};\n") > sysnames 361} ' 362 363cat $sysdcl $syscompat_files $sysent > $syssw 364 365#chmod 444 $sysnames $syshdr $syssw 366