4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
29 * University Copyright- Copyright (c) 1982, 1986, 1988
30 * The Regents of the University of California
33 * University Acknowledgment- Portions of this document are derived from
34 * software developed by the University of California, Berkeley, and its
39 * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
43 #include <rpc/types.h>
44 #include "rpc_parse.h"
47 extern void pdeclaration(char *, declaration
*, int, char *);
48 extern void printarglist(proc_list
*, char *, char *, char *);
50 static void write_program(definition
*);
51 static void printbody(proc_list
*);
53 static char RESULT
[] = "clnt_res";
55 #define DEFAULT_TIMEOUT 25 /* in seconds */
64 "\n/* Default timeout can be changed using clnt_control() */\n");
65 f_print(fout
, "static struct timeval TIMEOUT = { %d, 0 };\n",
67 for (l
= defined
; l
!= NULL
; l
= l
->next
) {
68 def
= (definition
*) l
->val
;
69 if (def
->def_kind
== DEF_PROGRAM
) {
76 write_program(definition
*def
)
81 for (vp
= def
->def
.pr
.versions
; vp
!= NULL
; vp
= vp
->next
) {
82 for (proc
= vp
->procs
; proc
!= NULL
; proc
= proc
->next
) {
85 ptype(proc
->res_prefix
, proc
->res_type
, 1);
87 pvname(proc
->proc_name
, vp
->vers_num
);
88 printarglist(proc
, RESULT
, "clnt", "CLIENT *");
90 f_print(fout
, "enum clnt_stat \n");
91 pvname(proc
->proc_name
, vp
->vers_num
);
92 printarglist(proc
, RESULT
, "clnt", "CLIENT *");
104 * Writes out declarations of procedure's argument list.
105 * In either ANSI C style, in one of old rpcgen style (pass by reference),
106 * or new rpcgen style (multiple arguments, pass by value);
109 /* sample addargname = "clnt"; sample addargtype = "CLIENT * " */
112 printarglist(proc_list
*proc
, char *result
, char *addargname
, char *addargtype
)
114 bool_t oneway
= streq(proc
->res_type
, "oneway");
118 /* old style: always pass argument by reference */
119 if (Cflag
) { /* C++ style heading */
121 ptype(proc
->args
.decls
->decl
.prefix
,
122 proc
->args
.decls
->decl
.type
, 1);
124 if (mtflag
) { /* Generate result field */
125 f_print(fout
, "*argp, ");
127 ptype(proc
->res_prefix
,
129 f_print(fout
, "*%s, ", result
);
131 f_print(fout
, "%s%s)\n",
132 addargtype
, addargname
);
134 f_print(fout
, "*argp, %s%s)\n",
135 addargtype
, addargname
);
138 f_print(fout
, "(argp, %s)\n", addargname
);
140 f_print(fout
, "(argp, ");
142 f_print(fout
, "%s, ",
145 f_print(fout
, "%s)\n",
149 ptype(proc
->args
.decls
->decl
.prefix
,
150 proc
->args
.decls
->decl
.type
, 1);
151 f_print(fout
, "*argp;\n");
152 if (mtflag
&& !oneway
) {
154 ptype(proc
->res_prefix
, proc
->res_type
, 1);
155 f_print(fout
, "*%s;\n", result
);
158 } else if (streq(proc
->args
.decls
->decl
.type
, "void")) {
159 /* newstyle, 0 argument */
165 ptype(proc
->res_prefix
,
167 f_print(fout
, "*%s, ", result
);
169 f_print(fout
, "%s%s)\n",
170 addargtype
, addargname
);
172 f_print(fout
, "(%s)\n", addargname
);
176 f_print(fout
, "(%s%s)\n", addargtype
, addargname
);
178 f_print(fout
, "(%s)\n", addargname
);
180 /* new style, 1 or multiple arguments */
183 for (l
= proc
->args
.decls
; l
!= NULL
; l
= l
->next
)
184 f_print(fout
, "%s, ", l
->decl
.name
);
185 if (mtflag
&& !oneway
)
186 f_print(fout
, "%s, ", result
);
188 f_print(fout
, "%s)\n", addargname
);
189 for (l
= proc
->args
.decls
; l
!= NULL
; l
= l
->next
) {
190 pdeclaration(proc
->args
.argname
,
193 if (mtflag
&& !oneway
) {
195 ptype(proc
->res_prefix
, proc
->res_type
, 1);
196 f_print(fout
, "*%s;\n", result
);
199 } else { /* C++ style header */
201 for (l
= proc
->args
.decls
; l
!= NULL
; l
= l
->next
) {
202 pdeclaration(proc
->args
.argname
, &l
->decl
, 0,
205 if (mtflag
&& !oneway
) {
206 ptype(proc
->res_prefix
, proc
->res_type
, 1);
207 f_print(fout
, "*%s, ", result
);
210 f_print(fout
, "%s%s)\n", addargtype
, addargname
);
215 f_print(fout
, "\t%s%s;\n", addargtype
, addargname
);
223 if (isvectordef(type
, REL_ALIAS
)) {
231 printbody(proc_list
*proc
)
234 bool_t args2
= (proc
->arg_num
> 1);
235 bool_t oneway
= streq(proc
->res_type
, "oneway");
238 * For new style with multiple arguments, need a structure in which
239 * to stuff the arguments.
241 if (newstyle
&& args2
) {
242 f_print(fout
, "\t%s", proc
->args
.argname
);
243 f_print(fout
, " arg;\n");
247 f_print(fout
, "\tstatic ");
248 if (streq(proc
->res_type
, "void")) {
249 f_print(fout
, "char ");
251 ptype(proc
->res_prefix
, proc
->res_type
, 0);
253 f_print(fout
, "%s;\n", RESULT
);
256 "\t(void) memset(%s%s, 0, sizeof (%s));\n",
257 ampr(proc
->res_type
), RESULT
, RESULT
);
260 if (newstyle
&& !args2
&&
261 (streq(proc
->args
.decls
->decl
.type
, "void"))) {
262 /* newstyle, 0 arguments */
265 f_print(fout
, "\t return ");
267 f_print(fout
, "\t if ");
270 "(clnt_call(clnt, %s,\n\t\t(xdrproc_t)xdr_void, ",
273 "NULL,\n\t\t(xdrproc_t)xdr_%s, "
275 stringfix(proc
->res_type
),
276 (mtflag
)?"":ampr(proc
->res_type
),
280 f_print(fout
, "\n\t\tTIMEOUT));\n");
283 "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
285 } else if (newstyle
&& args2
) {
287 * Newstyle, multiple arguments
288 * stuff arguments into structure
290 for (l
= proc
->args
.decls
; l
!= NULL
; l
= l
->next
) {
291 f_print(fout
, "\targ.%s = %s;\n",
292 l
->decl
.name
, l
->decl
.name
);
295 f_print(fout
, "\treturn ");
297 f_print(fout
, "\tif ");
299 "(clnt_call(clnt, %s,\n\t\t(xdrproc_t)xdr_%s",
300 proc
->proc_name
, proc
->args
.argname
);
302 ", (caddr_t)&arg,\n\t\t(xdrproc_t)xdr_%s, "
304 stringfix(proc
->res_type
),
305 (mtflag
)?"":ampr(proc
->res_type
),
308 f_print(fout
, "\n\t\tTIMEOUT));\n");
311 "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
312 } else { /* single argument, new or old style */
315 "\tif (clnt_call(clnt, "
316 "%s,\n\t\t(xdrproc_t)xdr_%s, "
317 "(caddr_t)%s%s,\n\t\t(xdrproc_t)xdr_%s, "
318 "(caddr_t)%s%s,\n\t\tTIMEOUT) != "
321 stringfix(proc
->args
.decls
->decl
.type
),
322 (newstyle
? "&" : ""),
324 proc
->args
.decls
->decl
.name
:
326 stringfix(proc
->res_type
),
327 ampr(proc
->res_type
),
331 "\treturn (clnt_call(clnt, "
332 "%s,\n\t\t(xdrproc_t)xdr_%s, "
333 "(caddr_t)%s%s,\n\t\t(xdrproc_t)xdr_%s, "
334 "(caddr_t)%s%s,\n\t\tTIMEOUT));\n",
336 stringfix(proc
->args
.decls
->decl
.type
),
337 (newstyle
? "&" : ""),
339 proc
->args
.decls
->decl
.name
:
341 stringfix(proc
->res_type
), "",
345 f_print(fout
, "\t\treturn (NULL);\n");
346 f_print(fout
, "\t}\n");
348 if (streq(proc
->res_type
, "void")) {
349 f_print(fout
, "\treturn ((void *)%s%s);\n",
350 ampr(proc
->res_type
), RESULT
);
352 f_print(fout
, "\treturn (%s%s);\n",
353 ampr(proc
->res_type
), RESULT
);
359 f_print(fout
, "\tstatic enum clnt_stat ");
360 f_print(fout
, "%s;\n", RESULT
);
363 "\t(void) memset(&%s, 0, sizeof (%s));\n",
367 if (newstyle
&& !args2
&&
368 (streq(proc
->args
.decls
->decl
.type
, "void"))) {
369 /* newstyle, 0 arguments */
372 f_print(fout
, "\t return (");
374 f_print(fout
, "\t if ((%s = ", RESULT
);
377 "clnt_send(clnt, %s,\n\t\t(xdrproc_t)xdr_void, ",
379 f_print(fout
, "NULL)");
382 f_print(fout
, ");\n");
384 f_print(fout
, ") != RPC_SUCCESS) {\n");
386 } else if (newstyle
&& args2
) {
388 * Newstyle, multiple arguments
389 * stuff arguments into structure
391 for (l
= proc
->args
.decls
; l
!= NULL
; l
= l
->next
) {
392 f_print(fout
, "\targ.%s = %s;\n",
393 l
->decl
.name
, l
->decl
.name
);
396 f_print(fout
, "\treturn (");
398 f_print(fout
, "\tif ((%s =", RESULT
);
400 "clnt_send(clnt, %s,\n\t\t(xdrproc_t)xdr_%s",
401 proc
->proc_name
, proc
->args
.argname
);
405 f_print(fout
, ");\n");
407 f_print(fout
, ") != RPC_SUCCESS) {\n");
408 } else { /* single argument, new or old style */
411 "\tif ((%s = clnt_send(clnt, "
412 "%s,\n\t\t(xdrproc_t)xdr_%s, "
413 "(caddr_t)%s%s)) != RPC_SUCCESS) {\n",
416 stringfix(proc
->args
.decls
->decl
.type
),
417 (newstyle
? "&" : ""),
419 proc
->args
.decls
->decl
.name
:
424 "\treturn (clnt_send(clnt, "
425 "%s,\n\t\t(xdrproc_t)xdr_%s, "
426 "(caddr_t)%s%s));\n",
428 stringfix(proc
->args
.decls
->decl
.type
),
429 (newstyle
? "&" : ""),
431 proc
->args
.decls
->decl
.name
:
435 f_print(fout
, "\t\treturn (NULL);\n");
436 f_print(fout
, "\t}\n");
438 f_print(fout
, "\treturn ((void *)&%s);\n",