home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume27
/
distributed-c-2.1
/
part15
< prev
next >
Wrap
Text File
|
1993-12-22
|
75KB
|
1,745 lines
Newsgroups: comp.sources.unix
From: pleierc@informatik.tu-muenchen.de (Christoph Pleier)
Subject: v27i189: distributed-c-2.1 - Distributed C Development Environment, V2.1, Part15/18
References: <1.756634932.28500@gw.home.vix.com>
Sender: unix-sources-moderator@gw.home.vix.com
Approved: vixie@gw.home.vix.com
Submitted-By: pleierc@informatik.tu-muenchen.de (Christoph Pleier)
Posting-Number: Volume 27, Issue 189
Archive-Name: distributed-c-2.1/part15
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 15 (of 18)."
# Contents: dcc/attr_decl.c lib/creation.c
# Wrapped by vixie@gw.home.vix.com on Thu Dec 23 00:12:06 1993
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'dcc/attr_decl.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'dcc/attr_decl.c'\"
else
echo shar: Extracting \"'dcc/attr_decl.c'\" \(35350 characters\)
sed "s/^X//" >'dcc/attr_decl.c' <<'END_OF_FILE'
X/***************************************************************************
X * *
X * @@@@ @@@ @@@@@ @@@@@ @@@@@ @@@ @@@@ @ @ @@@@@ @@@@@ @@@@ @@@ *
X * @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ *
X * @ @ @ @@@@@ @ @@@@@ @ @@@@@ @ @ @ @@@@@ @ @ @ *
X * @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ *
X * @@@@ @@@ @@@@@ @ @ @ @@@ @@@@ @@@@@ @ @@@@@ @@@@ @@@ *
X * *
X * A compiler for distributed programming with C *
X * *
X * a t t r _ d e c l . c *
X * *
X * Package : Compiler *
X * Version : 1.0 *
X * CreationDate : 04.09.91 *
X * LastUpDate : 08.11.91 *
X * *
X * All routines used for generating and managing attributes needed for *
X * handling structure and type definitions. *
X * *
X * Copyright (C) 1991-1994 by Christoph Pleier *
X * All rights reserved! *
X ***************************************************************************/
X
X/*
X * This file is part of the Distributed C Development Environment (DCDE).
X * DCDE is free software; you can redistribute it and/or modify
X * it under the terms written in the README-file.
X * DCDE is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
X * See the file README for more details.
X */
X
X#include <stdio.h>
X#include "config.h"
X#include "extern.h"
X#include "functions.h"
X
X/* NOTE:
X * During parsing of declarations an internal tree is dynamically generated
X * to store the information. Later this tree will only be converted to a string
X * or will be used for generating special data conversion routines and for
X * some sematic checks.
X * The structure of such trees is modelled directly on the syntax grammar (see
X * dcc.y). The appropriate data types are specified in config.h.
X */
X
X/******************************************************************************
X * gen_type_specifier_attr() *
X * *
X * Allocates memory for a type specifier attribute and initializes it. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XTS_ATTR *
Xgen_type_specifier_attr(t_elem, t_enum, t_struct, t_ident)
Xint t_elem;
XES_ATTR *t_enum;
XSUS_ATTR *t_struct;
XSYMBTABEL *t_ident;
X{
X register TS_ATTR *ptr;
X
X if (errflag) /* error handling! */
X return(NULL);
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** gen_type_specifier_attr():\n");
X fprintf(debugfile, "[type] params: t_elem = %d, t_enum = %d\n",
X t_elem, t_enum);
X fprintf(debugfile, "[type] t_struct = %d, t_ident = %d (%s)\n",
X t_struct, t_ident, (t_ident) ? t_ident->name : "null");
X#endif /* STRUCTDEBUG /**/
X ptr = (TS_ATTR *) Malloc(sizeof(TS_ATTR));
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] address of new attr is %d\n", ptr);
X#endif /* STRUCTDEBUG /**/
X ptr->type = t_elem;
X switch(t_elem) {
X case TS_ATTR_VOID:
X ptr->type = choose_void_type();
X break;
X case TS_ATTR_CHAR:
X case TS_ATTR_SHORT:
X case TS_ATTR_INT:
X case TS_ATTR_LONG:
X case TS_ATTR_FLOAT:
X case TS_ATTR_DOUBLE:
X case TS_ATTR_SIGNED:
X case TS_ATTR_UNSIGNED:
X break;
X case TS_ATTR_PROCESS:
X ptr->info.process = t_ident;
X break;
X case TS_ATTR_ENUM:
X ptr->info.enuminfo = t_enum;
X break;
X case TS_ATTR_STRUCT:
X ptr->info.structinfo = t_struct;
X break;
X case TS_ATTR_TYPENAME:
X ptr->info.typedefname = t_ident;
X break;
X default:
X Panic("unknown TS_ATTR type in gen_type_specifier_attr()");
X } /* switch */
X return(ptr);
X} /* gen_type_specifier_attr */
X
X/******************************************************************************
X * gen_storage_class_spec_attr() *
X * *
X * Allocates memory for a storage class specifier attribute and initializes *
X * it. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XSCS_ATTR *
Xgen_storage_class_spec_attr(type)
Xchar type;
X{
X register SCS_ATTR *ptr;
X
X if (errflag) /* error handling! */
X return(NULL);
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** gen_storage_class_attr():\n");
X fprintf(debugfile, "[type] params: type = %d\n", type);
X#endif /* STRUCTDEBUG /**/
X ptr = (SCS_ATTR *) Malloc(sizeof(SCS_ATTR));
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] address of new attr is %d\n", ptr);
X#endif /* STRUCTDEBUG /**/
X switch(type) {
X case SCS_ATTR_AUTO:
X case SCS_ATTR_REGISTER:
X case SCS_ATTR_STATIC:
X case SCS_ATTR_EXTERN:
X case SCS_ATTR_TYPEDEF:
X ptr->type = type;
X break;
X default:
X Panic("unknown type qualifier in gen_storage_class_spec_attr()");
X } /* switch */
X return(ptr);
X} /* gen_storage_class_spec_attr */
X
X/******************************************************************************
X * gen_type_qualifier_attr() *
X * *
X * Allocates memory for a type qualifier attribute and initializes it. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XTQ_ATTR *
Xgen_type_qualifier_attr(type)
Xchar type;
X{
X register TQ_ATTR *ptr;
X
X if (errflag) /* error handling! */
X return(NULL);
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** gen_type_qualifier_attr():\n");
X fprintf(debugfile, "[type] params: type = %d\n", type);
X#endif /* STRUCTDEBUG /**/
X ptr = (TQ_ATTR *) Malloc(sizeof(TQ_ATTR));
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] address of new attr is %d\n", ptr);
X#endif /* STRUCTDEBUG /**/
X switch(type) {
X case TQ_ATTR_CONST:
X case TQ_ATTR_VOLATILE:
X ptr->type = type;
X break;
X default:
X Panic("unknown type qualifier in gen_type_qualifier_attr()");
X } /* switch */
X return(ptr);
X} /* gen_type_qualifier_attr */
X
X/******************************************************************************
X * gen_struct_or_union_attr() *
X * *
X * Allocates memory for a struct or union attribute and initializes it. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XSU_ATTR *
Xgen_struct_or_union_attr(type)
Xchar type;
X{
X register SU_ATTR *ptr;
X
X if (errflag) /* error handling! */
X return(NULL);
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** gen_struct_or_union_attr():\n");
X fprintf(debugfile, "[type] params: type = %d\n", type);
X#endif /* STRUCTDEBUG /**/
X ptr = (SU_ATTR *) Malloc(sizeof(SU_ATTR));
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] address of new attr is %d\n", ptr);
X#endif /* STRUCTDEBUG /**/
X switch(type) {
X case SU_ATTR_STRUCT:
X case SU_ATTR_UNION:
X ptr->type = type;
X break;
X default:
X Panic("unknown type qualifier in gen_struct_or_union_attr()");
X } /* switch */
X return(ptr);
X} /* gen_struct_or_union_attr */
X
X/******************************************************************************
X * gen_struct_or_union_spec_attr() *
X * *
X * Allocates memory for a struct or union specifier attribute and initializes *
X * it. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XSUS_ATTR *
Xgen_struct_or_union_spec_attr(struct_or_union, tag, struct_declaration_list)
XSU_ATTR *struct_or_union;
XSYMBTABEL *tag;
XSTL_ATTR *struct_declaration_list;
X{
X register SUS_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** gen_struct_or_union_spec_attr():\n");
X fprintf(debugfile, "[type] params: struct_or_union = %d\n",
X struct_or_union);
X fprintf(debugfile, "[type] tag = %d\n", tag);
X fprintf(debugfile, "[type] struct_declaration_list = %d\n",
X struct_declaration_list);
X#endif /* STRUCTDEBUG /**/
X ptr = (SUS_ATTR *) Malloc(sizeof(SUS_ATTR));
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] address of new attr is %d\n", ptr);
X#endif /* STRUCTDEBUG /**/
X ptr->struct_or_union = struct_or_union;
X ptr->tag = tag;
X ptr->struct_decl_list = struct_declaration_list;
X return(ptr);
X} /* gen_struct_or_union_spec_attr */
X
X/******************************************************************************
X * gen_enum_specifier_attr() *
X * *
X * Allocates memory for an enum specifier attribute and initializes it. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XES_ATTR *
Xgen_enum_specifier_attr(codestr)
Xchar *codestr;
X{
X register ES_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** gen_enum_specifier_attr():\n");
X fprintf(debugfile, "[type] params: codestr = %s\n", codestr);
X#endif /* STRUCTDEBUG /**/
X ptr = (ES_ATTR *) Malloc(sizeof(ES_ATTR));
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] address of new attr is %d\n", ptr);
X#endif /* STRUCTDEBUG /**/
X ptr->codestr = codestr;
X return(ptr);
X} /* gen_enum_specifier_attr */
X
X/******************************************************************************
X * gen_struct_declaration_attr() *
X * *
X * Allocates memory for a struct declaration attribute and initializes it. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XST_ATTR *
Xgen_struct_declaration_attr(spec_qual_list, struct_decl_list)
XSQL_ATTR *spec_qual_list;
XSDL_ATTR *struct_decl_list;
X{
X register ST_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** gen_struct_declaration_attr():\n");
X fprintf(debugfile, "[type] params: spec_qual_list = %d\n",
X spec_qual_list);
X fprintf(debugfile, "[type] struct_decl_list = %d\n",
X struct_decl_list);
X#endif /* STRUCTDEBUG /**/
X ptr = (ST_ATTR *) Malloc(sizeof(ST_ATTR));
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] address of new attr is %d\n", ptr);
X#endif /* STRUCTDEBUG /**/
X ptr->spec_qual_list = spec_qual_list;
X ptr->struct_decl_list = struct_decl_list;
X return(ptr);
X} /* gen_struct_declaration_attr */
X
X/******************************************************************************
X * gen_spec_qual_list_attr() *
X * *
X * Allocates memory for a specifier qualifier list attribute and initializes *
X * it. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XSQL_ATTR *
Xgen_spec_qual_list_attr(type_specifier, type_qualifier)
XTS_ATTR *type_specifier;
XTQ_ATTR *type_qualifier;
X{
X register SQL_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** gen_spec_qual_list_attr():\n");
X fprintf(debugfile, "[type] params: type_specifier = %d\n",
X type_specifier);
X fprintf(debugfile, "[type] type_qualifier = %d\n",
X type_qualifier);
X#endif /* STRUCTDEBUG /**/
X ptr = (SQL_ATTR *) Malloc(sizeof(SQL_ATTR));
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] address of new attr is %d\n", ptr);
X#endif /* STRUCTDEBUG /**/
X if (type_specifier) {
X ptr->type = SQL_ATTR_SPECIFIER;
X ptr->info.type_specifier = type_specifier;
X } else {
X ptr->type = SQL_ATTR_QUALIFIER;
X ptr->info.type_qualifier = type_qualifier;
X }
X ptr->sq_list = NULL;
X return(ptr);
X} /* gen_spec_qual_list_attr */
X
X/******************************************************************************
X * gen_struct_declarator_list_attr() *
X * *
X * Allocates memory for a struct declarator list attribute and initializes it.*
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XSDL_ATTR *
Xgen_struct_declarator_list_attr(struct_declarator)
XSD_ATTR *struct_declarator;
X{
X register SDL_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** gen_struct_declarator_list_attr():\n");
X fprintf(debugfile, "[type] params: struct_declarator = %d\n",
X struct_declarator);
X#endif /* STRUCTDEBUG /**/
X ptr = (SDL_ATTR *) Malloc(sizeof(SDL_ATTR));
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] address of new attr is %d\n", ptr);
X#endif /* STRUCTDEBUG /**/
X ptr->struct_declarator = struct_declarator;
X ptr->sd_list = NULL;
X return(ptr);
X} /* gen_struct_declarator_list_attr */
X
X/******************************************************************************
X * gen_stru_declaration_list_attr() *
X * *
X * Allocates memory for a struct declaration list attribute and initializes *
X * it. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XSTL_ATTR *
Xgen_stru_declaration_list_attr(struct_declaration)
XST_ATTR *struct_declaration;
X{
X register STL_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** gen_stru_declaration_list_attr():\n");
X fprintf(debugfile, "[type] params: struct_declaration = %d\n",
X struct_declaration);
X#endif /* STRUCTDEBUG /**/
X ptr = (STL_ATTR *) Malloc(sizeof(STL_ATTR));
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] address of new attr is %d\n", ptr);
X#endif /* STRUCTDEBUG /**/
X ptr->struct_decl = struct_declaration;
X ptr->st_list = NULL;
X return(ptr);
X} /* gen_stru_declaration_list_attr */
X
X/******************************************************************************
X * gen_struct_declarator_attr() *
X * *
X * Allocates memory for a struct declarator attribute and initializes it. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XSD_ATTR *
Xgen_struct_declarator_attr(declarator, const_expr)
XD_ATTR *declarator;
Xchar *const_expr;
X{
X register SD_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** gen_struct_declarator_attr():\n");
X fprintf(debugfile, "[type] params: declarator = %d\n", declarator);
X fprintf(debugfile, "[type] const_expr = %s\n", const_expr);
X#endif /* STRUCTDEBUG /**/
X ptr = (SD_ATTR *) Malloc(sizeof(SD_ATTR));
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] address of new attr is %d\n", ptr);
X#endif /* STRUCTDEBUG /**/
X ptr->decl = declarator;
X ptr->const_expr = const_expr;
X return(ptr);
X} /* gen_struct_declarator_attr */
X
X/******************************************************************************
X * gen_declarator_attr() *
X * *
X * Allocates memory for a declarator attribute and initializes it. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XD_ATTR *
Xgen_declarator_attr(pointer, direct_decl)
XP_ATTR *pointer;
XDD_ATTR *direct_decl;
X{
X register D_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** gen_declarator_attr():\n");
X fprintf(debugfile, "[type] params: pointer = %d\n", pointer);
X fprintf(debugfile, "[type] direct_decl = %d\n", direct_decl);
X#endif /* STRUCTDEBUG /**/
X ptr = (D_ATTR *) Malloc(sizeof(D_ATTR));
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] address of new attr is %d\n", ptr);
X#endif /* STRUCTDEBUG /**/
X ptr->pointer = pointer;
X ptr->direct_decl = direct_decl;
X return(ptr);
X} /* gen_declarator_attr */
X
X/******************************************************************************
X * gen_direct_decl_attr() *
X * *
X * Allocates memory for a direct declarator attribute and initializes it. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XDD_ATTR *
Xgen_direct_decl_attr(type, ident, declarator, direct_decl, str)
Xchar type;
XSYMBTABEL *ident;
XD_ATTR *declarator;
XDD_ATTR *direct_decl;
Xchar *str;
X{
X register DD_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** gen_direct_decl_attr():\n");
X fprintf(debugfile, "[type] params: ident = %s\n",
X (ident) ? ident->name : "null");
X fprintf(debugfile, "[type] declarator = %d\n", declarator);
X#endif /* STRUCTDEBUG /**/
X ptr = (DD_ATTR *) Malloc(sizeof(DD_ATTR));
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] address of new attr is %d\n", ptr);
X#endif /* STRUCTDEBUG /**/
X ptr->type = type;
X switch(type) {
X case DD_ATTR_IDENT:
X ptr->ident = ident;
X break;
X case DD_ATTR_BRACED:
X ptr->info.declarator = declarator;
X break;
X case DD_ATTR_ARRAY:
X case DD_ATTR_FUNC:
X ptr->info.comp.direct_decl = direct_decl;
X ptr->info.comp.spec_str = str;
X break;
X default:
X Panic("unknown DD_ATTR type in gen_direct_decl_attr()");
X } /* switch */
X return(ptr);
X} /* gen_direct_decl_attr */
X
X/******************************************************************************
X * gen_pointer_attr() *
X * *
X * Allocates memory for a pointer attribute and initializes it. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XP_ATTR *
Xgen_pointer_attr(type, quali_list, pointer)
Xint type;
XTQL_ATTR *quali_list;
XP_ATTR *pointer;
X{
X register P_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** gen_pointer_attr():\n");
X fprintf(debugfile, "[type] params: type = %d\n", type);
X#endif /* STRUCTDEBUG /**/
X ptr = (P_ATTR *) Malloc(sizeof(P_ATTR));
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] address of new attr is %d\n", ptr);
X#endif /* STRUCTDEBUG /**/
X ptr->type = type;
X ptr->quali_list = quali_list;
X ptr->pointer = pointer;
X return(ptr);
X} /* gen_pointer_attr */
X
X/******************************************************************************
X * gen_type_qualifier_list_attr() *
X * *
X * Allocates memory for a type qualifier list attribute and initializes it. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XTQL_ATTR *
Xgen_type_qualifier_list_attr(type_qualifier)
XTQ_ATTR *type_qualifier;
X{
X register TQL_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** gen_type_qualifier_list_attr():\n");
X#endif /* STRUCTDEBUG /**/
X ptr = (TQL_ATTR *) Malloc(sizeof(TQL_ATTR));
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] address of new attr is %d\n", ptr);
X#endif /* STRUCTDEBUG /**/
X ptr->type_qualifier = type_qualifier;
X ptr->tq_list = NULL;
X return(ptr);
X} /* gen_type_qualifier_list_attr */
X
X/******************************************************************************
X * gen_declaration_specifiers_attr() *
X * *
X * Allocates memory for a declaration specifiers attribute and initializes it.*
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XDS_ATTR *
Xgen_declaration_specifiers_attr(scs, ts, tq, ds)
XSCS_ATTR *scs; /* storage class specifier */
XTS_ATTR *ts; /* type specifier */
XTQ_ATTR *tq; /* type qualifier */
XDS_ATTR *ds; /* declaration specifiers */
X{
X register DS_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** gen_declaration_specifiers_attr():\n");
X#endif /* STRUCTDEBUG /**/
X ptr = (DS_ATTR *) Malloc(sizeof(DS_ATTR));
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] address of new attr is %d\n", ptr);
X#endif /* STRUCTDEBUG /**/
X ptr->scs = scs;
X ptr->ts = ts;
X ptr->tq = tq;
X ptr->ds = ds;
X return(ptr);
X} /* gen_declaration_specifiers_attr */
X
X/******************************************************************************
X * gen_init_declarator_list_attr() *
X * *
X * Allocates memory for an init declarator list attribute and initializes it. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XIDL_ATTR *
Xgen_init_declarator_list_attr(id)
XID_ATTR *id; /* init declarator */
X{
X register IDL_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** gen_init_declarator_list_attr():\n");
X#endif /* STRUCTDEBUG /**/
X ptr = (IDL_ATTR *) Malloc(sizeof(IDL_ATTR));
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] address of new attr is %d\n", ptr);
X#endif /* STRUCTDEBUG /**/
X ptr->id_list = NULL;
X ptr->id = id;
X return(ptr);
X} /* gen_init_declarator_list_attr */
X
X/******************************************************************************
X * gen_init_declarator_attr() *
X * *
X * Allocates memory for an init declarator attribute and initializes it. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XID_ATTR *
Xgen_init_declarator_attr(declarator, initializer_str)
XD_ATTR *declarator;
Xchar *initializer_str;
X{
X register ID_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** gen_init_declarator_attr():\n");
X#endif /* STRUCTDEBUG /**/
X ptr = (ID_ATTR *) Malloc(sizeof(ID_ATTR));
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] address of new attr is %d\n", ptr);
X#endif /* STRUCTDEBUG /**/
X ptr->d = declarator;
X ptr->inistr = initializer_str;
X return(ptr);
X} /* gen_init_declarator_attr */
X
X/******************************************************************************
X * add_type_qualifier() *
X * *
X * Chains type qualifier list 'tq_list2' to the end of type qualifier list *
X * 'tq_list1'. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XTQL_ATTR *
Xadd_type_qualifier(tq_list1, tq_list2)
XTQL_ATTR *tq_list1, *tq_list2;
X{
X register TQL_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** add_type_qualifier():\n");
X fprintf(debugfile, "[type] params: tq_list1 = %d, tq_list2 = %d\n",
X tq_list1, tq_list2);
X#endif /* STRUCTDEBUG /**/
X for(ptr = tq_list1; ptr->tq_list; ptr = ptr->tq_list)
X ;
X ptr->tq_list = tq_list2;
X return(tq_list1);
X} /* add_type_qualifier */
X
X/******************************************************************************
X * add_struct_declarator() *
X * *
X * Chains struct declarator list 'sd_list2' to the end of struct declarator *
X * list 'sd_list1'. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XSDL_ATTR *
Xadd_struct_declarator(sd_list1, sd_list2)
XSDL_ATTR *sd_list1, *sd_list2;
X{
X register SDL_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** add_struct_declarator():\n");
X fprintf(debugfile, "[type] params: sd_list1 = %d, sd_list2 = %d\n",
X sd_list1, sd_list2);
X#endif /* STRUCTDEBUG /**/
X for(ptr = sd_list1; ptr->sd_list; ptr = ptr->sd_list)
X ;
X ptr->sd_list = sd_list2;
X return(sd_list1);
X} /* add_struct_declarator */
X
X/******************************************************************************
X * add_struct_declaration() *
X * *
X * Chains struct declaration list 'st_list2' to the end of struct declaration *
X * list 'st_list1'. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XSTL_ATTR *
Xadd_struct_declaration(st_list1, st_list2)
XSTL_ATTR *st_list1, *st_list2;
X{
X register STL_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** add_struct_declaration():\n");
X fprintf(debugfile, "[type] params: st_list1 = %d, st_list2 = %d\n",
X st_list1, st_list2);
X#endif /* STRUCTDEBUG /**/
X for(ptr = st_list1; ptr->st_list; ptr = ptr->st_list)
X ;
X ptr->st_list = st_list2;
X return(st_list1);
X} /* add_struct_declaration */
X
X/******************************************************************************
X * add_spec_qual_list() *
X * *
X * Chains specifier qualifier list 'sq_list2' to the end of specifier *
X * qualifier list 'sq_list1'. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XSQL_ATTR *
Xadd_spec_qual_list(sq_list1, sq_list2)
XSQL_ATTR *sq_list1, *sq_list2;
X{
X register SQL_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** add_spec_qual_list():\n");
X fprintf(debugfile, "[type] params: sq_list1 = %d, sq_list2 = %d\n",
X sq_list1, sq_list2);
X#endif /* STRUCTDEBUG /**/
X for(ptr = sq_list1; ptr->sq_list; ptr = ptr->sq_list)
X ;
X ptr->sq_list = sq_list2;
X return(sq_list1);
X} /* add_spec_qual_list */
X
X/******************************************************************************
X * add_init_declarator_list() *
X * *
X * Chains init declarator list 'id_list2' to the end of init declarator list *
X * 'id_list1'. *
X * *
X * Return values: pointer to new created attribute upon success / *
X * NULL during error handling *
X ******************************************************************************/
XIDL_ATTR *
Xadd_init_declarator_list(id_list1, id_list2)
XIDL_ATTR *id_list1, *id_list2;
X{
X register IDL_ATTR *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** add_init_declarator_list():\n");
X fprintf(debugfile, "[type] params: id_list1 = %d, id_list2 = %d\n",
X id_list1, id_list2);
X#endif /* STRUCTDEBUG /**/
X for(ptr = id_list1; ptr->id_list; ptr = ptr->id_list)
X ;
X ptr->id_list = id_list2;
X return(id_list1);
X} /* add_init_declarator_list */
X
X/******************************************************************************
X * store_struct_or_type_def() *
X * *
X * Stores a structure or type definition in the 'structure or type definition *
X * list' by generating a new list element and appending it to the end of the *
X * list. *
X * *
X * Return values: pointer to stored symbol table entry upon success / *
X * NULL during error handling *
X ******************************************************************************/
XSYMBTABEL *
Xstore_struct_or_type_def(symbol)
XSYMBTABEL *symbol;
X{
X register struct struct_type_list *ptr;
X
X#ifdef STRUCTDEBUG
X fprintf(debugfile, "[type] ***** store_struct_or_type_def(%s):\n",
X symbol->name);
X#endif /* STRUCTDEBUG /**/
X ptr = (struct struct_type_list *) Malloc(sizeof(struct struct_type_list));
X ptr->symbol = symbol;
X ptr->next = NULL;
X if (!first_structtype)
X first_structtype = last_structtype = ptr;
X else {
X last_structtype->next = ptr;
X last_structtype = ptr;
X }
X return(symbol);
X} /* store_struct_or_type_def */
END_OF_FILE
if test 35350 -ne `wc -c <'dcc/attr_decl.c'`; then
echo shar: \"'dcc/attr_decl.c'\" unpacked with wrong size!
fi
# end of 'dcc/attr_decl.c'
fi
if test -f 'lib/creation.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lib/creation.c'\"
else
echo shar: Extracting \"'lib/creation.c'\" \(35757 characters\)
sed "s/^X//" >'lib/creation.c' <<'END_OF_FILE'
X/***************************************************************************
X * *
X * @@@@ @@@ @@@@@ @@@@@ @@@@@ @@@ @@@@ @ @ @@@@@ @@@@@ @@@@ @@@ *
X * @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ *
X * @ @ @ @@@@@ @ @@@@@ @ @@@@@ @ @ @ @@@@@ @ @ @ *
X * @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ *
X * @@@@ @@@ @@@@@ @ @ @ @@@ @@@@ @@@@@ @ @@@@@ @@@@ @@@ *
X * *
X * A compiler for distributed programming with C *
X * *
X * c r e a t i o n . c *
X * *
X * Package : Runtime Library *
X * Version : 1.0 *
X * CreationDate : 26.07.90 *
X * LastUpDate : 06.12.93 *
X * *
X * All library routines needed during process creation. *
X * *
X * Portions Copyright 1990 Markus Pleier *
X * Copyright (C) 1990-1994 by Christoph Pleier *
X * All rights reserved! *
X ***************************************************************************/
X
X/*
X * This file is part of the Distributed C Development Environment (DCDE).
X * DCDE is free software; you can redistribute it and/or modify
X * it under the terms written in the README-file.
X * DCDE is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
X * See the file README for more details.
X */
X
X#include <stdio.h>
X#include <stdlib.h>
X#include <sys/types.h>
X#ifdef HETEROGENEOUS
X# include <rpc/rpc.h>
X#endif
X#include "ipc.h"
X#include "dcc.h"
X#include "run_Errno.h"
X#include "timeout.h"
X#include "config.h"
X
X#define DEBUG_CREATION /**/
X
X#ifdef DEBUG_CREATION
X/* the flag to control the debug messages output */
Xint _debug_creation = 0;
X#endif /* DEBUG_CREATION /**/
X
X#ifdef DEBUG_CREATION
X# define DEBUGPUTS(msg) if (_debug_creation) { \
X fprintf(_debugout, "[cre] %s %s\n", \
X _processprefix, msg); \
X if (_debugflush) \
X fflush(_debugout); \
X }
X# define DEBUGDISPERR(msg) if (_debug_creation) { \
X fprintf(_debugout, "[cre] %s error: %s\n", \
X _processprefix, msg); \
X fprintf(_debugout, "[cre] %s reason: %s\n",\
X _processprefix, sys_errlist[errno]); \
X if (_debugflush) \
X fflush(_debugout); \
X }
X#else
X# define DEBUGPUTS(msg) { /* nothing */ }
X# define DEBUGDISPERR(msg) { /* nothing */ }
X#endif
X
X/*
X * The process creation is divided in the following steps:
X *
X * (CP = Creator Process, NP = New Process, AP = Administration Process)
X *
X * I. iPSC (Intel Hypercube):
X * --------------------------
X * 1) CP creates NP (load(..))
X * 2a) CP establishes connection to NP (_make_connection(...))
X * 2b) NP accepts connection from CP (_accept_connection(...))
X * 3) CP sends creator and admin port info to NP (_send_data(...))
X * 4) NP receives the port info (_recv_data(...))
X * 5) CP sends process parameters (if any) (_send_data(...))
X * 6) NP receives process parameters (if any) (_recv_data(...))
X * 7) NP sends its process data to AP
X *
X * II. Unix Systems (SunOs, ConvexOs, SCO Xenix/Unix, ...):
X * --------------------------------------------------------
X * 1) CP creates NP (fork() and exec(NP) or exec("rsh", NP,...))
X * 2a) CP accepts connection from NP (_accept_connection(...))
X * 2b) NP establishes connection to CP (_make_connection(...))
X * 3) NP sends its process data to CP (_send_data(...))
X * 4) CP receives process data from NP (_recv_data(...))
X * 5) CP sends process parameters (if any) (_send_data(...))
X * 6) NP receives process parameters (if any) (_recv_data(...))
X * 7) NP sends its process data to AP
X *
X * The various steps are performed by the following functions:
X *
X * a) creator process
X *
X * | iPSC | Unix Systems |
X * ----------------------------------------------------------------------------
X * | 1) _generate_process(...) | 1) _generate_process(...) |
X * | 2a) _make_connection(...) | 2a) _accept_connection(...) |
X * | 3) _send_ports_data(...) | 4) _receive_process_data(...) |
X * | 5) { send parameters } | 5) { send parameters } |
X * ----------------------------------------------------------------------------
X *
X * a) new process
X *
X * | iPSC | Unix Systems |
X * ----------------------------------------------------------------------------
X * | 2b) _accept_connection(...) | 2b) _make_connection(...) |
X * | 4) _receive_ports_data(...) | 3) _send_process_data(...) |
X * | 6) { receive parameters } | 6) { receive parameters } |
X * | 7) _notify_admin_process(...) | 7) _notify_admin_process(...) |
X * ----------------------------------------------------------------------------
X *
X * Note: The actions in braces are generated at compile time!
X */
X
X/*
X * The following global variables are used to pass data between functions
X */
X
Xextern int Errno; /* to pass error code */
Xextern char *_programname, /* programname of actual process */
X *_processname; /* processname of actual process */
Xextern PORTDESCR _own_port, /* own port */
X _creator_port, /* port of creator process */
X _admin_port; /* port of administration process */
Xextern CONNECTIONDESCR _con_port; /* port specifying connections */
X
X#ifdef iPSC
X
X/******************************************************************************
X * _generate_process() iPSC Version *
X * *
X * Generates the process 'process' at the node 'node' with the process id *
X * 'pid' using the load-command. *
X * *
X * Return values: always OK for success *
X ******************************************************************************/
Xstatic int
X_generate_process(process, node, pid)
Xchar *process; /* which process to generate */
Xlong node; /* where to generate new process */
Xlong pid; /* process id of new process */
X{
X#ifdef DEBUG_CREATION
X if (_debug_creation) {
X fprintf(_debugout, "[cre] %s ***** _generate_process():\n", _processprefix);
X fprintf(_debugout, "[cre] %s generating \"%s\" at node %ld with pid %ld\n",
X _processprefix, process, node, pid);
X if (_debugflush)
X fflush(_debugout);
X }
X#endif /* DEBUG_CREATION /**/
X load(process, node, pid);
X Errno = -1;
X return(OK);
X} /* _generate_process */
X
X/******************************************************************************
X * _send_ports_data() iPSC Version *
X * *
X * Sends the port information of the creator and administration process to *
X * the process connected to by '_con_port'. *
X * *
X * Return values: OK upon success / ERROR upon error *
X ******************************************************************************/
Xstatic int
X_send_ports_data()
X{
X PORTSDATA portsinfo;
X
X#ifdef DEBUG_CREATION
X if (_debug_creation) {
X fprintf(_debugout, "[cre] %s ***** _send_ports_data():\n",
X _processprefix);
X fprintf(_debugout, "[cre] %s sending creator and admin port data\n",
X _processprefix);
X if (_debugflush)
X fflush(_debugout);
X }
X#endif /* DEBUG_CREATION /**/
X portsinfo.creator_port = _own_port;
X portsinfo.admin_port = _admin_port;
X if (_send_data(&_con_port, (char *) &portsinfo, sizeof(PORTSDATA), CPTONPPDATTIME) < 0) {
X if (Errno == ETIMEOUT)
X Errno = ETCCPTONPPDAT;
X return(ERROR);
X }
X Errno = -1;
X return(OK);
X} /* _send_ports_data */
X
X/******************************************************************************
X * _receive_ports_data() iPSC Version *
X * *
X * Receives the port information of the creator and administration process *
X * from the process connected to by '_con_port' and initializes the global *
X * variables '_creator_port' and '_admin_port'. *
X * *
X * Return values: OK upon success / ERROR upon error *
X ******************************************************************************/
Xint
X_receive_ports_data()
X{
X PORTSDATA portsinfo;
X
X DEBUGPUTS("receiving creator and admin port data");
X if (_recv_data(&_con_port, (char *) &portsinfo, sizeof(PORTSDATA), NPTOCPPDATTIME) < 0) {
X if (Errno == ETIMEOUT)
X Errno = ETCNPGETPDAT;
X return(ERROR);
X }
X _creator_port = portsinfo.creator_port;
X _admin_port = portsinfo.admin_port;
X#ifdef DEBUG_CREATION
X if (_debug_creation) {
X _display_port_info("[cre]", "_creator_port", _creator_port);
X _display_port_info("[cre]", "_admin_port ", _admin_port);
X if (_debugflush)
X fflush(_debugout);
X }
X#endif /* DEBUG_CREATION /**/
X Errno = -1;
X return(OK);
X} /* _receive_ports_data */
X
X/******************************************************************************
X * _create_process() iPSC Version *
X * *
X * Creates the process 'process' at the node specified by 'location'. If *
X * location equals NULL, the target node is choosen according to the entries *
X * in the configuration file by consulting the administration process. *
X * The result parameter 'p_descr' is initialized with the process descriptor *
X * of the new generated process. *
X * *
X * Return values: OK upon success / ERROR upon error *
X ******************************************************************************/
Xint
X_create_process(process, location, p_descr)
Xchar *process, /* which process to start */
X *location; /* where to start process */
XPROCESSDESCR *p_descr; /* process descriptor (result parameter) */
X{
X char tmpstr[20];
X PORTDESCR other_port;
X extern long _pidcount;
X
X if (location == NULL) {
X /* Choose target node by hostfile and continue */
X DEBUGPUTS("choosing target node by nodefile!");
X if (_get_location_from_admin(process, &location))
X return(ERROR);
X /* Note: In the configuration files nodes must be specified in the
X * form: "node-x" where x is the node number. Therefore we
X * must remove the prefix "node-"!
X */
X location += 5;
X }
X#ifdef DEBUG_CREATION
X if (_debug_creation) {
X fprintf(_debugout, "[cre] %s creating process \"%s\"\n",
X _processprefix, process);
X }
X#endif /* DEBUG_CREATION /**/
X if (!strcmp(location, "local")) {
X /* CASE 1: Target node is own node */
X if (_generate_process(process, mynode(), _pidcount))
X return(ERROR);
X init_port(&other_port, mynode(), _pidcount++);
X } else {
X /* CASE 2: Target node is an other node */
X if (_generate_process(process, atol(location), _pidcount))
X return(ERROR);
X init_port(&other_port, atol(location), _pidcount++);
X }
X DEBUGPUTS("connecting to NP");
X /* make connection to new process to send parameters */
X if (_make_connection(&_con_port, &_own_port, &other_port, CPTONPCONTIME)) {
X if (Errno == ETIMEOUT)
X Errno = ETCCPTONPCON;
X return(ERROR);
X }
X DEBUGPUTS("sending ports data to NP");
X if (_send_ports_data())
X return(ERROR);
X /* set result parameter */
X strcpy(p_descr->processname, process);
X p_descr->pid = _pidcount - 1;
X p_descr->port = other_port;
X Errno = -1;
X return(OK);
X} /* _create_process */
X
X#else /* AIX || CONVEX || HPUX || LINUX || SPARC || UNICOS || ... /**/
X
X/******************************************************************************
X * _generate_process() Unix Systems Version *
X * *
X * Generates the process 'process' at the host 'host' using the system calls *
X * fork and exec. Processes at foreign hosts are created by a combination of *
X * exec with the remote shell (rsh). *
X * Remark: The Xenix Version creates processes always at the local machine. *
X * *
X * Return values: OK upon success / ERROR upon error *
X ******************************************************************************/
Xstatic int
X_generate_process(process, host)
Xchar *process; /* which process to generate */
Xchar *host; /* where to generate new process */
X{
X static char *parv[10]; /* to store arguments for exec */
X#ifndef SINGLE
X static char *tmpstr1[10];
X static char *tmpstr2[10];
X#endif /* SINGLE /**/
X
X#ifdef DEBUG_CREATION
X if (_debug_creation) {
X fprintf(_debugout, "[cre] %s generating \"%s\" at host \"%s\"\n",
X _processprefix, process, host);
X fprintf(_debugout, "[cre] %s generating child process using fork()\n",
X _processprefix);
X if (_debugflush)
X fflush(_debugout);
X }
X#endif /* DEBUG_CREATION /**/
X switch(fork()) {
X case -1: /* error! */
X Errno = EPROCESSCREAT;
X return(ERROR);
X /* break */
X case 0: /* child! */
X#ifndef SINGLE
X if (!strcmp(host, _own_port.hostname)) {
X#endif /* !SINGLE /**/
X /* CASE 1: Target host is local host */
X DEBUGPUTS("target host is own host!");
X parv[0] = process;
X _convert_port_to_argv(parv, _own_port, _admin_port);
X DEBUGPUTS("transforming to new process using execvp()");
X execvp(process, parv);
X /* Note: execv returns only upon error */
X#ifndef SINGLE
X } else {
X /* CASE 2: Target host is a remote host */
X DEBUGPUTS("target host is a remote host");
X sprintf((char *) tmpstr1, "%d", _own_port.portnum);
X sprintf((char *) tmpstr2, "%d", _admin_port.portnum);
X DEBUGPUTS("transforming to new process using execlp(\"rsh\", ...)");
X#ifdef UNICOS
X execlp("remsh", "remsh", host, "-n", "exec", process,
X#else
X execlp("rsh", "rsh", host, "-n", "exec", process,
X#endif /* UNICOS /**/
X tmpstr1, _own_port.hostname,
X tmpstr2, _admin_port.hostname,
X (char *) NULL);
X /* Note: execlp returns only upon error */
X }
X#endif /* Not SINGLE /**/
X /* The following code is only executed upon error, because exec
X * returns only when an error has occured! Therefore we send an
X * error message to the creator process.
X */
X if (!strcmp(process, "dcadmin"))
X perror("Fatal error in execvp()");
X else {
X DEBUGDISPERR("Error in exec()");
X _notify_admin_process(NOTIFY_ERROR);
X }
X exit(ERROR);
X /* break; */
X default: /* parent! */
X Errno = -1;
X return(OK);
X } /* switch */
X} /* _generate_process */
X
X/******************************************************************************
X * _create_dcadmin() Unix Systems Version *
X * *
X * Creates the administration process at the local machine and sends the name *
X * of the configuration file 'filename' to it. *
X * The global variable '_admin_port' is initialized to specify the created *
X * process. *
X * *
X * Return values: OK upon success / ERROR upon error *
X ******************************************************************************/
Xint
X_create_dcadmin(adminpath, filename)
Xchar *adminpath, /* name of the administration process (complete path) */
X *filename; /* name of the configuration file */
X{
X PROCESSDATA pdata; /* process data variable */
X
X DEBUGPUTS("creating admin process");
X#ifdef MSGSEM
X init_port(&_admin_port, 0, 0);
X#else /* SOCKET /**/
X init_port(&_admin_port, 0, 0, "");
X#endif /* MSGSEM /**/
X#ifdef SINGLE
X if (_generate_process(adminpath, "local"))
X return(ERROR);
X#else
X if (_generate_process(adminpath, _own_port.hostname))
X return(ERROR);
X#endif /* SINGLE /**/
X DEBUGPUTS("accepting connection from admin process");
X if (_accept_connection(&_con_port, &_own_port, CPTONPACCTIME)) {
X if (Errno == ETIMEOUT)
X Errno = ETCCPTONPACC;
X return(ERROR);
X }
X DEBUGPUTS("receiving process data from admin process");
X if (_receive_process_data(&pdata))
X return(ERROR);
X if (_close_connection(&_con_port))
X return(ERROR);
X /* initialize admin port variable */
X _admin_port = pdata.port;
X#ifdef DEBUG_CREATION
X if (_debug_creation)
X _display_port_info("[cre]", "setting _admin_port to", _admin_port);
X#endif /* DEBUG_CREATION /**/
X /* send filename of configuration file to administration process */
X if (_send_filename_to_admin(filename))
X return(ERROR);
X /* send own process data to administration process */
X if (_notify_admin_process(NOTIFY_START))
X return(ERROR);
X Errno = -1;
X return(OK);
X} /* _create_dcadmin */
X
X/******************************************************************************
X * _create_process() Unix Systems Version *
X * *
X * Creates the process 'process' at the host specified by 'location'. If *
X * location equals NULL, the target host is choosen according to the entries *
X * in the configuration file by consulting the administration process. *
X * The result parameter 'p_descr' is initialized with the process descriptor *
X * of the new generated process. *
X * *
X * Return values: OK upon success / ERROR upon error *
X ******************************************************************************/
Xint
X_create_process(processname, process, location, p_descr)
Xchar *processname, /* name of process to start */
X *process, /* corresponding file name */
X *location; /* where to start process */
XPROCESSDESCR *p_descr; /* process descriptor (result parameter) */
X{
X PROCESSDATA pdata;
X
X if (location == NULL) {
X /* Choose target host by hostfile and continue */
X DEBUGPUTS("choosing target host by hostfile!");
X if (_get_location_from_admin(processname, process, &location))
X return(ERROR);
X }
X#ifdef DEBUG_CREATION
X if (_debug_creation) {
X fprintf(_debugout, "[cre] %s creating process \"%s\" (\"%s\") at \"%s\"\n",
X _processprefix, processname, process, location);
X }
X#endif /* DEBUG_CREATION /**/
X#ifdef SINGLE
X if (_generate_process(process, "local"))
X return(ERROR);
X#else
X if (!strcmp(location, "local"))
X location = _own_port.hostname;
X if (_generate_process(process, location))
X return(ERROR);
X#endif /* SINGLE /**/
X while(1) {
X DEBUGPUTS("accepting connection from NP");
X /* accept connections to receive reply message */
X if (_accept_connection(&_con_port, &_own_port, CPTONPACCTIME)) {
X if (Errno == ETIMEOUT)
X Errno = ETCCPTONPACC;
X return(ERROR);
X }
X DEBUGPUTS("receiving connection type");
X if (_receive_connection_type_or_answer() == CREATION_CONNECTION)
X break;
X DEBUGPUTS("wrong connection accepted");
X DEBUGPUTS("sending connection aborted (ABORT...)");
X if (_send_connection_type_or_answer(ABORT_CONNECTION))
X return(ERROR);
X DEBUGPUTS("closing connection and trying again");
X if (_close_connection(&_con_port))
X return(ERROR);
X }
X DEBUGPUTS("sending connection accepted (ACCEPT...)");
X if (_send_connection_type_or_answer(ACCEPT_CONNECTION))
X return(ERROR);
X DEBUGPUTS("receiving process data from NP");
X if (_receive_process_data(&pdata))
X return(ERROR);
X /* return result using the reference parameter */
X strcpy(p_descr->processname, pdata.processname);
X p_descr->pid = pdata.pid;
X p_descr->port = pdata.port;
X Errno = -1;
X return(OK);
X} /* _create_process */
X
X/******************************************************************************
X * _report_back() Unix Systems Version *
X * *
X * Makes a connection to the creator process and sends the own process info *
X * to it. This function is called by every new created process to report back *
X * to the creator process. *
X * *
X * Return values: OK upon success / ERROR upon error *
X ******************************************************************************/
Xint
X_report_back()
X{
X DEBUGPUTS("reporting back to creator process");
X /* connect to creator process */
X while(1) {
X DEBUGPUTS("connecting");
X if (_make_connection(&_con_port, &_own_port, &_creator_port, NPTOCPCONTIME)) {
X if (Errno == ETIMEOUT)
X Errno = ETCNPTOCPCON;
X return(ERROR);
X }
X DEBUGPUTS("sending connection type (CREAT...)");
X if (_send_connection_type_or_answer(CREATION_CONNECTION))
X return(ERROR);
X DEBUGPUTS("receiving connection answer");
X if (_receive_connection_type_or_answer() == ACCEPT_CONNECTION)
X break;
X DEBUGPUTS("connection not accepted");
X DEBUGPUTS("closing connection and trying again");
X if (_close_connection(&_con_port))
X return(ERROR);
X }
X if (_send_process_data(OK))
X return(ERROR);
X Errno = -1;
X return(OK);
X} /* _report_back */
X
X#endif /* iPSC /**/
X
X/******************************************************************************
X * _send_connection_type_or_answer() *
X * *
X * Sends the connection type info 'type' to the process connected to by the *
X * connection descriptor '_con_port'. *
X * *
X * Return values: OK upon success / ERROR upon error *
X ******************************************************************************/
Xint
X_send_connection_type_or_answer(type)
Xint type;
X{
X static char sendstr[10];
X
X sprintf(sendstr, "%d", type);
X if (_send_data(&_con_port, sendstr, 10, CONNTYPESNDTIME) < 0){
X if (Errno == ETIMEOUT)
X Errno = ETCONNTYPESND;
X return(ERROR);
X }
X Errno = -1;
X return(OK);
X} /* _send_connection_type_or_answer */
X
X/******************************************************************************
X * _receive_connection_type_or_answer() *
X * *
X * Receives a connection type info from the process connected to by the *
X * connection descriptor '_con_port'. *
X * *
X * Return values: received connection type upon success / ERROR upon error *
X ******************************************************************************/
Xint
X_receive_connection_type_or_answer()
X{
X int msg_type;
X static char recvstr[10];
X
X if (_recv_data(&_con_port, recvstr, 10, CONNTYPERCVTIME) < 0){
X if (Errno == ETIMEOUT)
X Errno = ETCONNTYPERCV;
X return(ERROR);
X }
X msg_type = atoi(recvstr);
X Errno = -1;
X return(msg_type);
X} /* _receive_connection_type_or_answer */
X
X/******************************************************************************
X * _send_process_data() *
X * *
X * Sends the own process information to the process connected to by the *
X * connection descriptor '_con_port'. *
X * *
X * Return values: OK upon success / ERROR upon error *
X ******************************************************************************/
Xint
X_send_process_data(error)
Xint error;
X{
X PROCESSDATA pdata;
X
X DEBUGPUTS("sending process data");
X strcpy(pdata.processname, _processname);
X#ifdef iPSC
X pdata.pid = mypid();
X#else
X pdata.pid = getpid();
X#endif /* iPSC /**/
X pdata.port = _own_port;
X pdata.error = error;
X#ifdef DEBUG_CREATION
X if (_debug_creation) {
X _display_processdata_info("[cre]", "process data:", pdata);
X if (_debugflush)
X fflush(_debugout);
X }
X#endif /* DEBUG_CREATION /**/
X#if defined(SINGLE) || defined(HOMOGENEOUS)
X if (_send_data(&_con_port, (char *) &pdata, sizeof(PROCESSDATA), NPTOAPSNDTIME) < 0){
X#else /* HETEROGENEOUS */
X if (_send_data_encoded(&_con_port, (char *) &pdata, xdr_PROCESSDATA, NPTOAPSNDTIME)){
X#endif /* SINGLE || HOMOGENEOUS /**/
X if (Errno == ETIMEOUT)
X Errno = ETCNPTOAPSND;
X return(ERROR);
X }
X Errno = -1;
X return(OK);
X} /* _send_process_data */
X
X/******************************************************************************
X * _receive_process_data() *
X * *
X * Receives the process information from the process connected to by the *
X * connection descriptor '_con_port' and stores it in the result parameter *
X * 'processdata' to pass it to the caller. *
X * *
X * Return values: OK upon success / ERROR upon error *
X ******************************************************************************/
Xint
X_receive_process_data(processdata)
XPROCESSDATA *processdata;
X{
X unsigned long size;
X
X#if defined(SINGLE) || defined(HOMOGENEOUS)
X if (_recv_data(&_con_port, (char *) processdata, sizeof(PROCESSDATA), CPTONPREPTIME) < 0) {
X#else /* HETEROGENEOUS */
X if (_recv_data_encoded(&_con_port, (char *) processdata, xdr_PROCESSDATA, CPTONPREPTIME)) {
X#endif /* SINGLE || HOMOGENEOUS /**/
X if (Errno == ETIMEOUT)
X Errno = ETCCPTONPRCV;
X return(ERROR);
X }
X#ifdef DEBUG_CREATION
X if (_debug_creation) {
X _display_processdata_info("[cre]", "received process data:", *processdata);
X if (_debugflush)
X fflush(_debugout);
X }
X#endif /* DEBUG_CREATION /**/
X Errno = -1;
X return(OK);
X} /* _receive_process_data */
X
X/******************************************************************************
X * _send_filename_to_admin() *
X * *
X * Connects to the administration process and sends the name of the configu- *
X * ration file to it. *
X * *
X * Return values: OK upon success / ERROR upon error *
X ******************************************************************************/
Xint
X_send_filename_to_admin(filename)
Xchar *filename;
X{
X ADMINCFGINFO cfgfile;
X CONNECTIONDESCR con_port;
X unsigned long size;
X
X if (_make_connection(&con_port, &_own_port, &_admin_port, CPTOAPCONTIME)) {
X if (Errno == ETIMEOUT)
X Errno = ETCCPTOAPCON;
X return(ERROR);
X }
X (void) strcpy(cfgfile.filename, filename);
X DEBUGPUTS("sending name of configuration file");
X#if defined(SINGLE) || defined(HOMOGENEOUS)
X if (_send_data(&con_port, (char *) &cfgfile, sizeof(ADMINCFGINFO), CPTOAPSNDTIME) < 0) {
X#else /* HETEROGENEOUS */
X if (_send_data_encoded(&con_port, (char *) &cfgfile, xdr_ADMINCFGINFO, CPTOAPSNDTIME)) {
X#endif /* SINGLE || HOMOGENEOUS /**/
X if (Errno == ETIMEOUT)
X Errno = ETCNPTOAPSND;
X return(ERROR);
X }
X if (_close_connection(&con_port))
X return(ERROR);
X Errno = -1;
X return(OK);
X} /* _send_filename_to_admin */
X
X/******************************************************************************
X * _notify_admin_process() *
X * *
X * Connects to the administration process to report the event 'what'. *
X * Valid events are: *
X * - creation of a process (NOTIFY_START) *
X * - termination of a process (NOTIFY_END) *
X * - start of execution of a select statement with terminate alternative *
X * (NOTIFY_ACCORTER_ON) *
X * - completion of a select statement with terminate alternative *
X * (NOTIFY_ACCORTER_OFF) *
X * - Occurance of a runtime error (NOTIFY_ERROR) *
X * *
X * Return values: OK upon success / ERROR upon error *
X ******************************************************************************/
Xint
X_notify_admin_process(what)
Xint what;
X{
X char *tmpptr;
X ADMINREQUEST adminrequest;
X CONNECTIONDESCR con_port;
X unsigned long size;
X
X#ifdef DEBUG_CREATION
X switch(what) {
X case NOTIFY_START:
X tmpptr = "NOTIFY_START";
X break;
X case NOTIFY_END:
X tmpptr = "NOTIFY_END";
X break;
X case NOTIFY_ACCORTER_ON:
X tmpptr = "NOTIFY_ACCORTER_ON";
X break;
X case NOTIFY_ACCORTER_OFF:
X tmpptr = "NOTIFY_ACCORTER_OFF";
X break;
X case NOTIFY_ERROR:
X tmpptr = "NOTIFY_ERROR";
X break;
X default:
X tmpptr = "UNKNOWN!";
X } /* switch */
X if (_debug_creation) {
X fprintf(_debugout, "[cre] %s notifying admin process:\n",
X _processprefix);
X fprintf(_debugout, "[cre] %s what = %s\n", _processprefix, tmpptr);
X fprintf(_debugout, "[cre] %s connecting to admin process\n",
X _processprefix);
X }
X#endif /* DEBUG_CREATION /**/
X if (_make_connection(&con_port, &_own_port, &_admin_port, NPTOAPCONTIME)) {
X if (Errno == ETIMEOUT)
X Errno = ETCNPTOAPCON;
X return(ERROR);
X }
X adminrequest.request_type = what;
X DEBUGPUTS("sending request type");
X#if defined(SINGLE) || defined(HOMOGENEOUS)
X if (_send_data(&con_port, (char *) &adminrequest, sizeof(ADMINREQUEST), NPTOAPREQTIME)<0) {
X#else /* HETEROGENEOUS */
X if (_send_data_encoded(&con_port, (char *) &adminrequest, xdr_ADMINREQUEST, NPTOAPREQTIME)) {
X#endif /* SINGLE || HOMOGENEOUS /**/
X if (Errno == ETIMEOUT)
X Errno = ETCNPTOAPREQ;
X _close_connection(&con_port);
X return(ERROR);
X }
X _con_port = con_port;
X if (_send_process_data(OK)) {
X _close_connection(&con_port);
X return(ERROR);
X }
X _close_connection(&_con_port);
X Errno = -1;
X return(OK);
X} /* _notify_admin_process */
X
X/******************************************************************************
X * _get_location_from_admin() *
X * *
X * Consults the administration process where to create the process with name *
X * 'processname'. The reference parameter 'location' is initialized with the *
X * received result to pass it to the caller. *
X * *
X * Return values: OK upon success / ERROR upon error *
X ******************************************************************************/
Xint
X_get_location_from_admin(processname, processfilename, location)
Xchar *processname,
X *processfilename,
X **location;
X{
X static ADMINLOCINFO locinfo;
X ADMINREQUEST adminrequest;
X CONNECTIONDESCR con_port;
X unsigned long size;
X
X if (_make_connection(&con_port, &_own_port, &_admin_port, CPTOAPCONTIME)) {
X if (Errno == ETIMEOUT)
X Errno = ETCCPTOAPCON;
X return(ERROR);
X }
X adminrequest.request_type = NOTIFY_GETLOCATION;
X DEBUGPUTS("sending request type");
X#if defined(SINGLE) || defined(HOMOGENEOUS)
X if (_send_data(&con_port, (char *) &adminrequest, sizeof(ADMINREQUEST), CPTOAPREQTIME)<0) {
X#else /* HETEROGENEOUS */
X if (_send_data_encoded(&con_port, (char *) &adminrequest, xdr_ADMINREQUEST, CPTOAPREQTIME)) {
X#endif /* SINGLE || HOMOGENEOUS /**/
X if (Errno == ETIMEOUT)
X Errno = ETCCPTOAPREQ;
X return(ERROR);
X }
X (void) strcpy(locinfo.processname, processname);
X (void) strcpy(locinfo.processfilename, processfilename);
X#ifdef SOCKET
X (void) strcpy(locinfo.creator_location, _own_port.hostname);
X#endif
X#ifdef SCO_UNIX
X /* simulation mode */
X (void) strcpy(locinfo.creator_location, "simulate");
X#endif
X DEBUGPUTS("sending process name");
X#if defined(SINGLE) || defined(HOMOGENEOUS)
X if (_send_data(&con_port, (char *) &locinfo, sizeof(ADMINLOCINFO), CPTOAPSNDTIME) < 0) {
X#else /* HETEROGENEOUS */
X if (_send_data_encoded(&con_port, (char *) &locinfo, xdr_ADMINLOCINFO, CPTOAPSNDTIME) < 0) {
X#endif /* SINGLE || HOMOGENEOUS /**/
X if (Errno == ETIMEOUT)
X Errno = ETCCPTOAPSND;;
X return(ERROR);
X }
X DEBUGPUTS("receiving hostname");
X#if defined(SINGLE) || defined(HOMOGENEOUS)
X if (_recv_data(&con_port, (char *) &locinfo, sizeof(ADMINLOCINFO), CPTOAPRCVTIME) < 0) {
X#else /* HETEROGENEOUS */
X if (_recv_data_encoded(&con_port, (char *) &locinfo, xdr_ADMINLOCINFO, CPTOAPRCVTIME)) {
X#endif /* HETEROGENEOUS /**/
X if (Errno == ETIMEOUT)
X Errno = ETCCPTOAPRCV;
X _close_connection(&con_port);
X return(ERROR);
X }
X _close_connection(&con_port);
X *location = locinfo.hostname;
X Errno = -1;
X return(OK);
X} /* _get_location_from_admin */
END_OF_FILE
if test 35757 -ne `wc -c <'lib/creation.c'`; then
echo shar: \"'lib/creation.c'\" unpacked with wrong size!
fi
# end of 'lib/creation.c'
fi
echo shar: End of archive 15 \(of 18\).
cp /dev/null ark15isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 18 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0