rpcgen(1)

๐Ÿ“ฆ
version 2.6.4 ยท 5 versions
, in alpine 3.22, alpine 3.23, alpine 3.24, arch rolling, centos-stream 10, centos-stream 9, debian bookworm, debian trixie, fedora 43, fedora 44, nixpkgs unstable, opensuse-leap 16.0, ubuntu jammy, ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking

๐ŸŽ€ NAME ๐ŸŽ€

rpcgen(1) ยท General Commands Manual ๐Ÿ“–

okay so rpcgen is an RPC protocol compiler ๐Ÿ’… rpcgen - an RPC protocol compiler

โœจ SYNOPSIS โœจ

rpcgen infile
rpcgen [-Dname[=value]] [-T] [-K secs] infile
rpcgen -c|-h|-l|-m|-M|-t [-o outfile ] infile
rpcgen [-I] -s nettype [-o outfile] infile
rpcgen -n netid [-o outfile] infile

๐Ÿ’– DESCRIPTION ๐Ÿ’–

okay bestie, listen up ๐Ÿซถ rpcgen is a tool that generates C code to implement an RPC protocol. The input is written in a language that looks a lot like C, called RPC Language (Remote Procedure Call Language). it's giving C but make it remote ๐Ÿ”ฅ

the first synopsis is the normal way to use it. you hand it an input file and it spits out up to four output files ๐Ÿงš if your infile is called proto.x, rpcgen makes:

  • a header file, proto.h
  • XDR routines, in proto_xdr.c
  • server-side stubs, in proto_svc.c
  • client-side stubs, in proto_clnt.c

with the -T option, it also makes the RPC dispatch table in proto_tbl.i โœจ with the -Sc option, it also generates sample code showing how to use the remote procedures on the client side, and that lives in proto_client.c ๐Ÿฆ‹ and with the -Ss option, it generates sample server code showing how to write the remote procedures, saved to proto_server.c ๐Ÿ’œ

the server you make can be started by the port monitors (like inetd or listen) or by itself ๐ŸŒธ when a port monitor starts it, it only makes servers for the transport that file descriptor 0 was passed in. the transport name has to be set up in the PM_TRANSPORT environment variable ๐Ÿซ  when the generated server runs on its own, it makes server handles for every transport listed in the NETPATH environment variable. if that's unset, it makes handles for all the visible transports from the /etc/netconfig file. note: the transports get picked at run time, not compile time, so no surprises ๐Ÿ‘‘

when you build for a port monitor (rpcgen -I) and the server starts itself, it backgrounds itself by default ๐ŸŒˆ if you want it in the foreground instead, define the special symbol RPC_SVC_FG ๐Ÿ™ˆ

the second synopsis is where things get fancy โœจ it unlocks more sophisticated RPC servers, with support for user-provided #defines and RPC dispatch tables. each entry in the dispatch table holds:

  • a pointer to the service routine for that procedure
  • a pointer to the input and output arguments
  • the size of those routines

a server can use the dispatch table to check authorization and then run the service routine, and a client library can use it to handle storage management and XDR data conversion. main character energy ๐Ÿ’…

the other three synopses are for when you don't want every output file, just one specific one. some examples are in the EXAMPLE section below ๐ŸŽ€ running rpcgen with -s makes servers for that particular class of transports, and running it with -n makes a server for the transport named by netid. if you don't specify an infile, rpcgen reads standard input ๐Ÿซถ

before rpcgen interprets the input file, the C preprocessor runs on it, using cc -E [see cc(1)]. for each type of output file, rpcgen defines a special preprocessor symbol you can use in your .x file:

  • RPC_HDR โ€” defined when compiling into header files
  • RPC_XDR โ€” defined when compiling into XDR routines
  • RPC_SVC โ€” defined when compiling into server-side stubs
  • RPC_CLNT โ€” defined when compiling into client-side stubs
  • RPC_TBL โ€” defined when compiling into RPC dispatch tables

any line that starts with % gets passed straight into the output file, and rpcgen doesn't touch it ๐Ÿ“

for every data type mentioned in infile, rpcgen assumes there's a routine named with xdr_ stuck on the front of the type name โœจ if that routine isn't in the RPC/XDR library, you have to provide it yourself. providing your own routine for an undefined data type is how you customize XDR routines ๐Ÿ”ฅ

๐ŸŽ€ The Options ๐ŸŽ€

