Warning: This HTML rendition of the RFC is experimental. It is programmatically generated, and small parts may be missing, damaged, or badly formatted. However, it is much more convenient to read via web browsers, however. Refer to the PostScript or text renditions for the ultimate authority.

OSF DCE SIG H. Melman (OSF)
Request For Comments: 34.2 August 1993

DCE 1.1 CODING STYLE GUIDE

INTRODUCTION

This RFC presents an internal coding style guide to be used for the DCE 1.1 project. It includes style information on C source files, build environment issues (including makefile style and source tree organization), and user interface style. This document is intended to be used as a reference guide for internal DCE programmers when writing DCE code.

NOTE:
This RFC contains contains information about cleanup issues relative to the build environment which are incomplete. All such items are clearly identified by Notes to Readers like this one. They will be completed in an updated version of this RFC as soon as the OSF RATs (Release and Tools) group has time to consider the issues. All other information described here should be considered complete.

Changes Since Last Publication

A number of changes have been made since this document was previously published in [RFC 34.1]. The changes that were made, in no particular order, are:

  1. Section 3.1.2 item (a) formerly suggested that the value of table-index be of the form: cmp_s_subcomp, it now suggests that it be of the form: cmp_svc_subcomp, which matches the examples in the serviceability code.
  2. Changed the name of the header file dce_assert.h to assert.h. Since it it is found in the /usr/include/dce directory, the proper way to include this file is by using:
    #include <dce/assert.h>
    
  3. The prototype of the routine dce_priv_proc_is_approprpriate() changed so that it now returns a boolean rather than an int.
  4. Updated the dce.h header file in Appendix B.
  5. Added recommendation on the use of extern's in section 2.3 item (n).
  6. In Section 2.6.1.1 the variable dsh__table changed to dsh_msg_table matching serviceablity guidelines.
  7. Various editorial changes and improvements to the DCE Error Message Style Guidelines.
  8. Migrated to the new RFC template (rfc0.1.roff).

C SOURCE CODE

The following sections describe guidelines for writing C source code. In DCE 1.1 an [ANSI C] environment is assumed to exist. DCE 1.1 will not guarantee non-ANSI [K&R] compatibility.

Compiler Switches

