Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 422c160db1 | |||
| b74ac99bbb | |||
| d86a290588 | |||
| fddf1f133e | |||
| ae34580f0c |
17
README.md
Normal file
17
README.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Build MINIX/arm with clang
|
||||
|
||||
It is now possible to build a full minix distribution for BeaglBone White/Black and BeagleBoardxM using clang instead of GCC.
|
||||
|
||||
This also add support to run the Kuya tests on ARM, which was not possible when GCC was used, because of problems in the C++ exception handling.
|
||||
|
||||
## Known Bugs
|
||||
|
||||
The following tests still fails:
|
||||
1. 53: Division by zero does not trigger exceptions
|
||||
2. 75: ru.tv_secs can't be zero (and is zero)
|
||||
3. 85: hangs
|
||||
4. isofs: Fails because of an out of memory condition
|
||||
5. vnd: crash
|
||||
6. Running two times the kyua tests in a row, without rebooting in between will lead to a mostly failed second run because of copy-on-write errors.
|
||||
|
||||
|
||||
@@ -81,6 +81,9 @@
|
||||
./usr/include/arm/vm.h minix-comp
|
||||
./usr/include/arm/vmparam.h minix-comp
|
||||
./usr/include/arm/wchar_limits.h minix-comp
|
||||
./usr/include/clang-3.6/arm_acle.h minix-comp llvm,llvmcmds
|
||||
./usr/include/clang-3.6/arm_neon.h minix-comp llvm,llvmcmds
|
||||
./usr/include/clang-3.6/stdatomic.h minix-comp llvm,llvmcmds
|
||||
./usr/include/evbarm minix-comp
|
||||
./usr/include/evbarm/disklabel.h minix-comp
|
||||
./usr/include/evbarm/intr.h minix-comp
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
#
|
||||
# Sorted using sort_set.pl in releasetools.
|
||||
# to add an entry simply add it at the end of the
|
||||
# file and run
|
||||
# ../../../../releasetools/sort_set.pl < mi > out
|
||||
# mv out mi
|
||||
#
|
||||
./usr/tests/minix-posix/test_arm_segfault minix-tests
|
||||
./usr/tests/minix-posix/test_arm_unaligned minix-tests
|
||||
@@ -3816,6 +3816,7 @@ class ARMTargetInfo : public TargetInfo {
|
||||
SizeType = UnsignedInt;
|
||||
|
||||
switch (T.getOS()) {
|
||||
case llvm::Triple::Minix:
|
||||
case llvm::Triple::NetBSD:
|
||||
WCharType = SignedInt;
|
||||
break;
|
||||
|
||||
@@ -275,7 +275,7 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
|
||||
// FIXME: Thumb should just be another -target-feaure, not in the triple.
|
||||
#if defined(__minix) || 1
|
||||
// Minix/ARM-specific force to ARMv7 and EABI.
|
||||
StringRef Suffix = "v7";
|
||||
StringRef Suffix = "v7a";
|
||||
Triple.setEnvironment(llvm::Triple::EABI);
|
||||
#else
|
||||
StringRef Suffix = Triple.isOSBinFormatMachO()
|
||||
|
||||
@@ -665,6 +665,10 @@ StringRef tools::arm::getARMFloatABI(const Driver &D, const ArgList &Args,
|
||||
}
|
||||
break;
|
||||
|
||||
case llvm::Triple::Minix:
|
||||
FloatABI = "softfp";
|
||||
break;
|
||||
|
||||
default:
|
||||
switch(Triple.getEnvironment()) {
|
||||
case llvm::Triple::GNUEABIHF:
|
||||
@@ -796,6 +800,9 @@ void Clang::AddARMTargetArgs(const ArgList &Args,
|
||||
ABIName = "aapcs";
|
||||
break;
|
||||
default:
|
||||
if (Triple.getOS() == llvm::Triple::Minix)
|
||||
ABIName = "apcs-gnu";
|
||||
|
||||
if (Triple.getOS() == llvm::Triple::NetBSD)
|
||||
ABIName = "apcs-gnu";
|
||||
else
|
||||
@@ -7733,6 +7740,11 @@ void minix::Link::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
// Many NetBSD architectures support more than one ABI.
|
||||
// Determine the correct emulation for ld.
|
||||
switch (getToolChain().getArch()) {
|
||||
case llvm::Triple::arm:
|
||||
case llvm::Triple::thumb:
|
||||
CmdArgs.push_back("-m");
|
||||
CmdArgs.push_back("armelf_minix");
|
||||
break;
|
||||
case llvm::Triple::x86:
|
||||
CmdArgs.push_back("-m");
|
||||
CmdArgs.push_back("elf_i386_minix");
|
||||
|
||||
@@ -638,6 +638,8 @@ llvm::Optional<ProgramStateRef> MallocChecker::performKernelMalloc(
|
||||
if (!KernelZeroFlagVal.hasValue()) {
|
||||
if (OS == llvm::Triple::FreeBSD)
|
||||
KernelZeroFlagVal = 0x0100;
|
||||
else if (OS == llvm::Triple::Minix)
|
||||
KernelZeroFlagVal = 0x0002;
|
||||
else if (OS == llvm::Triple::NetBSD)
|
||||
KernelZeroFlagVal = 0x0002;
|
||||
else if (OS == llvm::Triple::OpenBSD)
|
||||
|
||||
@@ -1074,6 +1074,8 @@ const char *Triple::getARMCPUForArch(StringRef MArch) const {
|
||||
// supported by LLVM.
|
||||
// FIXME: Should warn once that we're falling back.
|
||||
switch (getOS()) {
|
||||
case llvm::Triple::Minix:
|
||||
return "cortex-a8";
|
||||
case llvm::Triple::NetBSD:
|
||||
switch (getEnvironment()) {
|
||||
case llvm::Triple::GNUEABIHF:
|
||||
|
||||
@@ -59,6 +59,7 @@ ARMELFMCAsmInfo::ARMELFMCAsmInfo(StringRef TT) {
|
||||
|
||||
// Exceptions handling
|
||||
switch (TheTriple.getOS()) {
|
||||
case Triple::Minix:
|
||||
case Triple::NetBSD:
|
||||
ExceptionsType = ExceptionHandling::DwarfCFI;
|
||||
break;
|
||||
|
||||
@@ -43,9 +43,12 @@ INCS+= ieeefp.h
|
||||
INCSDIR= /usr/include
|
||||
|
||||
.if defined(__MINIX)
|
||||
# RPC is not compiled in the libc. This include also needs
|
||||
# rpcgen, which can be compiled if needed.
|
||||
SUBDIR+= ../minix/include
|
||||
.endif # defined(__MINIX)
|
||||
.else
|
||||
SUBDIR= rpc
|
||||
.endif # defined(__MINIX)
|
||||
SUBDIR+= ../common/include/prop
|
||||
SUBDIR+= ../common/include/ppath
|
||||
|
||||
|
||||
@@ -91,7 +91,11 @@ SUBDIR+= pkgconfig
|
||||
.include "${.CURDIR}/regex/Makefile.inc"
|
||||
.endif
|
||||
.include "${.CURDIR}/resolv/Makefile.inc"
|
||||
.if defined(__MINIX)
|
||||
# RPC needs pollts() and a reserved port allocator.
|
||||
.else
|
||||
.include "${.CURDIR}/rpc/Makefile.inc"
|
||||
.endif # defined(__MINIX)
|
||||
.include "${.CURDIR}/ssp/Makefile.inc"
|
||||
.include "${.CURDIR}/stdio/Makefile.inc"
|
||||
.include "${.CURDIR}/stdlib/Makefile.inc"
|
||||
|
||||
@@ -59,9 +59,6 @@ __RCSID("$NetBSD: clnt_generic.c,v 1.33 2014/05/28 14:45:19 christos Exp $");
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(__minix)
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#include "svc_fdset.h"
|
||||
#include "rpc_internal.h"
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
K(GRAVE_ACCENT) = { '\'', '"', A('\''),A('\''),A('"'), C('@') },
|
||||
K(COMMA) = { ',', '<', A(','), A(','), A('<'), C('@') },
|
||||
K(PERIOD) = { '.', '>', A('.'), A('.'), A('>'), C('@') },
|
||||
K(SLASH) = { ';', ':', A(';'), A(';'), A(':'), C('@') },
|
||||
K(SLASH) = { 59, 58, A(59), A(58), A(59), C('@') },
|
||||
K(CAPS_LOCK) = { CALOCK, CALOCK, CALOCK, CALOCK, CALOCK, CALOCK },
|
||||
K(F1) = { F1, SF1, AF1, AF1, ASF1, CF1 },
|
||||
K(F2) = { F2, SF2, AF2, AF2, ASF2, CF2 },
|
||||
@@ -94,11 +94,10 @@
|
||||
K(KP_8) = { NUP, '8', AUP, AUP, A('8'), CUP },
|
||||
K(KP_9) = { NPGUP, '9', APGUP, APGUP, A('9'), CPGUP },
|
||||
K(KP_0) = { NINSRT, '0', AINSRT, AINSRT, A('0'), CINSRT },
|
||||
K(KP_PERIOD) = { NDEL, ',', A(DEL), A(DEL), A(','), DEL },
|
||||
K(KP_PERIOD) = { NDEL, '.', A(DEL), A(DEL), A('.'), DEL },
|
||||
K(EUROPE_2) = { '\\', '|', A('\\'),A('|'), A('\\'),C('@') },
|
||||
K(APPLICATION) = { C('M'), C('M'), CA('M'),CA('M'),CA('M'),C('J') },
|
||||
K(I10L_1) = { '/', '?', A('/'), A('/'), A('?'), C('@') },
|
||||
K(EQUAL_SIGN) = { '.', '.', 0, 0, 0, 0 },
|
||||
K(KP_EQUAL) = { '?', 0, 0, 0, 0, 0 },
|
||||
K(SYSREQ) = { C('M'), C('M'), CA('M'),CA('M'),CA('M'),C('J') },
|
||||
K(LEFT_CTRL) = { LCTRL, LCTRL, LCTRL, LCTRL, LCTRL, LCTRL },
|
||||
K(LEFT_SHIFT) = { LSHIFT, LSHIFT, LSHIFT, LSHIFT, LSHIFT, LSHIFT },
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "fs.h"
|
||||
#include "inode.h"
|
||||
#include "clean.h"
|
||||
#include <assert.h>
|
||||
|
||||
/*===========================================================================*
|
||||
* fs_sync *
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "fs.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include "inode.h"
|
||||
|
||||
@@ -5,11 +5,6 @@ PROG= kernel
|
||||
BINDIR= /usr/sbin
|
||||
MAN=
|
||||
|
||||
.if ${MACHINE_ARCH} == "earm" && ${MKLLVM:Uno} == "yes"
|
||||
# BJG - problems with optimisation of the kernel by llvm
|
||||
DBG=-O0
|
||||
.endif
|
||||
|
||||
.include "arch/${MACHINE_ARCH}/Makefile.inc"
|
||||
|
||||
SRCS+= clock.c cpulocals.c interrupt.c main.c proc.c system.c \
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <machine/vm.h>
|
||||
#include <machine/signal.h>
|
||||
#include <arm/armreg.h>
|
||||
#include <arm/vfpreg.h>
|
||||
|
||||
#include <minix/u64.h>
|
||||
|
||||
@@ -26,16 +27,36 @@
|
||||
|
||||
void * k_stacks;
|
||||
|
||||
|
||||
#define VFP_COPROC 10
|
||||
#define VFP_COPROC2 11
|
||||
void fpu_init(void)
|
||||
{
|
||||
const char *model = NULL;
|
||||
uint32_t cpu_media_and_vfp_features[2];
|
||||
|
||||
const uint32_t cpacr_vfp = CPACR_CPn(VFP_COPROC);
|
||||
const uint32_t cpacr_vfp2 = CPACR_CPn(VFP_COPROC2);
|
||||
|
||||
/*
|
||||
* We first need to enable access to the coprocessors.
|
||||
*/
|
||||
uint32_t cpacr = armreg_cpacr_read();
|
||||
cpacr |= __SHIFTIN(CPACR_ALL, cpacr_vfp);
|
||||
cpacr |= __SHIFTIN(CPACR_ALL, cpacr_vfp2);
|
||||
armreg_cpacr_write(cpacr);
|
||||
|
||||
isb();
|
||||
|
||||
/* Enable vfp/neon unit */
|
||||
armreg_fpexc_write(VFP_FPEXC_EN);
|
||||
}
|
||||
|
||||
void save_local_fpu(struct proc *pr, int retain)
|
||||
{
|
||||
}
|
||||
|
||||
void save_fpu(struct proc *pr)
|
||||
void
|
||||
save_fpu(struct proc *pr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -109,36 +109,6 @@ static void pagefault( struct proc *pr,
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
data_abort(int is_nested, struct proc *pr, reg_t *saved_lr,
|
||||
struct ex_s *ep, u32_t dfar, u32_t dfsr)
|
||||
{
|
||||
/* Extract fault status bit [0:3, 10] from DFSR */
|
||||
u32_t fs = dfsr & 0x0F;
|
||||
fs |= ((dfsr >> 6) & 0x10);
|
||||
|
||||
/* Translation and permission faults are handled as pagefaults. */
|
||||
if (is_trans_fault(fs) || is_perm_fault(fs)) {
|
||||
pagefault(pr, saved_lr, is_nested, dfar, dfsr);
|
||||
} else if (!is_nested) {
|
||||
/* A user process caused some other kind of data abort. */
|
||||
int signum = SIGSEGV;
|
||||
|
||||
if (is_align_fault(fs)) {
|
||||
signum = SIGBUS;
|
||||
} else {
|
||||
printf("KERNEL: unknown data abort by proc %d sending "
|
||||
"SIGSEGV (dfar=0x%lx dfsr=0x%lx fs=0x%lx)\n",
|
||||
proc_nr(pr), dfar, dfsr, fs);
|
||||
}
|
||||
cause_sig(proc_nr(pr), signum);
|
||||
} else { /* is_nested */
|
||||
printf("KERNEL: inkernel data abort - disaster (dfar=0x%lx "
|
||||
"dfsr=0x%lx fs=0x%lx)\n", dfar, dfsr, fs);
|
||||
inkernel_disaster(pr, saved_lr, ep, is_nested);
|
||||
}
|
||||
}
|
||||
|
||||
static void inkernel_disaster(struct proc *saved_proc,
|
||||
reg_t *saved_lr, struct ex_s *ep,
|
||||
int is_nested)
|
||||
@@ -201,7 +171,7 @@ void exception_handler(int is_nested, reg_t *saved_lr, int vector)
|
||||
}
|
||||
|
||||
if (vector == DATA_ABORT_VECTOR) {
|
||||
data_abort(is_nested, saved_proc, saved_lr, ep, read_dfar(), read_dfsr());
|
||||
pagefault(saved_proc, saved_lr, is_nested, read_dfar(), read_dfsr());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,16 +21,6 @@
|
||||
#define INTERRUPT_VECTOR 6
|
||||
#define FAST_INTERRUPT_VECTOR 7
|
||||
|
||||
/* Data abort helper */
|
||||
#define is_align_fault(fault_status) \
|
||||
((fault_status) == FAULT_ALIGN_0)
|
||||
|
||||
#define is_trans_fault(fault_status) \
|
||||
(((fault_status) == FAULT_TRANS_S) || ((fault_status) == FAULT_TRANS_P))
|
||||
|
||||
#define is_perm_fault(fault_status) \
|
||||
(((fault_status) == FAULT_PERM_S) || ((fault_status) == FAULT_PERM_P))
|
||||
|
||||
/*
|
||||
* defines how many bytes are reserved at the top of the kernel stack for global
|
||||
* information like currently scheduled process or current cpu id
|
||||
|
||||
@@ -35,11 +35,9 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/poll.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/poll.h>
|
||||
#include <errno.h>
|
||||
|
||||
int
|
||||
poll(struct pollfd *p, nfds_t nfds, int timout)
|
||||
@@ -102,28 +100,3 @@ poll(struct pollfd *p, nfds_t nfds, int timout)
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
pollts(struct pollfd * __restrict fds, nfds_t nfds, const struct timespec * __restrict ts,
|
||||
const sigset_t * __restrict sigmask)
|
||||
{
|
||||
sigset_t oldmask;
|
||||
int timeout, rval;
|
||||
|
||||
if (NULL != sigmask) {
|
||||
sigprocmask(SIG_SETMASK, sigmask, &oldmask);
|
||||
}
|
||||
|
||||
if (NULL != ts) {
|
||||
timeout = ts->tv_sec * 1000 + ts->tv_nsec / 1000;
|
||||
rval = poll(fds, nfds, timeout);
|
||||
} else {
|
||||
rval = poll(fds, nfds, INFTIM);
|
||||
}
|
||||
|
||||
if (NULL != sigmask) {
|
||||
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
@@ -876,6 +876,11 @@ When exiting MINIX running under DOS the Boot Monitor's
|
||||
.B exit
|
||||
command will return you to the DOS prompt. The Boot Monitor and MINIX
|
||||
are together just a pretty big DOS program as far DOS is concerned.
|
||||
.SH FILES
|
||||
.TP 12
|
||||
.B /usr/ast
|
||||
Honorary home directory of Andrew S. Tanenbaum. Doubles as the place where
|
||||
the default setup for a new user is found.
|
||||
.SH "SEE ALSO"
|
||||
.BR dosminix (8),
|
||||
.BR monitor (8),
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <minix/callnr.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/ds.h>
|
||||
#include <minix/type.h>
|
||||
#include <minix/endpoint.h>
|
||||
#include <minix/minlib.h>
|
||||
#include <minix/type.h>
|
||||
|
||||
@@ -8,10 +8,6 @@ SRCS= main.c alloc.c utility.c exit.c fork.c break.c \
|
||||
mem_anon.c mem_directphys.c mem_anon_contig.c mem_shared.c \
|
||||
mem_cache.c cache.c vfs.c mem_file.c fdref.c acl.c
|
||||
|
||||
.if ${MACHINE_ARCH} == "earm"
|
||||
LDFLAGS+= -T ${.CURDIR}/arch/${MACHINE_ARCH}/vm.lds
|
||||
.endif
|
||||
|
||||
.if ${MKPAE:Uno} != "no"
|
||||
CPPFLAGS+= -DPAE=1
|
||||
.endif
|
||||
|
||||
@@ -1,249 +0,0 @@
|
||||
/* Script for -z combreloc: combine and sort reloc sections */
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
|
||||
"elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x8000)); . = SEGMENT_START("text-segment", 0x8000);
|
||||
.interp : { *(.interp) }
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rel.dyn :
|
||||
{
|
||||
*(.rel.init)
|
||||
*(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
|
||||
*(.rel.fini)
|
||||
*(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
|
||||
*(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
|
||||
*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
|
||||
*(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
|
||||
*(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
|
||||
*(.rel.ctors)
|
||||
*(.rel.dtors)
|
||||
*(.rel.got)
|
||||
*(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
|
||||
PROVIDE_HIDDEN (__rel_iplt_start = .);
|
||||
*(.rel.iplt)
|
||||
PROVIDE_HIDDEN (__rel_iplt_end = .);
|
||||
PROVIDE_HIDDEN (__rela_iplt_start = .);
|
||||
PROVIDE_HIDDEN (__rela_iplt_end = .);
|
||||
}
|
||||
.rela.dyn :
|
||||
{
|
||||
*(.rela.init)
|
||||
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
|
||||
*(.rela.fini)
|
||||
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
|
||||
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
|
||||
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
|
||||
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
|
||||
*(.rela.ctors)
|
||||
*(.rela.dtors)
|
||||
*(.rela.got)
|
||||
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
|
||||
PROVIDE_HIDDEN (__rel_iplt_start = .);
|
||||
PROVIDE_HIDDEN (__rel_iplt_end = .);
|
||||
PROVIDE_HIDDEN (__rela_iplt_start = .);
|
||||
*(.rela.iplt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_end = .);
|
||||
}
|
||||
.rel.plt :
|
||||
{
|
||||
*(.rel.plt)
|
||||
}
|
||||
.rela.plt :
|
||||
{
|
||||
*(.rela.plt)
|
||||
}
|
||||
.init :
|
||||
{
|
||||
KEEP (*(.init))
|
||||
} =0
|
||||
.plt : { *(.plt) }
|
||||
.iplt : { *(.iplt) }
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.*_unlikely)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
*(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)
|
||||
} =0
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(.fini))
|
||||
} =0
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) }
|
||||
PROVIDE_HIDDEN (__exidx_start = .);
|
||||
.ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
|
||||
PROVIDE_HIDDEN (__exidx_end = .);
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) }
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
|
||||
.gcc_except_table.*) }
|
||||
/* These sections are generated by the Sun/Oracle C++ compiler. */
|
||||
.exception_ranges : ONLY_IF_RO { *(.exception_ranges
|
||||
.exception_ranges*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
/* XXX: align on page boundary */
|
||||
/* . = ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1));*/
|
||||
. = ALIGN(4096);
|
||||
/* Exception handling */
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
|
||||
/* Thread Local Storage sections */
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
KEEP (*(.fini_array))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
}
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
}
|
||||
/* XXX: no jcr, got, etc.
|
||||
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
.got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
|
||||
*/
|
||||
.data :
|
||||
{
|
||||
__data_start = . ;
|
||||
/* XXX: put pagetable data at beginning */
|
||||
pagetable.o(.data)
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
/* XXX: 16KB align */
|
||||
. = ALIGN(16384);
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
_edata = .; PROVIDE (edata = .);
|
||||
__bss_start = .;
|
||||
__bss_start__ = .;
|
||||
.bss :
|
||||
{
|
||||
/* XXX: put pagetable bss at beginning */
|
||||
pagetable.o(.bss)
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
/* Align here to ensure that the .bss section occupies space up to
|
||||
_end. Align after .bss to ensure correct alignment even if the
|
||||
.bss section disappears because there are no input sections.
|
||||
FIXME: Why do we need it? When there is no .bss section, we don't
|
||||
pad the .data section. */
|
||||
. = ALIGN(. != 0 ? 32 / 8 : 1);
|
||||
}
|
||||
_bss_end__ = . ; __bss_end__ = . ;
|
||||
. = ALIGN(32 / 8);
|
||||
. = ALIGN(32 / 8);
|
||||
__end__ = . ;
|
||||
_end = .; PROVIDE (end = .);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* DWARF 3 */
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
.stack 0x80000 :
|
||||
{
|
||||
_stack = .;
|
||||
*(.stack)
|
||||
}
|
||||
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }
|
||||
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
|
||||
}
|
||||
@@ -40,7 +40,7 @@ static struct pdm {
|
||||
u32_t val;
|
||||
phys_bytes phys;
|
||||
u32_t *page_directories;
|
||||
} pagedir_mappings[MAX_PAGEDIR_PDES];
|
||||
} pagedir_mappings[MAX_PAGEDIR_PDES] __aligned(ARCH_PAGEDIR_SIZE);
|
||||
|
||||
static multiboot_module_t *kern_mb_mod = NULL;
|
||||
static size_t kern_size = 0;
|
||||
@@ -80,7 +80,7 @@ int missing_sparedirs = SPAREPAGEDIRS;
|
||||
static struct {
|
||||
void *pagedir;
|
||||
phys_bytes phys;
|
||||
} sparepagedirs[SPAREPAGEDIRS];
|
||||
} sparepagedirs[SPAREPAGEDIRS] __aligned(ARCH_PAGEDIR_SIZE);
|
||||
|
||||
#define is_staticaddr(v) ((vir_bytes) (v) < VM_OWN_HEAPSTART)
|
||||
|
||||
@@ -109,7 +109,10 @@ static char static_sparepages[VM_PAGE_SIZE*STATIC_SPAREPAGES]
|
||||
__aligned(VM_PAGE_SIZE);
|
||||
|
||||
#if defined(__arm__)
|
||||
static char static_sparepagedirs[ARCH_PAGEDIR_SIZE*STATIC_SPAREPAGEDIRS + ARCH_PAGEDIR_SIZE] __aligned(ARCH_PAGEDIR_SIZE);
|
||||
/* We need one ARCH_PAGEDIR_SIZE extra to be able to ensure the physical
|
||||
* addresses are aligned on pagetables boundaries. Without this the MMU will
|
||||
* fail to parse properly the L1 pagetables. */
|
||||
static char static_sparepagedirs[ARCH_PAGEDIR_SIZE*(STATIC_SPAREPAGEDIRS+1)];
|
||||
#endif
|
||||
|
||||
void pt_assert(pt_t *pt)
|
||||
@@ -1091,9 +1094,6 @@ void pt_init(void)
|
||||
int s, r, p;
|
||||
phys_bytes phys;
|
||||
vir_bytes sparepages_mem;
|
||||
#if defined(__arm__)
|
||||
vir_bytes sparepagedirs_mem;
|
||||
#endif
|
||||
static u32_t currentpagedir[ARCH_VM_DIR_ENTRIES];
|
||||
int m = kernel_boot_info.kern_mod;
|
||||
#if defined(__i386__)
|
||||
@@ -1117,12 +1117,6 @@ void pt_init(void)
|
||||
sparepages_mem = (vir_bytes) static_sparepages;
|
||||
assert(!(sparepages_mem % VM_PAGE_SIZE));
|
||||
|
||||
#if defined(__arm__)
|
||||
/* Get ourselves spare pagedirs. */
|
||||
sparepagedirs_mem = (vir_bytes) static_sparepagedirs;
|
||||
assert(!(sparepagedirs_mem % ARCH_PAGEDIR_SIZE));
|
||||
#endif
|
||||
|
||||
/* Spare pages are used to allocate memory before VM has its own page
|
||||
* table that things (i.e. arbitrary physical memory) can be mapped into.
|
||||
* We get it by pre-allocating it in our bss (allocated and mapped in by
|
||||
@@ -1132,20 +1126,40 @@ void pt_init(void)
|
||||
#if defined(__arm__)
|
||||
missing_sparedirs = 0;
|
||||
assert(STATIC_SPAREPAGEDIRS <= SPAREPAGEDIRS);
|
||||
for(s = 0; s < SPAREPAGEDIRS; s++) {
|
||||
vir_bytes v = (sparepagedirs_mem + s*ARCH_PAGEDIR_SIZE);;
|
||||
phys_bytes ph;
|
||||
if((r=sys_umap(SELF, VM_D, (vir_bytes) v,
|
||||
ARCH_PAGEDIR_SIZE, &ph)) != OK)
|
||||
{
|
||||
phys_bytes sparepagedirs_phys_mem;
|
||||
uint32_t offset;
|
||||
|
||||
/* Get ourselves spare pagedirs. */
|
||||
vir_bytes sparepagedirs_mem = (vir_bytes) static_sparepagedirs;
|
||||
|
||||
if ((r = sys_umap(SELF, VM_D, sparepagedirs_mem,
|
||||
ARCH_PAGEDIR_SIZE * (STATIC_SPAREPAGEDIRS + 1),
|
||||
&sparepagedirs_phys_mem)) != OK) {
|
||||
panic("pt_init: sys_umap failed: %d", r);
|
||||
if(s >= STATIC_SPAREPAGEDIRS) {
|
||||
sparepagedirs[s].pagedir = NULL;
|
||||
missing_sparedirs++;
|
||||
continue;
|
||||
}
|
||||
sparepagedirs[s].pagedir = (void *) v;
|
||||
sparepagedirs[s].phys = ph;
|
||||
}
|
||||
}
|
||||
/* Align to ARCH_PAGEDIR_SIZE sparepagedirs_phys_mem &
|
||||
* sparepagedirs_mem. */
|
||||
offset = ARCH_PAGEDIR_SIZE -
|
||||
(sparepagedirs_phys_mem % ARCH_PAGEDIR_SIZE);
|
||||
sparepagedirs_phys_mem += offset;
|
||||
sparepagedirs_mem += offset;
|
||||
|
||||
for(s = 0; s < SPAREPAGEDIRS; s++) {
|
||||
vir_bytes v = (sparepagedirs_mem + s*ARCH_PAGEDIR_SIZE);
|
||||
phys_bytes ph = (sparepagedirs_phys_mem + s*ARCH_PAGEDIR_SIZE);
|
||||
#if 0
|
||||
printf("sparepagedirs[%d] pagedir %p phys %p\n", s, v, ph);
|
||||
#endif
|
||||
if(s >= STATIC_SPAREPAGEDIRS) {
|
||||
sparepagedirs[s].pagedir = NULL;
|
||||
missing_sparedirs++;
|
||||
continue;
|
||||
}
|
||||
sparepagedirs[s].pagedir = (void *) v;
|
||||
sparepagedirs[s].phys = ph;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!(spare_pagequeue = reservedqueue_new(SPAREPAGES, 1, 1, 0)))
|
||||
|
||||
@@ -126,8 +126,6 @@ PROGS+= test63 mod
|
||||
OBJS.${o} += common.o
|
||||
.endfor
|
||||
|
||||
.include "./arch/${MACHINE_ARCH}/Makefile.inc"
|
||||
|
||||
# LSC Make sure there is not leftover after a failed testrun
|
||||
clean: .PHONY .MAKE
|
||||
@rm -rf DIR*
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
PROGS+= test_arm_segfault
|
||||
PROGS+= test_arm_unaligned
|
||||
|
||||
.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}
|
||||
|
||||
test_arm_segfault.o : test_arm_segfault.S
|
||||
test_arm_unaligned.o : test_arm_unaligned.S
|
||||
@@ -1,16 +0,0 @@
|
||||
.text
|
||||
.global main
|
||||
main:
|
||||
push {lr}
|
||||
ldr r0, =0xDEADBEE0 /* Hopefully this is not mapped... */
|
||||
ldr r1, [r0]
|
||||
ldr r0, =0x01010100 /* In case we survived, try something else */
|
||||
ldr r1, [r0]
|
||||
|
||||
ldr r0, =msg
|
||||
bl puts
|
||||
|
||||
mov r0, #0 /* test should check for non-zero exit code / signal */
|
||||
pop {pc}
|
||||
msg:
|
||||
.ascii "ERROR - caused no segfault\n"
|
||||
@@ -1,26 +0,0 @@
|
||||
.text
|
||||
.global main
|
||||
main:
|
||||
push {lr}
|
||||
mov r0, sp
|
||||
|
||||
/* This should work */
|
||||
ldr r0, [sp]
|
||||
|
||||
/* Unalign it */
|
||||
add r0, #2
|
||||
|
||||
/* Try a non-word aligned word-load, this may work if SCTRL.A == 0 */
|
||||
ldr r1, [r0]
|
||||
|
||||
/* Load non-word aligned dword, should die even with SCTRL.A == 0 */
|
||||
ldrd r2, r3, [r0]
|
||||
|
||||
|
||||
ldr r0, =msg
|
||||
bl puts
|
||||
|
||||
mov r0, #0 /* test should check for non-zero exit code / signal */
|
||||
pop {pc}
|
||||
msg:
|
||||
.ascii "ERROR - caused no sigbus\n"
|
||||
@@ -264,7 +264,7 @@ main(int argc, char *argv[])
|
||||
/* Determine the size of the device if not specified as -b or proto. */
|
||||
maxblocks = sizeup(argv[optind]);
|
||||
if (bblocks != 0 && bblocks + fs_offset_blocks > maxblocks && !insertmode) {
|
||||
errx(4, "Given size -b %d exceeds device capacity(%d)\n", bblocks, maxblocks);
|
||||
errx(4, "Given size -b %d exeeds device capacity(%d)\n", bblocks, maxblocks);
|
||||
}
|
||||
|
||||
if (argc - optind == 1 && bblocks == 0) {
|
||||
|
||||
@@ -28,9 +28,6 @@ fi
|
||||
: ${IMG=minix_arm_sd.img}
|
||||
|
||||
# ARM definitions:
|
||||
: ${BUILDVARS=-V MKGCCCMDS=yes -V MKLLVM=no}
|
||||
# These BUILDVARS are for building with LLVM:
|
||||
#: ${BUILDVARS=-V MKLIBCXX=no -V MKKYUA=no -V MKATF=no -V MKLLVMCMDS=no}
|
||||
: ${FAT_SIZE=$(( 10*(2**20) / 512))} # This is in sectors
|
||||
|
||||
# Beagleboard-xm
|
||||
|
||||
@@ -82,11 +82,6 @@ SMP_FLAGS += -DCONFIG_MAX_CPUS=${CONFIG_MAX_CPUS}
|
||||
|
||||
CPPFLAGS+= ${SMP_FLAGS}
|
||||
|
||||
# Disabled unaligned accesses on ARM
|
||||
.if !empty(MACHINE_ARCH:Mearm*)
|
||||
CFLAGS+= -mno-unaligned-access
|
||||
.endif
|
||||
|
||||
__uname_s!= uname -s
|
||||
.if ${__uname_s:Uunknown} == "Minix"
|
||||
USETOOLS?= never
|
||||
@@ -120,6 +115,11 @@ USETOOLS?= never
|
||||
# LSC FIXME: RELEASEMACHINEDIR is set to evbarm, instead of evbearm-el
|
||||
.if !empty(MACHINE:Mevbarm*)
|
||||
RELEASEMACHINEDIR:= evbearm-el
|
||||
# LSC: Clang uses floating point instruction to vectorize some operation, even
|
||||
# at -O0, make sure it uses soft-float as the minix uKernel doesn't yet
|
||||
# save / restore the hardware fpu context on ARM.
|
||||
CFLAGS+= -mno-implicit-float -fno-vectorize
|
||||
MKSOFTFLOAT=yes
|
||||
.endif
|
||||
|
||||
.if ${HAVE_GCC:Dyes} == "yes" || \
|
||||
|
||||
@@ -617,11 +617,7 @@ pci_subclass_name(pcireg_t reg)
|
||||
subclassp++;
|
||||
}
|
||||
|
||||
if (subclassp) {
|
||||
return subclassp->name;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
return subclassp->name;
|
||||
}
|
||||
#endif /* defined(__minix) && defined(_PCI_SERVER) */
|
||||
|
||||
|
||||
22
sys/lib/libkern/arch/arm/Makefile.inc
Normal file
22
sys/lib/libkern/arch/arm/Makefile.inc
Normal file
@@ -0,0 +1,22 @@
|
||||
# $NetBSD: Makefile.inc,v 1.21 2014/01/29 23:37:18 joerg Exp $
|
||||
|
||||
SRCS+= byte_swap_2.S byte_swap_4.S
|
||||
SRCS+= ffs.S
|
||||
SRCS+= memcmp.S memcpy.S memset.S memmove.S strcmp.S strncmp.S
|
||||
|
||||
.if !empty(MACHINE_ARCH:Mearm*)
|
||||
SRCS+= unwind_stub.c
|
||||
.endif
|
||||
.if empty(MACHINE_ARCH:Mearmv7*)
|
||||
CPUFLAGS.ffs.S+= -marm
|
||||
.endif
|
||||
CPUFLAGS.divide.S+= -marm
|
||||
CPUFLAGS.memcmp.S+= -marm
|
||||
CPUFLAGS.memcpy.S+= -marm
|
||||
CPUFLAGS.memmove.S+= -marm
|
||||
CPUFLAGS.memset.S+= -marm
|
||||
.if empty(CPPFLAGS:M-D_STANDALONE)
|
||||
CPUFLAGS.strcpy.S+= -marm
|
||||
CPUFLAGS.strlcpy.S+= -marm
|
||||
CPUFLAGS.strncpy.S+= -marm
|
||||
.endif
|
||||
48
sys/lib/libkern/arch/arm/unwind_stub.c
Normal file
48
sys/lib/libkern/arch/arm/unwind_stub.c
Normal file
@@ -0,0 +1,48 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Matt Thomas of 3am Software Foundry.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(1, "$NetBSD: unwind_stub.c,v 1.2 2013/08/12 23:42:14 matt Exp $");
|
||||
|
||||
#if defined(__minix)
|
||||
#include <ehabi.h>
|
||||
#else
|
||||
#include <arm/ehabi.h>
|
||||
#endif /* defined(__minix) */
|
||||
|
||||
static _Unwind_Reason_Code __used
|
||||
__aeabi_unwind_cpp_stub(_Unwind_State state, _Unwind_Control_Block *ucbp,
|
||||
_Unwind_Context *context)
|
||||
{
|
||||
return _URC_FAILURE;
|
||||
}
|
||||
|
||||
__weak_alias(__aeabi_unwind_cpp_pr0, __aeabi_unwind_cpp_stub)
|
||||
__weak_alias(__aeabi_unwind_cpp_pr1, __aeabi_unwind_cpp_stub)
|
||||
__weak_alias(__aeabi_unwind_cpp_pr2, __aeabi_unwind_cpp_stub)
|
||||
@@ -16,3 +16,9 @@ CPPFLAGS.libunwind.cxx+=-I${NETBSDSRCDIR}/sys/lib/libunwind
|
||||
.if ${LIBC_MACHINE_CPU} == "arm"
|
||||
AFLAGS.unwind_registers.S+= ${${ACTIVE_CC} == "clang":? -mfpu=vfp3 :}
|
||||
.endif
|
||||
|
||||
.if defined(__MINIX)
|
||||
.PATH: ${NETBSDSRCDIR}/sys/lib/libkern/arch/arm
|
||||
SRCS+= unwind_stub.c
|
||||
CPPFLAGS.unwind_stub.c+=-I${NETBSDSRCDIR}/sys/arch/arm/include
|
||||
.endif # defined(__MINIX)
|
||||
|
||||
@@ -12,7 +12,7 @@ SUBDIR+= tls_dso .WAIT # sync
|
||||
# LSC: db hangs, so compiled, installed, but not added to the testsuite by
|
||||
# default
|
||||
SUBDIR+= db
|
||||
TESTS_SUBDIRS+= hash inet locale net regex rpc stdlib
|
||||
TESTS_SUBDIRS+= hash inet locale net regex stdlib
|
||||
TESTS_SUBDIRS+= stdio string termios time
|
||||
|
||||
.if !defined(__MINIX)
|
||||
|
||||
@@ -5,19 +5,19 @@
|
||||
TESTSDIR= ${TESTSBASE}/lib/libc/gen
|
||||
|
||||
TESTS_SUBDIRS= execve
|
||||
#TESTS_SUBDIRS+= posix_spawn
|
||||
TESTS_SUBDIRS+= posix_spawn
|
||||
|
||||
TESTS_C+= t_alarm
|
||||
TESTS_C+= t_assert
|
||||
TESTS_C+= t_basedirname
|
||||
#TESTS_C+= t_closefrom
|
||||
#TESTS_C+= t_cpuset
|
||||
TESTS_C+= t_closefrom
|
||||
TESTS_C+= t_cpuset
|
||||
TESTS_C+= t_dir
|
||||
TESTS_C+= t_floatunditf
|
||||
TESTS_C+= t_fmtcheck
|
||||
TESTS_C+= t_fnmatch
|
||||
TESTS_C+= t_fpclassify
|
||||
#TESTS_C+= t_fpsetmask
|
||||
TESTS_C+= t_fpsetmask
|
||||
TESTS_C+= t_fpsetround
|
||||
TESTS_C+= t_ftok
|
||||
TESTS_C+= t_getcwd
|
||||
@@ -25,16 +25,16 @@ TESTS_C+= t_getgrent
|
||||
TESTS_C+= t_glob
|
||||
TESTS_C+= t_humanize_number
|
||||
TESTS_C+= t_isnan
|
||||
#TESTS_C+= t_nice
|
||||
TESTS_C+= t_nice
|
||||
TESTS_C+= t_pause
|
||||
TESTS_C+= t_raise
|
||||
TESTS_C+= t_randomid
|
||||
TESTS_C+= t_realpath
|
||||
TESTS_C+= t_setdomainname
|
||||
TESTS_C+= t_sethostname
|
||||
#TESTS_C+= t_siginfo
|
||||
#TESTS_C+= t_sleep
|
||||
#TESTS_C+= t_syslog
|
||||
TESTS_C+= t_siginfo
|
||||
TESTS_C+= t_sleep
|
||||
TESTS_C+= t_syslog
|
||||
TESTS_C+= t_time
|
||||
TESTS_C+= t_ttyname
|
||||
TESTS_C+= t_vis
|
||||
|
||||
@@ -112,7 +112,7 @@ SUBDIR+= gencat \
|
||||
makewhatis mtree nbperf .WAIT uudecode
|
||||
.endif
|
||||
|
||||
SUBDIR+= cat rpcgen join lorder m4 mkdep tsort .WAIT yacc .WAIT awk .WAIT lex
|
||||
SUBDIR+= cat join lorder m4 mkdep tsort .WAIT yacc .WAIT awk .WAIT lex
|
||||
|
||||
.if ${TOOLS_BUILDRUMP} == "no"
|
||||
SUBDIR += .WAIT texinfo \
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
# $NetBSD: Makefile,v 1.4 2002/12/08 20:20:05 thorpej Exp $
|
||||
|
||||
HOSTPROGNAME= ${_TOOL_PREFIX}rpcgen
|
||||
HOST_SRCDIR= usr.bin/rpcgen
|
||||
|
||||
.include "${.CURDIR}/../Makefile.host"
|
||||
@@ -1,7 +0,0 @@
|
||||
# $NetBSD: Makefile,v 1.13 2013/08/11 08:03:10 dholland Exp $
|
||||
|
||||
PROG= rpcgen
|
||||
SRCS= rpc_clntout.c rpc_cout.c rpc_hout.c rpc_main.c rpc_parse.c rpc_scan.c \
|
||||
rpc_svcout.c rpc_util.c rpc_sample.c rpc_tblout.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -1,264 +0,0 @@
|
||||
/* $NetBSD: rpc_clntout.c,v 1.15 2013/12/15 00:40:17 christos Exp $ */
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user or with the express written consent of
|
||||
* Sun Microsystems, Inc.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(__RCSID) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI";
|
||||
#else
|
||||
__RCSID("$NetBSD: rpc_clntout.c,v 1.15 2013/12/15 00:40:17 christos Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
|
||||
* Copyright (C) 1987, Sun Microsytsems, Inc.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <rpc/types.h>
|
||||
#include "rpc_scan.h"
|
||||
#include "rpc_parse.h"
|
||||
#include "rpc_util.h"
|
||||
|
||||
static void write_program(definition *);
|
||||
static const char *ampr(const char *);
|
||||
static const char *aster(const char *);
|
||||
static void printbody(proc_list *);
|
||||
|
||||
#define DEFAULT_TIMEOUT 25 /* in seconds */
|
||||
static char RESULT[] = "clnt_res";
|
||||
|
||||
|
||||
void
|
||||
write_stubs(void)
|
||||
{
|
||||
list *l;
|
||||
definition *def;
|
||||
|
||||
f_print(fout,
|
||||
"\n/* Default timeout can be changed using clnt_control() */\n");
|
||||
f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n",
|
||||
DEFAULT_TIMEOUT);
|
||||
for (l = defined; l != NULL; l = l->next) {
|
||||
def = (definition *) l->val;
|
||||
if (def->def_kind == DEF_PROGRAM) {
|
||||
write_program(def);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
write_program(definition *def)
|
||||
{
|
||||
version_list *vp;
|
||||
proc_list *proc;
|
||||
|
||||
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
|
||||
for (proc = vp->procs; proc != NULL; proc = proc->next) {
|
||||
f_print(fout, "\n");
|
||||
if (Mflag)
|
||||
f_print(fout, "enum clnt_stat\n");
|
||||
else {
|
||||
ptype(proc->res_prefix, proc->res_type, 1);
|
||||
f_print(fout, "*\n");
|
||||
}
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
printarglist(proc, RESULT, "clnt", "CLIENT *");
|
||||
f_print(fout, "{\n");
|
||||
printbody(proc);
|
||||
f_print(fout, "}\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Writes out declarations of procedure's argument list.
|
||||
In either ANSI C style, in one of old rpcgen style (pass by reference),
|
||||
or new rpcgen style (multiple arguments, pass by value);
|
||||
*/
|
||||
|
||||
/* sample addargname = "clnt"; sample addargtype = "CLIENT * " */
|
||||
|
||||
void
|
||||
printarglist(proc_list *proc, const char *result,
|
||||
const char *addargname, const char *addargtype)
|
||||
{
|
||||
|
||||
decl_list *l;
|
||||
|
||||
if (!newstyle) { /* old style: always pass argument by
|
||||
* reference */
|
||||
f_print(fout, "(");
|
||||
ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1);
|
||||
f_print(fout, "*argp, ");
|
||||
if (Mflag) {
|
||||
if (streq(proc->res_type, "void"))
|
||||
f_print(fout, "char ");
|
||||
else
|
||||
ptype(proc->res_prefix, proc->res_type, 0);
|
||||
f_print(fout, "%s%s, ", aster(proc->res_type),
|
||||
result);
|
||||
}
|
||||
f_print(fout, "%s%s)\n", addargtype, addargname);
|
||||
} else {
|
||||
f_print(fout, "(");
|
||||
if (!streq(proc->args.decls->decl.type, "void")) {
|
||||
/* new style, 1 or multiple arguments */
|
||||
for (l = proc->args.decls; l != NULL; l = l->next)
|
||||
pdeclaration(proc->args.argname,
|
||||
&l->decl, 0, ", ");
|
||||
}
|
||||
if (Mflag) {
|
||||
if (streq(proc->res_type, "void"))
|
||||
f_print(fout, "char ");
|
||||
else
|
||||
ptype(proc->res_prefix, proc->res_type, 0);
|
||||
f_print(fout, "%s%s, ", aster(proc->res_type),
|
||||
result);
|
||||
}
|
||||
f_print(fout, "%s%s)\n", addargtype, addargname);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
ampr(const char *type)
|
||||
{
|
||||
if (isvectordef(type, REL_ALIAS)) {
|
||||
return ("");
|
||||
} else {
|
||||
return ("&");
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
aster(const char *type)
|
||||
{
|
||||
if (isvectordef(type, REL_ALIAS)) {
|
||||
return ("");
|
||||
} else {
|
||||
return ("*");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
printbody(proc_list *proc)
|
||||
{
|
||||
decl_list *l;
|
||||
bool_t args2 = (proc->arg_num > 1);
|
||||
|
||||
/* For new style with multiple arguments, need a structure in which to
|
||||
* stuff the arguments. */
|
||||
if (newstyle && args2) {
|
||||
f_print(fout, "\t%s", proc->args.argname);
|
||||
f_print(fout, " arg;\n");
|
||||
}
|
||||
if (!Mflag) {
|
||||
f_print(fout, "\tstatic ");
|
||||
if (streq(proc->res_type, "void"))
|
||||
f_print(fout, "char ");
|
||||
else
|
||||
ptype(proc->res_prefix, proc->res_type, 0);
|
||||
f_print(fout, "%s;\n", RESULT);
|
||||
}
|
||||
f_print(fout, "\n");
|
||||
if (!Mflag)
|
||||
f_print(fout, "\tmemset((char *)%s%s, 0, sizeof(%s));\n",
|
||||
ampr(proc->res_type), RESULT, RESULT);
|
||||
if (newstyle && !args2 && (streq(proc->args.decls->decl.type, "void"))) {
|
||||
/* newstyle, 0 arguments */
|
||||
if (Mflag) {
|
||||
f_print(fout, "\treturn (clnt_call(clnt, %s, xdr_void",
|
||||
proc->proc_name);
|
||||
f_print(fout, ", NULL, xdr_%s, %s, TIMEOUT));\n",
|
||||
stringfix(proc->res_type), RESULT);
|
||||
} else {
|
||||
f_print(fout, "\tif (clnt_call(clnt, %s, xdr_void, ",
|
||||
proc->proc_name);
|
||||
f_print(fout,
|
||||
"NULL, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS)\n",
|
||||
stringfix(proc->res_type), ampr(proc->res_type),
|
||||
RESULT);
|
||||
}
|
||||
} else {
|
||||
if (newstyle && args2) {
|
||||
/* newstyle, multiple arguments: stuff arguments into
|
||||
* structure */
|
||||
for (l = proc->args.decls; l != NULL; l = l->next) {
|
||||
f_print(fout, "\targ.%s = %s;\n",
|
||||
l->decl.name, l->decl.name);
|
||||
}
|
||||
if (Mflag) {
|
||||
f_print(fout,
|
||||
"\treturn (clnt_call(clnt, %s, xdr_%s, &arg, xdr_%s, %s, TIMEOUT));\n",
|
||||
proc->proc_name, proc->args.argname,
|
||||
stringfix(proc->res_type), RESULT);
|
||||
} else {
|
||||
f_print(fout,
|
||||
"\tif (clnt_call(clnt, %s, xdr_%s, &arg, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS)\n",
|
||||
proc->proc_name, proc->args.argname,
|
||||
stringfix(proc->res_type),
|
||||
ampr(proc->res_type), RESULT);
|
||||
}
|
||||
} else { /* single argument, new or old style */
|
||||
if (Mflag) {
|
||||
f_print(fout,
|
||||
"\treturn (clnt_call(clnt, %s, xdr_%s, %s%s, xdr_%s, %s, TIMEOUT));\n",
|
||||
proc->proc_name,
|
||||
stringfix(proc->args.decls->decl.type),
|
||||
(newstyle ? "&" : ""),
|
||||
(newstyle ? proc->args.decls->decl.name : "argp"),
|
||||
stringfix(proc->res_type), RESULT);
|
||||
} else {
|
||||
f_print(fout,
|
||||
"\tif (clnt_call(clnt, %s, xdr_%s, %s%s, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS)\n",
|
||||
proc->proc_name,
|
||||
stringfix(proc->args.decls->decl.type),
|
||||
(newstyle ? "&" : ""),
|
||||
(newstyle ? proc->args.decls->decl.name : "argp"),
|
||||
stringfix(proc->res_type),
|
||||
ampr(proc->res_type), RESULT);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Mflag) {
|
||||
f_print(fout, "\t\treturn (NULL);\n");
|
||||
if (streq(proc->res_type, "void"))
|
||||
f_print(fout, "\treturn ((void *)%s%s);\n",
|
||||
ampr(proc->res_type), RESULT);
|
||||
else
|
||||
f_print(fout, "\treturn (%s%s);\n",
|
||||
ampr(proc->res_type), RESULT);
|
||||
}
|
||||
}
|
||||
@@ -1,725 +0,0 @@
|
||||
/* $NetBSD: rpc_cout.c,v 1.37 2015/09/20 16:57:13 kamil Exp $ */
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user or with the express written consent of
|
||||
* Sun Microsystems, Inc.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(__RCSID) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)rpc_cout.c 1.13 89/02/22 (C) 1987 SMI";
|
||||
#else
|
||||
__RCSID("$NetBSD: rpc_cout.c,v 1.37 2015/09/20 16:57:13 kamil Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* rpc_cout.c, XDR routine outputter for the RPC protocol compiler
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "rpc_scan.h"
|
||||
#include "rpc_parse.h"
|
||||
#include "rpc_util.h"
|
||||
|
||||
static int findtype(definition *, const char *);
|
||||
static int undefined(const char *);
|
||||
static void print_generic_header(const char *, int);
|
||||
static void print_header(definition *);
|
||||
static void print_prog_header(proc_list *);
|
||||
static void print_trailer(void);
|
||||
static void print_ifopen(int, const char *);
|
||||
static void print_ifarg(const char *);
|
||||
static void print_ifsizeof(const char *, const char *);
|
||||
static void print_ifclose(int);
|
||||
static void print_ifstat(int, const char *, const char *, relation,
|
||||
const char *, const char *, const char *);
|
||||
static void emit_enum(definition *);
|
||||
static void emit_program(definition *);
|
||||
static void emit_union(definition *);
|
||||
static void emit_struct(definition *);
|
||||
static void emit_typedef(definition *);
|
||||
static void print_stat(int, declaration *);
|
||||
|
||||
/*
|
||||
* Emit the C-routine for the given definition
|
||||
*/
|
||||
void
|
||||
emit(definition *def)
|
||||
{
|
||||
if (def->def_kind == DEF_CONST) {
|
||||
return;
|
||||
}
|
||||
if (def->def_kind == DEF_PROGRAM) {
|
||||
emit_program(def);
|
||||
return;
|
||||
}
|
||||
if (def->def_kind == DEF_TYPEDEF) {
|
||||
/* now we need to handle declarations like struct typedef foo
|
||||
* foo; since we dont want this to be expanded into 2 calls to
|
||||
* xdr_foo */
|
||||
|
||||
if (strcmp(def->def.ty.old_type, def->def_name) == 0)
|
||||
return;
|
||||
};
|
||||
|
||||
print_header(def);
|
||||
|
||||
switch (def->def_kind) {
|
||||
case DEF_UNION:
|
||||
emit_union(def);
|
||||
break;
|
||||
case DEF_ENUM:
|
||||
emit_enum(def);
|
||||
break;
|
||||
case DEF_STRUCT:
|
||||
emit_struct(def);
|
||||
break;
|
||||
case DEF_TYPEDEF:
|
||||
emit_typedef(def);
|
||||
break;
|
||||
case DEF_PROGRAM:
|
||||
case DEF_CONST:
|
||||
errx(1, "Internal error at %s:%d: Case %d not handled",
|
||||
__FILE__, __LINE__, def->def_kind);
|
||||
break;
|
||||
}
|
||||
print_trailer();
|
||||
}
|
||||
|
||||
static int
|
||||
findtype(definition *def, const char *type)
|
||||
{
|
||||
|
||||
if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) {
|
||||
return (0);
|
||||
} else {
|
||||
return (streq(def->def_name, type));
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
undefined(const char *type)
|
||||
{
|
||||
definition *def;
|
||||
|
||||
def = (definition *) FINDVAL(defined, type, findtype);
|
||||
|
||||
|
||||
return (def == NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
print_generic_header(const char *procname, int pointerp)
|
||||
{
|
||||
f_print(fout, "\n");
|
||||
f_print(fout, "bool_t\n");
|
||||
f_print(fout, "xdr_%s(", procname);
|
||||
f_print(fout, "XDR *xdrs, ");
|
||||
f_print(fout, "%s ", procname);
|
||||
if (pointerp)
|
||||
f_print(fout, "*");
|
||||
f_print(fout, "objp)\n{\n");
|
||||
}
|
||||
|
||||
static void
|
||||
print_header(definition *def)
|
||||
{
|
||||
print_generic_header(def->def_name,
|
||||
def->def_kind != DEF_TYPEDEF ||
|
||||
!isvectordef(def->def.ty.old_type, def->def.ty.rel));
|
||||
}
|
||||
|
||||
static void
|
||||
print_prog_header(proc_list *plist)
|
||||
{
|
||||
print_generic_header(plist->args.argname, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
print_trailer(void)
|
||||
{
|
||||
f_print(fout, "\treturn (TRUE);\n");
|
||||
f_print(fout, "}\n");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_ifopen(int indent, const char *name)
|
||||
{
|
||||
char _t_kludge[32];
|
||||
/*
|
||||
* XXX Solaris seems to strip the _t. No idea why.
|
||||
*/
|
||||
if (!strcmp(name, "rpcprog_t") || !strcmp(name, "rpcvers_t") ||
|
||||
!strcmp(name, "rpcproc_t") || !strcmp(name, "rpcprot_t") ||
|
||||
!strcmp(name, "rpcport_t") || !strcmp(name, "rpcpinline_t")) {
|
||||
strncpy(_t_kludge, name, strlen(name) - 2);
|
||||
name = _t_kludge;
|
||||
}
|
||||
tabify(fout, indent);
|
||||
f_print(fout, "if (!xdr_%s(xdrs", name);
|
||||
}
|
||||
|
||||
static void
|
||||
print_ifarg(const char *arg)
|
||||
{
|
||||
f_print(fout, ", %s", arg);
|
||||
}
|
||||
|
||||
static void
|
||||
print_ifsizeof(const char *prefix, const char *type)
|
||||
{
|
||||
if (streq(type, "bool")) {
|
||||
f_print(fout, ", (u_int)sizeof(bool_t), (xdrproc_t)xdr_bool");
|
||||
} else {
|
||||
f_print(fout, ", (u_int)sizeof(");
|
||||
if (undefined(type) && prefix) {
|
||||
f_print(fout, "%s ", prefix);
|
||||
}
|
||||
f_print(fout, "%s), (xdrproc_t)xdr_%s", type, type);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_ifclose(int indent)
|
||||
{
|
||||
f_print(fout, "))\n");
|
||||
tabify(fout, indent);
|
||||
f_print(fout, "\treturn (FALSE);\n");
|
||||
}
|
||||
|
||||
static void
|
||||
print_ifstat(int indent, const char *prefix, const char *type, relation rel,
|
||||
const char *amax, const char *objname, const char *name)
|
||||
{
|
||||
const char *alt = NULL;
|
||||
|
||||
switch (rel) {
|
||||
case REL_POINTER:
|
||||
print_ifopen(indent, "pointer");
|
||||
print_ifarg("(char **)(void *)");
|
||||
f_print(fout, "%s", objname);
|
||||
print_ifsizeof(prefix, type);
|
||||
break;
|
||||
case REL_VECTOR:
|
||||
if (streq(type, "string")) {
|
||||
alt = "string";
|
||||
} else
|
||||
if (streq(type, "opaque")) {
|
||||
alt = "opaque";
|
||||
}
|
||||
if (alt) {
|
||||
print_ifopen(indent, alt);
|
||||
print_ifarg(objname);
|
||||
} else {
|
||||
print_ifopen(indent, "vector");
|
||||
print_ifarg("(char *)(void *)");
|
||||
f_print(fout, "%s", objname);
|
||||
}
|
||||
print_ifarg(amax);
|
||||
if (!alt) {
|
||||
print_ifsizeof(prefix, type);
|
||||
}
|
||||
break;
|
||||
case REL_ARRAY:
|
||||
if (streq(type, "string")) {
|
||||
alt = "string";
|
||||
} else
|
||||
if (streq(type, "opaque")) {
|
||||
alt = "bytes";
|
||||
}
|
||||
if (streq(type, "string")) {
|
||||
print_ifopen(indent, alt);
|
||||
print_ifarg(objname);
|
||||
} else {
|
||||
if (alt) {
|
||||
print_ifopen(indent, alt);
|
||||
} else {
|
||||
print_ifopen(indent, "array");
|
||||
}
|
||||
print_ifarg("(char **)(void *)");
|
||||
if (*objname == '&') {
|
||||
f_print(fout, "%s.%s_val, (u_int *)%s.%s_len",
|
||||
objname, name, objname, name);
|
||||
} else {
|
||||
f_print(fout, "&%s->%s_val, (u_int *)&%s->%s_len",
|
||||
objname, name, objname, name);
|
||||
}
|
||||
}
|
||||
print_ifarg(amax);
|
||||
if (!alt) {
|
||||
print_ifsizeof(prefix, type);
|
||||
}
|
||||
break;
|
||||
case REL_ALIAS:
|
||||
print_ifopen(indent, type);
|
||||
print_ifarg(objname);
|
||||
break;
|
||||
}
|
||||
print_ifclose(indent);
|
||||
}
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
emit_enum(definition *def)
|
||||
{
|
||||
tabify(fout, 1);
|
||||
f_print(fout, "{\n");
|
||||
tabify(fout, 2);
|
||||
f_print(fout, "enum_t et = (enum_t)*objp;\n");
|
||||
print_ifopen(2, "enum");
|
||||
print_ifarg("&et");
|
||||
print_ifclose(2);
|
||||
tabify(fout, 2);
|
||||
f_print(fout, "*objp = (%s)et;\n", def->def_name);
|
||||
tabify(fout, 1);
|
||||
f_print(fout, "}\n");
|
||||
}
|
||||
|
||||
static void
|
||||
emit_program(definition *def)
|
||||
{
|
||||
decl_list *dl;
|
||||
version_list *vlist;
|
||||
proc_list *plist;
|
||||
|
||||
for (vlist = def->def.pr.versions; vlist != NULL; vlist = vlist->next)
|
||||
for (plist = vlist->procs; plist != NULL; plist = plist->next) {
|
||||
if (!newstyle || plist->arg_num < 2)
|
||||
continue; /* old style, or single
|
||||
* argument */
|
||||
print_prog_header(plist);
|
||||
for (dl = plist->args.decls; dl != NULL;
|
||||
dl = dl->next)
|
||||
print_stat(1, &dl->decl);
|
||||
print_trailer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
emit_union(definition *def)
|
||||
{
|
||||
declaration *dflt;
|
||||
case_list *cl;
|
||||
declaration *cs;
|
||||
char *object;
|
||||
static const char vecformat[] = "objp->%s_u.%s";
|
||||
static const char format[] = "&objp->%s_u.%s";
|
||||
|
||||
f_print(fout, "\n");
|
||||
print_stat(1, &def->def.un.enum_decl);
|
||||
f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name);
|
||||
for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
|
||||
f_print(fout, "\tcase %s:\n", cl->case_name);
|
||||
if (cl->contflag == 1) /* a continued case statement */
|
||||
continue;
|
||||
cs = &cl->case_decl;
|
||||
if (!streq(cs->type, "void")) {
|
||||
object = alloc(strlen(def->def_name) + strlen(format) +
|
||||
strlen(cs->name) + 1);
|
||||
if (isvectordef(cs->type, cs->rel)) {
|
||||
s_print(object, vecformat, def->def_name,
|
||||
cs->name);
|
||||
} else {
|
||||
s_print(object, format, def->def_name,
|
||||
cs->name);
|
||||
}
|
||||
print_ifstat(2, cs->prefix, cs->type, cs->rel,
|
||||
cs->array_max, object, cs->name);
|
||||
free(object);
|
||||
}
|
||||
f_print(fout, "\t\tbreak;\n");
|
||||
}
|
||||
dflt = def->def.un.default_decl;
|
||||
f_print(fout, "\tdefault:\n");
|
||||
if (dflt != NULL) {
|
||||
if (!streq(dflt->type, "void")) {
|
||||
object = alloc(strlen(def->def_name) + strlen(format) +
|
||||
strlen(dflt->name) + 1);
|
||||
if (isvectordef(dflt->type, dflt->rel)) {
|
||||
s_print(object, vecformat, def->def_name,
|
||||
dflt->name);
|
||||
} else {
|
||||
s_print(object, format, def->def_name,
|
||||
dflt->name);
|
||||
}
|
||||
print_ifstat(2, dflt->prefix, dflt->type, dflt->rel,
|
||||
dflt->array_max, object, dflt->name);
|
||||
free(object);
|
||||
}
|
||||
f_print(fout, "\t\tbreak;\n");
|
||||
} else {
|
||||
f_print(fout, "\t\treturn (FALSE);\n");
|
||||
}
|
||||
|
||||
f_print(fout, "\t}\n");
|
||||
}
|
||||
|
||||
static void
|
||||
emit_struct(definition *def)
|
||||
{
|
||||
decl_list *dl;
|
||||
int i, j, size, flag;
|
||||
decl_list *cur = NULL, *psav;
|
||||
bas_type *ptr;
|
||||
char *sizestr;
|
||||
const char *plus;
|
||||
char ptemp[256];
|
||||
int can_inline;
|
||||
|
||||
|
||||
if (doinline == 0) {
|
||||
f_print(fout, "\n");
|
||||
for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
|
||||
print_stat(1, &dl->decl);
|
||||
return;
|
||||
}
|
||||
size = 0;
|
||||
can_inline = 0;
|
||||
for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
|
||||
if ((dl->decl.prefix == NULL) &&
|
||||
((ptr = find_type(dl->decl.type)) != NULL) &&
|
||||
((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) {
|
||||
|
||||
if (dl->decl.rel == REL_ALIAS)
|
||||
size += ptr->length;
|
||||
else {
|
||||
can_inline = 1;
|
||||
break; /* can be inlined */
|
||||
};
|
||||
} else {
|
||||
if (size >= doinline) {
|
||||
can_inline = 1;
|
||||
break; /* can be inlined */
|
||||
}
|
||||
size = 0;
|
||||
}
|
||||
if (size > doinline)
|
||||
can_inline = 1;
|
||||
|
||||
if (can_inline == 0) { /* can not inline, drop back to old mode */
|
||||
f_print(fout, "\n");
|
||||
for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
|
||||
print_stat(1, &dl->decl);
|
||||
return;
|
||||
};
|
||||
|
||||
/* May cause lint to complain. but ... */
|
||||
f_print(fout, "\tint32_t *buf;\n");
|
||||
|
||||
flag = PUT;
|
||||
f_print(fout, "\n\tif (xdrs->x_op == XDR_ENCODE) {\n");
|
||||
|
||||
for (j = 0; j < 2; j++) {
|
||||
i = 0;
|
||||
size = 0;
|
||||
sizestr = NULL;
|
||||
for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { /* xxx */
|
||||
|
||||
/* now walk down the list and check for basic types */
|
||||
if ((dl->decl.prefix == NULL) && ((ptr = find_type(dl->decl.type)) != NULL) && ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) {
|
||||
if (i == 0)
|
||||
cur = dl;
|
||||
i++;
|
||||
|
||||
if (dl->decl.rel == REL_ALIAS)
|
||||
size += ptr->length;
|
||||
else {
|
||||
/* this is required to handle arrays */
|
||||
|
||||
if (sizestr == NULL)
|
||||
plus = "";
|
||||
else
|
||||
plus = " + ";
|
||||
|
||||
if (ptr->length != 1)
|
||||
s_print(ptemp, "%s%s * %d", plus, dl->decl.array_max, ptr->length);
|
||||
else
|
||||
s_print(ptemp, "%s%s", plus, dl->decl.array_max);
|
||||
|
||||
/* now concatenate to sizestr !!!! */
|
||||
if (sizestr == NULL)
|
||||
sizestr = strdup(ptemp);
|
||||
else {
|
||||
char *nsizestr;
|
||||
|
||||
nsizestr = realloc(sizestr, strlen(sizestr) + strlen(ptemp) + 1);
|
||||
if (nsizestr == NULL) {
|
||||
err(EXIT_FAILURE, "realloc");
|
||||
}
|
||||
sizestr = nsizestr;
|
||||
sizestr = strcat(sizestr, ptemp); /* build up length of
|
||||
* array */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (i > 0) {
|
||||
if (sizestr == NULL && size < doinline) {
|
||||
/* don't expand into inline
|
||||
* code if size < doinline */
|
||||
while (cur != dl) {
|
||||
print_stat(2, &cur->decl);
|
||||
cur = cur->next;
|
||||
}
|
||||
} else {
|
||||
|
||||
|
||||
|
||||
/* were already looking at a
|
||||
* xdr_inlineable structure */
|
||||
if (sizestr == NULL)
|
||||
f_print(fout, "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %d * BYTES_PER_XDR_UNIT);\n",
|
||||
size);
|
||||
else
|
||||
if (size == 0)
|
||||
f_print(fout,
|
||||
"\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %s * BYTES_PER_XDR_UNIT);\n",
|
||||
sizestr);
|
||||
else
|
||||
f_print(fout,
|
||||
"\t\tbuf = (int32_t *)XDR_INLINE(xdrs, (%d + %s) * BYTES_PER_XDR_UNIT);\n",
|
||||
size, sizestr);
|
||||
|
||||
f_print(fout, "\t\tif (buf == NULL) {\n");
|
||||
|
||||
psav = cur;
|
||||
while (cur != dl) {
|
||||
print_stat(3, &cur->decl);
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
f_print(fout, "\t\t} else {\n");
|
||||
|
||||
cur = psav;
|
||||
while (cur != dl) {
|
||||
emit_inline(&cur->decl, flag);
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
f_print(fout, "\t\t}\n");
|
||||
}
|
||||
}
|
||||
size = 0;
|
||||
i = 0;
|
||||
if (sizestr) {
|
||||
free(sizestr);
|
||||
sizestr = NULL;
|
||||
}
|
||||
print_stat(2, &dl->decl);
|
||||
}
|
||||
|
||||
}
|
||||
if (i > 0) {
|
||||
if (sizestr == NULL && size < doinline) {
|
||||
/* don't expand into inline code if size <
|
||||
* doinline */
|
||||
while (cur != dl) {
|
||||
print_stat(2, &cur->decl);
|
||||
cur = cur->next;
|
||||
}
|
||||
} else {
|
||||
|
||||
/* were already looking at a xdr_inlineable
|
||||
* structure */
|
||||
if (sizestr == NULL)
|
||||
f_print(fout, "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %d * BYTES_PER_XDR_UNIT);\n",
|
||||
size);
|
||||
else
|
||||
if (size == 0)
|
||||
f_print(fout,
|
||||
"\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %s * BYTES_PER_XDR_UNIT);\n",
|
||||
sizestr);
|
||||
else
|
||||
f_print(fout,
|
||||
"\t\tbuf = (int32_t *)XDR_INLINE(xdrs, (%d + %s) * BYTES_PER_XDR_UNIT);\n",
|
||||
size, sizestr);
|
||||
|
||||
f_print(fout, "\t\tif (buf == NULL) {\n");
|
||||
|
||||
psav = cur;
|
||||
while (cur != NULL) {
|
||||
print_stat(3, &cur->decl);
|
||||
cur = cur->next;
|
||||
}
|
||||
f_print(fout, "\t\t} else {\n");
|
||||
|
||||
cur = psav;
|
||||
while (cur != dl) {
|
||||
emit_inline(&cur->decl, flag);
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
f_print(fout, "\t\t}\n");
|
||||
|
||||
}
|
||||
}
|
||||
if (flag == PUT) {
|
||||
flag = GET;
|
||||
f_print(fout, "\t} else if (xdrs->x_op == XDR_DECODE) {\n");
|
||||
}
|
||||
}
|
||||
|
||||
f_print(fout, "\t} else {\n");
|
||||
|
||||
/* now take care of XDR_FREE case */
|
||||
|
||||
for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
|
||||
print_stat(2, &dl->decl);
|
||||
|
||||
f_print(fout, "\t}\n");
|
||||
}
|
||||
|
||||
static void
|
||||
emit_typedef(definition *def)
|
||||
{
|
||||
const char *prefix = def->def.ty.old_prefix;
|
||||
const char *type = def->def.ty.old_type;
|
||||
const char *amax = def->def.ty.array_max;
|
||||
relation rel = def->def.ty.rel;
|
||||
|
||||
f_print(fout, "\n");
|
||||
print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name);
|
||||
}
|
||||
|
||||
static void
|
||||
print_stat(int indent, declaration *dec)
|
||||
{
|
||||
const char *prefix = dec->prefix;
|
||||
const char *type = dec->type;
|
||||
const char *amax = dec->array_max;
|
||||
relation rel = dec->rel;
|
||||
char name[256];
|
||||
|
||||
if (isvectordef(type, rel)) {
|
||||
s_print(name, "objp->%s", dec->name);
|
||||
} else {
|
||||
s_print(name, "&objp->%s", dec->name);
|
||||
}
|
||||
print_ifstat(indent, prefix, type, rel, amax, name, dec->name);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
emit_inline(declaration *decl, int flag)
|
||||
{
|
||||
|
||||
/*check whether an array or not */
|
||||
|
||||
switch (decl->rel) {
|
||||
case REL_ALIAS:
|
||||
emit_single_in_line(decl, flag, REL_ALIAS);
|
||||
break;
|
||||
case REL_VECTOR:
|
||||
f_print(fout, "\t\t\t{\n");
|
||||
f_print(fout, "\t\t\t\tint i;\n");
|
||||
f_print(fout, "\t\t\t\t%s *genp;\n", decl->type);
|
||||
f_print(fout, "\n");
|
||||
f_print(fout, "\t\t\t\tfor (i = 0, genp = objp->%s;\n",
|
||||
decl->name);
|
||||
f_print(fout, "\t\t\t\t i < %s; i++) {\n\t\t",
|
||||
decl->array_max);
|
||||
emit_single_in_line(decl, flag, REL_VECTOR);
|
||||
f_print(fout, "\t\t\t\t}\n\t\t\t}\n");
|
||||
break;
|
||||
case REL_ARRAY:
|
||||
case REL_POINTER:
|
||||
errx(1, "Internal error at %s:%d: Case %d not handled",
|
||||
__FILE__, __LINE__, decl->rel);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
emit_single_in_line(declaration *decl, int flag, relation rel)
|
||||
{
|
||||
const char *upp_case;
|
||||
char *freeable;
|
||||
int freed = 0;
|
||||
|
||||
if (flag == PUT)
|
||||
f_print(fout, "\t\t\tIXDR_PUT_");
|
||||
else
|
||||
if (rel == REL_ALIAS)
|
||||
f_print(fout, "\t\t\tobjp->%s = IXDR_GET_", decl->name);
|
||||
else
|
||||
f_print(fout, "\t\t\t*genp++ = IXDR_GET_");
|
||||
|
||||
upp_case = freeable = upcase(decl->type);
|
||||
|
||||
/* hack - XX */
|
||||
if (strcmp(upp_case, "INT") == 0) {
|
||||
free(freeable);
|
||||
freed = 1;
|
||||
upp_case = "INT32";
|
||||
} else if (strcmp(upp_case, "U_INT") == 0) {
|
||||
free(freeable);
|
||||
freed = 1;
|
||||
upp_case = "U_INT32";
|
||||
}
|
||||
if (flag == PUT) {
|
||||
if (rel == REL_ALIAS)
|
||||
f_print(fout, "%s(buf, objp->%s);\n", upp_case, decl->name);
|
||||
else
|
||||
f_print(fout, "%s(buf, *genp++);\n", upp_case);
|
||||
|
||||
} else
|
||||
f_print(fout, "%s(buf);\n", upp_case);
|
||||
if (!freed)
|
||||
free(freeable);
|
||||
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
upcase(const char *str)
|
||||
{
|
||||
char *ptr, *hptr;
|
||||
|
||||
|
||||
ptr = malloc(strlen(str) + 1);
|
||||
if (ptr == NULL) {
|
||||
errx(EXIT_FAILURE, "Out of memory");
|
||||
}
|
||||
|
||||
hptr = ptr;
|
||||
while (*str != '\0')
|
||||
*ptr++ = toupper((unsigned char)*str++);
|
||||
|
||||
*ptr = '\0';
|
||||
return (hptr);
|
||||
|
||||
}
|
||||
@@ -1,543 +0,0 @@
|
||||
/* $NetBSD: rpc_hout.c,v 1.24 2015/09/20 15:45:07 kamil Exp $ */
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user or with the express written consent of
|
||||
* Sun Microsystems, Inc.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(__RCSID) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)rpc_hout.c 1.12 89/02/22 (C) 1987 SMI";
|
||||
#else
|
||||
__RCSID("$NetBSD: rpc_hout.c,v 1.24 2015/09/20 15:45:07 kamil Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* rpc_hout.c, Header file outputter for the RPC protocol compiler
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include "rpc_scan.h"
|
||||
#include "rpc_parse.h"
|
||||
#include "rpc_util.h"
|
||||
|
||||
static void pconstdef(definition *);
|
||||
static void pargdef(definition *);
|
||||
static void pstructdef(definition *);
|
||||
static void puniondef(definition *);
|
||||
static void pdefine(const char *, const char *);
|
||||
static void puldefine(const char *, const char *);
|
||||
static int define_printed(proc_list *, version_list *);
|
||||
static void pprogramdef(definition *);
|
||||
static void penumdef(definition *);
|
||||
static void ptypedef(definition *);
|
||||
static int undefined2(const char *, const char *);
|
||||
static void cplusplusstart(void);
|
||||
static void cplusplusend(void);
|
||||
|
||||
/*
|
||||
* Print the C-version of an xdr definition
|
||||
*/
|
||||
void
|
||||
print_datadef(definition *def)
|
||||
{
|
||||
|
||||
if (def->def_kind == DEF_PROGRAM) /* handle data only */
|
||||
return;
|
||||
|
||||
if (def->def_kind != DEF_CONST) {
|
||||
f_print(fout, "\n");
|
||||
}
|
||||
switch (def->def_kind) {
|
||||
case DEF_STRUCT:
|
||||
pstructdef(def);
|
||||
break;
|
||||
case DEF_UNION:
|
||||
puniondef(def);
|
||||
break;
|
||||
case DEF_ENUM:
|
||||
penumdef(def);
|
||||
break;
|
||||
case DEF_TYPEDEF:
|
||||
ptypedef(def);
|
||||
break;
|
||||
case DEF_PROGRAM:
|
||||
pprogramdef(def);
|
||||
break;
|
||||
case DEF_CONST:
|
||||
pconstdef(def);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
print_progdef(definition *def)
|
||||
{
|
||||
switch (def->def_kind) {
|
||||
case DEF_PROGRAM:
|
||||
f_print(fout, "\n");
|
||||
pprogramdef(def);
|
||||
break;
|
||||
case DEF_CONST:
|
||||
case DEF_TYPEDEF:
|
||||
case DEF_ENUM:
|
||||
case DEF_UNION:
|
||||
case DEF_STRUCT:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
print_funcdef(definition *def, int *did)
|
||||
{
|
||||
switch (def->def_kind) {
|
||||
case DEF_PROGRAM:
|
||||
case DEF_CONST:
|
||||
break;
|
||||
case DEF_TYPEDEF:
|
||||
case DEF_ENUM:
|
||||
case DEF_UNION:
|
||||
case DEF_STRUCT:
|
||||
if (!*did) {
|
||||
f_print(fout, "\n");
|
||||
cplusplusstart();
|
||||
*did = 1;
|
||||
}
|
||||
pxdrfuncdecl(def->def_name,
|
||||
def->def_kind != DEF_TYPEDEF ||
|
||||
!isvectordef(def->def.ty.old_type, def->def.ty.rel));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
print_funcend(int did) {
|
||||
if (did) {
|
||||
cplusplusend();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pxdrfuncdecl(const char *name, int pointerp)
|
||||
{
|
||||
|
||||
f_print(fout, "bool_t xdr_%s(XDR *, %s%s);\n", name,
|
||||
name, pointerp ? (" *") : "");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pconstdef(definition *def)
|
||||
{
|
||||
pdefine(def->def_name, def->def.co);
|
||||
}
|
||||
|
||||
/* print out the definitions for the arguments of functions in the
|
||||
header file
|
||||
*/
|
||||
static void
|
||||
pargdef(definition *def)
|
||||
{
|
||||
decl_list *l;
|
||||
version_list *vers;
|
||||
char *name;
|
||||
proc_list *plist;
|
||||
int did;
|
||||
|
||||
|
||||
for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
|
||||
for (plist = vers->procs; plist != NULL; plist = plist->next) {
|
||||
if (!newstyle || plist->arg_num < 2) {
|
||||
continue; /* old style or single args */
|
||||
}
|
||||
name = plist->args.argname;
|
||||
f_print(fout, "struct %s {\n", name);
|
||||
for (l = plist->args.decls;
|
||||
l != NULL; l = l->next) {
|
||||
pdeclaration(name, &l->decl, 1, ";\n");
|
||||
}
|
||||
f_print(fout, "};\n");
|
||||
f_print(fout, "typedef struct %s %s;\n", name, name);
|
||||
}
|
||||
}
|
||||
did = 0;
|
||||
for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
|
||||
for (plist = vers->procs; plist != NULL; plist = plist->next) {
|
||||
if (!newstyle || plist->arg_num < 2) {
|
||||
continue; /* old style or single args */
|
||||
}
|
||||
|
||||
if (!did) {
|
||||
cplusplusstart();
|
||||
did = 1;
|
||||
}
|
||||
pxdrfuncdecl(plist->args.argname, 1);
|
||||
}
|
||||
}
|
||||
if (did) {
|
||||
cplusplusend();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pstructdef(definition *def)
|
||||
{
|
||||
decl_list *l;
|
||||
const char *name = def->def_name;
|
||||
|
||||
f_print(fout, "struct %s {\n", name);
|
||||
for (l = def->def.st.decls; l != NULL; l = l->next) {
|
||||
pdeclaration(name, &l->decl, 1, ";\n");
|
||||
}
|
||||
f_print(fout, "};\n");
|
||||
f_print(fout, "typedef struct %s %s;\n", name, name);
|
||||
}
|
||||
|
||||
static void
|
||||
puniondef(definition *def)
|
||||
{
|
||||
case_list *l;
|
||||
const char *name = def->def_name;
|
||||
declaration *decl;
|
||||
|
||||
f_print(fout, "struct %s {\n", name);
|
||||
decl = &def->def.un.enum_decl;
|
||||
if (streq(decl->type, "bool")) {
|
||||
f_print(fout, "\tbool_t %s;\n", decl->name);
|
||||
} else {
|
||||
f_print(fout, "\t%s %s;\n", decl->type, decl->name);
|
||||
}
|
||||
f_print(fout, "\tunion {\n");
|
||||
for (l = def->def.un.cases; l != NULL; l = l->next) {
|
||||
if (l->contflag == 0)
|
||||
pdeclaration(name, &l->case_decl, 2, ";\n");
|
||||
}
|
||||
decl = def->def.un.default_decl;
|
||||
if (decl && !streq(decl->type, "void")) {
|
||||
pdeclaration(name, decl, 2, ";\n");
|
||||
}
|
||||
f_print(fout, "\t} %s_u;\n", name);
|
||||
f_print(fout, "};\n");
|
||||
f_print(fout, "typedef struct %s %s;\n", name, name);
|
||||
}
|
||||
|
||||
static void
|
||||
pdefine(const char *name, const char *num)
|
||||
{
|
||||
f_print(fout, "#define %s %s\n", name, num);
|
||||
}
|
||||
|
||||
static void
|
||||
puldefine(const char *name, const char *num)
|
||||
{
|
||||
f_print(fout, "#define %s %s\n", name, num);
|
||||
}
|
||||
|
||||
static int
|
||||
define_printed(proc_list *stop, version_list *start)
|
||||
{
|
||||
version_list *vers;
|
||||
proc_list *proc;
|
||||
|
||||
for (vers = start; vers != NULL; vers = vers->next) {
|
||||
for (proc = vers->procs; proc != NULL; proc = proc->next) {
|
||||
if (proc == stop) {
|
||||
return (0);
|
||||
} else
|
||||
if (streq(proc->proc_name, stop->proc_name)) {
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
errx(1, "Internal error at %s:%d: procedure not found",
|
||||
__FILE__, __LINE__);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static void
|
||||
cplusplusstart(void)
|
||||
{
|
||||
if (BSDflag)
|
||||
f_print(fout, "__BEGIN_DECLS\n");
|
||||
else
|
||||
f_print(fout, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
|
||||
}
|
||||
|
||||
static void
|
||||
cplusplusend(void)
|
||||
{
|
||||
if (BSDflag)
|
||||
f_print(fout, "__END_DECLS\n");
|
||||
else
|
||||
f_print(fout, "#ifdef __cplusplus\n};\n#endif\n");
|
||||
}
|
||||
|
||||
static void
|
||||
pprogramdef(definition *def)
|
||||
{
|
||||
version_list *vers;
|
||||
proc_list *proc;
|
||||
|
||||
pargdef(def);
|
||||
|
||||
puldefine(def->def_name, def->def.pr.prog_num);
|
||||
for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
|
||||
if (tblflag) {
|
||||
f_print(fout, "extern struct rpcgen_table %s_%s_table[];\n",
|
||||
locase(def->def_name), vers->vers_num);
|
||||
f_print(fout, "extern %s_%s_nproc;\n",
|
||||
locase(def->def_name), vers->vers_num);
|
||||
}
|
||||
puldefine(vers->vers_name, vers->vers_num);
|
||||
for (proc = vers->procs; proc != NULL; proc = proc->next) {
|
||||
if (!define_printed(proc, def->def.pr.versions)) {
|
||||
puldefine(proc->proc_name, proc->proc_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print out 3 definitions, one for ANSI-C, another for C++, a
|
||||
* third for old style C
|
||||
*/
|
||||
f_print(fout, "\n");
|
||||
cplusplusstart();
|
||||
for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
|
||||
for (proc = vers->procs; proc != NULL; proc = proc->next) {
|
||||
pprocdef(proc, vers, "CLIENT *", 0);
|
||||
pprocdef(proc, vers, "struct svc_req *", 1);
|
||||
}
|
||||
}
|
||||
cplusplusend();
|
||||
}
|
||||
|
||||
void
|
||||
pprocdef(proc_list *proc, version_list *vp, const char *addargtype,
|
||||
int server_p)
|
||||
{
|
||||
decl_list *dl;
|
||||
|
||||
if (Mflag) {
|
||||
if (server_p)
|
||||
f_print(fout, "bool_t ");
|
||||
else
|
||||
f_print(fout, "enum clnt_stat ");
|
||||
} else {
|
||||
ptype(proc->res_prefix, proc->res_type, 1);
|
||||
f_print(fout, "*");
|
||||
}
|
||||
if (server_p)
|
||||
pvname_svc(proc->proc_name, vp->vers_num);
|
||||
else
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
|
||||
f_print(fout, "(");
|
||||
if (proc->arg_num < 2 && newstyle &&
|
||||
streq(proc->args.decls->decl.type, "void")) {
|
||||
/* 0 argument in new style: do nothing */
|
||||
} else {
|
||||
for (dl = proc->args.decls; dl != NULL; dl = dl->next) {
|
||||
ptype(dl->decl.prefix, dl->decl.type, 1);
|
||||
if (!newstyle)
|
||||
f_print(fout, "*");
|
||||
f_print(fout, ", ");
|
||||
}
|
||||
}
|
||||
if (Mflag) {
|
||||
if (streq(proc->res_type, "void"))
|
||||
f_print(fout, "char");
|
||||
else
|
||||
ptype(proc->res_prefix, proc->res_type, 0);
|
||||
if (!isvectordef(proc->res_type, REL_ALIAS))
|
||||
f_print(fout, "*");
|
||||
f_print(fout, ", ");
|
||||
}
|
||||
f_print(fout, "%s);\n", addargtype);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
penumdef(definition *def)
|
||||
{
|
||||
const char *name = def->def_name;
|
||||
enumval_list *l;
|
||||
const char *last = NULL;
|
||||
int count = 0;
|
||||
const char *first = "";
|
||||
|
||||
f_print(fout, "enum %s {\n", name);
|
||||
for (l = def->def.en.vals; l != NULL; l = l->next) {
|
||||
f_print(fout, "%s\t%s", first, l->name);
|
||||
if (l->assignment) {
|
||||
f_print(fout, " = %s", l->assignment);
|
||||
last = l->assignment;
|
||||
count = 1;
|
||||
} else {
|
||||
if (last == NULL) {
|
||||
f_print(fout, " = %d", count++);
|
||||
} else {
|
||||
f_print(fout, " = %s + %d", last, count++);
|
||||
}
|
||||
}
|
||||
first = ",\n";
|
||||
}
|
||||
f_print(fout, "\n};\n");
|
||||
f_print(fout, "typedef enum %s %s;\n", name, name);
|
||||
}
|
||||
|
||||
static void
|
||||
ptypedef(definition *def)
|
||||
{
|
||||
const char *name = def->def_name;
|
||||
const char *old = def->def.ty.old_type;
|
||||
char prefix[8]; /* enough to contain "struct ", including NUL */
|
||||
relation rel = def->def.ty.rel;
|
||||
|
||||
|
||||
if (!streq(name, old)) {
|
||||
if (streq(old, "string")) {
|
||||
old = "char";
|
||||
rel = REL_POINTER;
|
||||
} else
|
||||
if (streq(old, "opaque")) {
|
||||
old = "char";
|
||||
} else
|
||||
if (streq(old, "bool")) {
|
||||
old = "bool_t";
|
||||
}
|
||||
if (undefined2(old, name) && def->def.ty.old_prefix) {
|
||||
s_print(prefix, "%s ", def->def.ty.old_prefix);
|
||||
} else {
|
||||
prefix[0] = 0;
|
||||
}
|
||||
f_print(fout, "typedef ");
|
||||
switch (rel) {
|
||||
case REL_ARRAY:
|
||||
f_print(fout, "struct {\n");
|
||||
f_print(fout, "\tu_int %s_len;\n", name);
|
||||
f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name);
|
||||
f_print(fout, "} %s", name);
|
||||
break;
|
||||
case REL_POINTER:
|
||||
f_print(fout, "%s%s *%s", prefix, old, name);
|
||||
break;
|
||||
case REL_VECTOR:
|
||||
f_print(fout, "%s%s %s[%s]", prefix, old, name,
|
||||
def->def.ty.array_max);
|
||||
break;
|
||||
case REL_ALIAS:
|
||||
f_print(fout, "%s%s %s", prefix, old, name);
|
||||
break;
|
||||
}
|
||||
f_print(fout, ";\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pdeclaration(const char *name, declaration *dec, int tab,
|
||||
const char *separator)
|
||||
{
|
||||
char buf[8]; /* enough to hold "struct ", include NUL */
|
||||
const char *prefix;
|
||||
const char *type;
|
||||
|
||||
if (streq(dec->type, "void")) {
|
||||
return;
|
||||
}
|
||||
tabify(fout, tab);
|
||||
if (streq(dec->type, name) && !dec->prefix) {
|
||||
f_print(fout, "struct ");
|
||||
}
|
||||
if (streq(dec->type, "string")) {
|
||||
f_print(fout, "char *%s", dec->name);
|
||||
} else {
|
||||
prefix = "";
|
||||
if (streq(dec->type, "bool")) {
|
||||
type = "bool_t";
|
||||
} else
|
||||
if (streq(dec->type, "opaque")) {
|
||||
type = "char";
|
||||
} else {
|
||||
if (dec->prefix) {
|
||||
s_print(buf, "%s ", dec->prefix);
|
||||
prefix = buf;
|
||||
}
|
||||
type = dec->type;
|
||||
}
|
||||
switch (dec->rel) {
|
||||
case REL_ALIAS:
|
||||
f_print(fout, "%s%s %s", prefix, type, dec->name);
|
||||
break;
|
||||
case REL_VECTOR:
|
||||
f_print(fout, "%s%s %s[%s]", prefix, type, dec->name,
|
||||
dec->array_max);
|
||||
break;
|
||||
case REL_POINTER:
|
||||
f_print(fout, "%s%s *%s", prefix, type, dec->name);
|
||||
break;
|
||||
case REL_ARRAY:
|
||||
f_print(fout, "struct {\n");
|
||||
tabify(fout, tab);
|
||||
f_print(fout, "\tu_int %s_len;\n", dec->name);
|
||||
tabify(fout, tab);
|
||||
f_print(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name);
|
||||
tabify(fout, tab);
|
||||
f_print(fout, "} %s", dec->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
f_print(fout, "%s", separator);
|
||||
}
|
||||
|
||||
static int
|
||||
undefined2(const char *type, const char *stop)
|
||||
{
|
||||
list *l;
|
||||
definition *def;
|
||||
|
||||
for (l = defined; l != NULL; l = l->next) {
|
||||
def = (definition *) l->val;
|
||||
if (def->def_kind != DEF_PROGRAM) {
|
||||
if (streq(def->def_name, stop)) {
|
||||
return (1);
|
||||
} else
|
||||
if (streq(def->def_name, type)) {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,618 +0,0 @@
|
||||
/* $NetBSD: rpc_parse.c,v 1.21 2015/05/09 23:29:51 dholland Exp $ */
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user or with the express written consent of
|
||||
* Sun Microsystems, Inc.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(__RCSID) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI";
|
||||
#else
|
||||
__RCSID("$NetBSD: rpc_parse.c,v 1.21 2015/05/09 23:29:51 dholland Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* rpc_parse.c, Parser for the RPC protocol compiler
|
||||
* Copyright (C) 1987 Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "rpc/types.h"
|
||||
#include "rpc_scan.h"
|
||||
#include "rpc_parse.h"
|
||||
#include "rpc_util.h"
|
||||
|
||||
#define ARGNAME "arg"
|
||||
|
||||
static void isdefined(definition *);
|
||||
static void def_struct(definition *);
|
||||
static void def_program(definition *);
|
||||
static void def_enum(definition *);
|
||||
static void def_const(definition *);
|
||||
static void def_union(definition *);
|
||||
static void check_type_name(const char *, int);
|
||||
static void def_typedef(definition *);
|
||||
static void get_declaration(declaration *, defkind);
|
||||
static void get_prog_declaration(declaration *, defkind, int);
|
||||
static void get_type(const char **, const char **, defkind);
|
||||
static void unsigned_dec(const char **);
|
||||
|
||||
/*
|
||||
* return the next definition you see
|
||||
*/
|
||||
definition *
|
||||
get_definition(void)
|
||||
{
|
||||
definition *defp;
|
||||
token tok;
|
||||
|
||||
defp = ALLOC(definition);
|
||||
get_token(&tok);
|
||||
switch (tok.kind) {
|
||||
case TOK_STRUCT:
|
||||
def_struct(defp);
|
||||
break;
|
||||
case TOK_UNION:
|
||||
def_union(defp);
|
||||
break;
|
||||
case TOK_TYPEDEF:
|
||||
def_typedef(defp);
|
||||
break;
|
||||
case TOK_ENUM:
|
||||
def_enum(defp);
|
||||
break;
|
||||
case TOK_PROGRAM:
|
||||
def_program(defp);
|
||||
break;
|
||||
case TOK_CONST:
|
||||
def_const(defp);
|
||||
break;
|
||||
case TOK_EOF:
|
||||
free(defp);
|
||||
return (NULL);
|
||||
default:
|
||||
error("Expected definition keyword");
|
||||
}
|
||||
scan(TOK_SEMICOLON, &tok);
|
||||
isdefined(defp);
|
||||
return (defp);
|
||||
}
|
||||
|
||||
static void
|
||||
isdefined(definition *defp)
|
||||
{
|
||||
STOREVAL(&defined, defp);
|
||||
}
|
||||
|
||||
static void
|
||||
def_struct(definition *defp)
|
||||
{
|
||||
token tok;
|
||||
declaration dec;
|
||||
decl_list *decls;
|
||||
decl_list **tailp;
|
||||
|
||||
defp->def_kind = DEF_STRUCT;
|
||||
|
||||
scan(TOK_IDENT, &tok);
|
||||
defp->def_name = tok.str;
|
||||
scan(TOK_LBRACE, &tok);
|
||||
tailp = &defp->def.st.decls;
|
||||
do {
|
||||
get_declaration(&dec, DEF_STRUCT);
|
||||
decls = ALLOC(decl_list);
|
||||
decls->decl = dec;
|
||||
*tailp = decls;
|
||||
tailp = &decls->next;
|
||||
scan(TOK_SEMICOLON, &tok);
|
||||
peek(&tok);
|
||||
} while (tok.kind != TOK_RBRACE);
|
||||
get_token(&tok);
|
||||
*tailp = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
def_program(definition *defp)
|
||||
{
|
||||
token tok;
|
||||
declaration dec;
|
||||
decl_list *decls;
|
||||
decl_list **tailp;
|
||||
version_list *vlist;
|
||||
version_list **vtailp;
|
||||
proc_list *plist;
|
||||
proc_list **ptailp;
|
||||
int num_args;
|
||||
bool_t isvoid = FALSE; /* whether first argument is void */
|
||||
defp->def_kind = DEF_PROGRAM;
|
||||
scan(TOK_IDENT, &tok);
|
||||
defp->def_name = tok.str;
|
||||
scan(TOK_LBRACE, &tok);
|
||||
vtailp = &defp->def.pr.versions;
|
||||
tailp = &defp->def.st.decls;
|
||||
scan(TOK_VERSION, &tok);
|
||||
do {
|
||||
scan(TOK_IDENT, &tok);
|
||||
vlist = ALLOC(version_list);
|
||||
vlist->vers_name = tok.str;
|
||||
scan(TOK_LBRACE, &tok);
|
||||
ptailp = &vlist->procs;
|
||||
do {
|
||||
/* get result type */
|
||||
plist = ALLOC(proc_list);
|
||||
get_type(&plist->res_prefix, &plist->res_type,
|
||||
DEF_PROGRAM);
|
||||
if (streq(plist->res_type, "opaque")) {
|
||||
error("Illegal result type");
|
||||
}
|
||||
scan(TOK_IDENT, &tok);
|
||||
plist->proc_name = tok.str;
|
||||
scan(TOK_LPAREN, &tok);
|
||||
/* get args - first one */
|
||||
num_args = 1;
|
||||
isvoid = FALSE;
|
||||
/* type of DEF_PROGRAM in the first
|
||||
* get_prog_declaration and DEF_STURCT in the next
|
||||
* allows void as argument if it is the only argument */
|
||||
get_prog_declaration(&dec, DEF_PROGRAM, num_args);
|
||||
if (streq(dec.type, "void"))
|
||||
isvoid = TRUE;
|
||||
decls = ALLOC(decl_list);
|
||||
plist->args.decls = decls;
|
||||
decls->decl = dec;
|
||||
tailp = &decls->next;
|
||||
/* get args */
|
||||
while (peekscan(TOK_COMMA, &tok)) {
|
||||
num_args++;
|
||||
get_prog_declaration(&dec, DEF_STRUCT,
|
||||
num_args);
|
||||
decls = ALLOC(decl_list);
|
||||
decls->decl = dec;
|
||||
*tailp = decls;
|
||||
if (streq(dec.type, "void"))
|
||||
isvoid = TRUE;
|
||||
tailp = &decls->next;
|
||||
}
|
||||
/* multiple arguments are only allowed in newstyle */
|
||||
if (!newstyle && num_args > 1) {
|
||||
error("Only one argument is allowed");
|
||||
}
|
||||
if (isvoid && num_args > 1) {
|
||||
error("Illegal use of void in program definition");
|
||||
}
|
||||
*tailp = NULL;
|
||||
scan(TOK_RPAREN, &tok);
|
||||
scan(TOK_EQUAL, &tok);
|
||||
scan_num(&tok);
|
||||
scan(TOK_SEMICOLON, &tok);
|
||||
plist->proc_num = tok.str;
|
||||
plist->arg_num = num_args;
|
||||
*ptailp = plist;
|
||||
ptailp = &plist->next;
|
||||
peek(&tok);
|
||||
} while (tok.kind != TOK_RBRACE);
|
||||
*ptailp = NULL;
|
||||
*vtailp = vlist;
|
||||
vtailp = &vlist->next;
|
||||
scan(TOK_RBRACE, &tok);
|
||||
scan(TOK_EQUAL, &tok);
|
||||
scan_num(&tok);
|
||||
vlist->vers_num = tok.str;
|
||||
/* make the argument structure name for each arg */
|
||||
for (plist = vlist->procs; plist != NULL;
|
||||
plist = plist->next) {
|
||||
plist->args.argname = make_argname(plist->proc_name,
|
||||
vlist->vers_num);
|
||||
/* free the memory ?? */
|
||||
}
|
||||
scan(TOK_SEMICOLON, &tok);
|
||||
scan2(TOK_VERSION, TOK_RBRACE, &tok);
|
||||
} while (tok.kind == TOK_VERSION);
|
||||
scan(TOK_EQUAL, &tok);
|
||||
scan_num(&tok);
|
||||
defp->def.pr.prog_num = tok.str;
|
||||
*vtailp = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
def_enum(definition *defp)
|
||||
{
|
||||
token tok;
|
||||
enumval_list *elist;
|
||||
enumval_list **tailp;
|
||||
|
||||
defp->def_kind = DEF_ENUM;
|
||||
scan(TOK_IDENT, &tok);
|
||||
defp->def_name = tok.str;
|
||||
scan(TOK_LBRACE, &tok);
|
||||
tailp = &defp->def.en.vals;
|
||||
do {
|
||||
scan(TOK_IDENT, &tok);
|
||||
elist = ALLOC(enumval_list);
|
||||
elist->name = tok.str;
|
||||
elist->assignment = NULL;
|
||||
scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
|
||||
if (tok.kind == TOK_EQUAL) {
|
||||
scan_num(&tok);
|
||||
elist->assignment = tok.str;
|
||||
scan2(TOK_COMMA, TOK_RBRACE, &tok);
|
||||
}
|
||||
*tailp = elist;
|
||||
tailp = &elist->next;
|
||||
} while (tok.kind != TOK_RBRACE);
|
||||
*tailp = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
def_const(definition *defp)
|
||||
{
|
||||
token tok;
|
||||
|
||||
defp->def_kind = DEF_CONST;
|
||||
scan(TOK_IDENT, &tok);
|
||||
defp->def_name = tok.str;
|
||||
scan(TOK_EQUAL, &tok);
|
||||
scan2(TOK_IDENT, TOK_STRCONST, &tok);
|
||||
defp->def.co = tok.str;
|
||||
}
|
||||
|
||||
static void
|
||||
def_union(definition *defp)
|
||||
{
|
||||
token tok;
|
||||
declaration dec;
|
||||
case_list *cases;
|
||||
case_list **tailp;
|
||||
|
||||
defp->def_kind = DEF_UNION;
|
||||
scan(TOK_IDENT, &tok);
|
||||
defp->def_name = tok.str;
|
||||
scan(TOK_SWITCH, &tok);
|
||||
scan(TOK_LPAREN, &tok);
|
||||
get_declaration(&dec, DEF_UNION);
|
||||
defp->def.un.enum_decl = dec;
|
||||
tailp = &defp->def.un.cases;
|
||||
scan(TOK_RPAREN, &tok);
|
||||
scan(TOK_LBRACE, &tok);
|
||||
scan(TOK_CASE, &tok);
|
||||
while (tok.kind == TOK_CASE) {
|
||||
scan2(TOK_IDENT, TOK_CHARCONST, &tok);
|
||||
cases = ALLOC(case_list);
|
||||
cases->case_name = tok.str;
|
||||
scan(TOK_COLON, &tok);
|
||||
/* now peek at next token */
|
||||
if (peekscan(TOK_CASE, &tok)) {
|
||||
|
||||
do {
|
||||
scan2(TOK_IDENT, TOK_CHARCONST, &tok);
|
||||
cases->contflag = 1; /* continued case
|
||||
* statement */
|
||||
*tailp = cases;
|
||||
tailp = &cases->next;
|
||||
cases = ALLOC(case_list);
|
||||
cases->case_name = tok.str;
|
||||
scan(TOK_COLON, &tok);
|
||||
|
||||
} while (peekscan(TOK_CASE, &tok));
|
||||
}
|
||||
get_declaration(&dec, DEF_UNION);
|
||||
cases->case_decl = dec;
|
||||
cases->contflag = 0; /* no continued case statement */
|
||||
*tailp = cases;
|
||||
tailp = &cases->next;
|
||||
scan(TOK_SEMICOLON, &tok);
|
||||
|
||||
scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
|
||||
}
|
||||
*tailp = NULL;
|
||||
if (tok.kind == TOK_DEFAULT) {
|
||||
scan(TOK_COLON, &tok);
|
||||
get_declaration(&dec, DEF_UNION);
|
||||
defp->def.un.default_decl = ALLOC(declaration);
|
||||
*defp->def.un.default_decl = dec;
|
||||
scan(TOK_SEMICOLON, &tok);
|
||||
scan(TOK_RBRACE, &tok);
|
||||
} else {
|
||||
defp->def.un.default_decl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *const reserved_words[] = {
|
||||
"array",
|
||||
"bytes",
|
||||
"destroy",
|
||||
"free",
|
||||
"getpos",
|
||||
"inline",
|
||||
"pointer",
|
||||
"reference",
|
||||
"setpos",
|
||||
"sizeof",
|
||||
"union",
|
||||
"vector",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *const reserved_types[] = {
|
||||
"opaque",
|
||||
"string",
|
||||
NULL
|
||||
};
|
||||
/* check that the given name is not one that would eventually result in
|
||||
xdr routines that would conflict with internal XDR routines. */
|
||||
static void
|
||||
check_type_name(const char *name, int new_type)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; reserved_words[i] != NULL; i++) {
|
||||
if (strcmp(name, reserved_words[i]) == 0) {
|
||||
error("Illegal (reserved) name '%s' in type definition", name);
|
||||
}
|
||||
}
|
||||
if (new_type) {
|
||||
for (i = 0; reserved_types[i] != NULL; i++) {
|
||||
if (strcmp(name, reserved_types[i]) == 0) {
|
||||
error("Illegal (reserved) name '%s' in type definition", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
def_typedef(definition *defp)
|
||||
{
|
||||
declaration dec;
|
||||
|
||||
defp->def_kind = DEF_TYPEDEF;
|
||||
get_declaration(&dec, DEF_TYPEDEF);
|
||||
defp->def_name = dec.name;
|
||||
check_type_name(dec.name, 1);
|
||||
defp->def.ty.old_prefix = dec.prefix;
|
||||
defp->def.ty.old_type = dec.type;
|
||||
defp->def.ty.rel = dec.rel;
|
||||
defp->def.ty.array_max = dec.array_max;
|
||||
}
|
||||
|
||||
static void
|
||||
get_declaration(declaration *dec, defkind dkind)
|
||||
{
|
||||
token tok;
|
||||
|
||||
get_type(&dec->prefix, &dec->type, dkind);
|
||||
dec->rel = REL_ALIAS;
|
||||
if (streq(dec->type, "void")) {
|
||||
return;
|
||||
}
|
||||
check_type_name(dec->type, 0);
|
||||
|
||||
scan2(TOK_STAR, TOK_IDENT, &tok);
|
||||
if (tok.kind == TOK_STAR) {
|
||||
dec->rel = REL_POINTER;
|
||||
scan(TOK_IDENT, &tok);
|
||||
}
|
||||
dec->name = tok.str;
|
||||
if (peekscan(TOK_LBRACKET, &tok)) {
|
||||
if (dec->rel == REL_POINTER) {
|
||||
error("No array-of-pointer declarations -- use typedef");
|
||||
}
|
||||
dec->rel = REL_VECTOR;
|
||||
scan_num(&tok);
|
||||
dec->array_max = tok.str;
|
||||
scan(TOK_RBRACKET, &tok);
|
||||
} else
|
||||
if (peekscan(TOK_LANGLE, &tok)) {
|
||||
if (dec->rel == REL_POINTER) {
|
||||
error("No array-of-pointer declarations -- use typedef");
|
||||
}
|
||||
dec->rel = REL_ARRAY;
|
||||
if (peekscan(TOK_RANGLE, &tok)) {
|
||||
dec->array_max = "(u_int)~0";
|
||||
/* unspecified size, use * max */
|
||||
} else {
|
||||
scan_num(&tok);
|
||||
dec->array_max = tok.str;
|
||||
scan(TOK_RANGLE, &tok);
|
||||
}
|
||||
}
|
||||
if (streq(dec->type, "opaque")) {
|
||||
if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
|
||||
error("Array declaration expected");
|
||||
}
|
||||
} else
|
||||
if (streq(dec->type, "string")) {
|
||||
if (dec->rel != REL_ARRAY) {
|
||||
error("Variable-length array declaration expected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_prog_declaration(declaration *dec, defkind dkind, int num /* arg number */)
|
||||
{
|
||||
token tok;
|
||||
char name[255]; /* argument name */
|
||||
|
||||
if (dkind == DEF_PROGRAM) {
|
||||
peek(&tok);
|
||||
if (tok.kind == TOK_RPAREN) { /* no arguments */
|
||||
dec->rel = REL_ALIAS;
|
||||
dec->type = "void";
|
||||
dec->prefix = NULL;
|
||||
dec->name = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
get_type(&dec->prefix, &dec->type, dkind);
|
||||
dec->rel = REL_ALIAS;
|
||||
if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */
|
||||
strcpy(name, tok.str);
|
||||
else
|
||||
sprintf(name, "%s%d", ARGNAME, num); /* default name of
|
||||
* argument */
|
||||
|
||||
dec->name = strdup(name);
|
||||
|
||||
if (streq(dec->type, "void")) {
|
||||
return;
|
||||
}
|
||||
if (streq(dec->type, "opaque")) {
|
||||
error("Opaque -- illegal argument type");
|
||||
}
|
||||
if (peekscan(TOK_STAR, &tok)) {
|
||||
if (streq(dec->type, "string")) {
|
||||
error("Pointer to string not allowed in program arguments\n");
|
||||
}
|
||||
dec->rel = REL_POINTER;
|
||||
if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */
|
||||
dec->name = strdup(tok.str);
|
||||
}
|
||||
if (peekscan(TOK_LANGLE, &tok)) {
|
||||
if (!streq(dec->type, "string")) {
|
||||
error("Arrays cannot be declared as arguments to procedures -- use typedef");
|
||||
}
|
||||
dec->rel = REL_ARRAY;
|
||||
if (peekscan(TOK_RANGLE, &tok)) {
|
||||
dec->array_max = "(u_int)~0";
|
||||
/* unspecified size, use max */
|
||||
} else {
|
||||
scan_num(&tok);
|
||||
dec->array_max = tok.str;
|
||||
scan(TOK_RANGLE, &tok);
|
||||
}
|
||||
}
|
||||
if (streq(dec->type, "string")) {
|
||||
if (dec->rel != REL_ARRAY) { /* .x specifies just string as
|
||||
* type of argument - make it
|
||||
* string<> */
|
||||
dec->rel = REL_ARRAY;
|
||||
dec->array_max = "(u_int)~0";
|
||||
/* unspecified size, use max */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
get_type(const char **prefixp, const char **typep, defkind dkind)
|
||||
{
|
||||
token tok;
|
||||
|
||||
*prefixp = NULL;
|
||||
get_token(&tok);
|
||||
switch (tok.kind) {
|
||||
case TOK_IDENT:
|
||||
*typep = tok.str;
|
||||
break;
|
||||
case TOK_STRUCT:
|
||||
case TOK_ENUM:
|
||||
case TOK_UNION:
|
||||
*prefixp = tok.str;
|
||||
scan(TOK_IDENT, &tok);
|
||||
*typep = tok.str;
|
||||
break;
|
||||
case TOK_UNSIGNED:
|
||||
unsigned_dec(typep);
|
||||
break;
|
||||
case TOK_SHORT:
|
||||
*typep = "short";
|
||||
(void) peekscan(TOK_INT, &tok);
|
||||
break;
|
||||
case TOK_LONG:
|
||||
*typep = "long";
|
||||
(void) peekscan(TOK_INT, &tok);
|
||||
break;
|
||||
case TOK_HYPER:
|
||||
*typep = "longlong_t";
|
||||
(void) peekscan(TOK_INT, &tok);
|
||||
break;
|
||||
case TOK_VOID:
|
||||
if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
|
||||
error("Void is allowed only inside union and program definitions with one argument");
|
||||
}
|
||||
*typep = tok.str;
|
||||
break;
|
||||
case TOK_STRING:
|
||||
case TOK_OPAQUE:
|
||||
case TOK_CHAR:
|
||||
case TOK_INT:
|
||||
case TOK_FLOAT:
|
||||
case TOK_DOUBLE:
|
||||
case TOK_BOOL:
|
||||
case TOK_QUAD:
|
||||
*typep = tok.str;
|
||||
break;
|
||||
default:
|
||||
error("Type specifier expected");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unsigned_dec(const char **typep)
|
||||
{
|
||||
token tok;
|
||||
|
||||
peek(&tok);
|
||||
switch (tok.kind) {
|
||||
case TOK_CHAR:
|
||||
get_token(&tok);
|
||||
*typep = "u_char";
|
||||
break;
|
||||
case TOK_SHORT:
|
||||
get_token(&tok);
|
||||
*typep = "u_short";
|
||||
(void) peekscan(TOK_INT, &tok);
|
||||
break;
|
||||
case TOK_LONG:
|
||||
get_token(&tok);
|
||||
*typep = "u_long";
|
||||
(void) peekscan(TOK_INT, &tok);
|
||||
break;
|
||||
case TOK_HYPER:
|
||||
get_token(&tok);
|
||||
*typep = "u_longlong_t";
|
||||
(void) peekscan(TOK_INT, &tok);
|
||||
break;
|
||||
case TOK_INT:
|
||||
get_token(&tok);
|
||||
*typep = "u_int";
|
||||
break;
|
||||
default:
|
||||
*typep = "u_int";
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
/* $NetBSD: rpc_parse.h,v 1.6 2015/05/09 21:44:47 christos Exp $ */
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user or with the express written consent of
|
||||
* Sun Microsystems, Inc.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
/* @(#)rpc_parse.h 1.3 90/08/29 (C) 1987 SMI */
|
||||
|
||||
/*
|
||||
* rpc_parse.h, Definitions for the RPCL parser
|
||||
*/
|
||||
|
||||
enum defkind {
|
||||
DEF_CONST,
|
||||
DEF_STRUCT,
|
||||
DEF_UNION,
|
||||
DEF_ENUM,
|
||||
DEF_TYPEDEF,
|
||||
DEF_PROGRAM
|
||||
};
|
||||
typedef enum defkind defkind;
|
||||
|
||||
typedef const char *const_def;
|
||||
|
||||
enum relation {
|
||||
REL_VECTOR, /* fixed length array */
|
||||
REL_ARRAY, /* variable length array */
|
||||
REL_POINTER, /* pointer */
|
||||
REL_ALIAS, /* simple */
|
||||
};
|
||||
typedef enum relation relation;
|
||||
|
||||
struct typedef_def {
|
||||
const char *old_prefix;
|
||||
const char *old_type;
|
||||
relation rel;
|
||||
const char *array_max;
|
||||
};
|
||||
typedef struct typedef_def typedef_def;
|
||||
|
||||
struct enumval_list {
|
||||
const char *name;
|
||||
const char *assignment;
|
||||
struct enumval_list *next;
|
||||
};
|
||||
typedef struct enumval_list enumval_list;
|
||||
|
||||
struct enum_def {
|
||||
enumval_list *vals;
|
||||
};
|
||||
typedef struct enum_def enum_def;
|
||||
|
||||
struct declaration {
|
||||
const char *prefix;
|
||||
const char *type;
|
||||
const char *name;
|
||||
relation rel;
|
||||
const char *array_max;
|
||||
};
|
||||
typedef struct declaration declaration;
|
||||
|
||||
struct decl_list {
|
||||
declaration decl;
|
||||
struct decl_list *next;
|
||||
};
|
||||
typedef struct decl_list decl_list;
|
||||
|
||||
struct struct_def {
|
||||
decl_list *decls;
|
||||
};
|
||||
typedef struct struct_def struct_def;
|
||||
|
||||
struct case_list {
|
||||
const char *case_name;
|
||||
int contflag;
|
||||
declaration case_decl;
|
||||
struct case_list *next;
|
||||
};
|
||||
typedef struct case_list case_list;
|
||||
|
||||
struct union_def {
|
||||
declaration enum_decl;
|
||||
case_list *cases;
|
||||
declaration *default_decl;
|
||||
};
|
||||
typedef struct union_def union_def;
|
||||
|
||||
struct arg_list {
|
||||
char *argname; /* name of struct for arg*/
|
||||
decl_list *decls;
|
||||
};
|
||||
|
||||
typedef struct arg_list arg_list;
|
||||
|
||||
struct proc_list {
|
||||
const char *proc_name;
|
||||
const char *proc_num;
|
||||
arg_list args;
|
||||
int arg_num;
|
||||
const char *res_type;
|
||||
const char *res_prefix;
|
||||
struct proc_list *next;
|
||||
};
|
||||
typedef struct proc_list proc_list;
|
||||
|
||||
struct version_list {
|
||||
const char *vers_name;
|
||||
const char *vers_num;
|
||||
proc_list *procs;
|
||||
struct version_list *next;
|
||||
};
|
||||
typedef struct version_list version_list;
|
||||
|
||||
struct program_def {
|
||||
const char *prog_num;
|
||||
version_list *versions;
|
||||
};
|
||||
typedef struct program_def program_def;
|
||||
|
||||
struct definition {
|
||||
const char *def_name;
|
||||
defkind def_kind;
|
||||
union {
|
||||
const_def co;
|
||||
struct_def st;
|
||||
union_def un;
|
||||
enum_def en;
|
||||
typedef_def ty;
|
||||
program_def pr;
|
||||
} def;
|
||||
};
|
||||
typedef struct definition definition;
|
||||
|
||||
definition *get_definition(void);
|
||||
|
||||
struct bas_type
|
||||
{
|
||||
const char *name;
|
||||
int length;
|
||||
struct bas_type *next;
|
||||
};
|
||||
|
||||
typedef struct bas_type bas_type;
|
||||
@@ -1,275 +0,0 @@
|
||||
/* $NetBSD: rpc_sample.c,v 1.13 2013/12/15 00:40:17 christos Exp $ */
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user or with the express written consent of
|
||||
* Sun Microsystems, Inc.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(__RCSID) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)rpc_sample.c 1.1 90/08/30 (C) 1987 SMI";
|
||||
#else
|
||||
__RCSID("$NetBSD: rpc_sample.c,v 1.13 2013/12/15 00:40:17 christos Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* rpc_sample.c, Sample client-server code outputter for the RPC protocol compiler
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rpc_scan.h"
|
||||
#include "rpc_parse.h"
|
||||
#include "rpc_util.h"
|
||||
|
||||
static char RQSTP[] = "rqstp";
|
||||
|
||||
static void write_sample_client(const char *, version_list *);
|
||||
static void write_sample_server(definition *);
|
||||
static void return_type(proc_list *);
|
||||
|
||||
void
|
||||
write_sample_svc(definition *def)
|
||||
{
|
||||
|
||||
if (def->def_kind != DEF_PROGRAM)
|
||||
return;
|
||||
write_sample_server(def);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
write_sample_clnt(definition *def)
|
||||
{
|
||||
version_list *vp;
|
||||
int count = 0;
|
||||
|
||||
if (def->def_kind != DEF_PROGRAM)
|
||||
return (0);
|
||||
/* generate sample code for each version */
|
||||
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
|
||||
write_sample_client(def->def_name, vp);
|
||||
++count;
|
||||
}
|
||||
return (count);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
write_sample_client(const char *program_name, version_list *vp)
|
||||
{
|
||||
proc_list *proc;
|
||||
decl_list *l;
|
||||
|
||||
f_print(fout, "\n\nvoid\n");
|
||||
pvname(program_name, vp->vers_num);
|
||||
f_print(fout, "(char *host)\n{\n");
|
||||
f_print(fout, "\tCLIENT *clnt;\n");
|
||||
|
||||
for (proc = vp->procs; proc != NULL; proc = proc->next) {
|
||||
/* print out declarations for arguments */
|
||||
if (proc->arg_num < 2 && !newstyle) {
|
||||
f_print(fout, "\t");
|
||||
if (streq(proc->args.decls->decl.type, "void"))
|
||||
f_print(fout, "char "); /* cannot have "void"
|
||||
* type */
|
||||
else
|
||||
ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1);
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
f_print(fout, "_arg;\n");
|
||||
} else {
|
||||
if (!streq(proc->args.decls->decl.type, "void")) {
|
||||
for (l = proc->args.decls; l != NULL; l = l->next) {
|
||||
f_print(fout, "\t");
|
||||
ptype(l->decl.prefix, l->decl.type, 1);
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
f_print(fout, "_%s;\n", l->decl.name);
|
||||
/* pdeclaration(proc->args.argname, &l->decl, 1, ";\n" );*/
|
||||
}
|
||||
}
|
||||
}
|
||||
/* print out declarations for results */
|
||||
f_print(fout, "\t");
|
||||
if (streq(proc->res_type, "void"))
|
||||
f_print(fout, "char"); /* cannot have "void"
|
||||
* type */
|
||||
else
|
||||
ptype(proc->res_prefix, proc->res_type, 1);
|
||||
if (!Mflag)
|
||||
f_print(fout, "*");
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
f_print(fout, "_res;\n");
|
||||
}
|
||||
f_print(fout, "\n");
|
||||
|
||||
/* generate creation of client handle */
|
||||
f_print(fout, "\tclnt = clnt_create(host, %s, %s, \"%s\");\n",
|
||||
program_name, vp->vers_name, tirpcflag ? "netpath" : "udp");
|
||||
f_print(fout, "\tif (clnt == NULL) {\n");
|
||||
f_print(fout, "\t\tclnt_pcreateerror(host);\n");
|
||||
f_print(fout, "\t\texit(1);\n\t}\n");
|
||||
|
||||
/* generate calls to procedures */
|
||||
for (proc = vp->procs; proc != NULL; proc = proc->next) {
|
||||
if (Mflag)
|
||||
f_print(fout, "\tif (");
|
||||
else {
|
||||
f_print(fout, "\t");
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
f_print(fout, "_res = ");
|
||||
}
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
if (proc->arg_num < 2 && !newstyle) {
|
||||
f_print(fout, "(");
|
||||
if (streq(proc->args.decls->decl.type, "void")) /* cast to void* */
|
||||
f_print(fout, "(void *)");
|
||||
f_print(fout, "&");
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
f_print(fout, "_arg, ");
|
||||
} else {
|
||||
if (streq(proc->args.decls->decl.type, "void")) {
|
||||
f_print(fout, "(clnt);\n");
|
||||
} else {
|
||||
f_print(fout, "(");
|
||||
for (l = proc->args.decls; l != NULL; l = l->next) {
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
f_print(fout, "_%s, ", l->decl.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Mflag) {
|
||||
f_print(fout, "&");
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
f_print(fout, "_res, clnt) != RPC_SUCCESS)\n");
|
||||
} else {
|
||||
f_print(fout, "clnt);\n");
|
||||
f_print(fout, "\tif (");
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
f_print(fout, "_res == NULL)\n");
|
||||
}
|
||||
f_print(fout, "\t\tclnt_perror(clnt, \"call failed\");\n");
|
||||
}
|
||||
|
||||
f_print(fout, "\tclnt_destroy(clnt);\n");
|
||||
f_print(fout, "}\n");
|
||||
}
|
||||
|
||||
static void
|
||||
write_sample_server(definition *def)
|
||||
{
|
||||
version_list *vp;
|
||||
proc_list *proc;
|
||||
|
||||
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
|
||||
for (proc = vp->procs; proc != NULL; proc = proc->next) {
|
||||
f_print(fout, "\n");
|
||||
if (Mflag)
|
||||
f_print(fout, "bool_t\n");
|
||||
else {
|
||||
return_type(proc);
|
||||
f_print(fout, "*\n");
|
||||
}
|
||||
pvname_svc(proc->proc_name, vp->vers_num);
|
||||
printarglist(proc, "result", RQSTP, "struct svc_req *");
|
||||
|
||||
f_print(fout, "{\n");
|
||||
if (Mflag) {
|
||||
f_print(fout, "\tbool_t retval = TRUE;\n");
|
||||
} else {
|
||||
f_print(fout, "\tstatic ");
|
||||
if (streq(proc->res_type, "void"))
|
||||
f_print(fout, "char "); /* cannot have void type */
|
||||
else
|
||||
return_type(proc);
|
||||
f_print(fout, "result;\n");
|
||||
}
|
||||
f_print(fout,
|
||||
"\n\t/*\n\t * insert server code here\n\t */\n\n");
|
||||
if (Mflag) {
|
||||
f_print(fout, "\treturn (retval);\n");
|
||||
} else {
|
||||
if (streq(proc->res_type, "void"))
|
||||
f_print(fout, "\treturn ((void *)&result);\n");
|
||||
else
|
||||
f_print(fout, "\treturn (&result);\n");
|
||||
}
|
||||
f_print(fout, "}\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
return_type(proc_list *plist)
|
||||
{
|
||||
ptype(plist->res_prefix, plist->res_type, 1);
|
||||
}
|
||||
|
||||
void
|
||||
add_sample_msg(void)
|
||||
{
|
||||
f_print(fout, "/*\n");
|
||||
f_print(fout, " * This is sample code generated by rpcgen.\n");
|
||||
f_print(fout, " * These are only templates and you can use them\n");
|
||||
f_print(fout, " * as a guideline for developing your own functions.\n");
|
||||
f_print(fout, " */\n\n");
|
||||
}
|
||||
|
||||
void
|
||||
write_sample_clnt_main(void)
|
||||
{
|
||||
list *l;
|
||||
definition *def;
|
||||
version_list *vp;
|
||||
|
||||
f_print(fout, "\n\n");
|
||||
f_print(fout, "int\nmain(int argc, char *argv[])\n{\n");
|
||||
f_print(fout, "\tchar *host;");
|
||||
f_print(fout, "\n\n\tif (argc < 2) {");
|
||||
f_print(fout, "\n\t\tprintf(\"usage: %%s server_host\\n\", argv[0]);\n");
|
||||
f_print(fout, "\t\texit(1);\n\t}");
|
||||
f_print(fout, "\n\thost = argv[1];\n");
|
||||
|
||||
for (l = defined; l != NULL; l = l->next) {
|
||||
def = l->val;
|
||||
if (def->def_kind != DEF_PROGRAM) {
|
||||
continue;
|
||||
}
|
||||
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
|
||||
f_print(fout, "\t");
|
||||
pvname(def->def_name, vp->vers_num);
|
||||
f_print(fout, "(host);\n");
|
||||
}
|
||||
}
|
||||
f_print(fout, "\texit(0);\n");
|
||||
f_print(fout, "}\n");
|
||||
}
|
||||
@@ -1,492 +0,0 @@
|
||||
/* $NetBSD: rpc_scan.c,v 1.15 2015/05/09 23:28:43 dholland Exp $ */
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user or with the express written consent of
|
||||
* Sun Microsystems, Inc.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(__RCSID) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI";
|
||||
#else
|
||||
__RCSID("$NetBSD: rpc_scan.c,v 1.15 2015/05/09 23:28:43 dholland Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* rpc_scan.c, Scanner for the RPC protocol compiler
|
||||
* Copyright (C) 1987, Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "rpc_scan.h"
|
||||
#include "rpc_parse.h"
|
||||
#include "rpc_util.h"
|
||||
|
||||
#define startcomment(where) (where[0] == '/' && where[1] == '*')
|
||||
#define endcomment(where) (where[-1] == '*' && where[0] == '/')
|
||||
|
||||
static void unget_token(token *);
|
||||
static void findstrconst(char **, const char **);
|
||||
static void findchrconst(char **, const char **);
|
||||
static void findconst(char **, const char **);
|
||||
static void findkind(char **, token *);
|
||||
static int cppline(const char *);
|
||||
static int directive(const char *);
|
||||
static void printdirective(const char *);
|
||||
static void docppline(char *, int *, const char **);
|
||||
|
||||
static int pushed = 0; /* is a token pushed */
|
||||
static token lasttok; /* last token, if pushed */
|
||||
|
||||
/*
|
||||
* scan expecting 1 given token
|
||||
*/
|
||||
void
|
||||
scan(tok_kind expect, token *tokp)
|
||||
{
|
||||
get_token(tokp);
|
||||
if (tokp->kind != expect) {
|
||||
expected1(expect);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* scan expecting any of the 2 given tokens
|
||||
*/
|
||||
void
|
||||
scan2(tok_kind expect1, tok_kind expect2, token *tokp)
|
||||
{
|
||||
get_token(tokp);
|
||||
if (tokp->kind != expect1 && tokp->kind != expect2) {
|
||||
expected2(expect1, expect2);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* scan expecting any of the 3 given token
|
||||
*/
|
||||
void
|
||||
scan3(tok_kind expect1, tok_kind expect2, tok_kind expect3, token *tokp)
|
||||
{
|
||||
get_token(tokp);
|
||||
if (tokp->kind != expect1 && tokp->kind != expect2
|
||||
&& tokp->kind != expect3) {
|
||||
expected3(expect1, expect2, expect3);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* scan expecting a constant, possibly symbolic
|
||||
*/
|
||||
void
|
||||
scan_num(token *tokp)
|
||||
{
|
||||
get_token(tokp);
|
||||
switch (tokp->kind) {
|
||||
case TOK_IDENT:
|
||||
break;
|
||||
default:
|
||||
error("Expected constant or identifier");
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Peek at the next token
|
||||
*/
|
||||
void
|
||||
peek(token *tokp)
|
||||
{
|
||||
get_token(tokp);
|
||||
unget_token(tokp);
|
||||
}
|
||||
/*
|
||||
* Peek at the next token and scan it if it matches what you expect
|
||||
*/
|
||||
int
|
||||
peekscan(tok_kind expect, token *tokp)
|
||||
{
|
||||
peek(tokp);
|
||||
if (tokp->kind == expect) {
|
||||
get_token(tokp);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* Get the next token, printing out any directive that are encountered.
|
||||
*/
|
||||
void
|
||||
get_token(token *tokp)
|
||||
{
|
||||
int commenting;
|
||||
|
||||
if (pushed) {
|
||||
pushed = 0;
|
||||
*tokp = lasttok;
|
||||
return;
|
||||
}
|
||||
commenting = 0;
|
||||
for (;;) {
|
||||
if (*where == 0) {
|
||||
for (;;) {
|
||||
if (!fgets(curline, MAXLINESIZE, fin)) {
|
||||
tokp->kind = TOK_EOF;
|
||||
*where = 0;
|
||||
return;
|
||||
}
|
||||
linenum++;
|
||||
if (commenting) {
|
||||
break;
|
||||
} else
|
||||
if (cppline(curline)) {
|
||||
docppline(curline, &linenum,
|
||||
&infilename);
|
||||
} else
|
||||
if (directive(curline)) {
|
||||
printdirective(curline);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
where = curline;
|
||||
} else
|
||||
if (isspace((unsigned char)*where)) {
|
||||
while (isspace((unsigned char)*where)) {
|
||||
where++; /* eat */
|
||||
}
|
||||
} else
|
||||
if (commenting) {
|
||||
for (where++; *where; where++) {
|
||||
if (endcomment(where)) {
|
||||
where++;
|
||||
commenting--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
if (startcomment(where)) {
|
||||
where += 2;
|
||||
commenting++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 'where' is not whitespace, comment or directive Must be a token!
|
||||
*/
|
||||
switch (*where) {
|
||||
case ':':
|
||||
tokp->kind = TOK_COLON;
|
||||
where++;
|
||||
break;
|
||||
case ';':
|
||||
tokp->kind = TOK_SEMICOLON;
|
||||
where++;
|
||||
break;
|
||||
case ',':
|
||||
tokp->kind = TOK_COMMA;
|
||||
where++;
|
||||
break;
|
||||
case '=':
|
||||
tokp->kind = TOK_EQUAL;
|
||||
where++;
|
||||
break;
|
||||
case '*':
|
||||
tokp->kind = TOK_STAR;
|
||||
where++;
|
||||
break;
|
||||
case '[':
|
||||
tokp->kind = TOK_LBRACKET;
|
||||
where++;
|
||||
break;
|
||||
case ']':
|
||||
tokp->kind = TOK_RBRACKET;
|
||||
where++;
|
||||
break;
|
||||
case '{':
|
||||
tokp->kind = TOK_LBRACE;
|
||||
where++;
|
||||
break;
|
||||
case '}':
|
||||
tokp->kind = TOK_RBRACE;
|
||||
where++;
|
||||
break;
|
||||
case '(':
|
||||
tokp->kind = TOK_LPAREN;
|
||||
where++;
|
||||
break;
|
||||
case ')':
|
||||
tokp->kind = TOK_RPAREN;
|
||||
where++;
|
||||
break;
|
||||
case '<':
|
||||
tokp->kind = TOK_LANGLE;
|
||||
where++;
|
||||
break;
|
||||
case '>':
|
||||
tokp->kind = TOK_RANGLE;
|
||||
where++;
|
||||
break;
|
||||
|
||||
case '"':
|
||||
tokp->kind = TOK_STRCONST;
|
||||
findstrconst(&where, &tokp->str);
|
||||
break;
|
||||
case '\'':
|
||||
tokp->kind = TOK_CHARCONST;
|
||||
findchrconst(&where, &tokp->str);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
tokp->kind = TOK_IDENT;
|
||||
findconst(&where, &tokp->str);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!(isalpha((unsigned char)*where) || *where == '_')) {
|
||||
if (isprint((unsigned char)*where)) {
|
||||
error("Illegal character '%c' in file", *where);
|
||||
} else {
|
||||
error("Illegal character %d in file", *where);
|
||||
}
|
||||
}
|
||||
findkind(&where, tokp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unget_token(token *tokp)
|
||||
{
|
||||
lasttok = *tokp;
|
||||
pushed = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
findstrconst(char **str, const char **val)
|
||||
{
|
||||
char *p;
|
||||
int size;
|
||||
char *tmp;
|
||||
|
||||
p = *str;
|
||||
do {
|
||||
p++;
|
||||
} while (*p && *p != '"');
|
||||
if (*p == 0) {
|
||||
error("Unterminated string constant");
|
||||
}
|
||||
p++;
|
||||
size = p - *str;
|
||||
tmp = alloc(size + 1);
|
||||
(void) strncpy(tmp, *str, size);
|
||||
tmp[size] = 0;
|
||||
*val = tmp;
|
||||
*str = p;
|
||||
}
|
||||
|
||||
static void
|
||||
findchrconst(char **str, const char **val)
|
||||
{
|
||||
char *p;
|
||||
int size;
|
||||
char *tmp;
|
||||
|
||||
p = *str;
|
||||
do {
|
||||
p++;
|
||||
} while (*p && *p != '\'');
|
||||
if (*p == 0) {
|
||||
error("Unterminated string constant");
|
||||
}
|
||||
p++;
|
||||
size = p - *str;
|
||||
if (size != 3) {
|
||||
error("Empty character");
|
||||
}
|
||||
tmp = alloc(size + 1);
|
||||
(void) strncpy(tmp, *str, size);
|
||||
tmp[size] = 0;
|
||||
*val = tmp;
|
||||
*str = p;
|
||||
}
|
||||
|
||||
static void
|
||||
findconst(char **str, const char **val)
|
||||
{
|
||||
char *p;
|
||||
int size;
|
||||
char *tmp;
|
||||
|
||||
p = *str;
|
||||
if (*p == '0' && *(p + 1) == 'x') {
|
||||
p++;
|
||||
do {
|
||||
p++;
|
||||
} while (isxdigit((unsigned char)*p));
|
||||
} else {
|
||||
do {
|
||||
p++;
|
||||
} while (isdigit((unsigned char)*p));
|
||||
}
|
||||
size = p - *str;
|
||||
tmp = alloc(size + 1);
|
||||
(void) strncpy(tmp, *str, size);
|
||||
tmp[size] = 0;
|
||||
*val = tmp;
|
||||
*str = p;
|
||||
}
|
||||
|
||||
static const token symbols[] = {
|
||||
{TOK_CONST, "const"},
|
||||
{TOK_UNION, "union"},
|
||||
{TOK_SWITCH, "switch"},
|
||||
{TOK_CASE, "case"},
|
||||
{TOK_DEFAULT, "default"},
|
||||
{TOK_STRUCT, "struct"},
|
||||
{TOK_TYPEDEF, "typedef"},
|
||||
{TOK_ENUM, "enum"},
|
||||
{TOK_OPAQUE, "opaque"},
|
||||
{TOK_BOOL, "bool"},
|
||||
{TOK_VOID, "void"},
|
||||
{TOK_CHAR, "char"},
|
||||
{TOK_INT, "int"},
|
||||
{TOK_UNSIGNED, "unsigned"},
|
||||
{TOK_SHORT, "short"},
|
||||
{TOK_LONG, "long"},
|
||||
{TOK_HYPER, "hyper"},
|
||||
{TOK_FLOAT, "float"},
|
||||
{TOK_DOUBLE, "double"},
|
||||
{TOK_QUAD, "quadruple"},
|
||||
{TOK_STRING, "string"},
|
||||
{TOK_PROGRAM, "program"},
|
||||
{TOK_VERSION, "version"},
|
||||
{TOK_EOF, "??????"},
|
||||
};
|
||||
|
||||
static void
|
||||
findkind(char **mark, token *tokp)
|
||||
{
|
||||
int len;
|
||||
const token *s;
|
||||
char *str;
|
||||
char *tmp;
|
||||
|
||||
str = *mark;
|
||||
for (s = symbols; s->kind != TOK_EOF; s++) {
|
||||
len = strlen(s->str);
|
||||
if (strncmp(str, s->str, len) == 0) {
|
||||
if (!isalnum((unsigned char)str[len]) &&
|
||||
str[len] != '_') {
|
||||
tokp->kind = s->kind;
|
||||
tokp->str = s->str;
|
||||
*mark = str + len;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
tokp->kind = TOK_IDENT;
|
||||
for (len = 0; isalnum((unsigned char)str[len]) ||
|
||||
str[len] == '_'; len++);
|
||||
tmp = alloc(len + 1);
|
||||
(void) strncpy(tmp, str, len);
|
||||
tmp[len] = 0;
|
||||
tokp->str = tmp;
|
||||
*mark = str + len;
|
||||
}
|
||||
|
||||
static int
|
||||
cppline(const char *line)
|
||||
{
|
||||
return (line == curline && *line == '#');
|
||||
}
|
||||
|
||||
static int
|
||||
directive(const char *line)
|
||||
{
|
||||
return (line == curline && *line == '%');
|
||||
}
|
||||
|
||||
static void
|
||||
printdirective(const char *line)
|
||||
{
|
||||
f_print(fout, "%s", line + 1);
|
||||
}
|
||||
|
||||
static void
|
||||
docppline(char *line, int *lineno, const char **fname)
|
||||
{
|
||||
char *file;
|
||||
int num;
|
||||
char *p;
|
||||
|
||||
line++;
|
||||
while (isspace((unsigned char)*line)) {
|
||||
line++;
|
||||
}
|
||||
num = atoi(line);
|
||||
while (isdigit((unsigned char)*line)) {
|
||||
line++;
|
||||
}
|
||||
while (isspace((unsigned char)*line)) {
|
||||
line++;
|
||||
}
|
||||
if (*line != '"') {
|
||||
error("Preprocessor error");
|
||||
}
|
||||
line++;
|
||||
p = file = alloc(strlen(line) + 1);
|
||||
while (*line && *line != '"') {
|
||||
*p++ = *line++;
|
||||
}
|
||||
if (*line == 0) {
|
||||
error("Preprocessor error");
|
||||
}
|
||||
*p = 0;
|
||||
if (*file == 0) {
|
||||
*fname = NULL;
|
||||
free(file);
|
||||
} else {
|
||||
*fname = file;
|
||||
}
|
||||
*lineno = num - 1;
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
/* $NetBSD: rpc_scan.h,v 1.10 2015/05/09 21:44:47 christos Exp $ */
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user or with the express written consent of
|
||||
* Sun Microsystems, Inc.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
/* @(#)rpc_scan.h 1.3 90/08/29 (C) 1987 SMI */
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* rpc_scan.h, Definitions for the RPCL scanner
|
||||
*/
|
||||
|
||||
/*
|
||||
* kinds of tokens
|
||||
*/
|
||||
enum tok_kind {
|
||||
TOK_IDENT,
|
||||
TOK_CHARCONST,
|
||||
TOK_STRCONST,
|
||||
TOK_LPAREN,
|
||||
TOK_RPAREN,
|
||||
TOK_LBRACE,
|
||||
TOK_RBRACE,
|
||||
TOK_LBRACKET,
|
||||
TOK_RBRACKET,
|
||||
TOK_LANGLE,
|
||||
TOK_RANGLE,
|
||||
TOK_STAR,
|
||||
TOK_COMMA,
|
||||
TOK_EQUAL,
|
||||
TOK_COLON,
|
||||
TOK_SEMICOLON,
|
||||
TOK_CONST,
|
||||
TOK_STRUCT,
|
||||
TOK_UNION,
|
||||
TOK_SWITCH,
|
||||
TOK_CASE,
|
||||
TOK_DEFAULT,
|
||||
TOK_ENUM,
|
||||
TOK_TYPEDEF,
|
||||
TOK_INT,
|
||||
TOK_SHORT,
|
||||
TOK_LONG,
|
||||
TOK_HYPER,
|
||||
TOK_UNSIGNED,
|
||||
TOK_FLOAT,
|
||||
TOK_DOUBLE,
|
||||
TOK_QUAD,
|
||||
TOK_OPAQUE,
|
||||
TOK_CHAR,
|
||||
TOK_STRING,
|
||||
TOK_BOOL,
|
||||
TOK_VOID,
|
||||
TOK_PROGRAM,
|
||||
TOK_VERSION,
|
||||
TOK_EOF
|
||||
};
|
||||
typedef enum tok_kind tok_kind;
|
||||
|
||||
/*
|
||||
* a token
|
||||
*/
|
||||
struct token {
|
||||
tok_kind kind;
|
||||
const char *str;
|
||||
};
|
||||
typedef struct token token;
|
||||
|
||||
|
||||
/*
|
||||
* routine interface
|
||||
*/
|
||||
void scan(tok_kind, token *);
|
||||
void scan2(tok_kind, tok_kind, token *);
|
||||
void scan3(tok_kind, tok_kind, tok_kind, token *);
|
||||
void scan_num(token *);
|
||||
void peek(token *);
|
||||
int peekscan(tok_kind, token *);
|
||||
void get_token(token *);
|
||||
@@ -1,969 +0,0 @@
|
||||
/* $NetBSD: rpc_svcout.c,v 1.30 2015/09/20 15:52:11 kamil Exp $ */
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user or with the express written consent of
|
||||
* Sun Microsystems, Inc.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(__RCSID) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)rpc_svcout.c 1.29 89/03/30 (C) 1987 SMI";
|
||||
#else
|
||||
__RCSID("$NetBSD: rpc_svcout.c,v 1.30 2015/09/20 15:52:11 kamil Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rpc_scan.h"
|
||||
#include "rpc_parse.h"
|
||||
#include "rpc_util.h"
|
||||
|
||||
static char RQSTP[] = "rqstp";
|
||||
static char TRANSP[] = "transp";
|
||||
static char ARG[] = "argument";
|
||||
static char RESULT[] = "result";
|
||||
static char ROUTINE[] = "local";
|
||||
|
||||
static void p_xdrfunc(const char *, const char *);
|
||||
static void internal_proctype(proc_list *);
|
||||
static void write_real_program(definition *);
|
||||
static void write_program(definition *, const char *);
|
||||
static void printerr(const char *, const char *);
|
||||
static void printif(const char *, const char *, const char *, const char *);
|
||||
static void write_inetmost(char *);
|
||||
static void print_return(const char *);
|
||||
static void print_pmapunset(const char *);
|
||||
static void print_err_message(const char *);
|
||||
static void write_timeout_func(void);
|
||||
static void write_caller_func(void);
|
||||
static void write_pm_most(char *, int);
|
||||
static void write_rpc_svc_fg(char *, const char *);
|
||||
static void open_log_file(char *, const char *);
|
||||
static const char *aster(const char *);
|
||||
|
||||
char _errbuf[256]; /* For all messages */
|
||||
|
||||
static void
|
||||
p_xdrfunc(const char *rname, const char *typename)
|
||||
{
|
||||
f_print(fout, "\t\txdr_%s = (xdrproc_t)xdr_%s;\n", rname,
|
||||
stringfix(typename));
|
||||
}
|
||||
|
||||
static void
|
||||
internal_proctype(proc_list *plist)
|
||||
{
|
||||
f_print(fout, "static ");
|
||||
ptype(plist->res_prefix, plist->res_type, 1);
|
||||
if (!Mflag)
|
||||
f_print(fout, "*");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* write most of the service, that is, everything but the registrations.
|
||||
*/
|
||||
void
|
||||
write_most(char *infile /* our name */, int netflag, int nomain)
|
||||
{
|
||||
if (inetdflag || pmflag) {
|
||||
const char *var_type;
|
||||
var_type = (nomain ? "" : "static ");
|
||||
f_print(fout, "%sint _rpcpmstart;", var_type);
|
||||
f_print(fout, "\t\t/* Started by a port monitor ? */\n");
|
||||
f_print(fout, "%sint _rpcfdtype;", var_type);
|
||||
f_print(fout, "\t\t/* Whether Stream or Datagram ? */\n");
|
||||
if (timerflag) {
|
||||
f_print(fout, "%sint _rpcsvcdirty;", var_type);
|
||||
f_print(fout, "\t/* Still serving ? */\n");
|
||||
}
|
||||
write_svc_aux(nomain);
|
||||
}
|
||||
/* write out dispatcher and stubs */
|
||||
write_programs(nomain ? NULL : "static");
|
||||
|
||||
if (nomain)
|
||||
return;
|
||||
|
||||
f_print(fout, "\n\n");
|
||||
f_print(fout, "int main(int, char *[]);\n");
|
||||
f_print(fout, "\nint\n");
|
||||
f_print(fout, "main(int argc, char *argv[])\n");
|
||||
f_print(fout, "{\n");
|
||||
if (inetdflag) {
|
||||
write_inetmost(infile); /* Includes call to write_rpc_svc_fg() */
|
||||
} else {
|
||||
if (tirpcflag) {
|
||||
if (netflag) {
|
||||
f_print(fout, "\tSVCXPRT *%s;\n", TRANSP);
|
||||
f_print(fout, "\tstruct netconfig *nconf = NULL;\n");
|
||||
}
|
||||
f_print(fout, "\tpid_t pid;\n");
|
||||
f_print(fout, "\tint i;\n");
|
||||
f_print(fout, "\tchar mname[FMNAMESZ + 1];\n\n");
|
||||
write_pm_most(infile, netflag);
|
||||
f_print(fout, "\telse {\n");
|
||||
write_rpc_svc_fg(infile, "\t\t");
|
||||
f_print(fout, "\t}\n");
|
||||
} else {
|
||||
f_print(fout, "\tSVCXPRT *%s;\n", TRANSP);
|
||||
f_print(fout, "\n");
|
||||
print_pmapunset("\t");
|
||||
}
|
||||
}
|
||||
|
||||
if (logflag && !inetdflag) {
|
||||
open_log_file(infile, "\t");
|
||||
}
|
||||
}
|
||||
/*
|
||||
* write a registration for the given transport
|
||||
*/
|
||||
void
|
||||
write_netid_register(const char *transp)
|
||||
{
|
||||
list *l;
|
||||
definition *def;
|
||||
version_list *vp;
|
||||
const char *sp;
|
||||
char tmpbuf[32];
|
||||
|
||||
sp = "";
|
||||
f_print(fout, "\n");
|
||||
f_print(fout, "%s\tnconf = getnetconfigent(\"%s\");\n", sp, transp);
|
||||
f_print(fout, "%s\tif (nconf == NULL) {\n", sp);
|
||||
(void) sprintf(_errbuf, "cannot find %s netid.", transp);
|
||||
sprintf(tmpbuf, "%s\t\t", sp);
|
||||
print_err_message(tmpbuf);
|
||||
f_print(fout, "%s\t\texit(1);\n", sp);
|
||||
f_print(fout, "%s\t}\n", sp);
|
||||
f_print(fout, "%s\t%s = svc_tli_create(RPC_ANYFD, nconf, 0, 0, 0);\n",
|
||||
sp, TRANSP);
|
||||
f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
|
||||
(void) sprintf(_errbuf, "cannot create %s service.", transp);
|
||||
print_err_message(tmpbuf);
|
||||
f_print(fout, "%s\t\texit(1);\n", sp);
|
||||
f_print(fout, "%s\t}\n", sp);
|
||||
|
||||
for (l = defined; l != NULL; l = l->next) {
|
||||
def = (definition *) l->val;
|
||||
if (def->def_kind != DEF_PROGRAM) {
|
||||
continue;
|
||||
}
|
||||
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
|
||||
f_print(fout,
|
||||
"%s\t(void) rpcb_unset(%s, %s, nconf);\n",
|
||||
sp, def->def_name, vp->vers_name);
|
||||
f_print(fout,
|
||||
"%s\tif (!svc_reg(%s, %s, %s, ",
|
||||
sp, TRANSP, def->def_name, vp->vers_name);
|
||||
pvname(def->def_name, vp->vers_num);
|
||||
f_print(fout, ", nconf)) {\n");
|
||||
(void) sprintf(_errbuf, "unable to register (%s, %s, %s).",
|
||||
def->def_name, vp->vers_name, transp);
|
||||
print_err_message(tmpbuf);
|
||||
f_print(fout, "%s\t\texit(1);\n", sp);
|
||||
f_print(fout, "%s\t}\n", sp);
|
||||
}
|
||||
}
|
||||
f_print(fout, "%s\tfreenetconfigent(nconf);\n", sp);
|
||||
}
|
||||
/*
|
||||
* write a registration for the given transport for TLI
|
||||
*/
|
||||
void
|
||||
write_nettype_register(const char *transp)
|
||||
{
|
||||
list *l;
|
||||
definition *def;
|
||||
version_list *vp;
|
||||
|
||||
for (l = defined; l != NULL; l = l->next) {
|
||||
def = (definition *) l->val;
|
||||
if (def->def_kind != DEF_PROGRAM) {
|
||||
continue;
|
||||
}
|
||||
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
|
||||
f_print(fout, "\tif (!svc_create(");
|
||||
pvname(def->def_name, vp->vers_num);
|
||||
f_print(fout, ", %s, %s, \"%s\")) {\n ",
|
||||
def->def_name, vp->vers_name, transp);
|
||||
(void) sprintf(_errbuf,
|
||||
"unable to create (%s, %s) for %s.",
|
||||
def->def_name, vp->vers_name, transp);
|
||||
print_err_message("\t\t");
|
||||
f_print(fout, "\t\texit(1);\n");
|
||||
f_print(fout, "\t}\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* write the rest of the service
|
||||
*/
|
||||
void
|
||||
write_rest(void)
|
||||
{
|
||||
f_print(fout, "\n");
|
||||
if (inetdflag) {
|
||||
f_print(fout, "\tif (%s == NULL) {\n", TRANSP);
|
||||
(void) sprintf(_errbuf, "could not create a handle");
|
||||
print_err_message("\t\t");
|
||||
f_print(fout, "\t\texit(1);\n");
|
||||
f_print(fout, "\t}\n");
|
||||
if (timerflag) {
|
||||
f_print(fout, "\tif (_rpcpmstart) {\n");
|
||||
f_print(fout,
|
||||
"\t\t(void) signal(SIGALRM, (SIG_PF)closedown);\n");
|
||||
f_print(fout, "\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
|
||||
f_print(fout, "\t}\n");
|
||||
}
|
||||
}
|
||||
f_print(fout, "\tsvc_run();\n");
|
||||
(void) sprintf(_errbuf, "svc_run returned");
|
||||
print_err_message("\t");
|
||||
f_print(fout, "\texit(1);\n");
|
||||
f_print(fout, "\t/* NOTREACHED */\n");
|
||||
f_print(fout, "}\n");
|
||||
}
|
||||
|
||||
void
|
||||
write_programs(const char *storage)
|
||||
{
|
||||
list *l;
|
||||
definition *def;
|
||||
|
||||
/* write out stubs for procedure definitions */
|
||||
for (l = defined; l != NULL; l = l->next) {
|
||||
def = (definition *) l->val;
|
||||
if (def->def_kind == DEF_PROGRAM) {
|
||||
write_real_program(def);
|
||||
}
|
||||
}
|
||||
|
||||
/* write out dispatcher for each program */
|
||||
for (l = defined; l != NULL; l = l->next) {
|
||||
def = (definition *) l->val;
|
||||
if (def->def_kind == DEF_PROGRAM) {
|
||||
write_program(def, storage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/* write out definition of internal function (e.g. _printmsg_1(...))
|
||||
which calls server's definition of actual function (e.g. printmsg_1(...)).
|
||||
Unpacks single user argument of printmsg_1 to call-by-value format
|
||||
expected by printmsg_1. */
|
||||
static void
|
||||
write_real_program(definition *def)
|
||||
{
|
||||
version_list *vp;
|
||||
proc_list *proc;
|
||||
decl_list *l;
|
||||
|
||||
if (!newstyle)
|
||||
return; /* not needed for old style */
|
||||
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
|
||||
for (proc = vp->procs; proc != NULL; proc = proc->next) {
|
||||
f_print(fout, "\n");
|
||||
internal_proctype(proc);
|
||||
f_print(fout, "\n_");
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
f_print(fout, "(");
|
||||
/* arg name */
|
||||
if (proc->arg_num > 1)
|
||||
f_print(fout, "%s ",
|
||||
proc->args.argname);
|
||||
else
|
||||
ptype(proc->args.decls->decl.prefix,
|
||||
proc->args.decls->decl.type, 0);
|
||||
f_print(fout, "*argp, ");
|
||||
if (Mflag) {
|
||||
if (streq(proc->res_type, "void"))
|
||||
f_print(fout, "char ");
|
||||
else
|
||||
ptype(proc->res_prefix,
|
||||
proc->res_type, 0);
|
||||
f_print(fout, "%sresult, ",
|
||||
aster(proc->res_type));
|
||||
}
|
||||
f_print(fout, "struct svc_req *%s)\n", RQSTP);
|
||||
f_print(fout, "{\n");
|
||||
f_print(fout, "\treturn (");
|
||||
pvname_svc(proc->proc_name, vp->vers_num);
|
||||
f_print(fout, "(");
|
||||
if (proc->arg_num < 2) { /* single argument */
|
||||
if (!streq(proc->args.decls->decl.type, "void"))
|
||||
f_print(fout, "*argp, "); /* non-void */
|
||||
} else {
|
||||
for (l = proc->args.decls; l != NULL; l = l->next)
|
||||
f_print(fout, "argp->%s, ", l->decl.name);
|
||||
}
|
||||
f_print(fout, "%s));\n}\n", RQSTP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
write_program(definition *def, const char *storage)
|
||||
{
|
||||
version_list *vp;
|
||||
proc_list *proc;
|
||||
int filled;
|
||||
|
||||
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
|
||||
f_print(fout, "\n");
|
||||
if (storage != NULL) {
|
||||
f_print(fout, "%s ", storage);
|
||||
}
|
||||
f_print(fout, "void ");
|
||||
pvname(def->def_name, vp->vers_num);
|
||||
f_print(fout, "(struct svc_req *%s, ", RQSTP);
|
||||
f_print(fout, "SVCXPRT *%s);\n", TRANSP);
|
||||
f_print(fout, "\n");
|
||||
if (storage != NULL) {
|
||||
f_print(fout, "%s ", storage);
|
||||
}
|
||||
f_print(fout, "void\n");
|
||||
pvname(def->def_name, vp->vers_num);
|
||||
|
||||
f_print(fout, "(struct svc_req *%s, ", RQSTP);
|
||||
f_print(fout, "SVCXPRT *%s)\n", TRANSP);
|
||||
f_print(fout, "{\n");
|
||||
|
||||
filled = 0;
|
||||
f_print(fout, "\tunion {\n");
|
||||
for (proc = vp->procs; proc != NULL; proc = proc->next) {
|
||||
if (proc->arg_num < 2) { /* single argument */
|
||||
if (streq(proc->args.decls->decl.type,
|
||||
"void")) {
|
||||
continue;
|
||||
}
|
||||
filled = 1;
|
||||
f_print(fout, "\t\t");
|
||||
ptype(proc->args.decls->decl.prefix,
|
||||
proc->args.decls->decl.type, 0);
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
f_print(fout, "_arg;\n");
|
||||
|
||||
} else {
|
||||
filled = 1;
|
||||
f_print(fout, "\t\t%s", proc->args.argname);
|
||||
f_print(fout, " ");
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
f_print(fout, "_arg;\n");
|
||||
}
|
||||
}
|
||||
if (!filled) {
|
||||
f_print(fout, "\t\tint fill;\n");
|
||||
}
|
||||
f_print(fout, "\t} %s;\n", ARG);
|
||||
if (Mflag) {
|
||||
f_print(fout, "\tunion {\n");
|
||||
for (proc = vp->procs; proc != NULL; proc = proc->next) {
|
||||
f_print(fout, "\t\t");
|
||||
if (streq(proc->res_type, "void"))
|
||||
f_print(fout, "char ");
|
||||
else
|
||||
ptype(proc->res_prefix, proc->res_type,
|
||||
1);
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
f_print(fout, "_res;\n");
|
||||
}
|
||||
f_print(fout, "\t} %s;\n", RESULT);
|
||||
f_print(fout, "\tbool_t retval;\n");
|
||||
} else
|
||||
f_print(fout, "\tchar *%s;\n", RESULT);
|
||||
|
||||
f_print(fout, "\txdrproc_t xdr_%s, xdr_%s;\n", ARG, RESULT);
|
||||
if (Mflag)
|
||||
f_print(fout,
|
||||
"\tbool_t (*%s)(char *, void *, struct svc_req *);\n",
|
||||
ROUTINE);
|
||||
else
|
||||
f_print(fout,
|
||||
"\tchar *(*%s)(char *, struct svc_req *);\n",
|
||||
ROUTINE);
|
||||
|
||||
f_print(fout, "\n");
|
||||
|
||||
if (callerflag)
|
||||
f_print(fout, "\tcaller = transp;\n"); /* EVAS */
|
||||
if (timerflag)
|
||||
f_print(fout, "\t_rpcsvcdirty = 1;\n");
|
||||
f_print(fout, "\tswitch (%s->rq_proc) {\n", RQSTP);
|
||||
if (!nullproc(vp->procs)) {
|
||||
f_print(fout, "\tcase NULLPROC:\n");
|
||||
f_print(fout,
|
||||
"\t\t(void) svc_sendreply(%s, (xdrproc_t)xdr_void, NULL);\n", TRANSP);
|
||||
print_return("\t\t");
|
||||
f_print(fout, "\n");
|
||||
}
|
||||
for (proc = vp->procs; proc != NULL; proc = proc->next) {
|
||||
f_print(fout, "\tcase %s:\n", proc->proc_name);
|
||||
if (proc->arg_num < 2) { /* single argument */
|
||||
p_xdrfunc(ARG, proc->args.decls->decl.type);
|
||||
} else {
|
||||
p_xdrfunc(ARG, proc->args.argname);
|
||||
}
|
||||
p_xdrfunc(RESULT, proc->res_type);
|
||||
if (Mflag)
|
||||
f_print(fout,
|
||||
"\t\t%s = (bool_t (*)(char *, void *, struct svc_req *))",
|
||||
ROUTINE);
|
||||
else
|
||||
f_print(fout,
|
||||
"\t\t%s = (char *(*)(char *, struct svc_req *))",
|
||||
ROUTINE);
|
||||
|
||||
if (newstyle) { /* new style: calls internal routine */
|
||||
f_print(fout, "_");
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
} else {
|
||||
pvname_svc(proc->proc_name, vp->vers_num);
|
||||
}
|
||||
f_print(fout, ";\n");
|
||||
f_print(fout, "\t\tbreak;\n\n");
|
||||
}
|
||||
f_print(fout, "\tdefault:\n");
|
||||
printerr("noproc", TRANSP);
|
||||
print_return("\t\t");
|
||||
f_print(fout, "\t}\n");
|
||||
|
||||
f_print(fout, "\t(void) memset(&%s, 0, sizeof(%s));\n", ARG, ARG);
|
||||
printif("getargs", TRANSP, "(caddr_t)&", ARG);
|
||||
printerr("decode", TRANSP);
|
||||
print_return("\t\t");
|
||||
f_print(fout, "\t}\n");
|
||||
|
||||
if (Mflag)
|
||||
f_print(fout, "\tretval = (*%s)((char *)&%s, (void *)&%s, %s);\n",
|
||||
ROUTINE, ARG, RESULT, RQSTP);
|
||||
else
|
||||
f_print(fout, "\t%s = (*%s)((char *)&%s, %s);\n",
|
||||
RESULT, ROUTINE, ARG, RQSTP);
|
||||
if (Mflag)
|
||||
f_print(fout,
|
||||
"\tif (retval > 0 && !svc_sendreply(%s, xdr_%s, (char *)&%s)) {\n",
|
||||
TRANSP, RESULT, RESULT);
|
||||
else
|
||||
f_print(fout,
|
||||
"\tif (%s != NULL && !svc_sendreply(%s, xdr_%s, %s)) {\n",
|
||||
RESULT, TRANSP, RESULT, RESULT);
|
||||
printerr("systemerr", TRANSP);
|
||||
f_print(fout, "\t}\n");
|
||||
|
||||
printif("freeargs", TRANSP, "(caddr_t)&", ARG);
|
||||
(void) sprintf(_errbuf, "unable to free arguments");
|
||||
print_err_message("\t\t");
|
||||
f_print(fout, "\t\texit(1);\n");
|
||||
f_print(fout, "\t}\n");
|
||||
|
||||
if (Mflag) {
|
||||
f_print(fout, "\tif (!");
|
||||
pvname(def->def_name, vp->vers_num);
|
||||
f_print(fout, "_freeresult");
|
||||
f_print(fout, "(%s, xdr_%s, (caddr_t)&%s)) {\n",
|
||||
TRANSP, RESULT, RESULT);
|
||||
(void) sprintf(_errbuf, "unable to free results");
|
||||
print_err_message("\t\t");
|
||||
f_print(fout, "\t\texit(1);\n");
|
||||
f_print(fout, "\t}\n");
|
||||
}
|
||||
|
||||
print_return("\t");
|
||||
f_print(fout, "}\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
printerr(const char *err, const char *transp)
|
||||
{
|
||||
f_print(fout, "\t\tsvcerr_%s(%s);\n", err, transp);
|
||||
}
|
||||
|
||||
static void
|
||||
printif(const char *proc, const char *transp, const char *prefix, const char *arg)
|
||||
{
|
||||
f_print(fout, "\tif (!svc_%s(%s, xdr_%s, %s%s)) {\n",
|
||||
proc, transp, arg, prefix, arg);
|
||||
}
|
||||
|
||||
int
|
||||
nullproc(proc_list *proc)
|
||||
{
|
||||
for (; proc != NULL; proc = proc->next) {
|
||||
if (streq(proc->proc_num, "0")) {
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
write_inetmost(char *infile)
|
||||
{
|
||||
f_print(fout, "\tSVCXPRT *%s = NULL;\n", TRANSP);
|
||||
f_print(fout, "\tint sock;\n");
|
||||
f_print(fout, "\tint proto = 0;\n");
|
||||
f_print(fout, "\tstruct sockaddr_in saddr;\n");
|
||||
f_print(fout, "\tsocklen_t asize = (socklen_t)sizeof(saddr);\n");
|
||||
f_print(fout, "\n");
|
||||
f_print(fout,
|
||||
"\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
|
||||
f_print(fout, "\t\tsocklen_t ssize = (socklen_t)sizeof(int);\n\n");
|
||||
f_print(fout, "\t\tif (saddr.sin_family != AF_INET)\n");
|
||||
f_print(fout, "\t\t\texit(1);\n");
|
||||
f_print(fout, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n");
|
||||
f_print(fout, "\t\t\t\t(void *)&_rpcfdtype, &ssize) == -1)\n");
|
||||
f_print(fout, "\t\t\texit(1);\n");
|
||||
f_print(fout, "\t\tsock = 0;\n");
|
||||
f_print(fout, "\t\t_rpcpmstart = 1;\n");
|
||||
f_print(fout, "\t\tproto = 0;\n");
|
||||
open_log_file(infile, "\t\t");
|
||||
f_print(fout, "\t} else {\n");
|
||||
write_rpc_svc_fg(infile, "\t\t");
|
||||
f_print(fout, "\t\tsock = RPC_ANYSOCK;\n");
|
||||
print_pmapunset("\t\t");
|
||||
f_print(fout, "\t}\n");
|
||||
}
|
||||
|
||||
static void
|
||||
print_return(const char *space)
|
||||
{
|
||||
if (exitnow)
|
||||
f_print(fout, "%sexit(0);\n", space);
|
||||
else {
|
||||
if (timerflag)
|
||||
f_print(fout, "%s_rpcsvcdirty = 0;\n", space);
|
||||
f_print(fout, "%sreturn;\n", space);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_pmapunset(const char *space)
|
||||
{
|
||||
list *l;
|
||||
definition *def;
|
||||
version_list *vp;
|
||||
|
||||
for (l = defined; l != NULL; l = l->next) {
|
||||
def = (definition *) l->val;
|
||||
if (def->def_kind == DEF_PROGRAM) {
|
||||
for (vp = def->def.pr.versions; vp != NULL;
|
||||
vp = vp->next) {
|
||||
f_print(fout, "%s(void) pmap_unset(%s, %s);\n",
|
||||
space, def->def_name, vp->vers_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_err_message(const char *space)
|
||||
{
|
||||
if (logflag)
|
||||
f_print(fout, "%ssyslog(LOG_ERR, \"%s\");\n", space, _errbuf);
|
||||
else
|
||||
if (inetdflag || pmflag)
|
||||
f_print(fout, "%s_msgout(\"%s\");\n", space, _errbuf);
|
||||
else
|
||||
f_print(fout, "%sfprintf(stderr, \"%s\");\n", space, _errbuf);
|
||||
}
|
||||
/*
|
||||
* Write the server auxiliary function ( _msgout, timeout)
|
||||
*/
|
||||
void
|
||||
write_svc_aux(int nomain)
|
||||
{
|
||||
if (!logflag)
|
||||
write_msg_out();
|
||||
if (!nomain)
|
||||
write_timeout_func();
|
||||
if (callerflag) /* EVAS */
|
||||
write_caller_func(); /* EVAS */
|
||||
}
|
||||
/*
|
||||
* Write the _msgout function
|
||||
*/
|
||||
void
|
||||
write_msg_out(void)
|
||||
{
|
||||
f_print(fout, "\n");
|
||||
f_print(fout, "static\n");
|
||||
f_print(fout, "void _msgout(const char *msg)\n");
|
||||
f_print(fout, "{\n");
|
||||
f_print(fout, "#ifdef RPC_SVC_FG\n");
|
||||
if (inetdflag || pmflag)
|
||||
f_print(fout, "\tif (_rpcpmstart)\n");
|
||||
f_print(fout, "\t\tsyslog(LOG_ERR, \"%%s\", msg);\n");
|
||||
f_print(fout, "\telse\n");
|
||||
f_print(fout, "\t\t(void) fprintf(stderr, \"%%s\\n\", msg);\n");
|
||||
f_print(fout, "#else\n");
|
||||
f_print(fout, "\tsyslog(LOG_ERR, \"%%s\", msg);\n");
|
||||
f_print(fout, "#endif\n");
|
||||
f_print(fout, "}\n");
|
||||
}
|
||||
/*
|
||||
* Write the timeout function
|
||||
*/
|
||||
static void
|
||||
write_timeout_func(void)
|
||||
{
|
||||
if (!timerflag)
|
||||
return;
|
||||
f_print(fout, "\n");
|
||||
f_print(fout, "static void closedown(void);\n");
|
||||
f_print(fout, "\n");
|
||||
f_print(fout, "static void\n");
|
||||
f_print(fout, "closedown(void)\n");
|
||||
f_print(fout, "{\n");
|
||||
f_print(fout, "\tif (_rpcsvcdirty == 0) {\n");
|
||||
f_print(fout, "\t\textern fd_set svc_fdset;\n");
|
||||
f_print(fout, "\t\tstatic int size;\n");
|
||||
f_print(fout, "\t\tint i, openfd;\n");
|
||||
if (tirpcflag && pmflag) {
|
||||
f_print(fout, "\t\tstruct t_info tinfo;\n\n");
|
||||
f_print(fout, "\t\tif (!t_getinfo(0, &tinfo) && (tinfo.servtype == T_CLTS))\n");
|
||||
} else {
|
||||
f_print(fout, "\n\t\tif (_rpcfdtype == SOCK_DGRAM)\n");
|
||||
}
|
||||
f_print(fout, "\t\t\texit(0);\n");
|
||||
f_print(fout, "\t\tif (size == 0) {\n");
|
||||
if (tirpcflag) {
|
||||
f_print(fout, "\t\t\tstruct rlimit rl;\n\n");
|
||||
f_print(fout, "\t\t\trl.rlim_max = 0;\n");
|
||||
f_print(fout, "\t\t\tif (getrlimit(RLIMIT_NOFILE, &rl) == -1)\n");
|
||||
f_print(fout, "\t\t\t\treturn;\n");
|
||||
f_print(fout, "\t\t\tif ((size = rl.rlim_max) == 0)\n");
|
||||
f_print(fout, "\t\t\t\treturn;\n");
|
||||
} else {
|
||||
f_print(fout, "\t\t\tsize = getdtablesize();\n");
|
||||
}
|
||||
f_print(fout, "\t\t}\n");
|
||||
f_print(fout, "\t\tfor (i = 0, openfd = 0; i < size && openfd < 2; i++)\n");
|
||||
f_print(fout, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n");
|
||||
f_print(fout, "\t\t\t\topenfd++;\n");
|
||||
f_print(fout, "\t\tif (openfd <= (_rpcpmstart?0:1))\n");
|
||||
f_print(fout, "\t\t\texit(0);\n");
|
||||
f_print(fout, "\t}\n");
|
||||
f_print(fout, "\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
|
||||
f_print(fout, "}\n");
|
||||
}
|
||||
|
||||
static void
|
||||
write_caller_func(void)
|
||||
{ /* EVAS */
|
||||
#define P(s) f_print(fout, s);
|
||||
|
||||
P("\n");
|
||||
P("char *svc_caller()\n");
|
||||
P("{\n");
|
||||
P(" struct sockaddr_in actual;\n");
|
||||
P(" struct hostent *hp;\n");
|
||||
P(" static struct in_addr prev;\n");
|
||||
P(" static char cname[128];\n\n");
|
||||
|
||||
P(" actual = *svc_getcaller(caller);\n\n");
|
||||
|
||||
P(" if (memcmp((char *)&actual.sin_addr, (char *)&prev,\n");
|
||||
P(" sizeof(struct in_addr)) == 0)\n");
|
||||
P(" return (cname);\n\n");
|
||||
|
||||
P(" prev = actual.sin_addr;\n\n");
|
||||
|
||||
P(" hp = gethostbyaddr((char *)&actual.sin_addr, sizeof(actual.sin_addr), AF_INET);\n");
|
||||
P(" if (hp == NULL) { /* dummy one up */\n");
|
||||
P(" extern char *inet_ntoa();\n");
|
||||
P(" strlcpy(cname, inet_ntoa(actual.sin_addr), sizeof(cname));\n");
|
||||
P(" } else {\n");
|
||||
P(" strlcpy(cname, hp->h_name, sizeof(cname));\n");
|
||||
P(" }\n\n");
|
||||
|
||||
P(" return (cname);\n");
|
||||
P("}\n");
|
||||
|
||||
#undef P
|
||||
}
|
||||
/*
|
||||
* Write the most of port monitor support
|
||||
*/
|
||||
static void
|
||||
write_pm_most(char *infile, int netflag)
|
||||
{
|
||||
list *l;
|
||||
definition *def;
|
||||
version_list *vp;
|
||||
|
||||
f_print(fout, "\tif (!ioctl(0, I_LOOK, mname) &&\n");
|
||||
f_print(fout, "\t\t(!strcmp(mname, \"sockmod\") ||");
|
||||
f_print(fout, " !strcmp(mname, \"timod\"))) {\n");
|
||||
f_print(fout, "\t\tchar *netid;\n");
|
||||
if (!netflag) { /* Not included by -n option */
|
||||
f_print(fout, "\t\tstruct netconfig *nconf = NULL;\n");
|
||||
f_print(fout, "\t\tSVCXPRT *%s;\n", TRANSP);
|
||||
}
|
||||
if (timerflag)
|
||||
f_print(fout, "\t\tint pmclose;\n");
|
||||
/* not necessary, defined in /usr/include/stdlib */
|
||||
/* f_print(fout, "\t\textern char *getenv();\n");*/
|
||||
f_print(fout, "\n");
|
||||
f_print(fout, "\t\t_rpcpmstart = 1;\n");
|
||||
if (logflag)
|
||||
open_log_file(infile, "\t\t");
|
||||
f_print(fout, "\t\tif ((netid = getenv(\"NLSPROVIDER\")) == NULL) {\n");
|
||||
sprintf(_errbuf, "cannot get transport name");
|
||||
print_err_message("\t\t\t");
|
||||
f_print(fout, "\t\t} else if ((nconf = getnetconfigent(netid)) == NULL) {\n");
|
||||
sprintf(_errbuf, "cannot get transport info");
|
||||
print_err_message("\t\t\t");
|
||||
f_print(fout, "\t\t}\n");
|
||||
/*
|
||||
* A kludgy support for inetd services. Inetd only works with
|
||||
* sockmod, and RPC works only with timod, hence all this jugglery
|
||||
*/
|
||||
f_print(fout, "\t\tif (strcmp(mname, \"sockmod\") == 0) {\n");
|
||||
f_print(fout, "\t\t\tif (ioctl(0, I_POP, 0) || ioctl(0, I_PUSH, \"timod\")) {\n");
|
||||
sprintf(_errbuf, "could not get the right module");
|
||||
print_err_message("\t\t\t\t");
|
||||
f_print(fout, "\t\t\t\texit(1);\n");
|
||||
f_print(fout, "\t\t\t}\n");
|
||||
f_print(fout, "\t\t}\n");
|
||||
if (timerflag)
|
||||
f_print(fout, "\t\tpmclose = (t_getstate(0) != T_DATAXFER);\n");
|
||||
f_print(fout, "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {\n",
|
||||
TRANSP);
|
||||
sprintf(_errbuf, "cannot create server handle");
|
||||
print_err_message("\t\t\t");
|
||||
f_print(fout, "\t\t\texit(1);\n");
|
||||
f_print(fout, "\t\t}\n");
|
||||
f_print(fout, "\t\tif (nconf)\n");
|
||||
f_print(fout, "\t\t\tfreenetconfigent(nconf);\n");
|
||||
for (l = defined; l != NULL; l = l->next) {
|
||||
def = (definition *) l->val;
|
||||
if (def->def_kind != DEF_PROGRAM) {
|
||||
continue;
|
||||
}
|
||||
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
|
||||
f_print(fout,
|
||||
"\t\tif (!svc_reg(%s, %s, %s, ",
|
||||
TRANSP, def->def_name, vp->vers_name);
|
||||
pvname(def->def_name, vp->vers_num);
|
||||
f_print(fout, ", 0)) {\n");
|
||||
(void) sprintf(_errbuf, "unable to register (%s, %s).",
|
||||
def->def_name, vp->vers_name);
|
||||
print_err_message("\t\t\t");
|
||||
f_print(fout, "\t\t\texit(1);\n");
|
||||
f_print(fout, "\t\t}\n");
|
||||
}
|
||||
}
|
||||
if (timerflag) {
|
||||
f_print(fout, "\t\tif (pmclose) {\n");
|
||||
f_print(fout, "\t\t\t(void) signal(SIGALRM, (SIGPF)closedown);\n");
|
||||
f_print(fout, "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
|
||||
f_print(fout, "\t\t}\n");
|
||||
}
|
||||
f_print(fout, "\t\tsvc_run();\n");
|
||||
f_print(fout, "\t\texit(1);\n");
|
||||
f_print(fout, "\t\t/* NOTREACHED */\n");
|
||||
f_print(fout, "\t}\n");
|
||||
}
|
||||
/*
|
||||
* Support for backgrounding the server if self started.
|
||||
*/
|
||||
static void
|
||||
write_rpc_svc_fg(char *infile, const char *sp)
|
||||
{
|
||||
f_print(fout, "#ifndef RPC_SVC_FG\n");
|
||||
f_print(fout, "%sint size;\n", sp);
|
||||
if (tirpcflag)
|
||||
f_print(fout, "%sstruct rlimit rl;\n", sp);
|
||||
if (inetdflag)
|
||||
f_print(fout, "%sint pid, i;\n\n", sp);
|
||||
f_print(fout, "%spid = fork();\n", sp);
|
||||
f_print(fout, "%sif (pid < 0) {\n", sp);
|
||||
f_print(fout, "%s\terr(EXIT_FAILURE, \"cannot fork\");\n", sp);
|
||||
f_print(fout, "%s}\n", sp);
|
||||
f_print(fout, "%sif (pid)\n", sp);
|
||||
f_print(fout, "%s\texit(0);\n", sp);
|
||||
/* get number of file descriptors */
|
||||
if (tirpcflag) {
|
||||
f_print(fout, "%srl.rlim_max = 0;\n", sp);
|
||||
f_print(fout, "%sif (getrlimit(RLIMIT_NOFILE, &rl) == -1)\n", sp);
|
||||
f_print(fout, "%s\terr(EXIT_FAILURE, \"getrlimit(RLIMIT_NOFILE)\");\n", sp);
|
||||
f_print(fout, "%sif ((size = rl.rlim_max) == 0)\n", sp);
|
||||
f_print(fout, "%s\texit(1);\n", sp);
|
||||
} else {
|
||||
f_print(fout, "%ssize = getdtablesize();\n", sp);
|
||||
}
|
||||
|
||||
f_print(fout, "%sfor (i = 0; i < size; i++)\n", sp);
|
||||
f_print(fout, "%s\t(void) close(i);\n", sp);
|
||||
/* Redirect stderr and stdout to console */
|
||||
f_print(fout, "%si = open(\"/dev/console\", 2);\n", sp);
|
||||
f_print(fout, "%s(void) dup2(i, 1);\n", sp);
|
||||
f_print(fout, "%s(void) dup2(i, 2);\n", sp);
|
||||
/* This removes control of the controlling terminal */
|
||||
if (tirpcflag)
|
||||
f_print(fout, "%ssetsid();\n", sp);
|
||||
else {
|
||||
f_print(fout, "%si = open(\"/dev/tty\", 2);\n", sp);
|
||||
f_print(fout, "%sif (i >= 0) {\n", sp);
|
||||
f_print(fout, "%s\t(void) ioctl(i, TIOCNOTTY, NULL);\n", sp);
|
||||
f_print(fout, "%s\t(void) close(i);\n", sp);
|
||||
f_print(fout, "%s}\n", sp);
|
||||
}
|
||||
if (!logflag)
|
||||
open_log_file(infile, sp);
|
||||
f_print(fout, "#endif\n");
|
||||
if (logflag)
|
||||
open_log_file(infile, sp);
|
||||
}
|
||||
|
||||
static void
|
||||
open_log_file(char *infile, const char *sp)
|
||||
{
|
||||
char *s, *p;
|
||||
|
||||
s = strrchr(infile, '.');
|
||||
if (s)
|
||||
*s = '\0';
|
||||
p = strrchr(infile, '/');
|
||||
if (p)
|
||||
p++;
|
||||
else
|
||||
p = infile;
|
||||
f_print(fout, "%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, p);
|
||||
if (s)
|
||||
*s = '.';
|
||||
}
|
||||
|
||||
/*
|
||||
* write a registration for the given transport for Inetd
|
||||
*/
|
||||
void
|
||||
write_inetd_register(const char *transp)
|
||||
{
|
||||
list *l;
|
||||
definition *def;
|
||||
version_list *vp;
|
||||
const char *sp;
|
||||
int isudp;
|
||||
char tmpbuf[32];
|
||||
|
||||
if (inetdflag)
|
||||
sp = "\t";
|
||||
else
|
||||
sp = "";
|
||||
if (streq(transp, "udp"))
|
||||
isudp = 1;
|
||||
else
|
||||
isudp = 0;
|
||||
f_print(fout, "\n");
|
||||
if (inetdflag) {
|
||||
f_print(fout, "\tif ((_rpcfdtype == 0) || (_rpcfdtype == %s)) {\n",
|
||||
isudp ? "SOCK_DGRAM" : "SOCK_STREAM");
|
||||
}
|
||||
if (inetdflag && streq(transp, "tcp")) {
|
||||
f_print(fout, "%s\tif (_rpcpmstart)\n", sp);
|
||||
|
||||
f_print(fout, "%s\t\t%s = svc%s_create(%s",
|
||||
sp, TRANSP, "fd", inetdflag ? "sock" : "RPC_ANYSOCK");
|
||||
if (!isudp)
|
||||
f_print(fout, ", 0, 0");
|
||||
f_print(fout, ");\n");
|
||||
|
||||
f_print(fout, "%s\telse\n", sp);
|
||||
|
||||
f_print(fout, "%s\t\t%s = svc%s_create(%s",
|
||||
sp, TRANSP, transp, inetdflag ? "sock" : "RPC_ANYSOCK");
|
||||
if (!isudp)
|
||||
f_print(fout, ", 0, 0");
|
||||
f_print(fout, ");\n");
|
||||
|
||||
} else {
|
||||
f_print(fout, "%s\t%s = svc%s_create(%s",
|
||||
sp, TRANSP, transp, inetdflag ? "sock" : "RPC_ANYSOCK");
|
||||
if (!isudp)
|
||||
f_print(fout, ", 0, 0");
|
||||
f_print(fout, ");\n");
|
||||
}
|
||||
f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
|
||||
(void) sprintf(_errbuf, "cannot create %s service.", transp);
|
||||
(void) sprintf(tmpbuf, "%s\t\t", sp);
|
||||
print_err_message(tmpbuf);
|
||||
f_print(fout, "%s\t\texit(1);\n", sp);
|
||||
f_print(fout, "%s\t}\n", sp);
|
||||
|
||||
if (inetdflag) {
|
||||
f_print(fout, "%s\tif (!_rpcpmstart)\n\t", sp);
|
||||
f_print(fout, "%s\tproto = IPPROTO_%s;\n",
|
||||
sp, isudp ? "UDP" : "TCP");
|
||||
}
|
||||
for (l = defined; l != NULL; l = l->next) {
|
||||
def = (definition *) l->val;
|
||||
if (def->def_kind != DEF_PROGRAM) {
|
||||
continue;
|
||||
}
|
||||
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
|
||||
f_print(fout, "%s\tif (!svc_register(%s, %s, %s, ",
|
||||
sp, TRANSP, def->def_name, vp->vers_name);
|
||||
pvname(def->def_name, vp->vers_num);
|
||||
if (inetdflag)
|
||||
f_print(fout, ", proto)) {\n");
|
||||
else
|
||||
f_print(fout, ", IPPROTO_%s)) {\n",
|
||||
isudp ? "UDP" : "TCP");
|
||||
(void) sprintf(_errbuf, "unable to register (%s, %s, %s).",
|
||||
def->def_name, vp->vers_name, transp);
|
||||
print_err_message(tmpbuf);
|
||||
f_print(fout, "%s\t\texit(1);\n", sp);
|
||||
f_print(fout, "%s\t}\n", sp);
|
||||
}
|
||||
}
|
||||
if (inetdflag)
|
||||
f_print(fout, "\t}\n");
|
||||
}
|
||||
|
||||
static const char *
|
||||
aster(const char *type)
|
||||
{
|
||||
if (isvectordef(type, REL_ALIAS)) {
|
||||
return ("");
|
||||
} else {
|
||||
return ("*");
|
||||
}
|
||||
}
|
||||
@@ -1,181 +0,0 @@
|
||||
/* $NetBSD: rpc_tblout.c,v 1.14 2013/12/15 00:40:17 christos Exp $ */
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user or with the express written consent of
|
||||
* Sun Microsystems, Inc.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(__RCSID) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)rpc_tblout.c 1.4 89/02/22 (C) 1988 SMI";
|
||||
#else
|
||||
__RCSID("$NetBSD: rpc_tblout.c,v 1.14 2013/12/15 00:40:17 christos Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* rpc_tblout.c, Dispatch table outputter for the RPC protocol compiler
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "rpc_scan.h"
|
||||
#include "rpc_parse.h"
|
||||
#include "rpc_util.h"
|
||||
|
||||
#define TABSIZE 8
|
||||
#define TABCOUNT 5
|
||||
#define TABSTOP (TABSIZE*TABCOUNT)
|
||||
|
||||
static char tabstr[TABCOUNT + 1] = "\t\t\t\t\t";
|
||||
|
||||
static const char tbl_hdr[] = "struct rpcgen_table %s_table[] = {\n";
|
||||
static const char tbl_end[] = "};\n";
|
||||
|
||||
static const char null_entry[] = "\t(char *(*)())0,\n\
|
||||
\t(xdrproc_t)xdr_void,\t\t0,\n\
|
||||
\t(xdrproc_t)xdr_void,\t\t0,\n";
|
||||
|
||||
static const char tbl_nproc[] =
|
||||
"u_int %s_nproc =\n\t(u_int)(sizeof(%s_table)/sizeof(%s_table[0]));\n\n";
|
||||
|
||||
static void write_table(definition *);
|
||||
static void printit(const char *, const char *);
|
||||
|
||||
void
|
||||
write_tables(void)
|
||||
{
|
||||
list *l;
|
||||
definition *def;
|
||||
|
||||
f_print(fout, "\n");
|
||||
for (l = defined; l != NULL; l = l->next) {
|
||||
def = (definition *) l->val;
|
||||
if (def->def_kind == DEF_PROGRAM) {
|
||||
write_table(def);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
write_table(definition *def)
|
||||
{
|
||||
version_list *vp;
|
||||
proc_list *proc;
|
||||
int current;
|
||||
int expected;
|
||||
char progvers[100];
|
||||
int warning;
|
||||
|
||||
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
|
||||
warning = 0;
|
||||
s_print(progvers, "%s_%s",
|
||||
locase(def->def_name), vp->vers_num);
|
||||
/* print the table header */
|
||||
f_print(fout, tbl_hdr, progvers);
|
||||
|
||||
if (nullproc(vp->procs)) {
|
||||
expected = 0;
|
||||
} else {
|
||||
expected = 1;
|
||||
f_print(fout, null_entry);
|
||||
}
|
||||
for (proc = vp->procs; proc != NULL; proc = proc->next) {
|
||||
if (expected != 0)
|
||||
f_print(fout, "\n");
|
||||
current = atoi(proc->proc_num);
|
||||
if (current != expected++) {
|
||||
f_print(fout,
|
||||
"/*\n * WARNING: table out of order\n */\n\n");
|
||||
if (warning == 0) {
|
||||
f_print(stderr,
|
||||
"WARNING %s table is out of order\n",
|
||||
progvers);
|
||||
warning = 1;
|
||||
nonfatalerrors = 1;
|
||||
}
|
||||
expected = current + 1;
|
||||
}
|
||||
f_print(fout, "\t(char *(*)())RPCGEN_ACTION(");
|
||||
|
||||
/* routine to invoke */
|
||||
if (!newstyle)
|
||||
pvname_svc(proc->proc_name, vp->vers_num);
|
||||
else {
|
||||
if (newstyle)
|
||||
f_print(fout, "_"); /* calls internal func */
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
}
|
||||
f_print(fout, "),\n");
|
||||
|
||||
/* argument info */
|
||||
if (proc->arg_num > 1)
|
||||
printit(NULL, proc->args.argname);
|
||||
else
|
||||
/* do we have to do something special for
|
||||
* newstyle */
|
||||
printit(proc->args.decls->decl.prefix,
|
||||
proc->args.decls->decl.type);
|
||||
/* result info */
|
||||
printit(proc->res_prefix, proc->res_type);
|
||||
}
|
||||
|
||||
/* print the table trailer */
|
||||
f_print(fout, tbl_end);
|
||||
f_print(fout, tbl_nproc, progvers, progvers, progvers);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
printit(const char *prefix, const char *type)
|
||||
{
|
||||
int len;
|
||||
int tabs;
|
||||
|
||||
|
||||
len = fprintf(fout, "\txdr_%s,", stringfix(type));
|
||||
/* account for leading tab expansion */
|
||||
len += TABSIZE - 1;
|
||||
/* round up to tabs required */
|
||||
tabs = (TABSTOP - len + TABSIZE - 1) / TABSIZE;
|
||||
f_print(fout, "%s", &tabstr[TABCOUNT - tabs]);
|
||||
|
||||
if (streq(type, "void")) {
|
||||
f_print(fout, "0");
|
||||
} else {
|
||||
f_print(fout, "(u_int)sizeof(");
|
||||
/* XXX: should "follow" be 1 ??? */
|
||||
ptype(prefix, type, 0);
|
||||
f_print(fout, ")");
|
||||
}
|
||||
f_print(fout, ",\n");
|
||||
}
|
||||
@@ -1,479 +0,0 @@
|
||||
/* $NetBSD: rpc_util.c,v 1.18 2015/09/20 16:57:13 kamil Exp $ */
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user or with the express written consent of
|
||||
* Sun Microsystems, Inc.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(__RCSID) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI";
|
||||
#else
|
||||
__RCSID("$NetBSD: rpc_util.c,v 1.18 2015/09/20 16:57:13 kamil Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* rpc_util.c, Utility routines for the RPC protocol compiler
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#include <ctype.h>
|
||||
#include "rpc_scan.h"
|
||||
#include "rpc_parse.h"
|
||||
#include "rpc_util.h"
|
||||
|
||||
#define ARGEXT "argument"
|
||||
|
||||
static void printwhere(void);
|
||||
|
||||
char curline[MAXLINESIZE]; /* current read line */
|
||||
char *where = curline; /* current point in line */
|
||||
int linenum = 0; /* current line number */
|
||||
|
||||
const char *infilename; /* input filename */
|
||||
|
||||
#define NFILES 7
|
||||
static const char *outfiles[NFILES]; /* output file names */
|
||||
int nfiles;
|
||||
|
||||
FILE *fout; /* file pointer of current output */
|
||||
FILE *fin; /* file pointer of current input */
|
||||
|
||||
list *defined; /* list of defined things */
|
||||
|
||||
static const char *toktostr(tok_kind);
|
||||
static void printbuf(void);
|
||||
static void printwhere(void);
|
||||
static int findit(definition *, const char *);
|
||||
static const char *fixit(const char *, const char *);
|
||||
static int typedefed(definition *, const char *);
|
||||
|
||||
/*
|
||||
* Reinitialize the world
|
||||
*/
|
||||
void
|
||||
reinitialize(void)
|
||||
{
|
||||
memset(curline, 0, MAXLINESIZE);
|
||||
where = curline;
|
||||
linenum = 0;
|
||||
defined = NULL;
|
||||
}
|
||||
/*
|
||||
* string equality
|
||||
*/
|
||||
int
|
||||
streq(const char *a, const char *b)
|
||||
{
|
||||
return (strcmp(a, b) == 0);
|
||||
}
|
||||
/*
|
||||
* find a value in a list
|
||||
*/
|
||||
definition *
|
||||
findval(list *lst, const char *val, int (*cmp)(definition *, const char *))
|
||||
{
|
||||
|
||||
for (; lst != NULL; lst = lst->next) {
|
||||
if ((*cmp) (lst->val, val)) {
|
||||
return (lst->val);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
/*
|
||||
* store a value in a list
|
||||
*/
|
||||
void
|
||||
storeval(list **lstp, definition *val)
|
||||
{
|
||||
list **l;
|
||||
list *lst;
|
||||
|
||||
|
||||
for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
|
||||
lst = ALLOC(list);
|
||||
lst->val = val;
|
||||
lst->next = NULL;
|
||||
*l = lst;
|
||||
}
|
||||
|
||||
static int
|
||||
findit(definition *def, const char *type)
|
||||
{
|
||||
return (streq(def->def_name, type));
|
||||
}
|
||||
|
||||
static const char *
|
||||
fixit(const char *type, const char *orig)
|
||||
{
|
||||
definition *def;
|
||||
|
||||
def = (definition *) FINDVAL(defined, type, findit);
|
||||
if (def == NULL || def->def_kind != DEF_TYPEDEF) {
|
||||
return (orig);
|
||||
}
|
||||
switch (def->def.ty.rel) {
|
||||
case REL_VECTOR:
|
||||
return (def->def.ty.old_type);
|
||||
case REL_ALIAS:
|
||||
return (fixit(def->def.ty.old_type, orig));
|
||||
default:
|
||||
return (orig);
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
fixtype(const char *type)
|
||||
{
|
||||
return (fixit(type, type));
|
||||
}
|
||||
|
||||
const char *
|
||||
stringfix(const char *type)
|
||||
{
|
||||
if (streq(type, "string")) {
|
||||
return ("wrapstring");
|
||||
} else {
|
||||
return (type);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ptype(const char *prefix, const char *type, int follow)
|
||||
{
|
||||
if (prefix != NULL) {
|
||||
if (streq(prefix, "enum")) {
|
||||
f_print(fout, "enum ");
|
||||
} else {
|
||||
f_print(fout, "struct ");
|
||||
}
|
||||
}
|
||||
if (streq(type, "bool")) {
|
||||
f_print(fout, "bool_t ");
|
||||
} else
|
||||
if (streq(type, "string")) {
|
||||
f_print(fout, "char *");
|
||||
} else {
|
||||
f_print(fout, "%s ", follow ? fixtype(type) : type);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
typedefed(definition *def, const char *type)
|
||||
{
|
||||
if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
|
||||
return (0);
|
||||
} else {
|
||||
return (streq(def->def_name, type));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
isvectordef(const char *type, relation rel)
|
||||
{
|
||||
definition *def;
|
||||
|
||||
for (;;) {
|
||||
switch (rel) {
|
||||
case REL_VECTOR:
|
||||
return (!streq(type, "string"));
|
||||
case REL_ARRAY:
|
||||
return (0);
|
||||
case REL_POINTER:
|
||||
return (0);
|
||||
case REL_ALIAS:
|
||||
def = (definition *) FINDVAL(defined, type, typedefed);
|
||||
if (def == NULL) {
|
||||
return (0);
|
||||
}
|
||||
type = def->def.ty.old_type;
|
||||
rel = def->def.ty.rel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
locase(const char *str)
|
||||
{
|
||||
char c;
|
||||
static char buf[100];
|
||||
char *p = buf;
|
||||
|
||||
while ((c = *str++) != '\0') {
|
||||
*p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
|
||||
}
|
||||
*p = 0;
|
||||
return (buf);
|
||||
}
|
||||
|
||||
void
|
||||
pvname_svc(const char *pname, const char *vnum)
|
||||
{
|
||||
f_print(fout, "%s_%s_svc", locase(pname), vnum);
|
||||
}
|
||||
|
||||
void
|
||||
pvname(const char *pname, const char *vnum)
|
||||
{
|
||||
f_print(fout, "%s_%s", locase(pname), vnum);
|
||||
}
|
||||
/*
|
||||
* print a useful (?) error message, and then die
|
||||
*/
|
||||
__printflike(1, 2) void
|
||||
error(const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
printwhere();
|
||||
fprintf(stderr, "%s:%d: ", infilename, linenum);
|
||||
va_start(ap, msg);
|
||||
vfprintf(stderr, msg, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "\n");
|
||||
errx(EXIT_FAILURE, "Cannot recover from this error");
|
||||
}
|
||||
/*
|
||||
* Something went wrong, unlink any files that we may have created and then
|
||||
* die.
|
||||
*/
|
||||
void
|
||||
crash(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!docleanup)
|
||||
return;
|
||||
|
||||
for (i = 0; i < nfiles; i++) {
|
||||
(void) unlink(outfiles[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
record_open(const char *file)
|
||||
{
|
||||
if (nfiles < NFILES) {
|
||||
outfiles[nfiles++] = file;
|
||||
} else {
|
||||
errx(EXIT_FAILURE, "Too many files!");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* error, token encountered was not the expected one
|
||||
*/
|
||||
void
|
||||
expected1(tok_kind exp1)
|
||||
{
|
||||
error("Expected '%s'", toktostr(exp1));
|
||||
}
|
||||
/*
|
||||
* error, token encountered was not one of two expected ones
|
||||
*/
|
||||
void
|
||||
expected2(tok_kind exp1, tok_kind exp2)
|
||||
{
|
||||
error("Expected '%s' or '%s'",
|
||||
toktostr(exp1),
|
||||
toktostr(exp2));
|
||||
}
|
||||
/*
|
||||
* error, token encountered was not one of 3 expected ones
|
||||
*/
|
||||
void
|
||||
expected3(tok_kind exp1, tok_kind exp2, tok_kind exp3)
|
||||
{
|
||||
error("Expected '%s', '%s', or '%s'",
|
||||
toktostr(exp1),
|
||||
toktostr(exp2),
|
||||
toktostr(exp3));
|
||||
}
|
||||
|
||||
void
|
||||
tabify(FILE *f, int tab)
|
||||
{
|
||||
while (tab--) {
|
||||
(void) fputc('\t', f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static token tokstrings[] = {
|
||||
{TOK_IDENT, "identifier"},
|
||||
{TOK_CONST, "const"},
|
||||
{TOK_RPAREN, ")"},
|
||||
{TOK_LPAREN, "("},
|
||||
{TOK_RBRACE, "}"},
|
||||
{TOK_LBRACE, "{"},
|
||||
{TOK_LBRACKET, "["},
|
||||
{TOK_RBRACKET, "]"},
|
||||
{TOK_STAR, "*"},
|
||||
{TOK_COMMA, ","},
|
||||
{TOK_EQUAL, "="},
|
||||
{TOK_COLON, ":"},
|
||||
{TOK_SEMICOLON, ";"},
|
||||
{TOK_UNION, "union"},
|
||||
{TOK_STRUCT, "struct"},
|
||||
{TOK_SWITCH, "switch"},
|
||||
{TOK_CASE, "case"},
|
||||
{TOK_DEFAULT, "default"},
|
||||
{TOK_ENUM, "enum"},
|
||||
{TOK_TYPEDEF, "typedef"},
|
||||
{TOK_INT, "int"},
|
||||
{TOK_SHORT, "short"},
|
||||
{TOK_LONG, "long"},
|
||||
{TOK_UNSIGNED, "unsigned"},
|
||||
{TOK_DOUBLE, "double"},
|
||||
{TOK_FLOAT, "float"},
|
||||
{TOK_CHAR, "char"},
|
||||
{TOK_STRING, "string"},
|
||||
{TOK_OPAQUE, "opaque"},
|
||||
{TOK_BOOL, "bool"},
|
||||
{TOK_VOID, "void"},
|
||||
{TOK_PROGRAM, "program"},
|
||||
{TOK_VERSION, "version"},
|
||||
{TOK_EOF, "??????"}
|
||||
};
|
||||
|
||||
static const char *
|
||||
toktostr(tok_kind kind)
|
||||
{
|
||||
token *sp;
|
||||
|
||||
for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
|
||||
return (sp->str);
|
||||
}
|
||||
|
||||
static void
|
||||
printbuf(void)
|
||||
{
|
||||
char c;
|
||||
int i;
|
||||
int cnt;
|
||||
|
||||
#define TABSIZE 4
|
||||
|
||||
for (i = 0; (c = curline[i]) != '\0'; i++) {
|
||||
if (c == '\t') {
|
||||
cnt = 8 - (i % TABSIZE);
|
||||
c = ' ';
|
||||
} else {
|
||||
cnt = 1;
|
||||
}
|
||||
while (cnt--) {
|
||||
(void) fputc(c, stderr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
printwhere(void)
|
||||
{
|
||||
int i;
|
||||
char c;
|
||||
int cnt;
|
||||
|
||||
printbuf();
|
||||
for (i = 0; i < where - curline; i++) {
|
||||
c = curline[i];
|
||||
if (c == '\t') {
|
||||
cnt = 8 - (i % TABSIZE);
|
||||
} else {
|
||||
cnt = 1;
|
||||
}
|
||||
while (cnt--) {
|
||||
(void) fputc('^', stderr);
|
||||
}
|
||||
}
|
||||
(void) fputc('\n', stderr);
|
||||
}
|
||||
|
||||
char *
|
||||
make_argname(const char *pname, const char *vname)
|
||||
{
|
||||
char *name;
|
||||
size_t len;
|
||||
|
||||
len = strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3;
|
||||
name = malloc(len);
|
||||
if (!name) {
|
||||
err(EXIT_FAILURE, "malloc");
|
||||
}
|
||||
snprintf(name, len, "%s_%s_%s", locase(pname), vname, ARGEXT);
|
||||
return (name);
|
||||
}
|
||||
|
||||
bas_type *typ_list_h;
|
||||
bas_type *typ_list_t;
|
||||
|
||||
void
|
||||
add_type(int len, const char *type)
|
||||
{
|
||||
bas_type *ptr;
|
||||
|
||||
if ((ptr = malloc(sizeof(bas_type))) == NULL) {
|
||||
err(EXIT_FAILURE, "malloc");
|
||||
}
|
||||
ptr->name = type;
|
||||
ptr->length = len;
|
||||
ptr->next = NULL;
|
||||
if (typ_list_t == NULL) {
|
||||
typ_list_t = ptr;
|
||||
typ_list_h = ptr;
|
||||
} else {
|
||||
typ_list_t->next = ptr;
|
||||
typ_list_t = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
bas_type *
|
||||
find_type(const char *type)
|
||||
{
|
||||
bas_type *ptr;
|
||||
|
||||
ptr = typ_list_h;
|
||||
|
||||
|
||||
while (ptr != NULL) {
|
||||
if (strcmp(ptr->name, type) == 0)
|
||||
return (ptr);
|
||||
else
|
||||
ptr = ptr->next;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
/* $NetBSD: rpc_util.h,v 1.12 2015/05/13 20:13:21 joerg Exp $ */
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user or with the express written consent of
|
||||
* Sun Microsystems, Inc.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
/* @(#)rpc_util.h 1.5 90/08/29 (C) 1987 SMI */
|
||||
|
||||
/*
|
||||
* rpc_util.h, Useful definitions for the RPC protocol compiler
|
||||
*/
|
||||
|
||||
#define alloc(size) ((char *)malloc((size_t)(size)))
|
||||
#define ALLOC(object) ((object *)malloc(sizeof(object)))
|
||||
|
||||
#define s_print (void) sprintf
|
||||
#define f_print (void) fprintf
|
||||
|
||||
struct list {
|
||||
definition *val;
|
||||
struct list *next;
|
||||
};
|
||||
typedef struct list list;
|
||||
|
||||
#define PUT 1
|
||||
#define GET 2
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
#define MAXLINESIZE 1024
|
||||
extern char curline[MAXLINESIZE];
|
||||
extern char *where;
|
||||
extern int linenum;
|
||||
extern int docleanup;
|
||||
|
||||
extern const char *infilename;
|
||||
extern FILE *fout;
|
||||
extern FILE *fin;
|
||||
|
||||
extern list *defined;
|
||||
|
||||
|
||||
extern bas_type *typ_list_h;
|
||||
extern bas_type *typ_list_t;
|
||||
|
||||
/*
|
||||
* All the option flags
|
||||
*/
|
||||
extern int inetdflag;
|
||||
extern int pmflag;
|
||||
extern int tblflag;
|
||||
extern int BSDflag;
|
||||
extern int logflag;
|
||||
extern int newstyle;
|
||||
extern int Mflag; /* multithread flag */
|
||||
extern int tirpcflag; /* flag for generating tirpc code */
|
||||
extern int doinline; /* if this is 0, then do not generate inline code */
|
||||
extern int callerflag;
|
||||
|
||||
/*
|
||||
* Other flags related with inetd jumpstart.
|
||||
*/
|
||||
extern int indefinitewait;
|
||||
extern int exitnow;
|
||||
extern int timerflag;
|
||||
|
||||
extern int nonfatalerrors;
|
||||
|
||||
/*
|
||||
* rpc_util routines
|
||||
*/
|
||||
|
||||
#define STOREVAL(list,item) \
|
||||
storeval(list,item)
|
||||
|
||||
#define FINDVAL(list,item,finder) \
|
||||
findval(list, item, finder)
|
||||
|
||||
void reinitialize(void);
|
||||
int streq(const char *, const char *);
|
||||
definition *findval(list *, const char *,
|
||||
int (*)(definition *, const char *));
|
||||
void storeval(list **, definition *);
|
||||
const char *fixtype(const char *);
|
||||
const char *stringfix(const char *);
|
||||
void ptype(const char *, const char *, int);
|
||||
int isvectordef(const char *, relation);
|
||||
char *locase(const char *);
|
||||
void pvname_svc(const char *, const char *);
|
||||
void pvname(const char *, const char *);
|
||||
__dead __printflike(1, 2) void error(const char *, ...);
|
||||
void crash(void);
|
||||
void record_open(const char *);
|
||||
void expected1(tok_kind) __dead;
|
||||
void expected2(tok_kind, tok_kind) __dead;
|
||||
void expected3(tok_kind, tok_kind, tok_kind) __dead;
|
||||
void tabify(FILE *, int);
|
||||
char *make_argname(const char *, const char *);
|
||||
void add_type(int, const char *);
|
||||
bas_type *find_type(const char *);
|
||||
/*
|
||||
* rpc_cout routines
|
||||
*/
|
||||
void emit(definition *);
|
||||
void emit_inline(declaration *, int);
|
||||
void emit_single_in_line(declaration *, int, relation);
|
||||
char *upcase(const char *);
|
||||
|
||||
/*
|
||||
* rpc_hout routines
|
||||
*/
|
||||
|
||||
void print_datadef(definition *);
|
||||
void print_progdef(definition *);
|
||||
void print_funcdef(definition *, int *);
|
||||
void print_funcend(int);
|
||||
void pxdrfuncdecl(const char *, int);
|
||||
void pprocdef(proc_list *, version_list *, const char *, int);
|
||||
void pdeclaration(const char *, declaration *, int, const char *);
|
||||
|
||||
/*
|
||||
* rpc_svcout routines
|
||||
*/
|
||||
void write_most(char *, int, int);
|
||||
void write_netid_register(const char *);
|
||||
void write_nettype_register(const char *);
|
||||
void write_rest(void);
|
||||
void write_programs(const char *);
|
||||
int nullproc(proc_list *);
|
||||
void write_svc_aux(int);
|
||||
void write_msg_out(void);
|
||||
void write_inetd_register(const char *);
|
||||
|
||||
/*
|
||||
* rpc_clntout routines
|
||||
*/
|
||||
void write_stubs(void);
|
||||
void printarglist(proc_list *, const char *, const char *, const char *);
|
||||
|
||||
|
||||
/*
|
||||
* rpc_tblout routines
|
||||
*/
|
||||
void write_tables(void);
|
||||
|
||||
/*
|
||||
* rpc_sample routines
|
||||
*/
|
||||
void write_sample_svc(definition *);
|
||||
int write_sample_clnt(definition *);
|
||||
void add_sample_msg(void);
|
||||
void write_sample_clnt_main(void);
|
||||
@@ -1,501 +0,0 @@
|
||||
.\" $NetBSD: rpcgen.1,v 1.24 2013/12/15 09:18:14 wiz Exp $
|
||||
.\" from: @(#)rpcgen.new.1 1.1 90/11/09 TIRPC 1.0; from 40.10 of 10/10/89
|
||||
.\" Copyright (c) 1988,1990 Sun Microsystems, Inc. - All Rights Reserved.
|
||||
.Dd December 14, 2013
|
||||
.Dt RPCGEN 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rpcgen
|
||||
.Nd Remote Procedure Call (RPC) protocol compiler
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Ar infile
|
||||
.Nm
|
||||
.Op Fl AaBbILMNTv
|
||||
.Op Fl D Ar name Op =value
|
||||
.Op Fl i Ar size
|
||||
.Op Fl K Ar secs
|
||||
.Op Fl Y Ar pathname
|
||||
.Ar infile
|
||||
.Nm
|
||||
.Fl c Li |
|
||||
.Fl h Li |
|
||||
.Fl l Li |
|
||||
.Fl m Li |
|
||||
.Fl t Li |
|
||||
.Fl S\&c Li |
|
||||
.Fl S\&s
|
||||
.\" .Fl S\&m
|
||||
.Op Fl o Ar outfile
|
||||
.Op Ar infile
|
||||
.Nm
|
||||
.Op Fl s Ar nettype
|
||||
.Op Fl o Ar outfile
|
||||
.Op Ar infile
|
||||
.Nm
|
||||
.Op Fl n Ar netid
|
||||
.Op Fl o Ar outfile
|
||||
.Op Ar infile
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a tool that generates C code to implement an
|
||||
.Tn RPC
|
||||
protocol.
|
||||
The input to
|
||||
.Nm
|
||||
is a language similar to C known as
|
||||
.Tn RPC
|
||||
Language (Remote Procedure Call Language).
|
||||
.Nm
|
||||
is normally used as in the first synopsis where
|
||||
it takes an input file and generates up to four output files.
|
||||
If the
|
||||
.Ar infile
|
||||
is named
|
||||
.Pa proto.x ,
|
||||
then
|
||||
.Nm
|
||||
will generate a header file in
|
||||
.Pa proto.h ,
|
||||
.Tn XDR
|
||||
routines in
|
||||
.Pa proto_xdr.c ,
|
||||
server-side stubs in
|
||||
.Pa proto_svc.c ,
|
||||
and client-side stubs in
|
||||
.Pa proto_clnt.c .
|
||||
With the
|
||||
.Fl T
|
||||
option,
|
||||
it will also generate the
|
||||
.Tn RPC
|
||||
dispatch table in
|
||||
.Pa proto_tbl.i .
|
||||
With the
|
||||
.Fl S\&c
|
||||
option,
|
||||
it will also generate sample code which would illustrate how to use the
|
||||
remote procedures on the client side.
|
||||
This code would be created in
|
||||
.Pa proto_client.c .
|
||||
With the
|
||||
.Fl S\&s
|
||||
option,
|
||||
it will also generate a sample server code which would illustrate how to write
|
||||
the remote procedures.
|
||||
This code would be created in
|
||||
.Pa proto_server.c .
|
||||
.Pp
|
||||
The server created can be started both by the port monitors
|
||||
(for example,
|
||||
.Em inetd
|
||||
or
|
||||
.Em listen )
|
||||
or by itself.
|
||||
When it is started by a port monitor,
|
||||
it creates servers only for the transport for which
|
||||
the file descriptor 0 was passed.
|
||||
The name of the transport must be specified
|
||||
by setting up the environmental variable
|
||||
.Ev PM_TRANSPORT .
|
||||
When the server generated by
|
||||
.Nm
|
||||
is executed,
|
||||
it creates server handles for all the transports
|
||||
specified in
|
||||
.Ev NETPATH
|
||||
environment variable,
|
||||
or if it is unset,
|
||||
it creates server handles for all the visible transports from
|
||||
.Pa /etc/netconfig
|
||||
file.
|
||||
.Pp
|
||||
.Em Note :
|
||||
the transports are chosen at run time and not at compile time.
|
||||
When the server is self-started,
|
||||
it backgrounds itself by default.
|
||||
A special define symbol
|
||||
.Dv RPC_SVC_FG
|
||||
can be used to run the server process in foreground.
|
||||
.Pp
|
||||
The second synopsis provides special features which allow
|
||||
for the creation of more sophisticated
|
||||
.Tn RPC
|
||||
servers.
|
||||
These features include support for user provided
|
||||
.Li #defines
|
||||
and
|
||||
.Tn RPC
|
||||
dispatch tables.
|
||||
The entries in the
|
||||
.Tn RPC
|
||||
dispatch table contain:
|
||||
.Pp
|
||||
.Bl -inset -offset indent -compact
|
||||
.It +
|
||||
pointers to the service routine corresponding to that procedure,
|
||||
.It +
|
||||
a pointer to the input and output arguments,
|
||||
.It +
|
||||
the size of these routines
|
||||
.El
|
||||
.Pp
|
||||
A server can use the dispatch table to check authorization
|
||||
and then to execute the service routine;
|
||||
a client library may use it to deal with the details of storage
|
||||
management and
|
||||
.Tn XDR
|
||||
data conversion.
|
||||
.Pp
|
||||
The other three synopses shown above are used when
|
||||
one does not want to generate all the output files,
|
||||
but only a particular one.
|
||||
Some examples of their usage is described in the
|
||||
.Sx EXAMPLES
|
||||
section below.
|
||||
When
|
||||
.Nm
|
||||
is executed with the
|
||||
.Fl s
|
||||
option,
|
||||
it creates servers for that particular class of transports.
|
||||
When
|
||||
executed with the
|
||||
.Fl n
|
||||
option,
|
||||
it creates a server for the transport specified by
|
||||
.Em netid .
|
||||
If
|
||||
.Ar infile
|
||||
is not specified,
|
||||
.Nm
|
||||
accepts the standard input.
|
||||
.Pp
|
||||
The C preprocessor,
|
||||
.Xr cpp 1
|
||||
is run on the input file before it is actually interpreted by
|
||||
.Nm
|
||||
For each type of output file,
|
||||
.Nm
|
||||
defines a special preprocessor symbol for use by the
|
||||
.Nm
|
||||
programmer:
|
||||
.Bl -tag -width RPC_CLNT
|
||||
.It Dv RPC_HDR
|
||||
defined when compiling into header files
|
||||
.It Dv RPC_XDR
|
||||
defined when compiling into
|
||||
.Tn XDR
|
||||
routines
|
||||
.It Dv RPC_SVC
|
||||
defined when compiling into server-side stubs
|
||||
.It Dv RPC_CLNT
|
||||
defined when compiling into client-side stubs
|
||||
.It Dv RPC_TBL
|
||||
defined when compiling into
|
||||
.Tn RPC
|
||||
dispatch tables
|
||||
.El
|
||||
.Pp
|
||||
Any line beginning with
|
||||
.Sq %
|
||||
is passed directly into the output file,
|
||||
uninterpreted by
|
||||
.Nm .
|
||||
.Pp
|
||||
For every data type referred to in
|
||||
.Ar infile
|
||||
.Nm
|
||||
assumes that there exists a
|
||||
routine with the string
|
||||
.Dq xdr_
|
||||
prepended to the name of the data type.
|
||||
If this routine does not exist in the
|
||||
.Tn RPC/XDR
|
||||
library, it must be provided.
|
||||
Providing an undefined data type
|
||||
allows customization of
|
||||
.Tn XDR
|
||||
routines.
|
||||
.Sh OPTIONS
|
||||
.Bl -tag -width indent
|
||||
.It Fl A
|
||||
Generate an
|
||||
.Fn svc_caller
|
||||
function.
|
||||
.It Fl a
|
||||
Generate all the files including sample code for client and server side.
|
||||
.It Fl B
|
||||
Generate BSD cplusplus macros (__BEGIN_DECLS, __END_DECLS).
|
||||
.It Fl b
|
||||
Compile stubs in "backwards compatible" mode, disabling support for
|
||||
transport-independent RPC.
|
||||
The
|
||||
.Fl b
|
||||
should always be specified when generating files for
|
||||
.Nx ,
|
||||
since there is no transport-independent RPC support in
|
||||
.Nx .
|
||||
.It Fl c
|
||||
Compile into
|
||||
.Tn XDR
|
||||
routines.
|
||||
.It Fl D Ar name Ns Op Ar =value
|
||||
Define a symbol
|
||||
.Dv name .
|
||||
Equivalent to the
|
||||
.Dv #define
|
||||
directive in the source.
|
||||
If no
|
||||
.Dv value
|
||||
is given,
|
||||
.Dv value
|
||||
is defined as 1.
|
||||
This option may be specified more than once.
|
||||
.It Fl h
|
||||
Compile into C data-definitions (a header file).
|
||||
The
|
||||
.Fl T
|
||||
option can be used in conjunction to produce a
|
||||
header file which supports
|
||||
.Tn RPC
|
||||
dispatch tables.
|
||||
.It Fl I
|
||||
Support
|
||||
.Xr inetd 8
|
||||
in the server side stubs.
|
||||
Servers generated using this flag can either be standalone or
|
||||
started from
|
||||
.Xr inetd 8 .
|
||||
If a server is started as standalone, then it places itself
|
||||
in the background, unless
|
||||
.Dv RCP_SVC_FG
|
||||
is defined, or the server is compiled without
|
||||
.Fl I .
|
||||
.It Fl i Ar size
|
||||
Size to decide when to start generating inline code.
|
||||
The default size is 3.
|
||||
.It Fl K Ar secs
|
||||
By default, services created using
|
||||
.Nm
|
||||
wait 120 seconds
|
||||
after servicing a request before exiting.
|
||||
That interval can be changed using the
|
||||
.Fl K
|
||||
flag.
|
||||
To create a server that exits immediately upon servicing a request,
|
||||
.Dq Fl K No 0
|
||||
can be used.
|
||||
To create a server that never exits, the appropriate argument is
|
||||
.Dq Fl K No -1 .
|
||||
.Pp
|
||||
When monitoring for a server,
|
||||
some port monitors, like the
|
||||
.At V.4
|
||||
utility
|
||||
.Ic listen ,
|
||||
.Em always
|
||||
spawn a new process in response to a service request.
|
||||
If it is known that a server will be used with such a monitor, the
|
||||
server should exit immediately on completion.
|
||||
For such servers,
|
||||
.Nm
|
||||
should be used with
|
||||
.Dq Fl K No -1 .
|
||||
.It Fl L
|
||||
Server errors will be sent to syslog instead of stderr.
|
||||
.It Fl l
|
||||
Compile into client-side stubs.
|
||||
.Xr inetd 8 .
|
||||
.It Fl M
|
||||
Generate thread-safe stubs.
|
||||
This alters the calling pattern of client and
|
||||
server stubs so that storage for results is allocated by the caller.
|
||||
Note
|
||||
that all components for a particular service (stubs, client and service
|
||||
wrappers, etc.) must be built either with or without the
|
||||
.Fl M
|
||||
flag.
|
||||
.It Fl m
|
||||
Compile into server-side stubs,
|
||||
but do not generate a
|
||||
.Fn main
|
||||
routine.
|
||||
This option is useful for doing callback-routines
|
||||
and for users who need to write their own
|
||||
.Fn main
|
||||
routine to do initialization.
|
||||
.It Fl N
|
||||
Use the newstyle of
|
||||
.Nm .
|
||||
This allows procedures to have multiple arguments.
|
||||
It also uses the style of parameter passing that closely resembles C.
|
||||
So, when passing an argument to a remote procedure you do not have
|
||||
to pass a pointer to the argument but the argument itself.
|
||||
This behaviour is different from the oldstyle
|
||||
of
|
||||
.Nm
|
||||
generated code.
|
||||
The newstyle is not the default case because of backward compatibility.
|
||||
.It Fl n Ar netid
|
||||
Compile into server-side stubs for the transport
|
||||
specified by
|
||||
.Ar netid .
|
||||
There should be an entry for
|
||||
.Ar netid
|
||||
in the
|
||||
netconfig database.
|
||||
This option may be specified more than once,
|
||||
so as to compile a server that serves multiple transports.
|
||||
.It Fl o Ar outfile
|
||||
Specify the name of the output file.
|
||||
If none is specified,
|
||||
standard output is used
|
||||
.Po
|
||||
.Fl c Fl h Fl l
|
||||
.Fl m Fl n Fl s
|
||||
modes only
|
||||
.Pc
|
||||
.It Fl s Ar nettype
|
||||
Compile into server-side stubs for all the
|
||||
transports belonging to the class
|
||||
.Ar nettype .
|
||||
The supported classes are
|
||||
.Em netpath ,
|
||||
.Em visible ,
|
||||
.Em circuit_n ,
|
||||
.Em circuit_v ,
|
||||
.Em datagram_n ,
|
||||
.Em datagram_v ,
|
||||
.Em tcp ,
|
||||
and
|
||||
.Em udp
|
||||
[see
|
||||
.Xr rpc 3
|
||||
for the meanings associated with these classes.
|
||||
.Em Note :
|
||||
.Bx
|
||||
currently supports only the
|
||||
.Em tcp
|
||||
and
|
||||
.Em udp
|
||||
classes].
|
||||
This option may be specified more than once.
|
||||
.Em Note :
|
||||
the transports are chosen at run time and not at compile time.
|
||||
.It Fl S\&c
|
||||
Generate sample code to show the use of remote procedure and how to bind
|
||||
to the server before calling the client side stubs generated by
|
||||
.Nm .
|
||||
.It Fl S\&s
|
||||
Generate skeleton code for the remote procedures on the server side.
|
||||
You would need
|
||||
to fill in the actual code for the remote procedures.
|
||||
.\" .It Fl S\&m
|
||||
.\" Generate a sample Makefile that can be used to compile the application.
|
||||
.It Fl T
|
||||
Generate the code to support
|
||||
.Tn RPC
|
||||
dispatch tables.
|
||||
.It Fl t
|
||||
Compile into
|
||||
.Tn RPC
|
||||
dispatch table.
|
||||
.It Fl v
|
||||
Display the version number.
|
||||
.It Fl Y Ar pathname
|
||||
Specify the directory where
|
||||
.Nm
|
||||
looks for the C pre-processor.
|
||||
.El
|
||||
.Pp
|
||||
The options
|
||||
.Fl c ,
|
||||
.Fl h ,
|
||||
.Fl l ,
|
||||
.Fl m ,
|
||||
.Fl s ,
|
||||
and
|
||||
.Fl t
|
||||
are used exclusively to generate a particular type of file,
|
||||
while the options
|
||||
.Fl D
|
||||
and
|
||||
.Fl T
|
||||
are global and can be used with the other options.
|
||||
.Sh ENVIRONMENT
|
||||
If the
|
||||
.Ev RPCGEN_CPP
|
||||
environment variable is set, its value is used as the pathname of the
|
||||
C preprocessor to be run on the input file.
|
||||
.Sh NOTES
|
||||
The
|
||||
.Tn RPC
|
||||
Language does not support nesting of structures.
|
||||
As a work-around,
|
||||
structures can be declared at the top-level,
|
||||
and their name used inside other structures in
|
||||
order to achieve the same effect.
|
||||
.Pp
|
||||
Name clashes can occur when using program definitions,
|
||||
since the apparent scoping does not really apply.
|
||||
Most of these can be avoided by giving
|
||||
unique names for programs,
|
||||
versions,
|
||||
procedures and types.
|
||||
.Pp
|
||||
The server code generated with
|
||||
.Fl n
|
||||
option refers to the transport indicated by
|
||||
.Em netid
|
||||
and hence is very site specific.
|
||||
.Sh EXAMPLES
|
||||
The command
|
||||
.Pp
|
||||
.Bd -literal -offset indent
|
||||
$ rpcgen -T prot.x
|
||||
.Ed
|
||||
.Pp
|
||||
generates the five files:
|
||||
.Pa prot.h ,
|
||||
.Pa prot_clnt.c ,
|
||||
.Pa prot_svc.c ,
|
||||
.Pa prot_xdr.c
|
||||
and
|
||||
.Pa prot_tbl.i .
|
||||
.Pp
|
||||
The following example sends the C data-definitions (header file)
|
||||
to standard output.
|
||||
.Pp
|
||||
.Bd -literal -offset indent
|
||||
$ rpcgen -h prot.x
|
||||
.Ed
|
||||
.Pp
|
||||
To send the test version of the
|
||||
.Dv -DTEST ,
|
||||
server side stubs for
|
||||
all the transport belonging to the class
|
||||
.Em datagram_n
|
||||
to standard output, use:
|
||||
.Pp
|
||||
.Bd -literal -offset indent
|
||||
$ rpcgen -s datagram_n -DTEST prot.x
|
||||
.Ed
|
||||
.Pp
|
||||
To create the server side stubs for the transport indicated by
|
||||
.Em netid
|
||||
.Em tcp ,
|
||||
use:
|
||||
.Pp
|
||||
.Bd -literal -offset indent
|
||||
$ rpcgen -n tcp -o prot_svc.c prot.x
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr cpp 1 ,
|
||||
.Xr inetd 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Fl M
|
||||
option was first implemented in RedHat Linux, and was reimplemented by
|
||||
Charles M. Hannum in
|
||||
.Nx 1.6 .
|
||||
Reference in New Issue
Block a user