1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77/* 78** NAME: 79** 80** sstubmts.c 81** 82** FACILITY: 83** 84** Interface Definition Language (IDL) Compiler 85** 86** ABSTRACT: 87** 88** Generation of server stub file for MTS compiler 89** 90*/ 91 92#include <nidl.h> 93#include <ast.h> 94#include <bedeck.h> 95#include <command.h> 96#include <ddbe.h> 97#include <ifspec.h> 98#include <cspeldcl.h> 99#include <cspell.h> 100#include <mtsbacke.h> 101#include <mtspipes.h> 102#include <sstubmts.h> 103#include <user_exc.h> 104#include <clihandl.h> 105#include <icharsup.h> 106#include <cstubmts.h> 107 108typedef struct param_node_link_t { 109 AST_parameter_n_t *p_param; 110 struct param_node_link_t *p_next; 111} param_node_link_t; 112/* Used to build a list of "interesting" parameters of an operation */ 113 114typedef enum { 115 /* handle_t parameter with [represent_as] */ 116 BE_no_rep_as_handle_t_k, /* not present */ 117 BE_val_rep_as_handle_t_k, /* passed by value */ 118 BE_ref_rep_as_handle_t_k /* passed by reference */ 119} BE_rep_as_handle_t_k_t; 120 121static char rep_as_handle_name[] = "IDL_handle_rep_as"; 122 123/* 124 * BE_server_binding_analyze 125 * 126 * Find whether operation can be called by [auto_handle] client, and 127 * whether there is a first handle_t parameter with a [represent_as] attribute 128 * 129 */ 130static void BE_server_binding_analyze 131( 132 AST_operation_n_t *p_operation, 133 boolean *server_binding_explicit, /* TRUE if no client can use [auto_handle] 134 binding with this operation */ 135 BE_rep_as_handle_t_k_t *p_rep_as_handle_param, 136 NAMETABLE_id_t *p_rep_as_type_name, /* type of handle param */ 137 NAMETABLE_id_t *p_binding_handle_name 138) 139{ 140 AST_parameter_n_t *p_first_parameter; 141 AST_type_n_t *p_type, *p_pointee_type; 142 143 *p_rep_as_handle_param = BE_no_rep_as_handle_t_k; 144 *p_binding_handle_name = NAMETABLE_add_id("IDL_binding_handle"); 145 p_first_parameter = p_operation->parameters; 146 if ( p_first_parameter == NULL ) 147 { 148 /* No parameters */ 149 *server_binding_explicit = false; 150 return; 151 } 152 p_type = p_first_parameter->type; 153 if ( p_type->kind == AST_handle_k ) 154 { 155 /* handle_t by value */ 156 *server_binding_explicit = true; 157 *p_binding_handle_name = p_first_parameter->name; 158 if ( p_type->rep_as_type != NULL ) 159 { 160 *p_rep_as_handle_param = BE_val_rep_as_handle_t_k; 161 *p_rep_as_type_name = p_type->name; 162 } 163 return; 164 } 165 if ( AST_HANDLE_SET(p_type) ) 166 { 167 /* Customized handle by value */ 168 *server_binding_explicit = true; 169 return; 170 } 171 if ( p_type->kind == AST_pointer_k ) 172 { 173 p_pointee_type = p_type->type_structure.pointer->pointee_type; 174 if ( p_pointee_type->kind == AST_handle_k ) 175 { 176 /* handle_t by reference */ 177 *server_binding_explicit = true; 178 *p_binding_handle_name = p_first_parameter->name; 179 if ( p_pointee_type->rep_as_type != NULL ) 180 { 181 *p_rep_as_handle_param = BE_ref_rep_as_handle_t_k; 182 *p_rep_as_type_name = p_pointee_type->name; 183 } 184 return; 185 } 186 if ( AST_HANDLE_SET(p_pointee_type) ) 187 { 188 /* Customized handle by reference */ 189 *server_binding_explicit = true; 190 return; 191 } 192 } 193 if ( AST_HAS_IN_CTX_SET(p_operation) ) 194 { 195 *server_binding_explicit = true; 196 return; 197 } 198 if ( AST_EXPLICIT_HANDLE_SET(p_operation) ) 199 { 200 /* [explicit_handle] in ACF */ 201 *server_binding_explicit = false; 202 return; 203 } 204 *server_binding_explicit = false; 205 return; 206} 207 208/* 209 * CSPELL_zero_initializer 210 * 211 * Emit a type-specific zero-initializer for a parameter that has been declared 212 * on the stack of a server stub routine. 213 */ 214static void CSPELL_zero_initializer 215( 216 FILE *fid, 217 const AST_type_n_t *type 218) 219{ 220 221 switch (type->kind) 222 { 223 case AST_pointer_k: 224 case AST_handle_k: 225 fprintf(fid, " = NULL"); 226 break; 227 case AST_boolean_k: 228 fprintf(fid, " = ndr_false"); 229 break; 230 case AST_short_float_k: 231 case AST_long_float_k: 232 fprintf(fid, " = 0.0"); 233 break; 234 case AST_small_integer_k: 235 case AST_short_integer_k: 236 case AST_long_integer_k: 237 case AST_small_unsigned_k: 238 case AST_short_unsigned_k: 239 case AST_long_unsigned_k: 240 fprintf(fid, " = 0"); 241 break; 242 case AST_hyper_integer_k: 243 fprintf(fid, " = 0ULL"); 244 break; 245 case AST_hyper_unsigned_k: 246 fprintf(fid, " = 0LL"); 247 break; 248 case AST_array_k: 249 case AST_structure_k: 250 case AST_disc_union_k: 251 fprintf(fid, " = {}"); 252 break; 253 default: 254 fprintf(fid, " /* no initializer for kind %d */", type->kind); 255 break; 256 } 257} 258 259/* 260 * DDBE_spell_stack_surrogates 261 * 262 * Spell server surrogates as stack variables 263 */ 264static void DDBE_spell_stack_surrogates 265( 266 FILE *fid, 267 param_node_link_t **p_fixed_char_array_list ATTRIBUTE_UNUSED, 268 /* Pointer to list of fixed size character array parameters */ 269 AST_operation_n_t *p_operation 270) 271{ 272 unsigned long param_index; 273 AST_parameter_n_t *pp; /* Pointer down list of parameters */ 274 AST_type_n_t array_elt_ptr_type_node; 275 AST_pointer_n_t array_elt_ptr_pointer_node; 276 277 param_index = 0; 278 for (pp = p_operation->parameters; pp != NULL; pp = pp->next) 279 { 280 param_index++; 281 if (param_index == 1) 282 { 283 if (pp->type->kind == AST_handle_k) 284 { 285 continue; 286 } 287 else if ( (pp->type->kind == AST_pointer_k) 288 && (pp->type->type_structure.pointer->pointee_type->kind 289 == AST_handle_k) ) 290 { 291 continue; 292 } 293 } 294 if (AST_REF_SET(pp) && (pp->type->rep_as_type == NULL) 295 && (AST_CONFORMANT_SET(pp->type) 296 || (DDBE_ARRAYIFIED(pp) 297 && AST_CONFORMANT_SET(pp->type->type_structure. 298 pointer->pointee_type->array_rep_type)))) 299 { 300 /* [ref] arrayified pointer or array without [ptr] or [unique] 301 Storage allocated by interpreter */ 302 continue; 303 } 304 if ((pp->type->kind == AST_pointer_k) && AST_REF_SET(pp) 305 && AST_CONFORMANT_SET(pp->type->type_structure.pointer 306 ->pointee_type) 307 && (pp->type->type_structure.pointer->pointee_type 308 ->rep_as_type == NULL)) 309 { 310 /* [ref] pointer to conformant object 311 Storage allocated by interpreter */ 312 continue; 313 } 314 /* 315 * No surrogate is needed for a [heap] parameter unless it has a 316 * non-[ref] pointer attribute in which case a surrogate for the 317 * pointer is needed and the pointee is allocated in the Interpreter. 318 */ 319 if (AST_HEAP_SET(pp) && !AST_PTR_SET(pp) && !AST_UNIQUE_SET(pp)) 320 { 321 /* No stack surrogate. Storage allocated by interpreter */ 322 continue; 323 } 324 if (AST_CONTEXT_SET(pp)) 325 { 326 /* Special data structure for context handle */ 327 fprintf(fid,"IDL_ee_context_t %s;\n", BE_get_name(pp->name)); 328 continue; 329 } 330 if (AST_CONTEXT_SET(pp)) 331 { 332 /* Special data structure for context handle */ 333 fprintf(fid,"IDL_ee_context_t %s;\n", BE_get_name(pp->name)); 334 continue; 335 } 336 if (pp->type->kind == AST_pointer_k) 337 { 338 CSPELL_typed_name(fid, 339 (AST_REF_SET(pp) 340 ? pp->type->type_structure.pointer->pointee_type 341 : pp->type), 342 pp->name, NULL, false, true, false); 343 344 CSPELL_zero_initializer(fid, 345 AST_REF_SET(pp) ? pp->type->type_structure.pointer->pointee_type 346 : pp->type); 347 } 348 else if ( (pp->type->kind == AST_array_k) 349 && (AST_UNIQUE_SET(pp) || AST_PTR_SET(pp)) ) 350 { 351 array_elt_ptr_pointer_node.pointee_type 352 = pp->type->type_structure.array->element_type; 353 array_elt_ptr_type_node.name = NAMETABLE_NIL_ID; 354 array_elt_ptr_type_node.kind = AST_pointer_k; 355 array_elt_ptr_type_node.flags = 0; 356 array_elt_ptr_type_node.xmit_as_type = NULL; 357 array_elt_ptr_type_node.rep_as_type = NULL; 358 array_elt_ptr_type_node.cs_char_type = NULL; 359 array_elt_ptr_type_node.array_rep_type = NULL; 360 array_elt_ptr_type_node.type_structure.pointer 361 = &array_elt_ptr_pointer_node; 362 CSPELL_typed_name(fid, &array_elt_ptr_type_node, 363 pp->name, NULL, false, true, false); 364 CSPELL_zero_initializer(fid, &array_elt_ptr_type_node); 365 } 366 else 367 { 368 CSPELL_typed_name(fid, pp->type, pp->name, NULL, false, true, 369 false); 370 CSPELL_zero_initializer(fid, pp->type); 371 } 372 fprintf(fid, ";\n"); 373 } 374} 375 376/* 377 * CSPELL_manager_call 378 * 379 * Emit a call to a manager operation 380 */ 381static void CSPELL_manager_call 382( 383 FILE *fid, 384 AST_interface_n_t *p_interface, 385 AST_operation_n_t *p_operation, 386 BE_rep_as_handle_t_k_t rep_as_handle_param, 387 NAMETABLE_id_t rep_as_type_name, 388 NAMETABLE_id_t binding_handle_name 389) 390{ 391 AST_parameter_n_t *pp; /* Pointer down list of parameters */ 392 int param_index; /* Index of parameter in param list */ 393 int visible_param_count; /* Number of parameters spelt into call */ 394 395 if ( rep_as_handle_param != BE_no_rep_as_handle_t_k ) 396 { 397 fprintf( fid, "%s_to_local(&%s,&%s);\n", 398 BE_get_name(rep_as_type_name), 399 BE_get_name(binding_handle_name), 400 rep_as_handle_name ); 401 } 402 403 fprintf (fid, "\n/* manager call */\n"); 404 fprintf( fid, "IDL_manager_entered = ndr_true;\n" ); 405 fprintf( fid, "RPC_SS_THREADS_DISABLE_ASYNC(IDL_async_cancel_state);\n"); 406 407 if (AST_NO_CANCEL_SET(p_operation)) 408 fprintf( fid, "RPC_SS_THREADS_DISABLE_GENERAL(IDL_general_cancel_state);\n" ); 409 else 410 fprintf( fid, "RPC_SS_THREADS_ENABLE_GENERAL(IDL_general_cancel_state);\n" ); 411 412 if (p_operation->result->type->kind != AST_void_k) 413 { 414 if (AST_CONTEXT_SET(p_operation->result)) 415 fprintf(fid, "IDL_function_result.local = "); 416 else 417 fprintf(fid, "IDL_function_result = "); 418 } 419 420 fprintf(fid, "(*((%s_v%ld_%ld_epv_t *)IDL_mgr_epv)->", 421 BE_get_name(p_interface->name), (p_interface->version%65536), 422 (p_interface->version/65536)); 423 spell_name(fid, p_operation->name); 424 425 fprintf(fid,")("); 426 visible_param_count = 0; 427 param_index = 1; 428 for (pp = p_operation->parameters; pp != NULL; pp = pp->next) 429 { 430 if (AST_HIDDEN_SET(pp)) 431 { 432 /* Parameter does not appear in signature delivered to user */ 433 /* Note that hidden parameter cannot appear before binding handle */ 434 param_index++; 435 continue; 436 } 437 else 438 { 439 visible_param_count++; 440 if (visible_param_count > 1) 441 fprintf (fid, ",\n "); 442 } 443 if (param_index == 1) 444 { 445 if ( rep_as_handle_param != BE_no_rep_as_handle_t_k ) 446 { 447 fprintf( fid, "%c%s", 448 ((rep_as_handle_param == BE_ref_rep_as_handle_t_k) 449 ) 450 ? '&' : ' ', 451 rep_as_handle_name ); 452 param_index++; 453 continue; 454 } 455 else if (pp->type->kind == AST_handle_k) 456 { 457 spell_name(fid, binding_handle_name); 458 param_index++; 459 continue; 460 } 461 else if ( (pp->type->kind == AST_pointer_k) 462 && (pp->type->type_structure.pointer->pointee_type->kind 463 == AST_handle_k) ) 464 { 465 fprintf(fid, "&%s", BE_get_name(binding_handle_name)); 466 param_index++; 467 continue; 468 } 469 } 470 471 if ((AST_HEAP_SET(pp) 472 || (AST_CONFORMANT_SET(pp->type) 473 && !AST_UNIQUE_SET(pp) && !AST_PTR_SET(pp)) 474 || ((pp->type->kind == AST_pointer_k) && AST_REF_SET(pp) 475 && (BE_Is_Arrayified(pp,pp->type) 476 || AST_CONFORMANT_SET(pp->type->type_structure.pointer 477 ->pointee_type)))) 478 ) 479 { 480 /* 481 * Cast needed on (void *) pointer to dynamically allocated store. 482 * A different cast is needed if we need to dereference the ptr. 483 */ 484 boolean deref; 485 if ((pp->type->kind == AST_array_k) 486 && (AST_UNIQUE_SET(pp) || AST_PTR_SET(pp))) 487 { 488 DDBE_spell_manager_param_cast( fid, pp->type ); 489 fprintf(fid, "*(rpc_void_p_t *)"); 490 } 491 else 492 { 493 deref = ((pp->type->kind != AST_pointer_k) 494 && (pp->type->kind != AST_array_k) 495 ); 496 if (!deref) 497 DDBE_spell_manager_param_cast( fid, pp->type ); 498 fprintf( fid, "%c", ((deref) ? '*' : ' ') ); 499 if (deref) 500 CSPELL_ptr_cast_exp( fid, pp->type ); 501 } 502 fprintf( fid, "(IDL_param_vec[%d])", param_index ); 503 } 504 else if (AST_CONTEXT_SET(pp)) 505 { 506 /* Opaque context handle type requires cast */ 507 if (pp->type->type_structure.pointer->pointee_type->kind 508 == AST_pointer_k 509 && pp->type->type_structure.pointer->pointee_type-> 510 type_structure.pointer->pointee_type->kind 511 == AST_structure_k) 512 CSPELL_cast_exp(fid, pp->type); 513 /* Context handle by value is pointer to void, 514 by reference is pointer to pointer to void */ 515 fprintf( fid, "%c%s.local", 516 ((pp->type->type_structure.pointer->pointee_type->kind 517 == AST_pointer_k) 518 ) 519 ? '&' : ' ', 520 BE_get_name(pp->name) ); 521 } 522 else 523 { 524 if ( 525 ((pp->type->kind == AST_pointer_k) && AST_REF_SET(pp) 526 && !(BE_Is_Arrayified(pp,pp->type))) ) 527 { 528 /* non-arrayified parameter passed by reference, but not for interfaces */ 529 if (!(pp->type->kind == AST_pointer_k && pp->type->type_structure.pointer->pointee_type->kind == AST_interface_k)) 530 fprintf(fid, "&"); 531 } 532 spell_name(fid, pp->name); 533 } 534 535 param_index++; 536 } 537 538 fprintf(fid, ");\n"); 539 fprintf( fid, 540 "RPC_SS_THREADS_RESTORE_GENERAL(IDL_general_cancel_state);\n" ); 541 fprintf( fid, "RPC_SS_THREADS_RESTORE_ASYNC(IDL_async_cancel_state);\n"); 542 543 if ( rep_as_handle_param != BE_no_rep_as_handle_t_k ) 544 { 545 fprintf( fid, "%s_free_local(&%s);\n", 546 BE_get_name(rep_as_type_name), 547 rep_as_handle_name ); 548 } 549} 550 551/* 552 * DDBE_convert_out_contexts 553 * 554 * Convert user [out] context handles from local format to wire format 555 * and change the param vector entries to point at the wire formats 556 * 557 */ 558static void DDBE_convert_out_contexts 559( 560 FILE *fid, 561 AST_operation_n_t *p_operation, 562 NAMETABLE_id_t binding_handle_name 563) 564{ 565 AST_parameter_n_t *pp; 566 567 if ( AST_CONTEXT_SET(p_operation->result) ) 568 { 569 fprintf(fid, 570"rpc_ss_ee_ctx_to_wire(IDL_function_result.local,&IDL_function_result.wire, %s,", 571 BE_get_name(binding_handle_name)); 572 if ( AST_CONTEXT_RD_SET(p_operation->result->type) ) 573 { 574 spell_name(fid, p_operation->result->type->name); 575 fprintf(fid, "_rundown, "); 576 } 577 else 578 fprintf(fid, "(void (*)())NULL, "); 579 fprintf(fid, "idl_false, &IDL_ms.IDL_status);\n"); 580 CSPELL_test_status(fid); 581 } 582 583 for (pp = p_operation->parameters; pp != NULL; pp = pp->next) 584 { 585 if ( AST_OUT_SET(pp) && AST_CONTEXT_SET(pp) ) 586 { 587 fprintf(fid, "rpc_ss_ee_ctx_to_wire(%s.local, &%s.wire, %s,", 588 BE_get_name(pp->name), BE_get_name(pp->name), 589 BE_get_name(binding_handle_name)); 590 /* [out] context must be passed by reference. 591 Does it require rundown? */ 592 if ( AST_CONTEXT_RD_SET(pp->type->type_structure.pointer 593 ->pointee_type) ) 594 { 595 spell_name(fid, pp->type->type_structure.pointer 596 ->pointee_type->name); 597 fprintf(fid, "_rundown, "); 598 } 599 else 600 fprintf(fid, "(void (*)())NULL, "); 601 fprintf(fid, "%s, &IDL_ms.IDL_status);\n", 602 AST_IN_SET(pp) ? "idl_true" : "idl_false"); 603 CSPELL_test_status(fid); 604 } 605 } 606} 607 608/* 609 * CSPELL_server_stub_routine 610 * 611 * Generate a server stub routine for an operation 612 */ 613static void CSPELL_server_stub_routine 614( 615 FILE *fid, 616 language_k_t language ATTRIBUTE_UNUSED, 617 AST_interface_n_t *p_interface, 618 AST_operation_n_t *p_operation, 619 int num_declared_exceptions, /* Count of user declared exceptions */ 620 int num_extern_exceptions, /* Count of user extern_exceptions */ 621 boolean *cmd_opt 622) 623{ 624 long first_pipe; /* Index of first pipe to be processed */ 625 boolean explicit_binding; 626 BE_rep_as_handle_t_k_t rep_as_handle_param; 627 NAMETABLE_id_t rep_as_type_name = NULL; 628 NAMETABLE_id_t binding_handle_name; 629 param_node_link_t *fixed_char_array_list = NULL; 630 /* List of fixed size character array parameters */ 631 BE_cs_info_t cs_info; /* I-char machinery description */ 632 BE_handle_info_t handle_info; 633 boolean midl_mode = cmd_opt[opt_midl]; 634 635 BE_server_binding_analyze(p_operation, &explicit_binding, 636 &rep_as_handle_param, &rep_as_type_name, &binding_handle_name); 637 handle_info.deref_assoc = ' '; 638 NAMETABLE_id_to_string(binding_handle_name, &handle_info.assoc_name); 639 640 fprintf (fid, "\nstatic void op%d_ssr", p_operation->op_number); 641 642 fprintf (fid, "\n"); 643 644 fprintf (fid, "(\n"); 645 fprintf (fid, " handle_t %s,\n", handle_info.assoc_name); 646 fprintf (fid, " rpc_call_handle_t IDL_call_h,\n"); 647 fprintf (fid, " rpc_iovector_elt_p_t IDL_elt_p,\n"); 648 fprintf (fid, " ndr_format_p_t IDL_drep_p,\n"); 649 fprintf (fid, " __IDL_UNUSED__ rpc_transfer_syntax_p_t IDL_transfer_syntax_p,\n"); 650 fprintf (fid, " rpc_mgr_epv_t IDL_mgr_epv,\n"); 651 fprintf (fid, " error_status_t *IDL_status_p\n)\n"); 652 653 fprintf (fid, "{\n"); 654 fprintf(fid, "IDL_ms_t IDL_ms;\n"); 655 fprintf(fid, "volatile ndr_boolean IDL_manager_entered = ndr_false;\n"); 656 fprintf(fid, 657 "volatile RPC_SS_THREADS_CANCEL_STATE_T IDL_async_cancel_state=RPC_SS_THREADS_CANCEL_STATE_T_INITIALIZER;\n"); 658 fprintf(fid, 659 "volatile RPC_SS_THREADS_CANCEL_STATE_T IDL_general_cancel_state=RPC_SS_THREADS_CANCEL_STATE_T_INITIALIZER;\n"); 660 fprintf(fid, "idl_byte IDL_stack_packet[IDL_STACK_PACKET_SIZE];\n"); 661 662 if (AST_HAS_IN_PIPES_SET(p_operation) 663 || AST_HAS_OUT_PIPES_SET(p_operation)) 664 { 665 fprintf(fid, "long IDL_current_pipe = 0;\n"); 666 } 667 668 DDBE_spell_param_vec_def( fid, p_operation, BE_server_side, 669 BE_cmd_opt, BE_cmd_val ); 670 DDBE_spell_stack_surrogates( fid, 671 &fixed_char_array_list, 672 p_operation ); 673 674 /* Does operation use I-char machinery? If so, declare needed variables */ 675 BE_cs_analyze_and_spell_vars(fid, p_operation, BE_server_side, &cs_info); 676 677 if (AST_HAS_IN_PTRS_SET(p_operation) 678 || AST_HAS_OUT_PTRS_SET(p_operation) 679 || AST_ENABLE_ALLOCATE_SET(p_operation)) 680 { 681 fprintf(fid, "rpc_ss_thread_support_ptrs_t IDL_support_ptrs;\n"); 682 } 683 684 /* If there is a function result, we need somewhere to put it */ 685 if (p_operation->result->type->kind != AST_void_k) 686 { 687 if ( AST_CONTEXT_SET(p_operation->result) ) 688 { 689 /* Declare stack workspace for the wire form of context handle 690 function result */ 691 fprintf(fid, "IDL_ee_context_t IDL_function_result;\n"); 692 } 693 else 694 { 695 CSPELL_typed_name(fid, p_operation->result->type, 696 NAMETABLE_add_id("IDL_function_result"), 697 NULL, false, true, false); 698 fprintf(fid, ";\n"); 699 } 700 } 701 702 if ( rep_as_handle_param != BE_no_rep_as_handle_t_k ) 703 { 704 fprintf( fid, "%s %s;\n", 705 BE_get_name(rep_as_type_name), rep_as_handle_name ); 706 } 707 708 if (AST_HAS_IN_CTX_SET(p_operation) 709 || AST_HAS_OUT_CTX_SET(p_operation)) 710 { 711 fprintf(fid, "rpc_client_handle_t IDL_client_id=NULL;\n"); 712 } 713 714 /* 715 * Start of executable code 716 */ 717 fprintf(fid, "RPC_SS_INIT_SERVER\n"); 718 fprintf(fid, "rpc_ss_init_marsh_state(IDL_type_vec, &IDL_ms);\n"); 719 720 /* Centeris: set memory management callbacks if in midl mode */ 721 if (midl_mode) 722 { 723 fprintf(fid, "IDL_ms.IDL_mem_handle.alloc = midl_user_allocate;\n"); 724 fprintf(fid, "IDL_ms.IDL_mem_handle.free = midl_user_free;\n"); 725 } 726 727 fprintf(fid, 728 "IDL_ms.IDL_stack_packet_status = IDL_stack_packet_unused_k;\n"); 729 fprintf(fid, "IDL_ms.IDL_stack_packet_addr = IDL_stack_packet;\n"); 730 fprintf(fid, "DCETHREAD_TRY\n"); 731 fprintf(fid, "IDL_ms.IDL_offset_vec = IDL_offset_vec;\n"); 732 fprintf(fid, "IDL_ms.IDL_rtn_vec = IDL_rtn_vec;\n"); 733 fprintf(fid, "IDL_ms.IDL_call_h = (volatile rpc_call_handle_t)IDL_call_h;\n"); 734 fprintf(fid, "IDL_ms.IDL_drep = *IDL_drep_p;\n"); 735 736 fprintf(fid, "IDL_ms.IDL_elt_p = IDL_elt_p;\n"); 737 DDBE_spell_param_vec_init( fid, p_operation, BE_server_side, 738 BE_cmd_opt, BE_cmd_val ); 739 fprintf(fid, "IDL_ms.IDL_param_vec = IDL_param_vec;\n"); 740 fprintf(fid, "IDL_ms.IDL_side = IDL_server_side_k;\n"); 741 fprintf(fid, "IDL_ms.IDL_language = "); 742 fprintf(fid, "IDL_lang_c_k"); 743 fprintf(fid, ";\n"); 744 745 /* Does operation use I-char machinery? If so, set up needed state */ 746 BE_spell_cs_state(fid, "IDL_ms.", BE_server_side, &cs_info); 747 if (cs_info.cs_machinery) 748 fprintf(fid, "IDL_ms.IDL_h=%s;\n", handle_info.assoc_name); 749 750 /* If there are user exceptions which are not external, initialize them */ 751 if (num_declared_exceptions != 0) 752 { 753 fprintf(fid, 754 "RPC_SS_THREADS_ONCE(&IDL_exception_once,IDL_exceptions_init);\n"); 755 } 756 757 /* 758 * Is there a reference from this client to a context? 759 */ 760 if (AST_HAS_IN_CTX_SET(p_operation) 761 || AST_HAS_OUT_CTX_SET(p_operation)) 762 { 763 fprintf(fid, 764"rpc_ss_ctx_client_ref_count_i_2(%s,&IDL_client_id,(error_status_t*)&IDL_ms.IDL_status);\n", 765 handle_info.assoc_name); 766 CSPELL_test_status(fid); 767 } 768 769 /* 770 * Node initializations 771 */ 772 if (AST_HAS_IN_PTRS_SET(p_operation) 773 || AST_HAS_OUT_PTRS_SET(p_operation) 774 || AST_ENABLE_ALLOCATE_SET(p_operation)) 775 { 776 fprintf( fid, 777"rpc_ss_create_support_ptrs( &IDL_support_ptrs,&IDL_ms.IDL_mem_handle);\n" ); 778 if (AST_HAS_FULL_PTRS_SET(p_operation)) 779 { 780 fprintf(fid, 781"rpc_ss_init_node_table(&IDL_ms.IDL_node_table,&IDL_ms.IDL_mem_handle);\n"); 782 if (AST_REFLECT_DELETIONS_SET(p_operation)) 783 { 784 fprintf(fid, 785 "rpc_ss_enable_reflect_deletes(IDL_ms.IDL_node_table);\n"); 786 } 787 } 788 } 789 790 /* 791 * Pipe initializations 792 */ 793 if (AST_HAS_IN_PIPES_SET(p_operation) || AST_HAS_OUT_PIPES_SET(p_operation)) 794 { 795 DDBE_init_server_pipes( fid, p_operation, &first_pipe ); 796 fprintf( fid, "IDL_current_pipe=(%ld);\n", first_pipe ); 797 } 798 799 /* Unmarshall the ins */ 800 DDBE_spell_marsh_or_unmar( fid, p_operation, "rpc_ss_ndr_unmar_interp", 801 "&IDL_ms", BE_server_side, BE_unmarshalling_k ); 802 803 /* If there is I-char machinery, call the [cs_tag_rtn] if there is one */ 804 BE_spell_cs_tag_rtn_call(fid, "IDL_ms.", p_operation, BE_server_side, 805 &handle_info, &cs_info, false); 806 807 CSPELL_manager_call(fid, p_interface, p_operation, 808 rep_as_handle_param, rep_as_type_name, binding_handle_name); 809 810 DDBE_convert_out_contexts(fid, p_operation, binding_handle_name); 811 812 if (AST_HAS_IN_PIPES_SET(p_operation) || AST_HAS_OUT_PIPES_SET(p_operation)) 813 { 814 fprintf( fid, "if (IDL_current_pipe != %d)\n", BE_FINISHED_WITH_PIPES ); 815 fprintf( fid, "{\n" ); 816 fprintf( fid, "DCETHREAD_RAISE(rpc_x_ss_pipe_discipline_error);\n" ); 817 fprintf( fid, "}\n" ); 818 } 819 820 /* Marshall the outs */ 821 fprintf(fid, "{\n"); 822 DDBE_spell_marsh_or_unmar( fid, p_operation, "rpc_ss_ndr_marsh_interp", 823 "&IDL_ms", BE_server_side, BE_marshalling_k ); 824 fprintf(fid, "if (IDL_ms.IDL_iovec.num_elt != 0)\n"); 825 fprintf(fid, 826" rpc_call_transmit((rpc_call_handle_t)IDL_ms.IDL_call_h,(rpc_iovector_p_t)&IDL_ms.IDL_iovec,\n"); 827 fprintf(fid, 828 " (unsigned32*)&IDL_ms.IDL_status); /* Send remaining outs */\n"); 829 fprintf(fid, "\n}"); 830 831 fprintf(fid, "\nIDL_closedown: __IDL_UNUSED_LABEL__;\n"); 832 fprintf(fid, "DCETHREAD_CATCH_ALL(THIS_CATCH)\n"); 833 834 fprintf(fid, "if ( IDL_manager_entered )\n{\n"); 835 fprintf(fid, 836 "RPC_SS_THREADS_RESTORE_GENERAL(IDL_general_cancel_state);\n"); 837 fprintf(fid, "RPC_SS_THREADS_RESTORE_ASYNC(IDL_async_cancel_state);\n"); 838 fprintf(fid, "}\n"); 839 840 /* 841 * For all exceptions other than report status, send the exception to the 842 * client. For the report status exception, just fall through and 843 * perform the normal failing status reporting. 844 */ 845 fprintf(fid, "rpc_ss_ndr_clean_up(&IDL_ms);\n"); 846 fprintf(fid, 847 "if (!RPC_SS_EXC_MATCHES(THIS_CATCH,&rpc_x_ss_pipe_comm_error))\n{\n"); 848 fprintf(fid, "if ( ! IDL_manager_entered )\n{\n"); 849 if ( ! explicit_binding ) 850 { 851 fprintf(fid, "IDL_ms.IDL_status = rpc_s_manager_not_entered;\n"); 852 } 853 fprintf(fid, "}\n"); 854 if ( ! explicit_binding ) 855 { 856 fprintf(fid, "else\n"); 857 } 858 fprintf(fid,"{\n"); 859 fprintf(fid,"rpc_ss_send_server_exception_2(IDL_call_h,THIS_CATCH,%d,%s,&IDL_ms);\n", 860 num_declared_exceptions + num_extern_exceptions, 861 (num_declared_exceptions + num_extern_exceptions) ? "IDL_exception_addresses" : "NULL" 862 ); 863 fprintf(fid, "IDL_ms.IDL_status = error_status_ok;\n}\n"); 864 fprintf(fid, "}\n"); 865 fprintf(fid, "DCETHREAD_ENDTRY\n"); 866 867 if (AST_HAS_IN_CTX_SET(p_operation) 868 || AST_HAS_OUT_CTX_SET(p_operation)) 869 { 870 fprintf(fid, 871 "rpc_ss_ctx_client_ref_count_d_2(%s, IDL_client_id);\n", 872 handle_info.assoc_name); 873 } 874 875 if (AST_HAS_IN_PTRS_SET(p_operation) 876 || AST_HAS_OUT_PTRS_SET(p_operation) 877 || AST_ENABLE_ALLOCATE_SET(p_operation)) 878 { 879 fprintf( fid, "rpc_ss_destroy_support_ptrs();\n" ); 880 } 881 fprintf(fid, "if (IDL_ms.IDL_mem_handle.memory)\n{\n"); 882 fprintf(fid, " rpc_ss_mem_free(&IDL_ms.IDL_mem_handle);\n}\n"); 883 fprintf(fid, "if (IDL_ms.IDL_status != error_status_ok)\n{\n"); 884 fprintf(fid, "if (IDL_ms.IDL_status == rpc_s_call_cancelled)\n{\n"); 885 fprintf(fid, "rpc_ss_send_server_exception("); 886 fprintf(fid, "IDL_call_h,&RPC_SS_THREADS_X_CANCELLED);\n"); 887 fprintf(fid, "IDL_ms.IDL_status = error_status_ok;\n"); 888 fprintf(fid, "}\nelse\n{\n"); 889 if ( ! explicit_binding ) 890 { 891 fprintf(fid, "if (IDL_manager_entered)\n"); 892 } 893 fprintf(fid, "{\nrpc_ss_send_server_exception("); 894 fprintf(fid, "IDL_call_h,&rpc_x_ss_remote_comm_failure);\n"); 895 fprintf(fid, "IDL_ms.IDL_status = error_status_ok;\n"); 896 fprintf(fid, "}\n}\n}\n"); 897 898 /* When reached here IDL_ms.IDL_status is either error_status_ok 899 * or rpc_s_manager_not_entered 900 */ 901 fprintf(fid, "*IDL_status_p = IDL_ms.IDL_status;\n"); 902 903 fprintf(fid, "}\n"); 904} 905 906/* 907 * BE_gen_sstub 908 * 909 * Public entry point for server stub file generation 910 */ 911void BE_gen_sstub 912( 913 FILE *fid, /* Handle for emitted C text */ 914 AST_interface_n_t *p_interface, /* Ptr to AST interface node */ 915 language_k_t language, /* Language stub is to interface to */ 916 char header_name[], /* Name of header file to be included in stub */ 917 boolean *cmd_opt, 918 void **cmd_val, 919 DDBE_vectors_t *dd_vip /* Data driven BE vector information ptr */ 920) 921{ 922 AST_export_n_t *p_export; 923 AST_operation_n_t *p_operation; 924 boolean first; 925 /* Exceptions may be declared or external. We need a count of both */ 926 int num_declared_exceptions; 927 int num_extern_exceptions; 928 929 /* 930 * Emit a #pragma nostandard to suppress warnings on non-standard C usage 931 */ 932 CSPELL_suppress_stub_warnings(fid); 933 934 /* 935 * Emit #defines and #includes 936 */ 937 CSPELL_mts_includes(fid, header_name); 938 939 /* 940 * Set up interpreter data structures 941 */ 942 DDBE_spell_offset_vec( fid, dd_vip, cmd_opt, cmd_val ); 943 DDBE_spell_rtn_vec( fid, dd_vip, cmd_opt, cmd_val, FALSE ); 944 DDBE_spell_type_vec( fid, dd_vip, cmd_opt, cmd_val ); 945 946 /* If there are any user exceptions, emit the necessary declarations */ 947 DDBE_user_exceptions(fid, p_interface, 948 &num_declared_exceptions, &num_extern_exceptions); 949 950 /* 951 * Emit manager entry point vector, if requested 952 */ 953 if (cmd_opt[opt_mepv]) 954 CSPELL_manager_epv(fid, p_interface); 955 956 /* 957 * Emit operation definitions 958 */ 959 for (p_export = p_interface->exports; p_export; p_export = p_export->next) 960 if ((p_export->kind == AST_operation_k) 961 && ( ! AST_ENCODE_SET(p_export->thing_p.exported_operation)) 962 && ( ! AST_DECODE_SET(p_export->thing_p.exported_operation))) 963 { 964 BE_push_malloc_ctx(); 965 NAMETABLE_set_temp_name_mode(); 966 p_operation = p_export->thing_p.exported_operation; 967 CSPELL_server_stub_routine(fid, language, p_interface, p_operation, 968 num_declared_exceptions, num_extern_exceptions, cmd_opt); 969 NAMETABLE_clear_temp_name_mode(); 970 BE_pop_malloc_ctx(); 971 } 972 973 /* 974 * Emit server epv 975 */ 976 fprintf (fid, "\nstatic rpc_v2_server_stub_proc_t IDL_epva[] = \n{\n"); 977 first = true; 978 for (p_export = p_interface->exports; p_export; p_export = p_export->next) 979 if (p_export->kind == AST_operation_k) 980 { 981 if (first) 982 first = false; 983 else 984 fprintf(fid, ",\n"); 985 if (AST_ENCODE_SET(p_export->thing_p.exported_operation) 986 || AST_DECODE_SET(p_export->thing_p.exported_operation)) 987 { 988 fprintf(fid, "NULL"); 989 } 990 else 991 fprintf( 992 fid, " (rpc_v2_server_stub_proc_t)op%d_ssr", 993 p_export->thing_p.exported_operation->op_number 994 ); 995 } 996 fprintf (fid, "\n};\n"); 997 998 /* 999 * Emit static if_spec definition and global exported pointer 1000 */ 1001 CSPELL_interface_def(fid, p_interface, BE_server_stub_k, cmd_opt[opt_mepv]); 1002 1003 /* 1004 * Emit a closing #pragma standard to match the nostandard pragma above 1005 */ 1006 CSPELL_restore_stub_warnings(fid); 1007} 1008