United States

Compaq C

# Compaq C
Run-Time Library Reference Manual for OpenVMS Systems

Previous | Contents | Index

# ctime, ctime_r

> Converts a time in seconds, since 00:00:00 January 1, 1970, to an ASCII string in the form generated by the `asctime` function.

## Format

> #include <time.h>

> char *ctime (const time_t *bintim);

> char *ctime_r (const time_t *bintim, char *buffer); (ISO POSIX-1)

Function Variants Compiling with the _DECC_V4_SOURCE and _VMS_V6_SOURCE feature-test macros defined enables a local-time-based entry point to this function that is equivalent to the behavior before OpenVMS Version 7.0.

## Argument

> ### bintim

> A pointer to a variable that specifies the time value (in seconds) to be converted.

> ### buffer

> A pointer to a character array that is at least 26 bytes long. This array is used to store the generated date-and-time string.

## Description

> The `ctime` and `ctime_r` functions convert the time pointed to by `bintim` into a 26-character string, and return a pointer to the string.

> The difference between the `ctime_r` and `ctime` functions is that the former puts its result into a user-specified buffer. The latter puts its result into thread-specific static memory allocated by the Compaq C RTL, which can be overwritten by subsequent calls to `ctime` or `asctime` ; you must make a copy if you want to save it.

> On success, `ctime` returns a pointer to the string; `ctime_r` returns its second argument. On failure, these functions return the NULL pointer.

> The type `time_t` is defined in the `<time.h>` header file as follows:

>     typedef long int time_t

> The `ctime` function behaves as if it called `tzset` .

> Note Generally speaking, UTC-based time functions can affect in-memory time-zone information, which is process-wide data. However, if the system time zone remains the same during the execution of the application (which is the common case) and the cache of timezone files is enabled (which is the default), then the `_r` variant of the time functions `asctime_r` , `ctime_r` , `gmtime_r` and `localtime_r` , is both thread-safe and AST-reentrant. If, however, the system time zone can change during the execution of the application or the cache of timezone files is not enabled, then both variants of the UTC-based time functions belong to the third class of functions, which are neither thread-safe nor AST-reentrant.

## Return Value

> x | A pointer to the 26-character ASCII string, if successful.
> NULL | Indicates failure.

# cuserid

> Returns a pointer to a character string containing the name of the user initiating the current process.

## Format

> #include <unistd.h> (X/OPEN, POSIX-1)

> #include <stdio.h> (X/OPEN)

> char *cuserid (char *str);

Function Variants This function also has variants named `_cuserid32` and `_cuserid64` for use with 32-bit and 64-bit pointer sizes, respectively. See Section 1.8 for more information on using pointer-size-specific functions.

## Argument

> ### str

> If this argument is NULL, the user name is stored internally. If the argument is not NULL, it points to a storage area of length `L_cuserid` (defined by the `<stdio.h>` header file), and the name is written into that storage. If the user name is a null string, the function returns NULL.

## Return Values

> pointer | Points to a string.
> NULL | If the user name is a null string.

# DECC$CRTL_INIT

> Allows you to call the Compaq C RTL from other languages or to use the Compaq C RTL when your main function is not in C. It initializes the run-time environment and establishes both an exit and condition handler. `VAXC$CRTL_INIT` is a synonym for `DECC$CRTL_INIT` . Either name invokes the same routine.

## Format

> #include <signal.h>

> void DECC$CRTL_INIT(void);

## Description

> The following example shows a Pascal program that calls the Compaq C RTL using the `DECC$CRTL_INIT` function:

>     $ PASCAL EXAMPLE1
>     $ LINK EXAMPLE1
>     $ TY EXAMPLE1.PAS
>     PROGRAM TESTC(input, output);
>     PROCEDURE DECC$CRTL_INIT; extern;
>     BEGIN
>        DECC$CRTL_INIT;
>     END

> A shareable image need only call this function if it contains a Compaq C function for signal handling, environment variables, I/O, exit handling, a default file protection mask, or if it is a child process that should inherit context.

> Although many of the initialization activities are performed only once, `DECC$CRTL_INIT` can safely be called multiple times. On OpenVMS VAX systems, `DECC$CRTL_INIT` establishes the Compaq C RTL internal OpenVMS exception handler in the frame of the routine that calls `DECC$CRTL_INIT` each time `DECC$CRTL_INIT` is called.