OSF/1, running on a specified platform, will serve as one of the DCE 1.1 reference platforms. On that platform gcc version 2.X\*(f!

Currently version 2.3 is used at OSF.
will be the ANSI C compiler used. The switches listed below will be used to have the compiler generate additional warnings which must be fixed in all DCE code. The exception is any kernel code which will follow the conventions of the kernel build environment.\*(f! For
Any C code generated by idl or mavros must also be [ANSI C] compliant and is subject to the same requirements as other DCE code.
a complete description of these switches (and others which are not required), see Appendix A.

  1. -ansi
  2. -pedantic
  3. -Wchar-subscripts
  4. -Wcomment
  5. -Wformat
  6. -Wid-clash-32
  7. -Wimplicit
  8. -Wmissing-prototypes
  9. -Wreturn-type
  10. -Wstrict-prototypes
  11. -Wswitch
  12. -Wtraditional\*(f!
    There are some issues with including the -Wtraditional switch in the above list. This switch is included to help catch any unintentional programming errors. Several programmers have found that it generates a lot of useless warning messages that are not correctable. If you find that the erros are innocuous ignore then, or remove them from the compile line of files that generate many of these warnings. If this switch does not show any useful warnings, I will remove it. If you do find that it generates a warning that helps you find a bug, please let me know.
  13. -Wunused

System Wide Definitions in dce.h

All DCE wide definitions will be in the machine dependent public header file dce.h. This file will include all typedefs, macro definitions, and common includes that span components. It is expected that dce.h will be included in most if not all DCE source files. See Appendix B for the current version of dce.h on the reference PMAX platform.

OSF will own dce.h; providers are responsible for including it in their code. Providers who have typedefs, macros, prototypes, etc., that need to be included in dce.h, must present them to OSF for inclusion.

It is required that each component use these definitions where appropriate for all existing and new code. No duplication of functions in dce.h will occur in component header files. (This is what will simplify the porting effort. It would make no sense to have a standard set of definitions and still use others.) The functions defined in dce.h are described below.

Common C Style

  1. C Preprocessor Macros.

    All C preprocessor macros that look like functions must be in all uppercase. Macros that implement standard routines will follow whatever conventions the standard requires (e.g., the pthreads routines defined by DCE Threads must be in lower-case). Existing macros in public header files may remain in lowercase.

  2. Do NOT Use __STDC__.

    Since some compilers only define this token in a strict ANSI mode, it cannot be used throughout DCE code. It can be used in limited configuration header files (such as dce.h) to set up global switches for certain compilers, but using it as a general prototype macro many times in a file is not allowed.

  3. Function Prototypes.

    In addition to supporting ANSI C, DCE 1.1 will require prototypes for all functions.\*(f! Functions

    All kernel code will follow the conventions of the kernel source code.
    which are defined as static should have their prototypes at the top of the C source file, whether there are forward references to these functions or not. This will prevent possible maintenance problems. No variable names are to be used in prototypes since they are subject to macro expansion. All function definitions will use the new style function definition format as defined in [ANSI C]. For example:
    int foo (a, b, c)
    int        a;
    void       *b;
    struct bar *c;
    
    becomes:
    int foo (int a, void *b, struct bar *c)
    

    This is required as there are slightly different semantics associated with the two forms. If the old form is used, all arguments are subject to promotion, in the new form, the compiler is not required to perform the promotion for performance reasons. For this reason, using a prototype with an old-style function declaration can lead to problems with arguments that are subject to promotion.

    DCE 1.1 code is not required to support compilers which do not handle prototypes. However, much DCE code currently does this by using a prototype macro. This support must either be removed completely (i.e., only use prototypes) or changed to use the following macro defined in dce.h:

    /* Declare a prototype like this (don't use variables) */
    int foo _DCE_PROTOTYPE_((int, void *, struct bar *))
    
    /* Define a function like this */
    int foo
    #if defined(_DCE_PROTO_)
        (
        int a,
        void *b,
        struct bar *c
        )
    #else
        (a, b, c)
        int a;
        void *b;
        struct bar *c;
    #endif
    
  4. Generic Pointers.

    DCE 1.1 assumes the presence of ANSI C, and therefore the generic pointer is to be of type void *. Those components wishing to support platforms where void pointers are not available, must use the following typedef for a generic pointer type defined in dce.h.

    /*
     * Note that this definition is for the PMAX specific
     * version of dce.h.  In this version we check for
     * __STDC__ to see if to use void * or char *.  This does
     * NOT violate coding conventions since it is being
     * checked in an isolated instance in a machine
     * dependent file.
     */
    #if defined(__STDC__)
      typedef void * pointer_t;
    #else
      typedef char * pointer_t;
    #endif
    
  5. Token Concatenation.

    DCE 1.1 assumes the presence of ANSI C, and therefore the use of the ## construct to perform token concatenations. Those components wishing to support platforms where ## is not available, must use the following macro for a token concatenation defined in dce.h.

    #if defined(_DCE_TOKENCONCAT_)
    #  define DCE_TOKENCONCAT(a, b)   a ## b
    #else
    #  define DCE_TOKENCONCAT(a, b)   a/**/b
    #endif
    
  6. Endian Checking.

    If code is endian specific, the endianess of the machine should be obtained by including dce.h and using #ifdef to check for either LITTLE_ENDIAN or BIG_ENDIAN. One of these is guaranteed to be defined by dce.h.

    If a port of DCE requires another form of endianess, it is the responsibility of the porter to handle the new form correctly in all DCE code. Each occurrence of endian-specific code must be documented in the DCE Porting and Testing Guide [PORTG].

  7. TRUE and FALSE.

    If the macro definitions of TRUE and FALSE are required, they should be obtained by including dce.h. They should not be redefined, nor should variants of these be defined or used (e.g., TP_TRUE in tp2.h).

  8. MIN and MAX.

    The classic definitions of MIN and MAX can be obtained by including dce.h. They should not be redefined in any form. The definitions are as follows. Note that the arguments are evaluated twice, and therefore arguments with side effects will probably not do what is desired. Also note that these routines return code set dependent values and therefore should not be called with char's as parameters.

    #if !defined(MIN)
    #  define MIN(x, y)         ((x) < (y) ? (x) : (y))
    #endif
    
    #if !defined(MAX)
    #  define MAX(x, y)         ((x) > (y) ? (x) : (y))
    #endif
    
  9. Obtaining the Path of the DCE Installation.

    DCE components which need to obtain the paths of the installation\*(f!

    This refers to the dceshared and dcelocal paths whose uses are specified in [RFC 35.0].
    must all use the mechanism described below.

    In order to facilitate a change in these paths without requiring the recompilation of many DCE source code files, a single file will define variables used to store the paths. This file will be built into libdceutil.a which is part of libdce.a. These variables can be accessed by DCE components by including dce.h to obtain the following definitions:

    extern const char *dceshared_path;
    extern const char *dcelocal_path;
    

    The use of these variables in DCE code will allow for a change in these paths by merely recompiling one file and relinking programs (this step might be unnecessary if shared libraries are used). The results of changing this path at runtime (that is, at any time after starting any DCE processes on a host) are undefined.

  10. Datatypes.

    The following machine dependent datatypes are to be used by all DCE code needing such datatypes. They are defined in dce.h.\*(f!

    Some are defined in dce.h by including idlbase.h via nbase.h

    1. byte -- unsigned \08-bit integer (idl_byte)
    2. boolean -- unsigned \08-bit integer (idl_boolean)
    3. unsigned8 -- unsigned \08-bit integer
    4. unsigned16 -- unsigned 16-bit integer
    5. unsigned32 -- unsigned 32-bit integer
    6. unsigned64 -- unsigned 64-bit integer (a struct)
    7. signed8 -- signed \08-bit integer
    8. signed16 -- signed 16-bit integer
    9. signed32 -- signed 32-bit integer
    10. signed64 -- signed 64-bit integer
  • Printing unsigned32's.

    In the face of 16, 32, and 64 bit machines, printing something like an unsigned32 can be a problem. Use the method described below. Other solutions can cause difficulties during ports, as it is necessary to track down format strings, which can be a real problem when using format strings from message catalogs.

    unsigned32 x = some_value();
    /* ... */
    printf("0x%lx\en", (long) x);
    
  • Null Pointers and the use of NULL.

    If a null pointer is required use NULL. Do not define a variable or macro to be a type or component specific null pointer (e.g., cma_c_null_ptr). The proper definition of NULL is as follows:

    #define NULL 0
    

    There are no casts required in either the definition or in any use of NULL. If the definition of NULL is incorrect on a platform, then it should be redefined in the dce.h file for that platform. The macro NULL is meant to be used only as a null pointer, do not use it to mean the integer zero. The following is incorrect although a compiler will allow it:

    int x = NULL;
    
  • Opaque Datatypes.

    The correct way to define a new opaque datatype in a public header file is as follows. In the public header file define something like:

    typedef struct private_foo_s_t *public_foo_t;
    

    The definition of struct private_foo is not included in the public header file, C allows this. In order for the private code to use this typedef, it needs a definiton of the private structure in a private header file as follows:

    struct private_foo_s_t {
        int   a;
        char *b;
        /* ... */
    }
    

    Any code needed to access the internals of a public_foo_t should include first the private header file, then the public one, and then can access the contents of the pointer. No casting is required. Also this provides some form of type checking, and is therefore much better than using a void (generic) pointer. Finally, this practice, allows the opaque datatypes to be understood by a debugger.

  • Extern Declarations

    This item is a recommendation for all code, it is not required for existing or new code. Declarations for extern's should only be in header files. Any \&.c files that need an extern should #include the appropriate header file. This header file must also be included in the \&.c file that contains the definition of the function, this way the compiler can check if the declaration and the definition match.

    Standard Library Routines

    The following hierarchy must be used when finding library routines to call in new DCE code. A routine found at some point in the list performing some function must be used instead of any other routine further down list (or not on the list, such as routines from [BSD]) performing a similar function. Any deviations from this hierarchy must be documented in the DCE Porting and Testing Guide.

    1. ANSI C.

      Routines in the standard C library defined in [ANSI C] (e.g., memcpy() instead of bcopy(), and stdarg instead of vararg ). See Appendix C for a complete listing of all functions defined in the Standard C Library.

    2. POSIX.1.

      Routines defined in [POSIX.1] (e.g., sigaction()). See Appendix D for a complete listing of all functions defined by [POSIX.1].

    3. XPG4.

      Routines defined by X/Open in [XPG4] (e.g., message and wide character routines catopen(), fgetws(), iswalpha()). See Appendix E for a complete listing of all functions defined by [XPG4].

    4. AES.

      Routines defined in the Operating System Programming Interfaces Volume of the Application Environment Specification [AES] from OSF. Its organization is similar to the other items on this list.

    5. Other.

      Finally, if none of the above standards are applicable, the routines need to be localized (isolated in as few places as is possible) and/or #ifdef'ed. This applies as well to alternative approaches that are used along side of the standard approach (e.g., sockets implementation as well as XTI in GDS).

    Threads wrappers

    All called non-thread-safe library routines must be protected by DCE Threads wrappers. For a list of all routines for which wrappers currently exist, see Appendix F. If you are calling a routine that is not wrapped and needs to be, you must have a wrapper created for it.

    Standard defined constants

    The standards mentioned above define many constants available for the application programmer to determine things like the size of an unsigned char, and the maximum number of characters in a filename. These constants must be used where applicable. See Appendix G for a list of the relevant constants.

    Exceptions to standards hierarchy

    There are some cases where this hierarchy is to be violated, such as certain functions whose use is expanded by some other implementation. For example, the internationalized version of printf, which is defined in [XPG4], is to be used instead of the one specified in ANSI C. All such instances are defined below and will be documented in the DCE Porting and Testing Guide.

    1. Signal Handling.

      [ANSI C] defines the signal() routine, however it is not to be used. Instead use the [POSIX.1] defined sigaction() routine.

    2. Internationalized Routines.

      [ANSI C] defines many routines that are limited in the code sets they can support. Where such differences are limiting factors in the code, expanded versions of those same (or similar) routines found in [XPG4] should be used.

    3. isascii().

      Some occurrences of isascii() must be replaced with isdcepcs() to support internationalization.

    4. Assertion Checking.

      The ANSI C assert() macro should not be used. Instead, use the dce_assert() macro (See below).

    5. Message Catalog Routines.

      The message catalog routines defined in [XPG4], catopen(), catclose(), and catgets(), should not be used directly. Instead use the DCE serviceability routines described below in Messaging interface that wrap these routines.\*(f!

      Certain uses of message catalogs in GDS can call the message catalog routines directly.

    DCE Utilities Library

    OSF will provide a library of utility routines to be used by DCE code known as libdceutils.a. These routines must be used in place of any others. Any deviations from this must be documented in the DCE Porting and Testing Guide. Providers wishing to add routines to libdceutils.a should make a request to OSF.

    This library will be part of libdce.a so that DCE library routines can call these routines without forcing a DCE application programmer to add another library to the link line.\*(f! Users

    The DCE utilities library will not be public, i.e, the routines will not be exposed to DCE application programmers.
    of this library will include the file dceutils.h in their code to obtain prototypes of the routines.

    Internationalization routines

    The following routines should be used to write correctly internationalized code.

    1. int dce_rpmatch(const char *response);

      This routine is a DCE version of the OSF/1 routine rpmatch. It determines whether the string value of the parameter matches (using extended regular expressions) the affirmative or negative response expression as specified by the LC_MESSAGES category in the current locale. This routine will return one of three values:

      1. 1 -- Returned if the string value of the parameter matches the affirmative expression.
      2. 0 -- Returned if the string value of the parameter matches the negative expression.
      3. \(mi1 -- Returned if the string value of the parameter matches the neither the affirmative or negative expression.
    2. int isdcepcs(int c);

      This routine returns TRUE or FALSE based on whether or not the character argument is in the DCE Portable Character Set. It is basically a replacement for the XPG4 routine isascii().

    Command line input

    The following two functions provide a line editing interface with text recall which should be used for all command line input.\*(f!

    While the interface is similar to GNU code, this implementation is not under the conditions of a copyleft.
    1. char * readline(char *prompt);

      This function displays the prompt to the user and returns an input line entered by the user. An emacs-like editing interface can be used while entering the line.

    2. void add_history(char *line);

      This function makes a copy of the specified line and adds it to the internal history list. The user has access to this history when input is read with the readline function. It is a separate function so that the programmer can determine what lines are entered in the history. For example, some interfaces might not want continued lines entered in the history.

    Below is an example of the use of these functions:

    while ((line = readline("> ") != NULL)
    {
        add_history(line);    /* add all lines to history */
        /* ... other work here ... */
    }
    

    Getting unique machine identifiers

    Some DCE code needs to get the hosts IEEE 802 address. Unfortunately there is no standard way of obtaining this from a system. Both the RPC and CDS components currently have different machine specific code to do this.\*(f! Both

    RPC in src/rpc/runtime/PMAX/uuidsys.c, and CDS in src/directory/cds/library/PMAX/unix_getaddr.c for the PMAX cases.
    must be changed to use the following interface, as well as any other code needing the 802 address of the host.
    char *dce_get_802_address (void);
    

    Determining appropriate privileges

    Presently, DCE relies upon a uid of 0 to determine appropriate (root) privilege (e.g., src/security/server/rs/rs_main.c). The [POSIX.1] standard does not prescribe that uid 0 is the root or superuser. In fact, uid 0 need not exist for POSIX compliance. Hence, the mechanism DCE employs to check for appropriate privilege, namely setuid(0) and subsequent checks for geteuid() == 0, may not suffice for some compliant POSIX systems. In fact, these will fail where a uid of 0 is not allowed/defined.

    The following new functions will be defined, in a target machine specific file, to isolate these issues. All existing and new code must call these routines where appropriate.

    1. int dce_priv_proc_enable(void);
    2. int dce_priv_proc_disable(void);
    3. boolean dce_priv_proc_is_appropriate(void);

    Common 64 and 128 bit arithmetic utilities

    The following macros for 64 bit math are to be used.\*(f! Any

    These macros are based on macros in src/file/config/stds.h for performing math on the hyper datatype. The only modifications have been to change the names of the macros (since they needed to be changed to uppercase anyway.)
    operations required that are not defined below will be added by OSF upon request. Note that DTS may continue to use the five operations defined in src/time/common/arith.c, namely emul(), uemul(), ueemul(), ediv(), and uediv(), since no other component has need of these operations.

    Note that these routines sometimes evaluate their parameters more than once. Also venders are free to modify these to suit their platform.

    /*
     * In these macro definitions, the arguments are named as follows:
     *    d  destination        (only used when a value is changed)
     *    s  source             (s1 and s2 for two sources)
     *    h  the high value     (either source or destination)
     *    l  the low value      (either source or destination)
     *    i  some integer amount
     */
    
    /*
     * U64CMP returns:  1 if s1 is greater;
     *                 -1 if s2 is greater,
     *                  0 if equal
     */
    #define U64CMP(s1,s2)   ((s1).hi < (s2).hi? -1 :                   \e
                             ((s1).hi > (s2).hi? 1 :                   \e
                              ((s1).lo < (s2).lo? -1 :                 \e
                               ((s1).lo > (s2).lo? 1 : 0))))
    #define U64EQUAL(s1,s2) ((s1).lo == (s2).lo && (s1).hi == (s2).hi)
    #define U64ISZERO(s)    ((s).lo == 0 && (s).hi == 0)
    #define U64FITSIN32(s)  ((s).hi == 0)
    
    #define U64SET(d,s)     ((d)=(s))
    #define U64SET32(d,l)   ((d).hi = 0, (d).lo = (l))
    #define U64SET64(d,h,l) ((d).hi = (h), (d).lo = (l))
    #define U64GET32(l,s)   ((l) = (s).lo)
    #define U64GET64(h,l,s) ((l) = (s).lo, (h) = (s).hi)
    #define U64ZERO(d)      U64SET64(d,0,0)
    #define U64ONES(d)      U64SET64(d,~0x0,~0x0)
    
    
    #define U64LSHIFT(d,i)  ((d).hi <<= (i),                           \e
                             (d).hi |= (((d).lo) >>                    \e
                             ((sizeof(unsigned32)*8)-(i))),            \e
                             (d).lo <<= (i))
    #define U64RSHIFT(d,i)  ((d).lo >>= (i),                           \e
                             (d).lo |= (((d).hi) <<                    \e
                             ((sizeof(unsigned32)*8)-(i))),            \e
                             (d).hi >>= (i))
    
    /*
     * The algorithm here is to check for two cases that cause a carry.
     * If the top two bits are different then if the sum has the top
     * bit off then there must have been a carry.  If the top bits are
     * both one then there is always a carry.  We assume 32 bit longs
     * and twos complement arithmetic.
     */
    #define SIGN          0x80000000
    #define U64ADD32(a,i) (((((a).lo ^ (long)(i)) & SIGN) ?             \e
                            (((((a).lo + (long)(i)) & SIGN) == 0) &&    \e
                             (a).hi++) :                                \e
                            (((a).lo & (long)(i) & SIGN) && (a).hi++)), \e
                           (a).lo += (long)(i))
    
    #define U64ADD(a,b)   (U64ADD32((a),(b).lo), (a).hi += (b).hi)
    #define U64SUB(a,b)   (U64ADD32((a),~((b).lo)),                \e
                           (a).hi += ~((b).hi),                    \e
                           U64ADD32((a),1))
    

    Serviceability

    Many of the internationalization and serviceability requirements require code clean-up-like activities (e.g., modifying all printf calls in the code). Guidelines for these requirements are presented here so that this one document can serve as a single reference source. Details on these areas of work can be found in [RFC 23.0] and [RFC 24.0] respectively.

    Much of the serviceability requirements are to be met by using the sams processor to create source files for messages. Coding guidelines for these source files are presented in this RFC after all guidelines for C sources files.

    Use of the sams processor will assign each message text a unique 32 bit message id. All messages for a given component are stored in a single message catalog. They are also compiled into the program in the form of a global table that contains id-text pairs generated by the sams processor. There are three sets of serviceability interfaces that deal with these message id's to process messages, and support for dce_error_inq_text:

    1. A set of routines that log serviceability messages as routed by the serviceability component. These are meant to be used for error and warning messages (mostly in servers, but perhaps clients as well). All of these routines begin with dce_svc_ and are documented in svc(3).
    2. A set of routines that handle strings to be shown to the end-user (mostly in clients, but perhaps servers as well). These are not error or warning messages, but rather questions or prompts. They are not meant to appear in a log file. These routines are similar to the printf family of the ANSI C library, and are documented in dceprintf(3).
    3. A set of routines that provide low level access to message catalogs. These are for the few times when complete control of the information in the catalogs is required. They are similar to the X/Open message catalog routines, but incorporate knowledge of the DCE status code space to find the proper catalogs. They all are prefixed with dce_msg_ and are documented in msg(3).
    4. The existing dce_error_inq_text() routine has been rewritten to use the messaging facilities. Any existing code that calls this routine may continue to do so. Most new code should use other messaging routines. The dce_error_inq_text() routine can be used to append the component name to the output string.

    Initialization

    There are two considerations for initialization:

    1. If there is to be an in-core message table of default messages (versus only obtaining message from a catalog and depending on the Message number 0x12345678 as a default message), then the in-core table must be registered with the messaging subsystem.
    2. Each serviceability component in a DCE executable must have its own serviceability sub-component table. The table must be registered with the serviceability library and turned into a handle (dce_svc_handle_t) at initialization time.

    Message initialization

    Initialization code should contain a call to:

    void dce_msg_define_msg_table(
        dce_msg_table_t *table,
        unsigned32       size,
        unsigned32      *status);
    
    It adds a message table to the in-core table. The table parameter should be a message table as generated by the sams processor; size specifies the number of elements in the table. In case of an error, status will be filled in with an error code. An example of its use (taken from DCE Shell code) is as follows:
    error_status_t  st = msg_s_ok;
    
    dce_msg_define_msg_table(dsh_msg_table,
                    sizeof dsh_msg_table / sizeof dsh_msg_table[0],
                    &st);
    /*
     * i18n not done here, since this reports an error
     * during i18n bootstraping
     */
    if (st != msg_s_ok) {
        (void)
        fprintf(stderr,
            "Cannot register dsh message table, error 0x%lx\en",
            st);
        exit(1);
    }
    

    Serviceability initialization

    There are two ways to register a table described below. When to use which method is also described; it is based on how and when initialization can happen for a component.

    #define DCE_SVC_DEFINE_HANDLE(handle, table, comp)
    
    dce_svc_handle_t dce_svc_register(
        dce_svc_subcomp_t *table,
        const idl_char    *comp_name,
        error_status_t    *status);
    
    void dce_svc_unregister(
        dce_svc_subcomp_t *table,
        error_status_t    *status);
    

    The first method to register a table is to create a global variable using the DCE_SVC_DEFINE_HANDLE macro. The first parameter is the name of the handle; the second is a pointer to the table, and the third is the name of the serviceability component. This macro creates a skeleton variable that will be completed the first time the handle is used. It should be used in cases where there is no convenient initialization code (e.g., the security library can be entered from any one of a number of API calls).

    When there is a convenient location for initialization code (e.g., in an executable near the top of main(), or if all parts of a library call a common initialization routine), the second method is preferred since a status is returned that can be checked. The second method is to call the dce_svc_register routine. The first parameter is a pointer to the sub-component table and the second is the name of the serviceability component.

    To destroy a handle, call dce_svc_unregister. This closes any open message routes and frees allocated resources. It is normally not necessary to call this routine, as enough cleanup will be done as part of the normal process exit.

    Logging API

    To generate all serviceability messages that can be written to a log file (e.g., errors, warnings, etc), the following macro and routine should be used:

    #define DCE_SVC(handle, argtypes)
    
    void dce_svc_printf(
        DCE_SVC(handle, argtypes) ,
        const unsigned32 table_index,
        const unsigned32 attributes,
        const unsigned32 msgid,
        ...);
    

    The DCE_SVC macro is used to generate the initial arguments for dce_svc_printf. The first argument is the handle. The second is a string that describes the variable arguments to the dce_svc_printf call. The format of the string is the same as the format string of a standard printf(3), except that only the conversion specifiers separated by a space are needed (e.g., "%d %u %s"), any addition characters are ignored. If the message will be routed to a binary file then the format is extended to add a %b specifier which takes two arguments: an integer size, and a buffer pointer. Using %b in a different routing will give unpredictable results.

    The dce_svc_printf routine is used to generate all messages. The first argument must be a call to the DCE_SVC macro. The table_index is an index into the serviceability sub-component table associated with the handle. It indicates which sub-component within the component is responsible for the message. The attributes categorizes the message. It must be chosen from the following set (defined in the header file):

    1. svc_c_sev_fatal
    2. svc_c_sev_error
    3. svc_c_sev_warning
    4. svc_c_sev_notice
    5. svc_c_sev_notice_verbose

    In addition, any of the following flags may be or'd in to cause additional action to happen:

    1. svc_c_route_stderr
    2. svc_c_route_nolog
    3. svc_c_action_abort
    4. svc_c_action_exit_bad
    5. svc_c_action_exit_ok
    6. svc_c_action_brief

    The last item is used to suppress the standard prolog. Note that using svc_c_route_nolog without using svc_c_route_stderr will result in no message being generated.

    Serviceability printf API

    For those times when a string needs to be obtained from a message catalog but no logging event is to be generated (e.g., obtaining a question to display on the command line, or checking a locale-sensitive response) do not use the logging API, instead use the following serviceability versions of the standard printf-familiy routines.

    1. int dce_printf(const unsigned32 msgid, ...);

      The dce_printf routine retrieves the message text that has the specified msgid and prints the message and its arguments on the standard output.

    2. int dce_fprintf(FILE *stream, const unsigned32 msgid, ...);

      The dce_fprintf routine performs the same action as dce_printf, but on the specified stream.

    3. unsigned char *dce_sprintf(const unsigned32 msgid, ...);

      The dce_sprintf routine is a convenience function that wraps around the DCE messaging calls and the standard sprintf(3) library routine. The first argument is the id of the message containing the format string. The remaining arguments are the arguments needed by the format. The routine returns a pointer to allocated space containing the formatted output, or NULL on error. The final formatted string generated by dce_sprintf must not exceed 1000 bytes.

    Messaging API

    For those times when tighter control is needed in obtaining messages, use the following routines. An example, might be GDS's use of message catalogs to store information about curses screens.

    1. \*(xBunsigned char *dce_msg_get_msg( unsigned32 msgid, unsigned32 *status);\*(xE
    2. This routine is intended to be used to get a user-visibile message string. See also the dce_printf-family of routines described above. It retrieves the text for the specified message by first searching the appropriate message catalog, and then the in-core message table. It returns a pointer to allocated space that must be unallocated by using free(). If the message cannot be found it returns a default string and fills in status with an error code. If memory cannot be allocated it returns NULL and fills in status with the msg_s_no_memory error code.

      An example of its use is as follows:

      unsigned char *mp;
      unsigned32 st;
      
      if (argc != 2) {
          mp = dce_msg_get_msg(dsh_s_wrong_num_args, &st);
          printf((char *)mp);
          free((char *)mp);
      }
      

      Note that calling dce_msg_get_msg inside the call to printf will make it impossible to free the string returned.

    3. \*(xBunsigned char *dce_msg_get_default_msg( unsigned32 msgid, unsigned32 *status); unsigned char *dce_msg_get_cat_msg( unsigned32 msgid, unsigned32 *status);\*(xE
    4. These routines are used when more control over where messages are obtained from is required. They obtain the message from either the in-core table of default message strings or from the message catalog respectively.

    5. \*(xBdce_msg_cat_handle_t dce_msg_cat_open( unsigned32 msgid, unsigned32 *status); unsigned char *dce_msg_cat_get_msg( dce_msg_cat_handle_t handle, unsigned32 msgid, unsigned32 *status); void dce_msg_cat_close( dce_msg_cat_handle_t handle, unsigned32 *status);\*(xE
    6. These routines provide a DCE abstraction over the XPG4 message catalog routines. The difference between these and their XPG4 counter-parts is that these take DCE message id's, and map them into message catalog names.

    Routing API

    The two routing routines may be used to specify the disposition of production and debug messages (described below). If called before the component is registered, then the disposition is stored until it is needed. In case of error, both of these routines fill in status with an error code. These routines a probably only needed when processing user input to decide message disposition (in DCE Shell and when processing a command-line switch to a server).

    1. \*(xBvoid dce_svc_routing(unsigned char *where, error_status_t *status);\*(xE
    2. The dce_svc_routing routine specifies how dce_svc_printf messages are routed. The where parameter is a three-field routing parameter as described in svcroute(5). This routine is normally called with the value of a command-line flag. For convenience, the first field of the routing specifier may be omitted to indicate that all levels should be routed as specified.

    3. \*(xBvoid dce_svc_debug_routing( unsigned char *where, error_status_t *status);\*(xE
    4. The dce_svc_debug_routing routine performs the same action for DCE_SVC_DEBUG messages; where is four-field routing parameter as described in svcroute(5). No shorthand is allowed; all four fields are required.

    5. \*(xBvoid dce_svc_debug_set_levels( unsigned char *where, error_status_t *status);\*(xE
    6. To set the debugging level for a component, use the dce_svc_debug_set_levels routine. The where parameter should consist of a component name and a comma-separated list of sub-component/level pairs, as described in svcroute(5).

    Code for debugging

    Debugging instructions will be activated if the macro DCE_DEBUG is defined. Defining this one macro via ODE for all of DCE will turn on all debugging statements. Further, individual components should define this macro in an internal, component-wide header file, if a component debug macro is defined. This must be done in an internal header file that other components will not be including, or else setting debugging on for one component could have an effect on another. This component debug macro is DCE_CMP_DEBUG, where CMP is the three letter acronym for the component in uppercase.\*(f! For

    One of: THR, RPC, CDS, SEC, DTS, GDS, DFS.
    example, the following should appear in a cds.h file:
    #if defined(DCE_CDS_DEBUG) && !defined(DCE_DEBUG)
    #  define DCE_DEBUG
    #endif                     /* defined(DCE_CDS_DEBUG) */
    

    DCE_SVC_DEBUG

    If (and only if) DCE_DEBUG is defined, then DCE_SVC_DEBUG() is defined to be a call to dce_svc__debug() (otherwise it is defined to be null). It must be called with four or more arguments: a handle, a table index, a debug level, a format string, and then any parameters to the format string. Since C does not allow a variable number of arguments to a macro, the double parentheses trick\*(f!

    This is where the arguments are grouped as one argument by placing them in parentheses, so the call must have two sets of parentheses, one for the macro itself, and one to group the arguments

    is used. The debug_level indicates the level of detail associated with this message and must be of the form svc_c_debugN, where N is an integer from 1 to 9. Larger numbers imply more detail, but the actual meaning of the debug level is left to the individual component. The effects of each debug level must be docoumented in the [PORTG]. An example of its use follows:

    void *allocate(int bytes)
    {
        char        *new;
    
        DCE_SVC_DEBUG((mem__svc_handle,
                       mem_svc_alloc,
                       svc_c_debug2,
                       "Allocating %d bytes\en",
                       bytes));
    
        if ((new = malloc(bytes)) == NULL) {
            dce_svc_printf(DCE_SVC(mem__svc_handle, "d"),
                           mem_svc_alloc,
                           svc_c_sev_fatal |
                               svc_c_action_exit_bad,
                           mem_s_noalloc,
                           bytes);
        }
    
        DCE_SVC_DEBUG((mem__svc_handle,
                       mem_svc_alloc,
                       svc_c_debug1,
                       "Allocated %d bytes at 0x%x\en",
                      bytes,
                       new));
        return new;
    }
    

    Notes for the above code:

    1. mem__svc_handle is a global variable that was assigned the result of a call to dce_svc_register().
    2. mem_svc_alloc is meant to be the index into the service table associated with the handle for the alloc facility of the mem component.
    3. mem_s_noalloc is the symbolic name of a message in the alloc facility.
    #define DCE_SVC_LOG((handle, table_index, debug_level, \e
    messageid, argtypes, ...))
    

    The DCE_SVC_LOG macro is a similar to DCE_SVC_DEBUG except that, like dce_svc_printf it takes a message identifier and a format specifier.

    Other DCE_SVC_DEBUG macros

    #define DCE_SVC_DEBUG_ATLEAST(handle, table_index, debug_level)
    #define DCE_SVC_DEBUG_IS(handle, table_index, debug_level)
    

    If debugging code is enabled, these macros may be used in an expression (e.g., in an if statement) to test the debug level of a subcomponent (as indexed in the serviceability table by table_index) for the specified handle. The first macro tests if the debug_level is not less then the specified level, while the second macro tests for an exact match. In either case, debug_level should be a number from 1 to 9.

    dce_assert

    void dce_assert(dce_svc_handle_t h, int expression)
    

    This routine is a replacement for the [ANSI C] assert() macro which uses DCE style error messages as defined by the serviceability component. Its arguments are a registered DCE serviceability handle (if it's NULL then an internal serviceability handle is used) and an expression.

    On execution, if the expression evaluates to zero, then dce_svc_printf() is called with parameters to identify the expression, and source file and line number. The message is generated as a svc_c_fatal message, with the svc_c_action_abort flag.

    Assertion-checking can be enabled or disabled at compile-time. If the macro DCE_ASSERT is defined, then assertion checking is enabled. If it is not defined, it is compiled out of the program.

    To use this routine include the header file dce/assert.h, which is shown in Appendix H.

    Internationalization

    In addition to following the messaging guidelines given above, all code should follow the internationalization guidelines described below.

    1. Use setlocale().

      All DCE programs that do locale-sensitive processing (i.e., display a date or time, generate messages, or compare lexicographic strings) must use setlocale() as described in [I18N]. Library routines should not call setlocale().

      (void) setlocale(LC_ALL, "");
      
    2. Localized Date and Time Format.

      All non-DTS-style time which is presented to the user, must be formatted with strftime() as shown in [I18N] section 5.5. To convert from a formatted time string to a tm structure, use the routine strptime(). Converting the code to use DTS style time is recommended.

      #include <time.h>
      #include <stdio.h>
      #include <locale.h>
      #include <langinfo.h>
      
      main()
      {
          char        buff[BUFSIZ];
          time_t      ct;
          char        *dt_fmt;           /* date/time format */
          struct tm   *local;            /* local time */
      
          (void) setlocale(LC_ALL, "");
      
          /* get the time in secs and convert to tm format */
          ct = time(NULL);
          local = localtime(&ct);
      
          /* get format from locale */
          dt_fmt = nl_langinfo(D_T_FMT);
      
          /* Now format the string and print it */
          if (strftime(buff, BUFSIZ, dt_fmt, local)) {
              printf("%s\en", buff);
          }
      }
      
    3. Yes and No User Responses.

      Internationalized user questions that require an affirmative or negative (i.e., yes/no) answer must use the dce_rpmatch() routine to parse the response.. If dce_rpmatch() is not used, the prompt must indicate appropriate responses (e.g., y/n).

    4. Character Manipulation.

      Remember that DCE code needs to support multiple code sets. Even those areas that are restricted to portable characters must support both ASCII and EBCDIC; other areas must handle a larger range of encodings. Keep in mind the following:

      1. Only a few places in DCE will need to worry about wide characters or multi-byte data. This is due the use of the Portable Character Set (PCS) for some data. DCE code will only need to worry about either of these, if the data can come from a user and is not limited to a particular code set by some DCE code.

        For example, all code that accepts and processes a cellname can be single-byte since cell names are limited to the PCS. However, if extended registry attributes are implemented then all code that accepts or processes them, must be wide-char or multi-byte capable. See [I18N] section 5 for details.

      2. Hard-coded character constants must be removed from all non-protocol related code. Instead of \e141 use 'a'.
      3. Use of isascii() must change to isdcepcs().
      4. Dependencies on code set constructions, such as whether or not numbers are contiguous in the code set, must be removed from all code.
      5. Arithmetic on character data must not be performed. To change the case of a character do not add or subtract a value to it, call toupper() or tolower() (for single-byte cases).
      6. Range checking on character data should only be performed using one of the library routines such as isprint() or islower(). In particular do not do something like the following when doing an isalpha()-like check.
        if ((code >= 'a') && (code <= 'z'))
        
        since, in EBCDIC the values for 'a' to 'z' are not contiguous.
      7. For collation of single-byte or multiple-byte data, use one of the following:
        1. strcoll() by itself
        2. strxfrm() followed by one or more calls to strcmp().

        When collating wide character data use the similar functions wcscoll() or wcsxfrm() and wcscmp().

    5. Guidelines For New Protocols.

      If a new protocol is being added to DCE, refer to [RFC 23.0] for mechanisms to use to allow for internationalized data to be properly handled.

    Include Files

    All header files in DCE 1.1 must be protected from duplicate inclusion in the following manner:

    #ifndef _HEADER_H
    #define _HEADER_H
        /* ... body of header.h ... */
    #endif /* _HEADER_H */
    

    where HEADER is the base name of the header file in uppercase.

    SAMS SOURCE FILES AND MESSAGES

    In DCE 1.1 all user-visible messages are to be isolated into message catalogs.\*(f! These

    The isolation of debug messages is not required, although debug messages are to use the provided serviceability interfaces.
    message catalogs must be maintained using the sams processor and should follow internationalization guidelines.

    sams

    Files which will be input to sams should end with the extension \&.sams. The sams processor will generate several files as described below. In all of the following filenames, cmp is the serviceability component name. Also the dce is generated based on the technology name, for all core components this will be dce, for DFS it will be dfs.

    1. dcecmpmsg.h -- Header file defining constants for message \& numbers.
    2. dcecmpmsg.c -- In-core table mapping message numbers to \& default text.
    3. dcecmp.msg -- Message catalog file for input to the \& gencat program.
    4. dcecmp.cat -- Message catalog generated by gencat.
    5. dcecmpmsg.man -- A subset of a man page containing error \& codes and their descriptions.
    6. dcecmpmsg.sgm -- Markup file for Problem Determination Guide.
    7. dcecmpsvc.h -- Serviceability header file.
    8. dcecmpsvc.c -- Serviceability sub-component table.
    9. dcecmpmac.h -- Convenience macros to be used in calls to \& serviceability routines.

    The input file is divided into three parts. A header containing information used in processing the whole file, such as the component name. A second part used to define information about the serviceability table\*(f!

    This is also known as the sub-component table as it has one entry for each sub-component.
    which can be generated by sams, and final part which describes each message.

    The header

    The header of the \&.sams file syntacticly must contain the component field with the serviceability component name.\*(f! This

    This component name must be a three-letter word chosen from the set of 38 characters, a-z_0-9- (i.e., the RAD40 alphabet).
    style guide also requires the use of the technology field. Most components will set this to the default of dce but DFS will have to set it to dfs. All other fields are optional and can (and in most cases should) be left out.

    The serviceability table information

    The second part of the file is used to specify the DCE serviceability table and handle. All \&.sams files that define serviceability messages should contain such a specification. It should appear in the following format:

    serviceability table table_name handle handle_name start
        sub-component table-index subcomp full_descrip_id
        sub-component table-index subcomp full_descrip_id
        ...
    end
    

    Where:

    1. table-index

      The name of a macro whose value will be generated by sams. It is used as an index into the serviceability table. It is also used as a value of a sub-component field as presented below. It is recommended that the name be cmp_svc_subcomp.

    2. subcomp

      A one word name that will only be used to identify a sub-component to route debug messages.

    3. full_descrip_id

      The code of a message listed somewhere in the file that provides the full description of the sub-component. It is recommended that the name be cmp_i_svc_subcomp.

    An example follows. Note that portions of the third part of the input file are listed here. The syntax of that portion of the input file is described in the next section. This style guide recommends listing all the messages that are used to describe a sub-component together before any other messages in the input file.

    serviceability table dts_svc_table handle dts_svc_handle
    start
        sub-component dts_s_general "general" dts_i_svc_general
        sub-component dts_s_provider "provider" dts_i_svc_provider
    end
    
    ## Messages for serviceability table
    start       !intable undocumented
    code        dts_i_svc_general
    text        "General administrative actions
    explanation "
    action      "
    end
    
    start       !intable undocumented
    code        dts_i_svc_provider
    text        "Interactions with time-providers
    explanation "
    action      "
    end
    

    The messages

    The final part of the file defines the individual messages. It consists of a series of records where each record specifies one message. Each record is of the form:

    start optional_flags
    field_list
    end
    
    The field_list is a set of key-value pairs from the following lists. All messages must have the following fields:
    1. code name[=value]

      This is the symbolic name of the message. It is used to create a header file that has #define statements that map all message ID's to their numeric value. It also appears in the generated .man file. If the text of this field is of the form name=value, then that the numeric value is explicitly assigned as opposed to being generated with a simple counter. This should be used only when needed to ensure compatibility with older message versions.

    2. text text

      This is a short description of the error. It is stored in the in-core table of default messages and in the message catalog. It is intended to be displayed by messaging routines. The text must be shorter than the size of the dce_error_string_t typedef defined in dce_error.h.

    3. explanation text

      This is a verbose description of the message; it can be blank if the message is not for an error condition. It is used in the .man and .sgm files and should provide additional information that can be used for fault isolation.

    4. action text

      The text describes the action that should be taken when this error occurs. The text appears in the generated \&.sgm file.

    All messages used in serviceability calls must have the following two fields. They are both only used to generate convenience macros in the dcecmpmac.h file.

    1. attributes text

      Indicates the attributes assigned to the message. Multiple attributes can be separated by |'s. Valid attributes are defined in dce_svc.h; do not use the ones reserved for vender use. Valid ones are listed below.

      1. svc_c_action_abort
      2. svc_c_action_brief
      3. svc_c_action_exit_bad
      4. svc_c_action_exit_ok
      5. svc_c_action_none
      6. svc_c_route_nolog
      7. svc_c_route_stderr
      8. svc_c_sev_alarm
      9. svc_c_sev_error
      10. svc_c_sev_fatal
      11. svc_c_sev_notice
      12. svc_c_sev_notice_verbose
      13. svc_c_sev_warning
    2. sub-component table-index

      Indicates the sub-component that the message belongs to. The value must be one of the table-index's listed in the serviceability table description.

    The following fields are optional:

    1. notes text

      Optional notes for translators. This text, if it exists, appears as comments in the message catalog. Note that the internationalization guidelines specify that translator notes must be used copiously. See section 2.6.1.3 item (f) for details.

    2. tables (keywords)

      If a single component is used for several executables, the message table can get unreasonably large, containing texts that will never be used. Using the table command, a space-separated list of keywords can be assigned to each message. If the sams processor is invoked with a -t switch specifying a keyword, then only those messages having that keyword in the table field will be included in the generated in-core default message table.

    3. engineer text

      This is used to specify the software engineer responsible for the code where this message could occur. It may be omitted (and will be in most cases).

    How to Write Proper Messages

    In addition to using the sams processor described above, all messages must meet internationalization and guidelines described in [I18N]. They are summarized below:

    1. Messages must be clear and easy to understand. Remember that translators will be working from the message catalog only, and may not understand the what the code does. Do not use slang.
    2. Messages must not use abbreviations. Examples of bad abbreviations are pkt and ack. Some common acronyms are permissible such as DCE, official component names (e.g., thr not cma), and command names (e.g., cdsd instead of the CDS server). If it is not clear if an acronym is acceptable, do not use it. If it must be used, then include a notes field in the message description to define it.
    3. Messages must not use fragmentation. Do not use common C tricks to make words in strings plural or to negate them. The following code should be changed to use two separate messages:
      printf("Server directory access is %sokay\en",
             (result ? "" : "not "));
      
      Messages that have fragments can be difficult or impossible to translate. This does not mean that variable substitution cannot be used in messages, however, it must be used for complete units such as a filename, a numerical amount, a process name, etc.
    4. Initial message strings (i.e., the default messages) do not need to use the XPG4 variable parameter syntax; it is unnecessary since the argument order is correct for the default string, and it slows down the code.
    5. Default text must be included in the catgets call and must be in English encoded in ASCII. Proper use of the messaging API and the sams processor will ensure that this requirement is met with no explicit action required by the programmer.
    6. Notes must be included in the message catalog (i.e., the \&.sams file) for any item needing further explanation. The example in the above item referring to variable parameter substitution used a string to represent the data. If the catalog contained only the string, then a translator would have no way to know what it is in order to translate it. An explanation of this type message is required in the notes field of the \&.sams file. In this case it should say something like: This is a data format string. The first field is the month, the second is the day, and the third is the year.

      Notes should also be used to explain any potentially ambiguous parts of the message and to specify words or phrases that should not be translated. For example, in the message string "The read system call failed. Cannot read %s", the notes section should say something like: Do not translate "read" in the phrase "read system call". %s is a filename.

    The following guidelines were developed by the DCE Technical Writers for writing message text in sams files. Follow these guidelines in addition to the internationalization guidelines stated previously. All new messages must, and all existing messages should meet these guidelines.

    1. The most important thing is to be clear and concise. When in doubt refer to this guideline.
    2. The text field should be descriptive and not prescriptive. In other words, describe the problem, not what to do about it. The action field should be used to describe corrective actions to be taken.
    3. Use complete short sentences in the explanation and action fields. Sentence fragments may be used in text fields. Sentence fragments do not need to end with a period (or other punctuation), but complete sentences must. This means a message like file not found is acceptable, although it would be better if it gave the name of the file.
    4. Use active voice and change passive voice to active voice wherever possible. For example, the following sentences are in passive voice:
      The job was cancelled.
      Month and year must be entered as numbers.
      Data was updated by administrator.
      

      The following sentences are in active voice:

      Job cancelled by operator.
      Enter month and year as numbers.
      The administrator updated data.
      
    5. Use correct case for macro names, commands, keyword parameters, module names, and acronyms. Capitalize the first word of a sentence, but not a sentence fragment. Do not begin a sentence with a command name that must be in lowercase. Use Use cdscp to..., instead of cdscp is used....
    6. In text fields, do not use any mechanism (e.g., double or single quotes, asterisks, uppercase, SML markups) to show emphasis for words. However, if the text contains a literal (e.g., a filename, command name, or any name) do use the appropriate fonts for literals as described below.

      In explanation and action fields use the standard SML markup for bold, italic, and constant width fonts. To begin the font change use the appropriate markup from the following table. To end it, use \e*O (that's a capital letter O) to return to the ordinary text font.

      1. Commands \e*L
      2. Keywords \e*L
      3. Functions \e*L
      4. Data types \e*L
      5. Command Options \e*L
      6. Arguments \e*V
      7. Pathnames \e*L
      8. Return Values Uppercase
      9. Sample Commands:
        1. user input \e*L
        2. system response \e*C
    7. Follow internationalization practices for expressing plurality. Do not use (s) to show possible plurality (e.g., error(s) cannot be translated). Two separate messages should be written and output appropriately.
    8. Indicate ranges using the word to (do not use a dash, or the word through) and by being inclusive. Include the first and last elements in the range. If the legal values for an entry are 0, 1, 2, and 3, use The legal values are 0 to 3.
    9. Do not use the construction and/or; it does not exist in other languages. Usually it is better to use or to indicate that it is not necessary to do both.
    10. Do not use the first or second person (i.e., I, we, or you) in text fields; however, they are acceptable in explanation and action fields.
    11. You can use contractions, as long as they're grammatical contractions (e.g., don't, you've, etc.). Do not use non-standard contractions or abbreviations for words; for example, req'd for required or ack for acknowledged.
    12. Only use acronyms that are better known to your audience than their spelled-out version (e.g., DCE instead of Distributed Computing Environment). If some acronym is border-line, use the acronym in the text field and the spelled-out version in the explanation or action field.

      To make a plural of an acronym, add a lowercase s, without an apostrophe. A list of acronyms is provided in the next section.

    13. Use the present tense. For example, use The foo command displays a calendar. instead of The foo command will display a calendar. In general, don't mix tenses. Of course there are some cases where it is necessary to refer to something that happened in the past, and what the program is now doing in response.
    14. Use positive language. For example, Do not use the f option more than once. uses negative language, while Use the -f flag only once., uses positive language. There are some exceptions; for example, file does not exist is clearer and more easily understandable (and translatable) than the message file nonexistent. In explanation and action fields, make positive statements when you can. Explanations may or may not be positive, but actions should always be positive. Avoid using double negatives.
    15. Use the imperative mood (command phrase) and active verbs; for example, specify, use, check, choose, and wait. This applies for all fields, but will be relevant mostly to explanation and action fields.
    16. Do not use humor, slang, or your company's internal jargon. Industry-standard terminology such as queue, toggle or click is acceptable.
    17. Be as precise as possible when refering to objects such as a file, cell, principal, etc. Use the specific name. If it is appropriate, use an article (i.e., a, an, or the). The following three examples are bad, better, and best:
      1. Fix client configuration.
      2. Fix the client configuration.
      3. Fix configuration of client /.../my_cell.osf.org/hosts/gumby
    18. Once you use a name for an object, continue to refer to it the same way. For example, if you call something the cdsd.log file in one place within the message explanation, do not refer to it as the log output later.
    19. When in doubt refer to a dictionary. Do this for spelling and grammar. Don't use nouns as verbs (e.g., use enter your response rather than key in your response, ). If you're still in doubt, ask a writer.
    20. While it is not concise to repeat things, go back and reread guideline (a).

    Approved acronyms in messages

    Here is a list of DCE acronyms that can be used in message texts:

    1. ACF Attribute Configuration File
    2. ACL Access Control List
    3. ACSE Association Control Service Element
    4. API Application Programming Interface
    5. ASN.1 Abstract Syntax Notation One
    6. AVA Attribute Value Assertion
    7. C-ISAM C-language Indexed Sequential Access Method
    8. CDS Cell Directory Service
    9. CPU Central Processing Unit
    10. DAP Directory Access Protocol
    11. DCE Distributed Computing Environment
    12. DFS Distributed File Service
    13. DIB Directory Information Base
    14. DIT Directory Information Tree
    15. DLC Diskless Configuration Service
    16. DNS Domain Name Service
    17. DSA Directory System Agent
    18. DSP Directory System Protocol
    19. DTS Distributed Time Service
    20. DUA Directory User Agent
    21. GDA Global Directory Agent
    22. GDS Global Directory Service
    23. IDL Interface Definition Language
    24. ISO International Organization for Standardization
    25. LAN Local Area Network
    26. LFS Local File System
    27. NSAP Network Service Access Point (OSI)
    28. NTP Network Time Protocol
    29. OSF Open Software Foundation
    30. OSI Open Systems Interconnection
    31. OSS OSI Session Service
    32. RDN Relative Distinguished Name
    33. ROS Remote Operation Service
    34. ROSE Remote Operation Service Elements
    35. RPC Remote Procedure Call
    36. TCP/IP Transmission Control Protocol/Internet Protocol
    37. TDF Time Differential Factor
    38. UDP/IP User Datagram Protocol/Internet Protocol
    39. UFS UNIX File System
    40. UTC Coordinated Universal Time
    41. UUID Universal Unique Identifier
    42. WAN Wide Area Network
    43. XDS X/Open Directory Service
    44. XOM X/Open OSI-Abstract-Data Manipulation

    FILENAMES AND DIRECTORY NAMES

    The names of files and directories (in the filesystem) used by DCE services must comply with the following:

    1. There must be at most one period in filenames and it should be immediately before the extension.
    2. There must be no periods in directory names. The only exceptions to this rule are directories under /opt such as dce1.0
    3. [RFC 35.0] must be followed for choosing where files will reside.

    Location of core Files

    All processes implementing DCE core services should, if at all possible, change directory into a running directory early on so that any core dumps they generate will be easy to locate, and not show up in the root directory of the system. The path will be:

    /opt/dcelocal/var/component-name/adm
    

    This path is what is documented in [RFC 35.0] as where servers should place log files, caches, and core dumps. These directories should be owned by root and mode 700 by default, to protect the core dumps (which probablay contain encryption keys) from prying eyes.

    BUILD ENVIRONMENT

    While DCE is generally thought of as C source code, those who port DCE learn very quickly that the DCE distribution comes with some very complex Makefile's as well. In fact, many of the complaints about DCE's portability are related to the Makefile's. In order to make porting DCE as easy as possible, the following guidelines must be followed when writing Makefile's and when addressing other build environment issues.

    Makefiles

    The following rules must be followed in all Makefile's in DCE. See Appendix I for overview information about ODE and a description of the variables that ODE defines that can be used in Makefile's.
    1. One Target per Makefile or Directory.

      All new build targets (programs, libraries, etc.) must live in their own directory, with a Makefile that builds only that target. This is desirable for existing targets as well, but is not required. However, existing directories that have two targets where one is a library and one is a program that depends on that library, should be separated wherever possible. This particular situation exacerbates a bug in make.

    2. Avoid Target-Specific Variables.

      Almost all variables can be set in a target-specific manner, by setting target_variable. For example, compiler flags for only the cdsd target could be set in the Makefile by setting cdsd_CFLAGS. This should be avoided wherever possible by having only one target in a directory. However, where this is not avoidable, care should be taken so that the defaults for these variables (those variables which are not target-specific) are set in a general manner, and only a few exceptions needed are set in a target-specific manner.

    3. Use the install Tree Properly.

      The goal of the build is to populate the install tree. Both the obj and export trees are intermediaries in achieving this goal. All programs, libraries, header files, and datafiles used by an end-user; and all tests, scripts and datafiles used by a DCE developer must be in the install tree after the build completes successfully. ODE will look first in the obj tree and then in the src tree to find targets.

    4. Use ODE Passes Properly.

      ODE implements the build process as a number of passes. Each pass performs different actions. Directories in the src tree should either contain source code, or contain subdirectories, not both.\*(f! For

      The exception are subdirectories that handle machine dependencies are permitted in directories with source code.
      those that contain subdirectories, they must have a Makefile that defines the appropriate variables for subdirectory traversal by make and nothing else, except for some logic if necessary, such as not visiting the src/file directory if NO_DFS is defined. The variables must be listed in the order the passes are performed.\*(f!
      This is not an ODE requirement, but rather a stylistic requirement.
    5. Describe All Dependencies in Makefile's.

      All dependencies must be listed in Makefile's. This includes library dependences for executables and any cross-directory dependencies. Do not depend on another pass being run the another directory to create dependencies (e.g., idl being run on a \&.idl file in a headers directory creating stub files). It is permissible to depend on another pass being run in the same directory, or on an export pass being run in another directory.

    6. Use Appropriate Makefile's.

      Makefile information must be properly placed in either a Makefile, machdep.mk file, or the src/Makeconf file. Note that component.mk files are being removed in DCE 1.1. The information currently in these files must be moved to the appropriate Makefile.

    7. Use of VPATH is discouraged.
    8. Use Libraries Where Needed.

      If an object is to be included in more than one executable it must be in a library and that library should be linked into each executable.

    9. Build DCE in NFS Mounted Sandbox.

      DCE should be able to be built in a sandbox which is mounted via NFS. Currently this is not possible due to the way a database is created for GDS. This must be investigated and corrected if possible. This work is to be done by provider companies with support from the OSF Release and Tools Group.

    10. Structure of New Source Subtrees.

      New subtrees must be created in the following style. There should be one target per subdirectory. Each target should reside in a directory which is named the same as the target. Component wide header files should reside in a single subdirectory as should \&.idl and \&.sams files.

      1. comp
      2. comp/h all headers that are component wide
      3. comp/idl IDL files
      4. comp/sams SAMS files
      5. comp/lib directory for libraries
      6. comp/lib/libA contains source for library A
      7. comp/lib/libB contains source for library B
      8. comp/food all sources for the foo daemon
      9. comp/foocp all sources for the foo control program\} comp/foocp all sources for the foo control program\}
      10. comp/fooclerk all sources for the foo clerk
    11. IDL Files.
      NOTE:
      This needs to be defined by the RATs. Included here are the requirements from [RFC 17.0]. The right thing is to define a variable such as IDLFILES to set all \&.idl files to, and let make do the rest. This might involve a separate pass, so that other Makefile's will have to change to follow this path. It also might involve an enhancement to idl to add a switch that searches for the \&.acf over a path, or doesn't produce a \&.h file.

      There shall be a rule for creating all stubs and headers from \&.idl files so that they are not built more than once as they currently are. This is one of the few things preventing DCE from using the parallel make. The rule will create these files once, probably in their own pass after the headers are exported and before the libraries are exported (pass=SECOND?). It might involve a new switch to idl being created so that it can be run without generating a header file. Also, there are some places in DCE (e.g., Security) where the same \&.idl file is processed more than once with different \&.acf files so that the generated stubs are different. This must be done in an orderly way. The OSF Release and Tools Group will be responsible for determining the solution to this problem. Provider companies will implement the solution. Since the number of \&.idl files is small, this is not expected to be a large work item.

    12. SAMS Files.
      NOTE:
      This needs to be defined by the RATs. I expect these files to be handled similarly as IDL files. The design work should be simpler since it only takes one input file. A suggestion for the variable name is SAMSFILES.

    Machine Dependency Handling

    The best way to handle machine dependencies is not to have them in the first place. To this end, machine dependencies should be removed and replaced with feature dependencies. For example, instead of coding endianess specific code in #ifdef's for mips or AIX, they should be coded in an #ifdef that checks for LITTLE_ENDIAN or BIG_ENDIAN which will be defined in dce.h. Feature macros should be defined in the header file that most fits their scope. The endian macros mentioned above will be in dce.h as they could be used for many components, however, the MISPACKED_HEADER macro used only by RPC will be defined in an RPC header file. All feature macros must be documented in the DCE Porting and Testing Guide.

    There will be cases where machine dependent code is necessary. Machine dependencies must be divided into those dependencies on machines (i.e., hardware) or on operating systems (i.e., system software). The term machine dependency will be used to refer to both. Wherever possible, machine dependencies must be separated out into functions that have interfaces documented in the DCE Porting and Testing Guide and that are implemented in machine dependent files. Where the code involved is small and isolated\*(f! then

    As a guideline, code that is under 10 continuous lines, closely tied to surrounding code, and not quite worth the overhead of a function call can be considered small and isolated.
    an #ifdef for a machine defined macro is appropriate. Another qualifier to use is how many machine dependencies appear in a file. If there are many sections of code that are small and isolated, then the whole file should be considered as a machine dependent file.

    Machine dependent files

    NOTE:
    This needs to be defined by the RATs. Included here are the requirements from [RFC 17.0]. My guess is that the resolution will involve some approved form of conventions for organizing machine and operating system dependent files under subdirectories, and the use of VPATH with TARGET_OS and TARGET_MACHINE, or their equivalent, in the Makefile's.

    The methods of handling machine dependencies in DCE are both varied and unwieldy. First of all a solution to the PMAX versus MIPS debate must be finalized. It will include how to differentiate between TARGET_MACHINE and TARGET_OS and even TARGET_OS_VERSION (how will differences between OSF/1 1.0 and OSF/1 1.1 be handled?). The OSF Release and Tools Group will be responsible for determining the solution to this problem. Provider companies will be responsible for the implementation.

    Machine defined macros

    In those cases where machine dependent conditionalized code (i.e., #ifdef's) is appropriate, the following macros are to be use in the check. They are the macros that the compilers used on these platforms define. In the table, platform names are the informally defined ones used up through DCE 1.0.2 development.

        Platform Machine Operating System
      1. PMAX __mips__ __OSF__
      2. AT386 __i386__ __OSF__
      3. AIX _IBMR2 _AIX
      4. SVR4 i386 unix
      5. HPUX __hppa\*(f! __hpux
        Having __hppa defined means that the machine supports the HP Precision Architecture rev 1.0 or greater, (i.e., all PA machines). Having _PA_RISC1_1 defined means that the machine supports the HP Precision Architecture rev 1.1 or greater, (i.e., all s700 and all new s800 machines).
      6. RISC Ultrix __MIPSEL ultrix
      7. VAX Ultrix vax ultrix
      8. VAX VMS vax VMS
      9. AXP OSF/1 __alpha __osf__
      10. AXP VMS __alpha __VMS

        Machine dependencies in Makefile's

        NOTE:
        This needs to be defined by the RATs. Included here are the requirements from [RFC 17.0]. The complaints are that there are too many places to look to find how make variables are set, and some say that component.mk files are slow since they do tests for each directory. There are several choices:
          \(mi
          Leave things the way they are. Perhaps a cleanup of the component.mk files by the RATs could make things a little better than they are now.
          \(mi
          Remove component.mk files completely and put the information either in the Makefile's (some say this will confuse the makefiles), or machdep.mk files (some don't like lots of little machdep.mk files, or in Makeconf or common makefiles as appropriate.
          \(mi
          Keep the component.mk files for only component wide things (not DCE wide things, they should be in Makeconf or the common makefiles if they are general to ODE and not DCE) and place all the directory specific stuff in either the Makefile's or machdep.mk's.

        The component.mk files will be removed and replaced with machdep.mk files. Currently all the components have a top level file which sets machine specific flags for each directory in the component, that is named with the name of the component followed by .mk, for example, src/rpc/rpc.mk. The result is that many (not all) of the machine specific flags are in one place. However, the build is longer since this lengthy file must be read every time that make is invoked, porting is less clear since machine dependencies occur in component.mk files, in the osf.dce.mk file, in the Makeconf file, in machdep.mk files, in the Makefile, etc. These will be isolated so that there is one file with project wide machine specific settings (either Makeconf or osf.dce.mk) and then separate files with machine specific settings in each directory where needed. These component.mk files were created to simplify porting, but they seem to have just made it more complicated. The OSF RATs will be responsible for this work.

        RECOMMENDED CODING CONVENTIONS

        This section describes recommended coding conventions. These conventions are not required for either old or new code. If the new code fits into another component with rigorous coding conventions, follow them. However, these are probably suitable for a new component. They are based on the coding conventions used in the RPC source.

        This section uses the traditional DCE definition of component. A component is defined to be made up of facilities. For example, the rpc component has the following facilities: com, dg, cn, ip, ns, mgt, etc.

        File Organization

        Source files should be kept to a reasonable size. Reasonable must be determined by the developer, but a guideline is that a source file should implement some functionality that can be stated in a single concise statement, such as This file implements the messaging facility. For those that need a more precise guideline, 2000 lines is about as big as it should get.

        The organization of \&.c files should be as follows:

        1. File header comment.
        2. #include preprocessor directives.
        3. #define and typedef declarations that are internal to this file.
        4. Internal variable definitions.
        5. Function declarations (i.e., prototypes) for all the internal functions .
        6. Function definitions.

        A limitation of ODE is that all header files should be included by using angle brackets and not double quotes. In order to simplify the include file structure and make things as explicit as possible, header files should not be nested. The organization of \&.h files should be as follows:

        1. File header comment.
        2. Protect the header file from duplicate inclusion.
        3. #define and typedef declarations.
        4. Function declarations (i.e., prototypes).

        Naming Conventions

        All names are to be formed from the set of lowercase portable letters (a-z), digits (0-9), and the underscore character (not a dollar sign). Macros are to be in uppercase portable letters (A-Z) only. All names must be unique to 31 characters in length. All names must begin with a prefix that identifies the subcomponent to which it belongs. Names should be long enough to be descriptive. Avoid the need to notice the difference between 1 (a digit), l (a lowercase letter), and I (an uppercase letter).

        File names should begin with a facility prefix which should be no longer than three characters. C source files, should be named as the facility prefix followed by a name for the file. If sub-facilities are required, they should be included after the facility prefix. C header files, should be named as a facility prefix followed by a name for the header file. If sub-facilities are required, they should be included after the facility prefix. If the header file is private, there should be a p before the \&.h extension.

        Name functions, variables, and constants, etc., as follows:

        1. comp_fac_name public function
        2. comp__fac_name private function
        3. comp_g_fac_name global variable
        4. comp_s_fac_name status codes
        5. comp_c_fac_name constants
        6. comp_e_fac_name enumeration values

        If name is composed of more than one word, they should be separated by underscores.

        Macros should be named in all uppercase unless they are specified by a standard to be otherwise (e.g., getchar()). If they are behaving as some other C object that has naming conventions, they should be followed, but should still be in uppercase.

        The names of typedef's and struct's should be formed as follows. Always create a tag for a struct.

        1. comp_fac_name_t typedef
        2. comp_fac_name_p_t pointer to typedef
        3. comp_fac_name_s_t struct tag

        For example:

        typedef struct rpc_handle_s_t
        {
            struct rpc_handle_s_t *next;
            int                    date;
        } rpc_handle_t, *rpc_handle_p_t;
        

        Comments

        There are four types of comments:

        1. All files should have the file header comment at the beginning of the file. Define a new style or use one from DCE code.
        2. All functions should have the function header comment immediately before their definition. Define a new style or use one from DCE code.
        3. Block comments are used to document a section of code. They should start at the same level of indentation as the code they describe. Use them liberally.
        4. In-line comments appear on the same line as the code they describe. If the comment does not fit on the same line, then use a block comment above the line.

        Functions

        Keep the length of functions reasonable, in general under 100 lines. Always explicitly define type of the return value of a function, don't let it default to int. If there is no return value, define the function as returning void. Avoid side effects (implicit parameters) wherever possible.

        Parameters should be ordered with all input parameters first, then all input-output parameters, and finally all output parameters. Any function which can fail should return an output status parameter.

        Input parameters which are pointers to a typedef, should be defined with the type type_p_t. Input-output and output parameters which are pointers to a typedef, should be defined with the type type_t *. Aside from making the code easier to read (an input parameter will never be prefixed with a * while, input-output and output will), idl requires that input-output and output parameters have an explicit top-level *.

        Some existing DCE code uses macros (e.g., EXTERNAL, GLOBAL, PUBLIC, PRIVATE, and INTERNAL) just before the function definition to define the scope of functions. Since C does support such a rich set of scope definitions, they are usually defined to be nothing and are used for commenting purposes only. Often these macros have the effect of confusing tools that try to parse C code (admittedly poorly). Do not use these macros, instead use the C storage class specifiers static or extern; if they do not provide enough specification, include more in a comment block.

        Statements

        Each line should contain at most one statement. If a statement must be broken at line boundaries, indent the second line to same level as the logic. So parameters that are on separate line should all line up vertically, or expressions that are broken onto separate lines all line up logically as in the following example:

        foo_p->size = strlen (bufp->prefix)+
                      strlen (bufp->text)+
                      strlen (bufp->suffix)+
                      strlen (bufp->prefix);
        

        Use blank spaces between reserved works (or function names) and a following open parenthesis. For example:

        if (condition)
        
        instead of:
        if(condition)
        

        Avoid using the goto statement.

        Switch statements should always have a default case. If it is not reachable then it should indicate a fatal error. All cases should have a break statement, do not let one case fall through to another. Several case labels can be associated with one block of code.

        eow = 0;
        while ((c = getchar ()) != EOF)
        {
            switch(c)
            {
                case '\en':
                case '\et':
                case ' ':
                    if (c == '\en')
                    {
                        lines++;
                    }
                    words += eow;
                    eow = 0;
                    letters++;
                    break;
                default:
                    letters++;
                    eow = 1;
                    break;
            }
        }                /* while */
        words += eow;
        

        Use the brace style as shown below, with an indentation level of 4 spaces. Always use braces around the bodies of control structures, even if the body is only one line, as follows:

        if (foo == 5)
        {
            count +=7;
        }
        

        Expressions and Operators

        Use parentheses whenever there are more than one operators involved in an expression to make things clear. Spaces should surround binary operators (e.g., =, +, +=), but there should be no spaces between a unary operator and its operand.

        GCC 2.3 OPTIONS

        The following descriptions of options is taken from the GNU C Compiler 2.3 documentation (with some reformatting) [GCC]. All language and warning options are listed, except those that are for C++ code only.

        Options Controlling Dialect

        The following options control the dialect of C or C++ that the compiler accepts:

        1. -ansi

          Support all ANSI standard C programs.

          This turns off certain features of GNU C that are incompatible with ANSI C, such as the asm, inline and typeof keywords, and predefined macros such as unix and vax that identify the type of system you are using. It also enables the undesirable and rarely used ANSI trigraph feature, and disallows $ as part of identifiers.

          The alternate keywords __asm__, __extension__, __inline__ and __typeof__ continue to work despite -ansi. You would not want to use them in an ANSI C program, of course, but it useful to put them in header files that might be included in compilations done with -ansi. Alternate predefined macros such as __unix__ and __vax__ are also available, with or without -ansi.

          The -ansi option does not cause non-ANSI programs to be rejected gratuitously. For that, -pedantic is required in addition to -ansi.

          The macro __STRICT_ANSI__ is predefined when the -ansi option is used. Some header files may notice this macro and refrain from declaring certain functions or defining certain macros that the ANSI standard doesn't call for; this is to avoid interfering with any programs that might use these names for other things.

          The functions alloca, abort, exit, and _exit are not builtin functions when -ansi is used.

        2. -fno-asm

          Do not recognize asm, inline or typeof as a keyword. These words may then be used as identifiers. You can use __asm__, __inline__ and __typeof__ instead. -ansi implies -fno-asm.

        3. -fno-builtin

          Don't recognize built-in functions that do not begin with two leading underscores. Currently, the functions affected include _exit, abort, abs, alloca, cos, exit, fabs, labs, memcmp, memcpy, sin, sqrt, strcmp, strcpy, and strlen.

          The -ansi option prevents alloca and _exit from being builtin functions.

        4. -trigraphs

          Support ANSI C trigraphs. You don't want to know about this brain-damage. The -ansi option implies -trigraphs.

        5. -traditional

          Attempt to support some aspects of traditional C compilers. Specifically:

          1. All extern declarations take effect globally even if they are written inside of a function definition. This includes implicit declarations of functions.
          2. The keywords typeof, inline, signed, const and volatile are not recognized. (You can still use the alternative keywords such as __typeof__, __inline__, and so on.)
          3. Comparisons between pointers and integers are always allowed.
          4. Integer types unsigned short and unsigned char promote to unsigned int.
          5. Out-of-range floating point literals are not an error.
          6. String constants are not necessarily constant; they are stored in writable space, and identical looking constants are allocated separately. (This is the same as the effect of -fwritable-strings.)
          7. All automatic variables not declared register are preserved by longjmp. Ordinarily, GNU C follows ANSI C: automatic variables not declared volatile may be clobbered.
          8. In the preprocessor, comments convert to nothing at all, rather than to a space. This allows traditional token concatenation.
          9. In the preprocessor, macro arguments are recognized within string constants in a macro definition (and their values are stringified, though without additional quote marks, when they appear in such a context). The preprocessor always considers a string constant to end at a newline.
          10. The predefined macro __STDC__ is not defined when you use -traditional, but __GNUC__ is (since the GNU extensions which __GNUC__ indicates are not affected by -traditional). If you need to write header files that work differently depending on whether -traditional is in use, by testing both of these predefined macros you can distinguish four situations: GNU C, traditional GNU C, other ANSI C compilers, and other old C compilers.

            You may wish to use -fno-builtin as well as -traditional if your program uses names that are normally GNU C builtin functions for other purposes of its own.

        6. -traditional-cpp

          Attempt to support some aspects of traditional C preprocessors. This includes the last three items in the table immediately above, but none of the other effects of -traditional.

        7. -fcond-mismatch

          Allow conditional expressions with mismatched types in the second and third arguments. The value of such an expression is void.

        8. -funsigned-char

          Let the type char be unsigned, like unsigned char.

          Each kind of machine has a default for what char should be. It is either like unsigned char by default or like signed char by default.

          Ideally, a portable program should always use signed char or unsigned char when it depends on the signedness of an object. But many programs have been written to use plain char and expect it to be signed, or expect it to be unsigned, depending on the machines they were written for. This option, and its inverse, let you make such a program work with the opposite default.

          The type char is always a distinct type from each of signed char or unsigned char, even though its behavior is always just like one of those two.

        9. -fsigned-char

          Let the type char be signed, like signed char.

          Note that this is equivalent to -fno-unsigned-char, which is the negative form of -funsigned-char. Likewise, -fno-signed-char is equivalent to -funsigned-char.

        10. -fsigned-bitfields
        11. -funsigned-bitfields
        12. -fno-signed-bitfields
        13. -fno-unsigned-bitfields

          These 4 options control whether a bitfield is signed or unsigned, when the declaration does not use either signed or unsigned. By default, such a bitfield is signed, because this is consistent: the basic integer types such as int are signed types.

          However, when -traditional is used, bitfields are all unsigned no matter what.

        14. -fwritable-strings

          Store string constants in the writable data segment and don't uniquize them. This is for compatibility with old programs which assume they can write into string constants. -traditional also has this effect.

          Writing into string constants is a very bad idea; constants should be constant.

        Options to Request or Suppress Warnings

        Warnings are diagnostic messages that report constructions which are not inherently erroneous but which are risky or suggest there may have been an error.

        You can request many specific warnings with options beginning -W, for example -Wimplicit to request warnings on implicit declarations. Each of these specific warning options also has a negative form beginning -Wno- to turn off warnings; for example, -Wno-implicit. This manual lists only one of the two forms, whichever is not the default.

        These options control the amount and kinds of warnings produced by GNU CC:

        1. -fsyntax-only

          Check the code for syntax errors, but don't emit any output.

        2. -w \&

          Inhibit all warning messages.

        3. -Wno-import

          Inhibit warning messages about the use of #import.

        4. -pedantic

          Issue all the warnings demanded by strict ANSI standard C; reject all programs that use forbidden extensions.

          Valid ANSI standard C programs should compile properly with or without this option (though a rare few will require -ansi). However, without this option, certain GNU extensions and traditional C features are supported as well. With this option, they are rejected.

          -pedantic does not cause warning messages for use of the alternate keywords whose names begin and end with __. Pedantic warnings are also disabled in the expression that follows __extension__. However, only system header files should use these escape routes; application programs should avoid them.

          This option is not intended to be useful; it exists only to satisfy pedants who would otherwise claim that GNU CC fails to support the ANSI standard.

          Some users try to use -pedantic to check programs for strict ANSI C conformance. They soon find that it does not do quite what they want: it finds some non-ANSI practices, but not all--only those for which ANSI C requires a diagnostic.

          A feature to report any failure to conform to ANSI C might be useful in some instances, but would require considerable additional work and would be quite different from -pedantic. We recommend, rather, that users take advantage of the extensions of GNU C and disregard the limitations of other compilers. Aside from certain supercomputers and obsolete small machines, there is less and less reason ever to use any other C compiler other than for bootstrapping GNU CC.

        5. -pedantic-errors

          Like -pedantic, except that errors are produced rather than warnings.

        6. -W

          Print extra warning messages for these events:

          1. A nonvolatile automatic variable might be changed by a call to longjmp. These warnings as well are possible only in optimizing compilation.

            The compiler sees only the calls to setjmp. It cannot know where longjmp will be called; in fact, a signal handler could call it at any point in the code. As a result, you may get a warning even when there is in fact no problem because longjmp cannot in fact be called at the place which would cause a problem.

          2. A function can return either with or without a value. (Falling off the end of the function body is considered returning without a value.) For example, this function would evoke such a warning:
            foo (a)
            {
              if (a > 0)
                return a;
            }
            
          3. An expression-statement contains no side effects.
          4. An unsigned value is compared against zero with > or <=.
          5. A comparison like x<=y<=z appears; this is equivalent to (x<=y ? 1 : 0) <= z, which is a different interpretation from that of ordinary mathematical notation.
          6. Storage-class specifiers like static are not the first things in a declaration. According to the C Standard, this usage is obsolescent.
          7. An aggregate has a partly bracketed initializer. For example, the following code would evoke such a warning, because braces are missing around the initializer for x.h:
            struct s { int f, g; };
            struct t { struct s h; int i; };
            struct t x = { 1, 2, 3 };
            
        7. -Wimplicit

          Warn whenever a function or parameter is implicitly declared.

        8. -Wreturn-type

          Warn whenever a function is defined with a return-type that defaults to int. Also warn about any return statement with no return-value in a function whose return-type is not void.

        9. -Wunused

          Warn whenever a local variable is unused aside from its declaration, whenever a function is declared static but never defined, and whenever a statement computes a result that is explicitly not used.

          If you want to prevent a warning for a particular variable, you can use this macro:

          #define USE(var) \e
            static void * use_##var = (&use_##var, (void *) &var)
          
          USE (string);
          
        10. -Wswitch

          Warn whenever a switch statement has an index of enumeral type and lacks a case for one or more of the named codes of that enumeration. (The presence of a default label prevents this warning.) case labels outside the enumeration range also provoke warnings when this option is used.

        11. -Wcomment

          Warn whenever a comment-start sequence /* appears in a comment.

        12. -Wtrigraphs

          Warn if any trigraphs are encountered (assuming they are enabled).

        13. -Wformat

          Check calls to printf and scanf, etc., to make sure that the arguments supplied have types appropriate to the format string specified.

        14. -Wchar-subscripts

          Warn if an array subscript has type char. This is a common cause of error, as programmers often forget that this type is signed on some machines.

        15. -Wuninitialized

          An automatic variable is used without first being initialized.

          These warnings are possible only in optimizing compilation, because they require data flow information that is computed only when optimizing. If you don't specify -O, you simply won't get these warnings.

          These warnings occur only for variables that are candidates for register allocation. Therefore, they do not occur for a variable that is declared volatile, or whose address is taken, or whose size is other than 1, 2, 4 or 8 bytes. Also, they do not occur for structures, unions or arrays, even when they are in registers.

          Note that there may be no warning about a variable that is used only to compute a value that itself is never used, because such computations may be deleted by data flow analysis before the warnings are printed.

          These warnings are made optional because GNU CC is not smart enough to see all the reasons why the code might be correct despite appearing to have an error. Here is one example of how this can happen:

          {
            int x;
            switch (y)
              {
              case 1: x = 1;
                break;
              case 2: x = 4;
                break;
              case 3: x = 5;
              }
            foo (x);
          }
          

          If the value of y is always 1, 2 or 3, then x is always initialized, but GNU CC doesn't know this. Here is another common case:

          {
            int save_y;
            if (change_y) save_y = y, y = new_y;
            /* ... */
            if (change_y) y = save_y;
          }
          

          This has no bug because save_y is used only if it is set.

          Some spurious warnings can be avoided if you declare as volatile all the functions you use that never return.

        16. -Wparentheses

          Warn if parentheses are omitted in certain contexts.

        17. -Wall \&

          All of the above -W options combined. These are all the options which pertain to usage that we recommend avoiding and that we believe is easy to avoid, even in conjunction with macros.

        The remaining -W... options are not implied by -Wall because they warn about constructions that we consider reasonable to use, on occasion, in clean programs.

        1. -Wtraditional

          Warn about certain constructs that behave differently in traditional and ANSI C.

          1. Macro arguments occurring within string constants in the macro body. These would substitute the argument in traditional C, but are part of the constant in ANSI C.
          2. A function declared external in one block and then used after the end of the block.
          3. A switch statement has an operand of type long.
        2. -Wshadow

          Warn whenever a local variable shadows another local variable.

        3. -Wid-clash-LEN

          Warn whenever two distinct identifiers match in the first LEN characters. This may help you prepare a program that will compile with certain obsolete, brain-damaged compilers.

        4. -Wpointer-arith

          Warn about anything that depends on the size of a function type or of void. GNU C assigns these types a size of 1, for convenience in calculations with void * pointers and pointers to functions.

        5. -Wcast-qual

          Warn whenever a pointer is cast so as to remove a type qualifier from the target type. For example, warn if a const char * is cast to an ordinary char *.

        6. -Wcast-align

          Warn whenever a pointer is cast such that the required alignment of the target is increased. For example, warn if a char * is cast to an int * on machines where integers can only be accessed at two- or four-byte boundaries.

        7. -Wwrite-strings

          Give string constants the type const char[LENGTH] so that copying the address of one into a non-const char * pointer will get a warning. These warnings will help you find at compile time code that can try to write into a string constant, but only if you have been very careful about using const in declarations and prototypes. Otherwise, it will just be a nuisance; this is why we did not make -Wall request these warnings.

        8. -Wconversion

          Warn if a prototype causes a type conversion that is different from what would happen to the same argument in the absence of a prototype. This includes conversions of fixed point to floating and vice versa, and conversions changing the width or signedness of a fixed point argument except when the same as the default promotion.

        9. -Waggregate-return

          Warn if any functions that return structures or unions are defined or called. (In languages where you can return an array, this also elicits a warning.)

        10. -Wstrict-prototypes

          Warn if a function is declared or defined without specifying the argument types. (An old-style function definition is permitted without a warning if preceded by a declaration which specifies the argument types.)

        11. -Wmissing-prototypes

          Warn if a global function is defined without a previous prototype declaration. This warning is issued even if the definition itself provides a prototype. The aim is to detect global functions that fail to be declared in header files.

        12. -Wredundant-decls

          Warn if anything is declared more than once in the same scope, even in cases where multiple declaration is valid and changes nothing.

        13. -Wnested-externs

          Warn if an extern declaration is encountered within an function.

        14. -Winline

          Warn if a function can not be inlined, and either it was declared as inline, or else the -finline-functions option was given.

        15. -Werror

          Make all warnings into errors.

        dce.h

        /*
         *  @OSF_COPYRIGHT@
         */
        
        #if !defined(_DCE_H)
        #define _DCE_H
        
        /*
         * Common definitions for DCE
         * This is a machine specific file that must be ported to each
         * platform.
         */
        
        /*
         * Define the endianess of the platform, either BIG_ENDIAN or
         * LITTLE_ENDIAN.
         * Definitions for byte order, by byte significance from low address
         * to high.
         *   #define LITTLE_ENDIAN   1234   least-significant byte first
         *   #define BIG_ENDIAN      4321   most-significant byte first
         */
        #define LITTLE_ENDIAN
        
        /* Only one place needed for DCE to define these */
        #define FALSE 0
        #define TRUE 1
        
        #if !defined(MIN)
        #  define MIN(x, y)         ((x) < (y) ? (x) : (y))
        #endif
        
        #if !defined(MAX)
        #  define MAX(x, y)         ((x) > (y) ? (x) : (y))
        #endif
        
        /*
         * Machine dependent typedefs for boolean, byte, and (un)signed
         * integers.
         * All DCE code should be using these typedefs where applicable.
         * The following are defined in nbase.h:
         *     unsigned8       unsigned  8 bit integer
         *     unsigned16      unsigned 16 bit integer
         *     unsigned32      unsigned 32 bit integer
         *     signed8           signed  8 bit integer
         *     signed16          signed 16 bit integer
         *     signed32          signed 32 bit integer
         * Define the following from idl types in idlbase.h (which is
         * included by nbase.h:
         *     byte            unsigned  8 bits
         *     boolean         unsigned  8 bits
         * Define (un)signed64 to be used with the U64* macros
         */
        #include <dce/nbase.h>
        typedef idl_byte        byte;
        typedef idl_boolean     boolean;
        typedef struct unsigned64_s_t {
            unsigned long hi;
            unsigned long lo;
        } unsigned64;
        
        typedef struct signed64_s_t {
            unsigned long hi;
            unsigned long lo;
        } signed64;
        
        /*
         * The following allows for the support of both old and new style
         * function definitions and prototypes.  All DCE code is required to
         * be ANSI C compliant and to use prototypes.  For those components
         * that wish to support old-style definitions, the following macros
         * must be used.
         *
         *  Declare a prototype like this (don't use variables):
         *      int foo _DCE_PROTOTYPE_((int, void *, struct bar *))
         *
         *  Define a function like this:
         *      int foo
         *      #if defined(_DCE_PROTO_)
         *              (
         *              int a,
         *              void *b,
         *              struct bar *c
         *              )
         *      #else
         *              (a, b, c)
         *              int a;
         *              void *b;
         *              struct bar *c;
         *      #endif
         */
        #if defined(__STDC__)                   /* other conditionals
                                                   can be tested */
        #  define _DCE_PROTO_
        #endif                                  /* defined(__STDC__) */
        
        #if defined(_DCE_PROTO_)
        #  define _DCE_PROTOTYPE_(arg) arg
        #else                                   /* defined(_DCE_PROTO_) */
        #  define _DCE_PROTOTYPE_(arg) ()
        #endif                                  /* defined(_DCE_PROTO_) */
        
        /*
         * For those components wishing to support platforms where void
         * pointers are not available, they can use the following typedef for
         * a generic pointer type.  If they are supporting such platforms
         * they must use this.
         */
        #if defined(__STDC__)
        #  define _DCE_VOID_
        #endif                                  /* defined(__STDC__) */
        
        #if defined(_DCE_VOID_)
          typedef void * pointer_t;
        #else                                   /* defined(_DCE_VOID_) */
          typedef char * pointer_t;
        #endif                                  /* defined(_DCE_VOID_) */
        
        /*
         * Here is a macro that can be used to support token concatenation in
         * an ANSI and non-ANSI environment.  Support of non-ANSI
         * environments is not required, but where done, this macro must be
         * used.
         */
        #if defined(__STDC__)
        #  define _DCE_TOKENCONCAT_
        #endif
        
        #if defined(_DCE_TOKENCONCAT_)
        #  define DCE_CONCAT(a, b)      a ## b
        #else                                /* defined(_DCE_TOKENCONCAT_) */
        #  define DCE_CONCAT(a, b)      a/**/b
        #endif                               /* defined(_DCE_TOKENCONCAT_) */
        
        /*
         * Define the dcelocal and dceshared directories
         */
        extern const char *dcelocal_path;
        extern const char *dceshared_path;
        
        /* If DCE_DEBUG is defined then debugging code is activated. */
        #define DCE_DEBUG
        
        /*
         * Serviceability and perhaps other DCE-wide include files
         * will be included here.  This is a sample only.
         */
        #include <dce/dce_svc.h>
        
        /* from the editline package */
        char *readline(char *);
        void add_history(char *);
        
        #endif                                  /* _DCE_H */
        

        ANSI C LIBRARY FUNCTIONS

        This appendix is included for reference purposes. It lists all routines (functions or macros) defined by [ANSI C]. The routines are grouped by the header file that declares the prototype, thus all math functions are grouped together, as are all string functions. Prototypes are given with variable names for documentation purposes.

        assert.h

        
        

        1. \*(xBvoid assert(int expression);\*(xE

        ctype.h

        1. \*(xBint isalnum(int c);\*(xE
        2. \*(xBint isalpha(int c);\*(xE
        3. \*(xBint iscntrl(int c);\*(xE
        4. \*(xBint isdigit(int c);\*(xE
        5. \*(xBint isgraph(int c);\*(xE
        6. \*(xBint islower(int c);\*(xE
        7. \*(xBint isprint(int c);\*(xE
        8. \*(xBint ispunct(int c);\*(xE
        9. \*(xBint isspace(int c);\*(xE
        10. \*(xBint isupper(int c);\*(xE
        11. \*(xBint isxdigit(int c);\*(xE
        12. \*(xBint tolower(int c);\*(xE
        13. \*(xBint toupper(int c);\*(xE

        locale.h

        1. \*(xBstruct lconv * localeconv(void);\*(xE
        2. \*(xBchar * setlocale(int category, const char *locale);\*(xE

        math.h

        1. \*(xBdouble acos(double x);\*(xE
        2. \*(xBdouble asin(double x);\*(xE
        3. \*(xBdouble atan(double x);\*(xE
        4. \*(xBdouble atan2(double y,double x);\*(xE
        5. \*(xBdouble ceil(double x);\*(xE
        6. \*(xBdouble cos(double x);\*(xE
        7. \*(xBdouble cosh(double x);\*(xE
        8. \*(xBdouble exp(double x);\*(xE
        9. \*(xBdouble fabs(double x);\*(xE
        10. \*(xBdouble floor(double x);\*(xE
        11. \*(xBdouble fmod(double x, double y);\*(xE
        12. \*(xBdouble frexp(double value, int * exp);\*(xE
        13. \*(xBdouble ldexp(double x, int exp);\*(xE
        14. \*(xBdouble log(double x);\*(xE
        15. \*(xBdouble log10(double x);\*(xE
        16. \*(xBdouble modf(double value, double *iptr);\*(xE
        17. \*(xBdouble pow(double x, double y);\*(xE
        18. \*(xBdouble sin(double x);\*(xE
        19. \*(xBdouble sinh(double x);\*(xE
        20. \*(xBdouble sqrt(double x);\*(xE
        21. \*(xBdouble tan(double x);\*(xE
        22. \*(xBdouble tanh(double x);\*(xE

        setjmp.h

        1. \*(xBvoid longjmp(jmp_buf env, int val);\*(xE
        2. \*(xBint setjmp(jmp_buf env);\*(xE

        signal.h

        1. \*(xBint raise(int sig);\*(xE
        2. \*(xBvoid (*signal(int sig, void (*func)(int)))(int);\*(xE

        stdarg.h

        1. \*(xB<type> va_arg(va_list ap, <type>)\*(xE
        2. \*(xBvoid va_end(va_list);\*(xE
        3. \*(xBvoid va_start(va_list ap, parmN)\*(xE

        stdio.h

        1. \*(xBvoid clearerr(FILE *stream);\*(xE
        2. \*(xBint fclose(FILE *stream);\*(xE
        3. \*(xBint feof(FILE *stream);\*(xE
        4. \*(xBint ferror(FILE *stream);\*(xE
        5. \*(xBint fflush(FILE *stream);\*(xE
        6. \*(xBint fgetc(FILE *stream);\*(xE
        7. \*(xBint fgetpos(FILE *stream, fpos_t *pos);\*(xE
        8. \*(xBchar * fgets(char *s, int n, FILE *stream);\*(xE
        9. \*(xBFILE * fopen(const char *filename, const char \& *mode);\*(xE
        10. \*(xBint fprintf(FILE *stream, const char *format, \& ...);\*(xE
        11. \*(xBint fputc(int c, FILE *stream);\*(xE
        12. \*(xBint fputs(const char *s, FILE *stream);\*(xE
        13. \*(xBsize_t fread(void *ptr, size_t size, size_t nmemb, \& FILE *stream);\*(xE
        14. \*(xBFILE * freopen(const char *filename, const char \& *mode, FILE *stream);\*(xE
        15. \*(xBint fscanf(FILE *stream, const char *format, \& ...));\*(xE
        16. \*(xBint fseek(FILE *stream, long offset, int whence);\*(xE
        17. \*(xBint fsetpos(FILE *stream, const fpos_t *pos);\*(xE
        18. \*(xBlong ftell(FILE *stream);\*(xE
        19. \*(xBsize_t fwrite(const void *ptr, size_t size, size_t \& nmemb, FILE *stream);\*(xE
        20. \*(xBint getc(FILE *stream);\*(xE
        21. \*(xBint getchar(void);\*(xE
        22. \*(xBchar * gets(char *s);\*(xE
        23. \*(xBvoid perror(const char *s);\*(xE
        24. \*(xBint printf(const char *format, ...);\*(xE
        25. \*(xBint putc(int c, FILE *stream);\*(xE
        26. \*(xBint putchar(int c);\*(xE
        27. \*(xBint puts(const char *s);\*(xE
        28. \*(xBint remove(const char *filename);\*(xE
        29. \*(xBint rename(const char *old, const char *new);\*(xE
        30. \*(xBvoid rewind(FILE *stream);\*(xE
        31. \*(xBint scanf(const char *format, ...);\*(xE
        32. \*(xBvoid setbuf(FILE *stream, char *buf);\*(xE
        33. \*(xBint setvbuf(FILE *stream, char *buf, int mode, \& size_t size);\*(xE
        34. \*(xBint sprintf(char *s, const char *format, ...);\*(xE
        35. \*(xBint sscanf(const char *s, const char *format, \& ...);\*(xE
        36. \*(xBint ungetc(int c, FILE *stream);\*(xE
        37. \*(xBint vfprintf(FILE *stream, const char *format, \& va_list arg);\*(xS
        38. \*(xBint vprintf(const char *format, va_list arg);\*(xE
        39. \*(xBint vsprintf(char *s, const char *format, \& va_list arg));\*(xE
        40. \*(xBFILE * tmpfile(void);\*(xE
        41. \*(xBchar * tmpnam(char *s);\*(xE

        stdlib.h

        1. \*(xBvoid abort(void);\*(xE
        2. \*(xBint abs(int j);\*(xE
        3. \*(xBint atexit(void (*func)(void));\*(xE
        4. \*(xBdouble atof(const char *nptr);\*(xE
        5. \*(xBint atoi(const char *nptr);\*(xE
        6. \*(xBlong int atol(const char *nptr);\*(xE
        7. \*(xBvoid * bsearch(const void *key, const void *base, \& size_t nmemb, size_t size, \& int (*compar)(const void *, const \& void *));\*(xE
        8. \*(xBvoid * calloc(size_t nmemb, size_t size);\*(xE
        9. \*(xBdiv_t div(int numer, int denon);\*(xE
        10. \*(xBvoid exit(int status);\*(xE
        11. \*(xBvoid free(void *ptr);\*(xE
        12. \*(xBchar * getenv(const char *name);\*(xE
        13. \*(xBlong int labs(long int j);\*(xE
        14. \*(xBldiv_t ldiv(long int numer, long int denom);\*(xE
        15. \*(xBvoid * malloc(size_t size);\*(xE
        16. \*(xBint mblen(const char *s, size_t n);\*(xE
        17. \*(xBint mbtowc(wchar_t *pwc, const char *s, size_t \& n);\*(xE
        18. \*(xBsize_t mbstowcs(wchar_t *pwcs, const char *s, size_t \& n);\*(xE
        19. \*(xBvoid qsort(void *base, size_t nmemb, size_t size, \& int (*compar)(const void *, const void \& *));\*(xE
        20. \*(xBint rand(void);\*(xE
        21. \*(xBvoid * realloc(void *ptr, size_t size);\*(xE
        22. \*(xBvoid srand(unsigned int seed);\*(xE
        23. \*(xBdouble strtod(const char *nptr, char **endptr);\*(xE
        24. \*(xBlong int strtol(const char *nptr, char **endptr, int \& base);\*(xE
        25. \*(xBunsigned long int strtoul(const char *nptr, char **endptr, int \& base);\*(xE
        26. \*(xBint system(const char *string);\*(xE
        27. \*(xBsize_t wcstombs(char *s, const wchar_t *pwcs, size_t \& n);\*(xE
        28. \*(xBint wctomb(char *s, const wchar_t wchar);\*(xE

        string.h

        1. \*(xBvoid * memchr(const void *s, int c, size_t n);\*(xE
        2. \*(xBint memcmp(const void *s1, const void *s2, size_t \& n);\*(xE
        3. \*(xBvoid * memcpy(void *s1, const void *s2, size_t n);\*(xE
        4. \*(xBvoid * memmove(void *s1, const void *s2, size_t n);\*(xE
        5. \*(xBvoid * memset(void *s, int c, size_t n);\*(xE
        6. \*(xBchar * strcat(char *s1, const char *s2);\*(xE
        7. \*(xBchar * strchr(const char *s, int c);\*(xE
        8. \*(xBint strcmp(const char *s1, const char *s2);\*(xE
        9. \*(xBint strcoll(const char *s1, const char *s2);\*(xE
        10. \*(xBchar * strcpy(char *s1, const char *s2);\*(xE
        11. \*(xBsize_t strcspn(const char *s1, const char *s2);\*(xE
        12. \*(xBchar * strerror(int errnum);\*(xE
        13. \*(xBsize_t strlen(const char *s);\*(xE
        14. \*(xBchar * strncat(char *s1, const char *s2, size_t n);\*(xE
        15. \*(xBint strncmp(const char *s1,const char *s2, size_t \& n);\*(xE
        16. \*(xBchar * strncpy(char *s1, const char *s2, size_t n);\*(xE
        17. \*(xBchar * strpbrk(const char *s1, const char *s2);\*(xE
        18. \*(xBchar * strrchr(const char *s, int c);\*(xE
        19. \*(xBsize_t strspn(const char *s1, const char *s2);\*(xE
        20. \*(xBchar * strstr(const char *s1, const char *s2);\*(xE
        21. \*(xBchar * strtok(char *s1, const char *s2);\*(xE
        22. \*(xBsize_t strxfrm(char *s1, const char *s2, size_t n);\*(xE

        time.h

        1. \*(xBchar * asctime(const struct tm *timeptr);\*(xE
        2. \*(xBclock_t clock(void);\*(xE
        3. \*(xBchar * ctime(const time_t *timer);\*(xE
        4. \*(xBdouble difftime(time_t time1, time_t time0);\*(xE
        5. \*(xBstruct tm * gmtime(const time_t *timer);\*(xE
        6. \*(xBstruct tm * localtime(const time_t *timer);\*(xE
        7. \*(xBtime_t mktime(struct tm *timeptr);\*(xE
        8. \*(xBsize_t strftime(char *s, size_t maxsize, \& const char *format, \& const struct tm *timeptr);\*(xE
        9. \*(xBtime_t time(time_t *timer);\*(xE

        POSIX.1 LIBRARY FUNCTIONS

        This appendix is included for reference purposes. It lists all routines (functions or macros) defined by [POSIX.1] which are not defined in [ANSI C]. The routines are grouped by the header file that declares the prototype. Prototypes are given with variable names for documentation purposes.

        dirent.h

        1. \*(xBint closedir(DIR *dirp);\*(xE
        2. \*(xBDIR * opendir(const char *dirname);\*(xE
        3. \*(xBstruct dirent * readdir(DIR *dirp);\*(xE
        4. \*(xBvoid rewinddir(DIR *dirp);\*(xE

        fcntl.h

        1. \*(xBint creat(const char *path, mode_t mode);\*(xE
        2. \*(xBint fcntl(int fildes, int cmd, ...);\*(xE
        3. \*(xBint open(const char *path, int oflag, ...);\*(xE

        grp.h

        1. \*(xBstruct group * getgrgid(gid_t gid);\*(xE
        2. \*(xBstruct group * getgrnam(const char *name);\*(xE

        pwd.h

        1. \*(xBstruct passwd * getpwnam(const char *name);\*(xE
        2. \*(xBstruct passwd * getpwuid(uid_t uid);\*(xE

        setjmp.h

        1. \*(xBvoid siglongjmp(sigjmp_buf env, int val);\*(xE
        2. \*(xBint sigsetjmp(sigjmp_buf env, int savemask);\*(xE

        signal.h

        1. \*(xBint kill(pid_t pid, int sig);\*(xE
        2. \*(xBint sigaction(int sig, const struct sigaction \& *act, struct sigaction *oact);\*(x
        3. \*(xBint sigaddset(sigset_t *set, int signo);\*(xE
        4. \*(xBint sigdelset(sigset_t *set, int signo);\*(xE
        5. \*(xBint sigemptyset(sigset_t *set);\*(xE
        6. \*(xBint sigfillset(sigset_t *set);\*(xE
        7. \*(xBint sigismember(const sigset_t *set, int signo);\*(xE
        8. \*(xBint sigpending(sigset_t *set);\*(xE
        9. \*(xBint sigprocmask(int how, const sigset_t *set, \& sigset_t *oset);\*(x
        10. \*(xBint sigsuspend(const sigset_t *sigmask);\*(xE

        stdio.h

        1. \*(xBchar * ctermid(char *s);\*(xE
        2. \*(xBFILE * fdopen(int fildes, const char *type);\*(xE
        3. \*(xBint fileno(FILE *stream);\*(xE

        sys/stat.h

        1. \*(xBint chmod(const char *path, mode_t mode);\*(xE
        2. \*(xBint fstat(int fildes, struct stat *buf);\*(xE
        3. \*(xBint mkdir(const char *path, mode_t mode);\*(xE
        4. \*(xBint mkfifo(const char *path, code_t mode);\*(xE
        5. \*(xBint stat(const char *path, struct stat *buf);\*(xE
        6. \*(xBmode_t umask(mode_t cmask);\*(xE

        sys/times.h

        1. \*(xBclock_t times(struct tms *buffer);\*(xE

        sys/utsname.h

        1. \*(xBint uname(struct utsname *name);\*(xE

        sys/wait.h

        1. \*(xBpid_t wait(int *stat_loc);\*(xE
        2. \*(xBpid_t waitpid(pid_t pid, int *stat_loc, int \& options);\*(xE

        termios.h

        1. \*(xBspeed_t cfgetispeed(const struct termios *termios_p);\*(xE
        2. \*(xBspeed_t cfgetospeed(const struct termios *termios_p);\*(xE
        3. \*(xBspeed_t cfsetispeed(struct termios *termios_p, \& speed_t speed);\*(xE
        4. \*(xBspeed_t cfsetospeed(struct termios *termios_p, \& speed_t speed);\*(xE
        5. \*(xBint tcdrain(int fildes);\*(xE
        6. \*(xBint tcflow(int fildes, int action);\*(xE
        7. \*(xBint tcflush(int fildes, int queue_selector);\*(xE
        8. \*(xBint tcgetattr(int fildes, struct termios \& *termios_p);\*(xE
        9. \*(xBint tcsendbreak(int fildes, int duration);\*(xE
        10. \*(xBint tcsetattr(int fildes, int opt_acts, \& const struct termios *termios_p);\*(xE

        time.h

        1. \*(xBvoid tzset(void);\*(xE

        utime.h

        1. \*(xBint utime(const char *path, \& const struct utimbuf *times);\*(xE

        unistd.h

        1. \*(xBvoid _exit(int status);\*(xE
        2. \*(xBint access(const char *path, int amode);\*(xE
        3. \*(xBunsigned int alarm(unsigned int seconds);\*(xE
        4. \*(xBint chdir(const char *path);\*(xE
        5. \*(xBint chown(const char *path, uid_t owner, gid_t \& group);\*(xE
        6. \*(xBint close(int fildes);\*(xE
        7. \*(xBchar * cuserid(char *);\*(xE
        8. \*(xBint dup2(int fildes, int fildes2);\*(xE
        9. \*(xBint dup(int fildes);\*(xE
        10. \*(xBint execl(const char *path, const char *arg, \& ...);\*(xE
        11. \*(xBint execle(const char *path, const char *arg, \& ...);\*(xE
        12. \*(xBint execlp(const char *file, const char *arg, \& ...);\*(xE
        13. \*(xBint execv(const char *path, char *const argv[]);\*(xE
        14. \*(xBint execve(const char *path, char *const argv[], \& char *const envp[]);\*(xE
        15. \*(xBint execvp(const char *file, char *const argv[]);\*(xE
        16. \*(xBpid_t fork(void);\*(xE
        17. \*(xBlong fpathconf(int fildes, int name);\*(xE
        18. \*(xBchar * getcwd(char *buf, size_t size);\*(xE
        19. \*(xBgid_t getegid(void);\*(xE
        20. \*(xBuid_t geteuid(void);\*(xE
        21. \*(xBgid_t getgid(void);\*(xE
        22. \*(xBint getgroups(int gidsetsize, gid_t grouplist[]);\*(xE
        23. \*(xBchar * getlogin(void);\*(xE
        24. \*(xBpid_t getpgrp(void);\*(xE
        25. \*(xBpid_t getpid(void);\*(xE
        26. \*(xBpid_t getppid(void);\*(xE
        27. \*(xBuid_t getuid(void);\*(xE
        28. \*(xBint isatty(int fildes);\*(xE
        29. \*(xBint link(const char *existing, const char *new);\*(xE
        30. \*(xBoff_t lseek(int fildes, off_t offset, int whence);\*(xE
        31. \*(xBlong pathconf(const char *path, int name);\*(xE
        32. \*(xBint pause(void);\*(xE
        33. \*(xBint pipe(int fildes[2]);\*(xE
        34. \*(xBssize_t read(int fildes, void *buf, size_t nbyte);\*(xE
        35. \*(xBint rmdir(const char *path);\*(xE
        36. \*(xBint setgid(gid_t gid);\*(xE
        37. \*(xBint setpgid(pid_t pid, pid_t pgid);\*(xE
        38. \*(xBpid_t setsid(void);\*(xE
        39. \*(xBint setuid(uid_t uid);\*(xE
        40. \*(xBunsigned int sleep(unsigned int seconds);\*(xE
        41. \*(xBlong sysconf(int name);\*(xE
        42. \*(xBpid_t tcgetpgrp(int fildes);\*(xE
        43. \*(xBint tcsetpgrp(int fildes, pid_t pgrp_id);\*(xE
        44. \*(xBchar * ttyname(int fildes);\*(xE
        45. \*(xBint unlink(const char *path);\*(xE
        46. \*(xBssize_t write(int fildes , const void *buf, size_t \& nbyte);\*(xE

        XPG4 LIBRARY FUNCTIONS

        This appendix is included for reference purposes. It lists all routines (functions or macros) defined by [XPG4] which are not defined in either [ANSI C] or [POSIX.1] and are not marked as TO BE WITHDRAWN from [XPG4]. The routines are grouped by the header file that declares the prototype, thus all math functions are grouped together, as are all string functions. Prototypes are given with variable names for documentation purposes.

        ctype.h

        
        
        1. \*(xBint _tolower(int c);\*(xE
        2. \*(xBint _toupper(int c);\*(xE
        3. \*(xBint isascii(int c);\*(xE
        4. \*(xBint toascii(int c);\*(xE

        dirent.h

        1. \*(xBvoid seekdir(DIR *dirp, long int loc);\*(xE
        2. \*(xBlong int telldir(DIR *dirp);\*(xE

        ftw.h

        1. \*(xBint ftw(const char *path, \& int (*fn)(const char *, const struct stat \& *, int), \& int ndirs);\*(xE

        iconv.h

        1. \*(xBsize_t iconv(iconv_t cd, char **inbuf, \& size_t *inbytesleft, char **outbuf, \& size_t *outbytesleft);\*(xE
        2. \*(xBint iconv_close(iconvt_t cd);\*(xE
        3. \*(xBiconv_t iconv_open(cont char *tocode, \& const char *fromcode);\*(xE

        math.h

        1. \*(xBdouble erf(double x);\*(xE
        2. \*(xBdouble erfc(double x);\*(xE
        3. \*(xBdouble gamma(double x);\*(xE
        4. \*(xBdouble hypot(double x, double y);\*(xE
        5. \*(xBdouble isnan(double x);\*(xE
        6. \*(xBdouble j0(double x);\*(xE
        7. \*(xBdouble j1(double x);\*(xE
        8. \*(xBdouble jn(int n, double x);\*(xE
        9. \*(xBdouble lgamma(double x);\*(xE
        10. \*(xBdouble y0(double x);\*(xE
        11. \*(xBdouble y1(double x);\*(xE
        12. \*(xBdouble yn(int n, double x);\*(xE

        monetary.h

        1. \*(xBssize_t strfmon(char *s, size_t maxsize, const char \& *format, ...);\*(xE

        nl_types.h.h

        1. \*(xBint catclose(nlcatd catd);\*(xE
        2. \*(xBint catgets(nlcatd catd, int set_id, int msg_id, \& const char *s);\*(xE
        3. \*(xBint catopen(const char *name, int oflag);\*(xE

        search.h

        1. \*(xBint hcreate(size_t nel);\*(xE
        2. \*(xBvoid hdestroy(void);\*(xE
        3. \*(xBENTRY * hsearch(ENTRY item, ACTION action);\*(xE
        4. \*(xBvoid * lfind(const void *key, const void *base, \& size_t *nelp, size_t width, \& int (*compar)(const void *, const void \& *));\*(xE
        5. \*(xBvoid * lsearch(const void *key, void *base, \& size_t *nelp, size_t width, \& int (*compar)(const void *, const \& void *));\*(xE
        6. \*(xBvoid * tdelete(const void *key, void **rootp, \& int (*compar)(const void *, const \& void *));\*(xE
        7. \*(xBvoid * tsearch(const void *key, void **rootp, \& int (*compar)(const void *, const \& void *));\*(xE
        8. \*(xBvoid twalk(const void *root, \& void (*action)(const void *, VISIT, \& const int));\*(xE

        stdio.h

        1. \*(xBint getw(FILE *stream);\*(xE
        2. \*(xBint putw(int w, FILE *stream);\*(xE
        3. \*(xBchar * tempnam(const char *dir, const char *pfx);\*(xE

        stdlib.h

        1. \*(xBdouble drand48(void);\*(xE
        2. \*(xBdouble erand48(unsigned short int xsubi[3]);\*(xE
        3. \*(xBlong int jrand48(unsigned short int xsubi[3]);\*(xE
        4. \*(xBvoid lcong48(unsigned short int param[7]);\*(xE
        5. \*(xBlong int lrand48(void);\*(xE
        6. \*(xBlong int mrand48(void);\*(xE
        7. \*(xBlong int nrand48(unsigned short int xsubi[3]);\*(xE
        8. \*(xBint putenv(char *string);\*(xE
        9. \*(xBunsigned short * seed48(unsigned short int seed16v[3]);\*(xE
        10. \*(xBvoid setkey(const char *key);\*(xE
        11. \*(xBvoid srand48(long int seedval);\*(xE

        string.h

        1. \*(xBvoid * memccpy(void *s1, const void *s2, int c, \& size_t n);\*(xE

        sys/msg.h

        1. \*(xBint msgctl(int msqid, int cmd, struct msqid_ds \& *buf);\*(xE
        2. \*(xBint msgget(key_t key, int msgflg);\*(xE
        3. \*(xBint msgrcv(int msqid, void *msgp, size_t msgsz, \& long int msgtyp, int msgflg);\*(xE
        4. \*(xBint msgsnd(int msqid, void *msgp, size_t msgsz, \& int msgflg);\*(xE

        sys/sem.h

        1. \*(xBint semctl(int semid, int semnum, int cmd, ...);\*(xE
        2. \*(xBint semget(key_t key, int nsems, int semflg);\*(xE
        3. \*(xBint semop(int semid, struct sembuf *sops, \& unsigned int nsops);\*(xE

        sys/shm.h

        1. \*(xBvoid * shmat(int shmid, void *shmaddr, int shmflg);\*(xE
        2. \*(xBint shmctl(int shmid, int cmd, struct shmid_ds \& *buf);\*(xE
        3. \*(xBint shmdt(const void *shmaddr);\*(xE
        4. \*(xBint shmget(key_t key, size_t size, int shmflg);\*(xE

        time.h

        1. \*(xBchar * strptime(const char *buf, const char *format, \& struct tm *tm);\*(xE

        ulimit.h

        1. \*(xBlong int ulimit(int cmd, ...);\*(xE

        unistd.h

        1. \*(xBchar * crypt(const char *key, const char *salt);\*(xE
        2. \*(xBchar * encrypt(char block[64], int edflag);\*(xE
        3. \*(xBint fsync(int fildes);\*(xE
        4. \*(xBint nice(int incr);\*(xE
        5. \*(xBvoid swab(const void *src, void *des, size_t \& nbytes);\*(xE

        wchar.h

        1. \*(xBwchar_t * fgetws(wchar_t *, int, FILE *);\*(xE
        2. \*(xBwint_t fgetwc(FILE *stream);\*(xE
        3. \*(xBwint_t fputwc(wint_t c, FILE * stream);\*(xE
        4. \*(xBint fputws(const wchar_t *s, FILE *stream);\*(xE
        5. \*(xBwint_t getwc(FILE *stream);\*(xE
        6. \*(xBwint_t getwchar(void);\*(xE
        7. \*(xBwchar_t * getws(wchar_t *s);\*(xE
        8. \*(xBint iswalnum(wint_t wc);\*(xE
        9. \*(xBint iswalpha(wint_t wc);\*(xE
        10. \*(xBint iswcntrl(wint_t wc);\*(xE
        11. \*(xBint iswctype(wint_t wc, wctype_t prop);\*(xE
        12. \*(xBint iswdigit(wint_t wc);\*(xE
        13. \*(xBint iswgraph(wint_t wc);\*(xE
        14. \*(xBint iswlower(wint_t wc);\*(xE
        15. \*(xBint iswprint(wint_t wc);\*(xE
        16. \*(xBint iswpunct(wint_t wc);\*(xE
        17. \*(xBint iswspace(wint_t wc);\*(xE
        18. \*(xBint iswupper(wint_t wc);\*(xE
        19. \*(xBint iswxdigit(wint_t wc);\*(xE
        20. \*(xBwint_t putwc(wint_t c, FILE *stream);\*(xE
        21. \*(xBwint_t putwchar(wint_t c);\*(xE
        22. \*(xBint putws(const wchar_t *s);\*(xE
        23. \*(xBwint_t towlower(wint_t wc);\*(xE
        24. \*(xBwint_t towupper(wint_t wc);\*(xE
        25. \*(xBwint_t ungetwc(wint_t c, FILE * stream);\*(xE
        26. \*(xBwchar_t * wcscat(wchar_t *ws1, const wchar_t *ws2);\*(xE
        27. \*(xBwchar_t * wcschr(const wchar_t *ws, wchar_t wc);\*(xE
        28. \*(xBint wcscmp(const wchar_t *ws1, const wchar_t \& *ws2);\*(xE
        29. \*(xBint wcscoll(const wchar_t *ws1, const wchar_t \& *ws2);\*(xE
        30. \*(xBwchar_t * wcscpy(wchar_t *ws1, const wchar_t *ws2);\*(xE
        31. \*(xBsize_t wcscspn(const wchar_t *ws1, const wchar_t \& *ws2);\*(xE
        32. \*(xBsize_t wcsftime(wchar_t *wcs, size_t maxsize, \& const char *fmt, const struct tm \& *timptr);\*(xE
        33. \*(xBsize_t wcslen(const wchar_t *wc);\*(xE
        34. \*(xBwchar_t * wcsncat(wchar_t *ws1, const wchar_t *ws2, \& size_t n);\*(xE
        35. \*(xBint wcsncmp(const wchar_t *ws1, const wchar_t \& *ws2, size_t n);\*(xE
        36. \*(xBwchar_t * wcsncpy(wchar_t *ws1, const wchar_t *ws2, \& size_t n);\*(xE
        37. \*(xBwchar_t * wcspbrk(const wchar_t *ws1, const wchar_t \& *ws2);\*(xE
        38. \*(xBwchar_t * wcsrchr(const wchar_t *ws, wchar_t wc);\*(xE
        39. \*(xBsize_t wcsspn(const wchar_t *ws1, const wchar_t \& *ws2);\*(xE
        40. \*(xBdouble wcstod(const wchar_t *nptr, wchar_t \& **endptr);\*(xE
        41. \*(xBwchar_t * wcstok(wchar_t *ws1, const wchar_t *ws2);\*(xE
        42. \*(xBlong int wcstol(const wchar_t *nptr, wchar_t **endptr, \& int base);\*(xE
        43. \*(xBunsigned long int wcstoul(const wchar_t *nptr, wchar_t \& **endptr, int base);\*(xE
        44. \*(xBwchar_t * wcswcs(const wchar_t *ws1, const wchar_t \& *ws2);\*(xE
        45. \*(xBint wcswidth(const wchar_t *pwcs, size_t n);\*(xE
        46. \*(xBsize_t wcsxfrm(wchar_t *ws1, const wchar_t *ws2, \& size_t n);\*(xE
        47. \*(xBint wcwidth(const wchar_t wc);\*(xE
        48. \*(xBwctype_t wctype(const char *property);\*(xE

        ROUTINES WRAPPED BY DCE THREADS

        This appendix lists all the wrappers that DCE Threads provides and the header file in which they are defined. Wrappers need to be added to DCE Threads for any library routines called which are not in this list. Those wrappers marked with a * are only wrapped on an SVR4 platform. Some wrappers that are not marked are not on the SVR4 platform as they use reentrant libraries for thread-safety.

          * 1
          \*(xB_sleep [cma_ux.h]\*(xE
        1. \*(xBaccept [cma_ux.h]\*(xE
          * 1
          \*(xBatfork [cma_ux.h]\*(xE
        2. \*(xBcalloc [cmalib_crtlx.h]\*(xE
        3. \*(xBcatclose [cma_stdio.h]\*(xE
        4. \*(xBcatgets [cma_stdio.h]\*(xE
        5. \*(xBcatopen [cma_stdio.h]\*(xE
        6. \*(xBcfree [cmalib_crtlx.h]\*(xE
        7. \*(xBclose [cma_ux.h]\*(xE
        8. \*(xBconnect [cma_ux.h]\*(xE
        9. \*(xBcreat [cma_ux.h]\*(xE
        10. \*(xBctermid [cma_stdio.h]\*(xE
        11. \*(xBcuserid [cma_stdio.h]\*(xE
        12. \*(xBdup [cma_ux.h]\*(xE
        13. \*(xBdup2 [cma_ux.h]\*(xE
        14. \*(xBfclose [cma_stdio.h]\*(xE
        15. \*(xBfcntl [cma_ux.h]\*(xE
        16. \*(xBfdopen [cma_stdio.h]\*(xE
        17. \*(xBfflush [cma_stdio.h]\*(xE
        18. \*(xBfgetc [cma_stdio.h]\*(xE
        19. \*(xBfgets [cma_stdio.h]\*(xE
        20. \*(xBfopen [cma_stdio.h]\*(xE
        21. \*(xBfork [cma_ux.h]\*(xE
        22. \*(xBfprintf [cma_stdio.h]\*(xE
        23. \*(xBfputc [cma_stdio.h]\*(xE
        24. \*(xBfputs [cma_stdio.h]\*(xE
        25. \*(xBfread [cma_stdio.h]\*(xE
        26. \*(xBfree [cmalib_crtlx.h]\*(xE
        27. \*(xBfreopen [cma_stdio.h]\*(xE
        28. \*(xBfscanf [cma_stdio.h]\*(xE
        29. \*(xBfseek [cma_stdio.h]\*(xE
        30. \*(xBftell [cma_stdio.h]\*(xE
        31. \*(xBfwrite [cma_stdio.h]\*(xE
        32. \*(xBgetc [cma_stdio.h]\*(xE
        33. \*(xBgetchar [cma_stdio.h]\*(xE
        34. \*(xBgets [cma_stdio.h]\*(xE
        35. \*(xBgetw [cma_stdio.h]\*(xE
        36. \*(xBisatty [cma_stdio.h]\*(xE
        37. \*(xBmalloc [cmalib_crtlx.h]\*(xE
        38. \*(xBmktemp [cma_stdio.h]\*(xE
        39. \*(xBopen [cma_ux.h]\*(xE
        40. \*(xBpclose [cma_stdio.h]\*(xE
        41. \*(xBpipe [cma_ux.h]\*(xE
        42. \*(xBpopen [cma_stdio.h]\*(xE
        43. \*(xBprintf [cma_stdio.h]\*(xE
        44. \*(xBputc [cma_stdio.h]\*(xE
        45. \*(xBputchar [cma_stdio.h]\*(xE
        46. \*(xBputs [cma_stdio.h]\*(xE
        47. \*(xBputw [cma_stdio.h]\*(xE
        48. \*(xBread [cma_ux.h]\*(xE
        49. \*(xBreadv [cma_ux.h]\*(xE
        50. \*(xBrealloc [cmalib_crtlx.h]\*(xE
        51. \*(xBrecv [cma_ux.h]\*(xE
        52. \*(xBrecvfrom [cma_ux.h]\*(xE
        53. \*(xBrecvmsg [cma_ux.h]\*(xE
        54. \*(xBrewind [cma_stdio.h]\*(xE
        55. \*(xBscanf [cma_stdio.h]\*(xE
        56. \*(xBselect [cma_ux.h]\*(xE
        57. \*(xBsend [cma_ux.h]\*(xE
        58. \*(xBsendmsg [cma_ux.h]\*(xE
        59. \*(xBsendto [cma_ux.h]\*(xE
        60. \*(xBsetbuf [cma_stdio.h]\*(xE
        61. \*(xBsetbuffer [cma_stdio.h]\*(xE
        62. \*(xBsetlinebuf [cma_stdio.h]\*(xE
        63. \*(xBsetvbuf [cma_stdio.h]\*(xE
        64. \*(xBsigaction [cma_px.h]\*(xE
        65. \*(xBsigwait [cma_sigwait.h]\*(xE
          * 1
          \*(xBsleep [cma_ux.h]\*(xE
        66. \*(xBsocket [cma_ux.h]\*(xE
        67. \*(xBsocketpair [cma_ux.h]\*(xE
        68. \*(xBsprintf [cma_stdio.h]\*(xE
        69. \*(xBsscanf [cma_stdio.h]\*(xE
        70. \*(xBsystem [cma_stdio.h]\*(xE
        71. \*(xBtempnam [cma_stdio.h]\*(xE
        72. \*(xBtmpfile [cma_stdio.h]\*(xE
        73. \*(xBtmpnam [cma_stdio.h]\*(xE
        74. \*(xBttyname [cma_stdio.h]\*(xE
        75. \*(xBttyslot [cma_stdio.h]\*(xE
        76. \*(xBvfprintf [cma_stdio.h]\*(xE
        77. \*(xBvprintf [cma_stdio.h]\*(xE
        78. \*(xBvsprintf [cma_stdio.h]\*(xE
        79. \*(xBwrite [cma_ux.h]\*(xE
        80. \*(xBwritev [cma_ux.h]\*(xE

        STANDARD SYSTEM DEFINED CONSTANTS

        This appendix lists constants defined by [ANSI C], [POSIX.1], and [XPG4] that a programmer might wish to check for. It does not list all macros that are defined, but rather those that might be of interest. For example, the macros used to define flags to routines, signals, and error cases are not list here. However, those that define the maximum size of an unsigned int and the number of bits in a char are.

        limits.h

        Numerical limits

        1. CHAR_BIT Number of bits in a char
        2. CHAR_MAX Max value for a char
        3. CHAR_MIN Min value for a char
        4. INT_MAX Max value for an int
        5. INT_MIN Min value for an int
        6. LONG_BIT Number of bits in a long int
        7. LONG_MAX Max value for a long int
        8. LONG_MIN Min value for a long int
        9. MB_LEN_MAX Max number of bytes in a multibyte \& character, for any supported locale
        10. SCHAR_MAX Max value for a signed char
        11. SCHAR_MIN Min value for a signed char
        12. SHRT_MAX Max value for a short int
        13. SHRT_MIN Min value for a short int
        14. UCHAR_MAX Max value for an unsigned char
        15. UINT_MAX Max value for an unsigned int
        16. ULONG_MAX Max value for an unsigned long int
        17. USHRT_MAX Max value for an unsigned short int
        18. WORD_BIT Number of bits in a word or int

        Run-time invariant values

        1. ARG_MAX Max length of arg to exec (including \& env data)
        2. CHILD_MAX Max number of simultaneous processes per \& real uid
        3. OPEN_MAX Max number of files that a process can \& have open
        4. STREAM_MAX Max number of streams that a process can \& have open
        5. TZNAME_MAX Max number of bytes supported for name of \& a time zone

        Pathname variable values

        1. LINK_MAX Max number of links to a single file
        2. MAX_CANON Max number of types in a terminal \& canonical input file
        3. MAX_INPUT Min number of bytes available in a \& terminal input queue
        4. NAME_MAX Max number of types in a filename (not \& including the null)
        5. PATH_MAX Max number of bytesin a pathname \& (including the null)
        6. PIPE_BUF Max number bytes that is guaranteed to be \& atomic when writing to a pipe

        Other invariant values

        1. CHARCLASS_NAME_MAX Max number of bytes in a character class \& name
        2. NL_ARGMAX Max value of digits in calls to printf \& and scanf
        3. NL_LANGMAX Max number of types in a LANG name
        4. NL_MSGMAX Max message number
        5. NL_NMAX Max number of bytes in an N-to-1 \& collation mapping
        6. NL_SETMAX Max set number
        7. NL_TEXTMAX Max number of bytes in a message string
        8. NZERO Default process priority

        float.h

        1. DBL_EPSILON 1ulp when exponent = 0
        2. DBL_MANT_DIG Number of base-FLT_RADIX digits in the \& floating-point significand
        3. DBL_MAX_10_EXP Largest base 10 exponent of NORMALIZED \& double
        4. DBL_MAX_EXP Exponent of largest NORMALIZED double
        5. DBL_MIN_10_EXP Min base 10 exponent of NORMALIZED \& double
        6. DBL_MIN_EXP Exponent of smallest NORMALIZED double
        7. FLT_EPSILON 1ulp when exponent = 0
        8. FLT_MANT_DIG Number of base-FLT_RADIX digits in the \& floating-point significand
        9. FLT_MAX_10_EXP Largest base 10 exponent of NORMALIZED \& float
        10. FLT_MAX_EXP Exponent of largest NORMALIZED float
        11. FLT_MIN_10_EXP Min base 10 exponent of NORMALIZED \& float
        12. FLT_MIN_EXP Exponent of smallest NORMALIZED float \& number
        13. FLT_RADIX Radix of exponent representation
        14. FLT_ROUNDS Macro that returns current rounding mode \& value
        15. LDBL_DIG Number of decimal digits of precision
        16. LDBL_EPSILON 1ulp when unbiased exponent = 0
        17. LDBL_MANT_DIG Number of base-FLT_RADIX digits in the \& floating-point significand
        18. LDBL_MAX Largest NORMALIZED long double
        19. LDBL_MAX_10_EXP Largest base 10 exponent of NORMALIZED \& long double
        20. LDBL_MAX_EXP Exponent of largest NORMALIZED long \& double
        21. LDBL_MIN Smallest NORMALIZED long double
        22. LDBL_MIN_10_EX Min base 10 exponent of NORMALIZED long \& double
        23. LDBL_MIN_EXP Exponent of smallest NORMALIZED long \& double

        stddef.h

        1. NULL An implementation defined null pointer \& constant

        math.h


        .ds pI \(*p

        .ds h1 \s-2\de\u\s+2

        .ds h2 \s-2\d2\u\s+2

        .ds h3 \s-2\d10\u\s+2

        .ds h4 \s-2\u\(12\d\s+2

        .ds h5 \s-2\u-\(12\d\s+2
        1. HUGE_VAL A positive double expression, not \& necessarily representable as a float
        2. MAXFLOAT Max non-infinite single-precision \& floating point number
        3. M_1_PI Value of 1/\*(pI
        4. M_2_PI Value of 2/\*(pI
        5. M_2_SQRTPI Value of 2 \(mu \*(pI\*(h5
        6. M_E Value of e
        7. M_LN10 Value of log\*(h1(10)
        8. M_LN2 Value of log\*(h1(2)
        9. M_LOG10E Value of log\*(h3(e)
        10. M_LOG2E Value of log\*(h2(e)
        11. M_PI Value of \*(pI
        12. M_PI_2 Value of \*(pI/2
        13. M_PI_4 Value of \*(pI/4
        14. M_SQRT1_2 Value of 2 \*(h5
        15. M_SQRT2 Value of 2 \*(h4

        stdio.h

        1. BUFSIZ The size of the buffer used by setbuf
        2. EOF Negative integral constant indicating \& end-of-file
        3. FILENAME_MAX Max number of char's in a filename
        4. FOPEN_MAX The min number of files that can be open \& simultaneously
        5. L_tmpnam Max number of char's in a filename \& generated by tmpnam
        6. TMP_MAX Min number of unique filenames generated \& by tmpnam

        stdlib.h

        1. EXIT_FAILURE Can be passed to exit to indicate \& failure
        2. EXIT_SUCCESS Can be passed to exit to indicate \& success
        3. MB_CUR_MAX Max number of bytes in a multi-byte \& character for the extended character set \& specified by the current locale, and \& whose value is never greater than \& MB_LEN_MAX
        4. RAND_MAX The max value returned by rand

        time.h

        1. CLOCKS_PER_SEC The number per second of the value \& returned by clock

        unistd.h

        1. STDIN_FILENO File number of stdin
        2. STDOUT_FILENO File number of stdout
        3. STDERR_FILENO File number of stderr

        dce/assert.h

        /*
         *  @OSF_COPYRIGHT@
         */
        
        /*
         *  The dce_assert() macro; like ANSI C's assert().
         */
        
        #if     defined(dce_assert)
        #undef dce_assert
        #endif  /* defined(dce_assert) */
        
        #if     defined(DCE_ASSERT)
        
        extern void dce___assert(
            struct dce_svc_handle_s_t *, const char *, const char *, int
        );
        
        #define dce_assert(h, EX) \e
                ((EX) ? ((void)0) \e
                      : dce___assert(h, # EX, __FILE__, __LINE__))
        
        #else
        
        #define dce_assert(h, EX)       ((void)0)
        
        #endif  /* defined(DCE_ASSERT) */
        

        DCE ODE DOCUMENTATION

        This appendix describes ODE from a user's perspective. It does not provide full documentation on building backing tree or sandboxes or in using the ODE commands. It does provide detailed information on variables used in DCE Makefile's and some background information on ODE tree organization and the ODE system of passes to build a product.

        Overview of the Build Tree Layout

        ODE organizes the build tree into several main parts:

        1. src

          All source files reside here. Beneath this directory are subtrees for each component of DCE.

        2. obj

          An internal building area. All compiles are run here, and all object and executables are created here.

        3. export

          Another internal building area. All inter-component dependencies are resolved by exporting files (usually headers and libraries) here, and then having other components look here instead of in the src subtree of other components.

        4. install

          The final resting place of user-visible programs, libraries, headers, datafiles, tests, etc. The format of this tree mirrors the format of an installed DCE system (i.e., programs are found in a bin directory, etc.).

        5. tools

          A directory storing all tools needed during the build process. Both ODE tools (e.g., make) and DCE tools (e.g., idl, mavros, etc.) reside here.

        6. rc_files

          This directory contains files (known as rc_file's) used by ODE to control the environment of ODE commands. They describe sandbox and backing tree information.\*(f! See

          For an explanation of these terms see ODE documentation. [DUG] This section of this appendix will assume understanding of these terms.
          below for a short description of the rc_files and their syntax.

        The rc_files define the environment used by the ODE tools. In particular, these include workon, build, and sbinfo. This last one is used to display information on these environment variables. The workon creates a new shell with various ODE variables exported to the shell environment. The build command is a wrapper around make that ODE uses. All variables described in the rc_files are defined in the environment of ODE tools (e.g., build), only some are exported to the environment of the shell by the workon command.

        Each sandbox and backing tree contain two basic rc_files, they are: shared and local. The rc_files support an include command to include the contents of other rc_file's. The rc_file's are chained together using this command.

        All ODE commands that read the rc_file's do so by reading the local file in the sandbox. This file includes the shared file in the sandbox. The shared file includes the shared file in the backing tree (however many levels back there are, i.e., any shared sandboxes have their shared rc_file included as well).

        The rc_files contain the following types of commands (square brackets denote optional keywords):

        include filename
        [on machine_type] [replace] [setenv] variable value
        

        where:

        1. The include command includes the named file. It is similar to the #include command that the C preprocessor understands.
        2. If a command is prefaced with on machine_type, then that command is only run on machines of that type. The machine_type value is compiled into the ODE tools for each architecture. They are currently: pmax, rios, etc.
        3. The setenv keyword means that workon will set this variable in the environment of the new shell. If setenv is not included in the command, then the variable is only set in the environment of ODE commands (e.g., build).
        4. If the replace keyword is not given on a command line, then that variable is only set if it previously had no value. This applies to commands with or without the setenv keyword. If the replace keyword is given on a command line, then that variable is set regardless of any previous value.

        Overview of Build Passes and Makefiles

        ODE organizes the DCE build process into several passes. Passes have numbers (e.g., FIRST, FIRSTA, etc.) and tags (e.g., SETUP, EXPINC, EXPLIB, etc.) associated with them. The tags then have actions (e.g., export, build, comp, clobber, etc.) associated with them.

        1. setup

          This pass builds tools needed during the export pass. The primary example is idl, which is built during this pass so that headers generated by it can be exported during the export pass.

        2. export

          This pass builds headers (if necessary) and libraries needed by one component from another component. Most programs need headers and functions contained in libdce.a, these are built and placed the export tree during this pass.

        3. comp

          This pass builds all other programs and datafiles needed. Any libraries that are not exported are built during this pass as well.

        4. install

          This pass takes built programs libraries and datafiles and places them into the install tree.

        There are other passes defined as well. These allow lint and various tags creating programs (e.g., ctags or etags) to be run on the source files, as well as several cleanup passes that remove objects from the obj tree.

        ODE and DCE define several different types of makefiles that are meant, by convention, to contain different types of build information.

        1. common makefiles

          The common makefiles are all located in src/lbe/mk and are considered to be a part of ODE, although DCE uses its own version of them. All of their names are of the form osf.*.mk. They define the variables and rules that can be used in other makefiles. All the built in rules are defined in the common makefiles, and are accessible in other makefiles that include the common makefiles by using the line:

          \&.include <${RULES_MK}>
          
          This line always appears after all variable defines in the Makefile. These files are owned by the OSF RATs, DCE developers should have little reason to modify any of these files.
        2. Makefile's

          These are most analogous to standard Makefiles. They appear in each directory of the src tree, and make use of variables and rules defined in the common makefiles. DCE developers create and modify these as required during the development of a component.

        3. machdep.mk files

          These files are used to handle machine dependencies in the source code. Whenever a function is machine dependent, it is placed in a file in a target machine subdirectory. In the Makefile for the program which contains this function, there is a command to include this file from whichever target machine subdirectory is appropriate. It usually looks like:

          \&.if exists(${TARGET_MACHINE}/machdep.mk)
          \&.include "${TARGET_MACHINE}/machdep.mk
          \&.endif
          

          DCE developers create and modify these as required during the development of a component.

        4. src/Makeconf

          This file is used internally by ODE to locate the top of the src tree particularly in relationship to the other subtrees in the build tree (e.g., obj and export). DCE uses this file to define various platform-specific build variables that apply to all of DCE. DCE developers may have need to modify this file, however it is generally considered to be own by the OSF RATs.

        5. component \&.mk files

          These are makefiles that are located in the top-most directory of each component, and named with the name of the component followed by \&.mk (e.g., src/rpc/rpc.mk). They are found by the build process in the following manner. The common makefile osf.dce.mk determines what component make is being run in, and includes the appropriate component makefiles with a \&.include command.

          These are a creation of DCE (they are not a part of ODE) and were meant to capture all build dependencies that were machine specific for an entire component. The theory being that by editing this one file during a port, any build switches that needed to be changed or anything else, could be done in one place as opposed to several. This turned out not be true and added yet another file to look at to find out how a particular build line was generated. They must not be used for any new or existing code. Instead the information should be in the Makefile's and machdep.mk files.

        ODE Variables

        The following are the variables that can be defined in DCE Makefile's to control the build process. They are specified by category and by the passes in which they are used.

        1. Subdirectory Variables

          The following variables can be used in Makefiles to define subdirectories to visit during specified passes.

          1. SETUP_SUBDIRS

            This variable defines a list of subdirectories to visit during the setup pass. This pass is used to define tools that are needed during the export passes

          2. EXPINC_SUBDIRS

            This variable defines a list of subdirectories to visit during the export include file pass. This pass is used to place headers needed by other components into the export tree.

          3. EXPLIB_SUBDIRS

            This variable defines a list of subdirectories to visit during the export libraries pass. This pass is used to place libraries needed by other components into the export tree.

          4. EXPSHLIB_SUBDIRS

            This variable defines a list of subdirectories to visit during the export shared libraries pass. This pass is used to place shared libraries needed by other components into the export tree. Currently it is only used for libdce.so.

          5. SUBDIRS

            This variable defines a list of subdirectories to visit during all the other passes. Principally, this means the comp pass which is used to build programs and the install pass, but it is also used for the clean, rmtarget, clobber, lint, and tags passes as well.

        2. ODE Variables Used in the setup Pass

          These variables are used by ODE during the setup pass to determine various targets and dependencies. The goal of the setup pass is to build various tools needed during the export pass. Currently, this list of tools is: compile_et, idl, idl.cat, mavcod, mavros, msg, and prs. The built tools are placed in the tools subtree by default.

          To build the tools, run the setup pass by typing: build setup_all. Note that DEFTOOLBASE must be set in some way. It can be defined on the build command line, added to the local rc_file, or the -sb_rc can be used so that the setup rc_file is read instead of the local rc_file (this file includes local and then sets DEFTOOLBASE).

          1. SETUP_INCLUDES

            This variable defines a list of include

          2. SETUP_PROGRAMS

            This variable defines a list of programs to be built during the setup pass.

          3. SETUP_SCRIPTS

            This variable defines a list of scripts to be built during the setup pass.

          4. SETUP_OTHERS

            This variable defines a list of other things to be built during the setup pass.

          5. DEFTOOLBASE

            This variable defines the directory where tools built during the setup pass are placed, and where these tools are looked for during other passes. Note that the path assigned to this variable must begin and end with a /.

        3. ODE Variables Used in the export Passes

          These variables are used by ODE during the export pass to determine various targets and dependencies. The goal of the export pass is to place any dependency needed between components into the export tree.

          1. INCLUDES

            This variable defines a list of include files to be exported to the export tree.

          2. EXPLIB_TARGETS

            This variable defines a list of libraries to be built and exported to the export tree during the EXPLIB pass of the build. If this variable is not set, then all libraries listed in the variable LIBRARIES (see below) will be exported. If this variable is set, then only the libraries listed in this variable will be exported, regardless of the values of LIBRARIES.

            The value of this variable is a list of libraries; each library name must be preceded with export_. Any targets in the EXPLIB_TARGETS list that do not have the export_ prefix will be built, but not exported. Ensuring the prefix is present can be done in two ways: either by including it by hand, or by including just the library names without the export_ and then including a substitution command after the definition to add the prefix as follows:

            EXPLIB_TARGETS = liba.a libb.a libc.a
            EXPLIB_TARGETS = ${EXPLIB_TARGETS:S/^/export_/g}
            
          3. EXPSHLIB_TARGETS

            Same as EXPLIB_TARGETS above, but use SHARED_LIBRARIES, etc.

          4. EXPDIR

            This variable defines the directory into which include files and libraries will be exported. It is relative to the export/machine directory in the sandbox. Note that the path assigned to this variable must begin and end with a /.

          5. IDLFILES

            This variable defines a list of \&.idl files to run the idl compiler on. This is done during an export pass to generate \&.h files for the export tree.

          6. SAMSFILES

            This variable defines a list of \&.sams files to run the sams processor on.

          Some ODE documentation describes the variables EXPLINKS and EXPBIN. Do not use these as they are not supported by the DCE common makefiles.

        4. ODE Variables Used in the build Pass

          These variables are used by ODE during the build pass to determine various targets and dependencies. The build pass is when programs and non-exported libraries are built. It is the main build pass.

          1. LIBRARIES

            This variable defines a list of libraries which need to be compiled and archived. See the definition of EXPLIB_TARGETS for how to export libraries. If EXPLIB_TARGETS is not defined then all libraries listed here will be exported during the EXPLIB pass. Libraries have dependencies on objects defined in OFILES and headers defined in HFILES, both described below.

          2. SHARED_LIBRARIES

            This variable defines a list of shared libraries which need to be compiled and archived. See the definition of EXPSHLIB_TARGETS for how to export shared libraries. If EXPSHLIB_TARGETS is not defined then all libraries listed here will be exported during the EXPSHLIB pass. Shared libraries have dependencies on objects defined in OFILES and headers defined in HFILES, both described below.

            There are differences in building shared libraries on different platforms. The best place to find out more about these differences is Chapter 10 of the DCE Porting and Testing Guide for DCE 1.0.2.

          3. PROGRAMS

            This variable defines a list of programs to compile and link. Programs have dependencies on objects defined in OFILES and headers defined in HFILES, both described below.

          4. OBJECTS

            This variable defines a list of objects that need to be compiled. Do not use this to build programs, use this only for special cases where objects must be explicitly placed into the obj tree. Some Makefile's that build libdce use this.

          5. SCRIPTS

            This variable defines a list of shell scripts that get built. If this variable is defined then rules for files ending in \&.csh and \&.sh are created by including the common makefile osf.script.mk. In this case built means the following three things happening:

            1. Shell scripts are copied to the obj tree and are stripped of their extension. The elements of the SCRIPTS list must not have a \&.sh or \&.csh extension, however the corresponding files in the src tree must have one of the extensions. So the correct way to specify a script to the build is to have in the Makefile:
              SCRIPTS = foo
              
              which will result in make looking in the src tree for either foo.sh or foo.csh and then it will create a file called foo in the obj tree.
            2. All of the execution bits are set on the file created in the obj tree.
            3. Runs sed on the file to change all occurrences of @SOURCEWARNING@ into:
              THIS IS NOT A SOURCE FILE - DO NOT EDIT
              

              If the variable SED_OPTIONS is set then its value is passed to sed as well. A possible use of this variable is to strip all the comments out of scripts.

            Use this variable only if scripts need some processing before being installed. If the script in the src tree is what should be installed on a system, then use the ILIST, et al variables described below and not the SCRIPTS variable. Do not use SCRIPTS as a convenient name for a variable and then include it in some other variable list such as DATEFILES or ILIST; only use it for its intended purpose.

          6. DATAFILES

            This variable defines a list of files that get copied from the src tree to the obj tree, and keep the same name. Defining them with this variable creates a rule that make can use to check if the file in the obj tree is up-to-date. This need only be used for files that need to be in the obj tree during some later parts of the build (files can go directly from the src tree to the install tree), and which have the same name in the object tree as in the source tree.

            An example of the need for this variable is a tool that is compiled (so it is in the obj tree which does not have some equivalent of cpp's -I switch. In this case, ODE has no way to tell it about search paths in the src tree. Therefore, to use this tool, the file will have to be copied to the obj tree, but what if it is then updated in the src? If the file is just copied, make has no way knowing that the file changed. If however, it is defined with DATAFILES, then make can check if it is up-to-date, and copy it to the "obj" tree only when necessary.

          7. OTHERS

            This variable defines a list of targets to be built which do not fall into another categories. These targets are built by make but the common makefiles do not have any rules on how to build OTHERS. To build others, specific make rules will have to be specified in the Makefiles.

          8. OFILES

            This variable defines a list of object files that comprise a program or library. If there is only one program or library described in the Makefile, then just use this variable name, if there are more than one, then use the syntax target_OFILES, where target is the name of the program or library.

          9. HFILES

            This variable defines a list of header files on which a program or library depends. If there is only one program or library described in the Makefile, then just use this variable name, if there are more than one, then use the syntax target_HFILES, where target is the name of the program or library.

        5. ODE Variable Conventions,

          ODE has several conventions for its variable naming scheme. The suffix of variable names defines the manner in which the variable should be set.

          1. ARGS -- Variables to be set on the command line.
          2. ENV -- Variables to be set in the environment
          3. FLAGS -- Variables to be set in Makefile's
          4. DIRS -- Variables to be set in rc_files's

          For example, there are four variables used to generate the list of -I's to a compile line. They are INCARGS, INCENV, INCFLAGS, and INCDIRS.

        6. The ODE Flag Variables

          The following is a list of the variables that ODE uses to determine flags to set on various command lines. The flags given below should be set in Makefile's. Those that end with the suffix FLAGS follow the ODE variable naming conventions described above, and therefore have alternate forms to be set in different manners.

          1. CFLAGS (also ARGS and ENV)

            This variable defines a list of flags to pass to the C Compiler.

          2. INCFLAGS (also ARGS, ENV and DIRS)

            This variable defines a list of directories to be included in the C compiler invocation line with the -I switch. Each directory included on this list is used as an argument to genpath so that the equivalent directory in the sandbox and backing tree (and any intermediary shared sandboxes) are included in the compile line.

          3. LDFLAGS (also ARGS and ENV)

            This variable defines a list of flags to pass to the linker.

          4. LIBFLAGS (also ARGS, ENV and DIRS)

            This variable defines a list of directories to be included in the linker invocation line with the -L switch. The values in this list are of the form -Lpath where path is a relative path to the directory where the library should be found.

            Each directory included on this list is used as an argument to genpath so that the equivalent directory in the sandbox and backing tree (and any intermediary shared sandboxes) are included in the link line.

          5. IDLFLAGS (also ARGS and ENV)

            This variable defines a list of flags to pass to idl.

          6. IDLINCFLAGS (also ARGS and ENV)

            This variable defines a list of directories to be included in the idl compiler invocation line with the -I switch. The values in this list are of the form -Ipath where path is a relative path to the directory where the library should be found.

            Each directory included on this list is used as an argument to genpath so that the equivalent directory in the sandbox and backing tree (and any intermediary shared sandboxes) are included in the compile line.

          7. LFLAGS (also ARGS and ENV)

            This variable defines a list of flags to pass to lex.

          8. YFLAGS (also ARGS and ENV)

            This variable defines a list of flags to pass to yacc.

          9. OPT_LEVEL

            This variable is meant to define debugging and optimization switches. It is included in the both the compile and link invocation lines. To specify optimization for just one of these lines use the following variables:

            1. CC_OPT_LEVEL -- Used to specify optimization for just the compiler.
            2. LD_OPT_LEVEL -- Used to specify optimization for just the linker.
        7. Variables Used in the install Pass.

          These variables are used by ODE during the install pass to determine various targets and dependencies. The install pass populates the install tree with targets found in either the obj tree or the src tree. ODE will look first in the obj tree and then in the src tree to find targets.

          1. ILIST

            This variable defines a list of targets to place in the install tree.

          2. TOSTAGE

            This variable defines the base directory to install all target listed in ILIST. It is usually set by the rc_files and is set to include ${sandbox_base}.

          3. IDIR

            This variable defines the directory (relative to TOSTAGE) in which to install the targets listed in ILIST. Targets are installed in the directory ${TOSTAGE}/${IDIR}. Note that the path assigned to this variable is terminated with a /.

          4. IMODE

            This variable defines the permissions to set on installed targets.

          5. IGROUP

            This variable defines the group to set on installed targets.

          6. IOWNER

            This variable defines the owner to set on installed targets.

          REFERENCES

          [AES]
          Application Environment Specification -- Operating System Programming Interfaces Volume, Revision A, Open Software Foundation, 1989.
          [ANSI C]
          ANS X3.159-1989, Programming Language C (which is identical to ISO/IEC 9899:1990, Programming Languages -- C).
          [BSD]
          UNIX Programmer's Reference Manual 4.3 Berkeley Software Distribution (BSD), April 1986.
          [DUG]
          OSF Development Environment User's Guide, ODE Release 2.2, Open Software Foundation, January 1993.
          [GCC]
          R. M. Stallman, The GNU C Compiler.
          [K&R]
          B. W. Kernighan and D. M. Ritchie, The C Programming Language, 1st ed., Prentice Hall, 1986.
          [I18N]
          T. Ogura, DCE 1.1 I18N Workbook, DCE Document, October 1992.
          [PORTG]
          DCE Porting and Testing Guide, Open Software Foundation, 1992.
          [POSIX.1]
          ISO/IEC 9945-1:1990, Information technology -- Portable Operating System Interface (POSIX) -- Part 1: System Application Program Interface (API) [C Language] (which is identical to IEEE Std 1003.1-1990).
          [POSIX.2]
          ISO/IEC DIS 9945-2:1990, Information technology -- Portable Operating System Interface (POSIX) -- Part 2: Shells and Utilities (which is identical to IEEE Std 1003.2-Draft).
          [RFC 17.0]
          H. Melman, DCE-RFC 17.0, DCE Code Clean-Up Requirements, December 1992.
          [RFC 23.0]
          R. Mackey, DCE-RFC 23.0, DCE 1.1 Internationalization Guide, January 1993.
          [RFC 24.0]
          R. Salz, DCE-RFC 24.0, DCE 1.1 Serviceability Proposal, November 1992.
          [RFC 34.0]
          H. Melman, DCE 1.1 Coding Style Guide, April 1993.
          [RFC 34.1]
          H. Melman, DCE 1.1 Coding Style Guide, June 1993.
          [RFC 35.0]
          H. Melman, DCE-RFC 35.0, Location of DCE files, January 1993.
          [XPG4]
          X/Open Portability Guide Issue 4, Volume 2 -- 1992 XSI System Interface and Headers.

          AUTHOR'S ADDRESS

          Howard Melman Internet email: melman@osf.org
          Open Software Foundation Telephone: +1-617-621-8989
          11 Cambridge Center
          Cambridge, MA 02142
          USA