here's everything you can pass, bestie ๐Ÿ’–

  • -a โ€” makes all the files, including sample code for both the client and server side ๐ŸŒธ
  • -b โ€” generates code for the SunOS4.1 style of rpc. it's there for backward compatibility, and it's the default ๐Ÿฆ‹
  • -5 โ€” generates code for the SysVr4 style of rpc ๐Ÿ’… this is the one used by Transport Independent RPC on Svr4 systems. by default rpcgen generates the SunOS4.1 style of rpc
  • -c โ€” compiles into XDR routines ๐Ÿงš
  • -C โ€” generates code in ANSI C. this also makes code that can be compiled by a C++ compiler, and it's the default โœจ
  • -k โ€” generates code in K&R C. the default is ANSI C ๐Ÿซ 
  • -Dname[=value] โ€” defines a symbol called name, same as a #define in the source. if you don't give a value, it's set to 1. you can use this option more than once ๐Ÿ’œ
  • -h โ€” compiles into C data-definitions, aka a header file ๐ŸŽ€ you can pair it with the -T option to make a header that supports RPC dispatch tables ๐Ÿ‘‘
  • -I โ€” generates a service that can be started from inetd ๐ŸŒˆ the default is a static service that handles the transports you pick with -s. using -I lets you start the service either way ๐Ÿ™ˆ
  • -K secs โ€” by default, services made with rpcgen wait 120 seconds after handling a request before they exit ๐Ÿ˜ญ you can change that interval with -K. for a server that exits right after handling a request, use -K 0. for a server that never exits, use -K -1 ๐Ÿ’€

when you're monitoring for a server, some port monitors, like listen(1M), always spawn a new process for each service request. if you know your server will be used with one of those, it should exit immediately when it's done. for those servers, run rpcgen with -K -1 ๐Ÿ“

  • -l โ€” compiles into client-side stubs ๐Ÿฆ‹
  • -m โ€” compiles into server-side stubs, but doesn't generate a โ€œmainโ€ routine ๐Ÿ’œ this is handy for callback routines, and for people who want to write their own โ€œmainโ€ for setup stuff ๐Ÿซถ
  • -M โ€” generates multithread-safe stubs for passing arguments and results between rpcgen-generated code and the code you write ๐Ÿงต this one's great if you want threads in your code โœจ
  • -n netid โ€” compiles into server-side stubs for the transport named by netid ๐Ÿ”ฅ there should be an entry for that netid in the netconfig database. you can use this option more than once to build a server that serves multiple transports ๐ŸŒธ
  • -N โ€” uses the newstyle of rpcgen ๐Ÿ’… this lets procedures take multiple arguments, and it passes parameters in a way that looks a lot more like C. so when you pass an argument to a remote procedure, you pass the argument itself, not a pointer to it ๐Ÿซ  this is different from the oldstyle generated code. newstyle isn't the default because of backward compatibility ๐Ÿ‘‘
  • -o outfile โ€” names the output file ๐ŸŽ€ if you don't pick one, the output goes to standard output. this works for the -c, -h, -l, -m, -n, -s, -Sc, -Sm, -Ss, and -t modes only ๐Ÿงš
  • -s nettype โ€” compiles into server-side stubs for every transport in the nettype class โœจ the supported classes are netpath, visible, circuit_n, circuit_v, datagram_n, datagram_v, tcp, and udp [see rpc(3N) for what these classes mean]. you can use this option more than once ๐Ÿ’– note: the transports are chosen at run time, not compile time ๐ŸŒˆ
  • -Sc โ€” generates sample code showing how to use the remote procedures and how to bind to the server before calling the client-side stubs rpcgen made ๐Ÿฆ‹
  • -Sm โ€” generates a sample Makefile you can use to compile the application ๐Ÿ“
  • -Ss โ€” generates skeleton code for the remote procedures on the server side ๐ŸŒธ you'll need to fill in the actual code for them yourself ๐Ÿ™ˆ
  • -t โ€” compiles into an RPC dispatch table ๐Ÿ’œ
  • -T โ€” generates the code that supports RPC dispatch tables ๐Ÿงš

the options -c, -h, -l, -m, -s, and -t are used exclusively, meaning each one makes one specific type of file ๐Ÿ”ฅ the options -D and -T are global, so you can combine them with the other options ๐Ÿซถ


๐Ÿ™ˆ NOTES ๐Ÿ™ˆ

heads up: the RPC Language doesn't support nesting structures ๐Ÿ˜ญ the workaround is to declare structures at the top level, then use their names inside other structures to get the same effect ๐Ÿ’…

name clashes can happen with program definitions, because the apparent scoping doesn't really apply ๐Ÿ’€ you can avoid most of them by giving programs, versions, procedures, and types unique names โœจ

the server code generated with the -n option refers to the transport indicated by netid, so it's very site specific ๐ŸŒ


๐Ÿงš EXAMPLE ๐Ÿงš

this one's a classic ๐Ÿ’– it generates five files:

$ rpcgen -T prot.x

the files are prot.h, prot_clnt.c, prot_svc.c, prot_xdr.c, and prot_tbl.i โœจ

this one sends the C data-definitions (the header file) to standard output ๐ŸŽ€

$ rpcgen -h prot.x

to send the test version of the server-side stubs for all the transports in the datagram_n class to standard output, with -DTEST defined, use this ๐Ÿฆ‹

$ rpcgen -s datagram_n -DTEST prot.x

and to create the server-side stubs for the transport indicated by netid tcp, use this ๐Ÿซถ

$ rpcgen -n tcp -o prot_svc.c prot.x

๐ŸŒˆ SEE ALSO ๐ŸŒˆ

cc(1) ๐Ÿ’…


ok that's the whole tea โ˜• rpcgen(1), signing off ๐Ÿ’œ๐Ÿฆ‹โœจ

๐Ÿ“ฆ where this page comes from