> At least one frame in the current call stack must have that handler established for OpenVMS exceptions to get mapped to UNIX signals.

# decc$fix_time

> Converts OpenVMS binary system times to UNIX binary times.

## Format

> #include <unixlib.h>

> unsigned int decc$fix_time (void *vms_time);

## Argument

> ### vms_time

> The address of a quadword containing an OpenVMS binary time:

>     unsigned int quadword[2];
>     unsigned int *vms_time = quadword;

## Description

> This routine converts an OpenVMS binary system time (a 64-bit quadword containing the number of 100-nanosecond ticks since 00:00 November 17, 1858) to a UNIX binary time (a longword containing the number of seconds since 00:00 January 1, 1970). This routine is useful for converting binary times returned by OpenVMS system services and RMS services to the format used by some Compaq C RTL routines, such as `ctime` and `localtime` .

## Return Values

> x | A longword containing the number of seconds since 00:00 January 1, 1970.
> ( `unsigned int` )(--1) | Indicates an error. Be aware, that a return value of ( `unsigned int` )(--1) can also represent a valid date of Sun Feb 7 06:28:15 2106.

## Example

>     #include <unixlib.h>
>     #include <stdio.h>
>     #include <starlet.h>    /* VMS Specific SYS$ routines)  */

>     main()
>     {
>        unsigned int current_vms_time[2];  /* quadword for OpenVMS time */
>        unsigned int number_of_seconds;    /* number of seconds     */

>        /* first get the current system time */
>        sys$gettim(&current_vms_time[0]);

>        /* fix the time */
>        number_of_seconds = decc$fix_time(&current_vms_time[0]);

>        printf("Number of seconds since 00:00 January 1, 1970 = %d",
>                number_of_seconds);
>     }

> This example shows how to use the `decc$fix_time` routine in Compaq C. It also shows the use of the SYS$GETTIM system service.

# decc$from_vms

> Converts OpenVMS file specifications to UNIX style file specifications.

## Format

> #include <unixlib.h>

> int decc$from_vms (const char *vms_filespec, int action_routine, int wild_flag);

## Arguments

> ### vms_filespec

> The address of a null-terminated string containing a name in OpenVMS file specification format.

> ### action_routine

> The address of a routine that takes as its only argument a null-terminated string containing the translation of the given OpenVMS file name to a valid UNIX style file name.

> If the action_routine returns a nonzero value (TRUE), file translation continues. If it returns a zero value (FALSE), no further file translation takes place.

> ### wild_flag

> Either 0 or 1, passed by value. If a 0 is specified, wildcards found in vms_filespec are not expanded. Otherwise, wildcards are expanded and each one is passed to action_routine. Only expanded file names that correspond to existing UNIX style files are included.

## Description

> This routine converts the given OpenVMS file specification into the equivalent UNIX style file specification. It allows you to specify OpenVMS wildcards, which are translated into a list of corresponding existing files in UNIX style file specification format.

## Return Value

> x | The number of file names that result from the specified OpenVMS file specification.

## Example

>     /* This example must be run as a foreign command        */
>     /* and be supplied with a VMS file specification        */

>     #include <unixlib.h>
>     #include <stdio.h>

>     int main(int argc, char *argv[])
>     {
>         int number_found;           /* number of files found */
>         int print_name();           /* name printer          */

>         printf("Translating: %s\n", argv[1]);
>         number_found = decc$from_vms(argv[1], print_name, 1);
>         printf("\n%d files found", number_found);
>     }

>     /* print the name on each line */
>     print_name(char *name)
>     {
>         printf("\n%s", name);
>         /* will continue as long as success status is returned */
>         return (1);
>     }

> This example shows how to use the `decc$from_vms` routine in Compaq C. It produces a simple form of the `ls` command that lists existing files that match an OpenVMS file specification supplied on the command line. The matching files are displayed in UNIX style file specification format.

# decc$match_wild

> Matches a string to a pattern.

## Format

> #include <unixlib.h>

> int decc$match_wild (char *test_string, char *string_pattern);

## Arguments

> ### test_string

> The address of a null-terminated string.

> ### string_pattern

> The address of a string containing the pattern to be matched. This pattern can contain wildcards (such as asterisks (*), question marks (?), and percent signs (%) as well as regular expressions (such as the range [a-z]).

## Description

> This routine determines whether the specified test string is a member of the set of strings specified by the pattern.

## Return Values

> 1 (TRUE) | The string matches the pattern.
> 0 (FALSE) | The string does not match the pattern.

## Example

>     /* Define as a foreign command and then provide two parameters  */
>     /*     match_wild  string_to_test  pattern                      */

>     #include <unixlib.h>
>     #include <stdio.h>
>     int main(int argc, char *argv[])
>     {
>         if (decc$match_wild(argv[1], argv[2]))
>             printf("\n%s matches %s", argv[1], argv[2]);
>         else
>             printf("\n%s does not match %s", argv[1], argv[2]);
>     }

# decc$record_read

> Reads a record from a file.

## Format

> #include <stdio.h>

> int decc$record_read (FILE *fp, void *buffer, int nbytes);

## Arguments

> ### fp

> A file pointer. The specified file pointer must refer to a file currently opened for reading.

> ### buffer

> The address of contiguous storage in which the input data is placed.

> ### nbytes

> The maximum number of bytes involved in the read operation.

## Description

> This function is specific to OpenVMS systems and should not be used when writing portable applications.

> The `decc$record_read` function is functionally equivalent to the `read` function, except that the first argument is a file pointer, not a file descriptor.

## Return Values

> x | The number of characters read.
> --1 | Indicates a read error, including physical input errors, illegal buffer addresses, protection violations, undefined file descriptors, and so forth.

# decc$record_write

> Writes a record to a file.

## Format

> #include <stdio.h>

> int decc$record_write (FILE *fp, void *buffer, int nbytes);

## Arguments

> ### fp

> A file pointer. The specified file pointer must refer to a file currently opened for writing or updating.

> ### buffer

> The address of contiguous storage from which the output data is taken.

> ### nbytes

> The maximum number of bytes involved in the write operation.

## Description

> This function is specific to OpenVMS systems and should not be used when writing portable applications.

> The `decc$record_write` function is functionally equivalent to the `write` function, except that the first argument is a file pointer, not a file descriptor.

## Return Values

> x | The number of bytes written.
> --1 | Indicates errors, including undefined file descriptors, illegal buffer addresses, and physical I/O errors.

# decc$set_child_standard_streams

> For a child spawned by a function from the exec family of functions, associates specified file descriptors with a child's standard streams: stdin, stdout, and stderr.

## Format

> #include <unistd.h>

> int decc$set_child_standard_streams (int fd1, int fd2, int fd3);

## Arguments

> ### fd1

> The file associated with this file descriptor in the parent process is associated with file descriptor number 0 (stdin) in the child process. If -1 is specified, the file associated with the parent's file descriptor number 0 is used (the default).

> ### fd2

> The file associated with this file descriptor in the parent process is associated with file descriptor number 1 (stdout) in the child process. If -1 is specified, the file associated with the parent's file descriptor number 1 is used (the default).

> ### fd3

> The file associated with this file descriptor in the parent process is associated with file descriptor number 2 (stderr) in the child process. If -1 is specified, the file associated with the parent's file descriptor number 2 is used (the default).

## Description

> This function allows mapping of specified file descriptors to the child's stdin/out/err streams, thereby compensating, to a certain degree, the lack of a real `fork` function on OpenVMS systems.

> On UNIX systems, the code between `fork` and `exec` is executed in the context of the child process:

>     parent:
>       create pipes p1, p2 and p3
>       fork
>     child:
>       map stdin to p1  like dup2(stdin,  p1);
>       map stdout to p2 like dup2(stdout, p2);
>       map stderr to p3 like dup2(stderr, p3);
>       exec (child reads from stdin and writes to stdout and stderr)
>       exit
>     parent:
>       communicates with the child using pipes

> On OpenVMS systems, the same task could be achieved as follows:

>     parent:
>       create pipes p1, p2 and p3
>       decc$set_child_standard_streams(p1, p2, p3);
>       vfork
>       exec (child reads from stdin and writes to stdout and stderr)
>     parent:
>       communicates with the child using pipes

> Once established through the call to `decc$set_child_standard_streams` , the mapping of the child's standard streams remains in effect until explicitly disabled by one of the following calls:

>     decc$set_child_standard_streams(-1, -1, -1);

>        OR

>     decc$set_child_standard_streams(0, 1, 2);

> Usually, the child process inherits all its parent's open file descriptors. However, if file descriptor number n was specified in the call to `decc$set_child_standard_streams` , it is not inherited by the child process as file descriptor number n; instead, it becomes one of the child's standard streams.

> Notes Standard streams can be redirected only to pipes. If the parent process redefines the DCL DEFINE command, this redefinition is not in effect in a subprocess with user-defined channels. The subprocess always sees the standard DCL DEFINE command. It is the responsibility of the parent process to consume all the output written by the child process to stdout and stderr. Depending on how the subprocess writes to stdout and stderr -- in wait or nowait mode---the subprocess might be placed in LEF state waiting for the reader. For example, DCL writes to SYS$OUTPUT and SYS$ERROR in a wait mode, so a child process executing a DCL command procedure will wait until all the output is read by the parent process. Recommendation: Read the pipes associated with the child process' stdout and stderr in a loop until an EOF message is received, or declare write attention ASTs on these mailboxes. The amount of data written to SYS$OUTPUT depends on the verification status of the process (SET VERIFY/NOVERIFY command); the subprocess inherits the verification status of the parent process. It is the caller's responsibility to set the verification status of the parent process to match the expected amount of data written to SYS$OUTPUT by the subprocess. Some applications, like DTM, define SYS$ERROR as SYS$OUTPUT. If stderr is not redefined by the caller, it is set in the subprocess as the parent's SYS$ERROR, which in this case translates to the parent's SYS$OUTPUT. If the caller redefines stdout to a pipe and does not redefine stderr, output sent to stderr goes to the pipe associated with stdout, and the amount of data written to this mailbox may be more than expected. Although redefinition of any subset of standard channels is supported, it is always safe to explicitly redefine all of them (or at least stdout and stderr) to avoid this situation. For a child process executing a DCL command procedure, SYS$COMMAND is set to the pipe specified for the child's stdin so that the parent process can feed the child requesting data from SYS$COMMAND through the pipe. For DCL command procedures, it is impossible to pass data from the parent to the child by means of the child's SYS$INPUT because for a command procedure, DCL defines SYS$INPUT as the command file itself.

## Return Value

> x | The number of file descriptors set for the child. This number does not include file descriptors specified as --1 in the call.
> --1 | indicates that an invalid file descriptor was specified; `errno` is set to EBADF.

## Example

>     parent.c
>     ========

>     #include <stdio.h>
>     #include <string.h>
>     #include <unistd.h>

>     int decc$set_child_standard_streams(int, int, int);

>     main()
>     {
>         int fdin[2], fdout[2], fderr[2];
>         char msg[] = "parent writing to child's stdin";
>         char buf[80];
>         int nbytes;

>         pipe(fdin);
>         pipe(fdout);
>         pipe(fderr);

>         if ( vfork() == 0 ) {
>             decc$set_child_standard_streams(fdin[0], fdout[1], fderr[1]);
>           execl( "child", "child" );
>         }
>         else {
>             write(fdin[1], msg, sizeof(msg));
>             nbytes = read(fdout[0], buf, sizeof(buf));
>             buf[nbytes] = '\0';
>             puts(buf);
>             nbytes = read(fderr[0], buf, sizeof(buf));
>             buf[nbytes] = '\0';
>             puts(buf);
>         }
>     }

>     child.c
>     =======

>     #include <stdio.h>
>     #include <unistd.h>

>     main()
>     {
>         char msg[] = "child writing to stderr";
>         char buf[80];
>         int nbytes;

>         nbytes = read(0, buf, sizeof(buf));
>         write(1, buf, nbytes);
>         write(2, msg, sizeof(msg));
>     }

>     child.com
>     =========

>     $ read sys$command s
>     $ write sys$output s
>     $ write sys$error "child writing to stderr"

> This example program returns the following for both child.c and child.com:

>     $ run parent
>     parent writing to child's stdin
>     child writing to stderr

> Note that in order to activate `child.com` , you must explicitly specify `execl("child.com", ...)` in the `parent.c` program.

Previous | Next | Contents | Index

privacy and legal statement