  | 
		
		
			
			
Compaq C
Compaq C Run-Time Library Reference Manual for 
OpenVMS Systems
 
 
 
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(¤t_vms_time[0]); 
 
   /* fix the time */ 
   number_of_seconds = decc$fix_time(¤t_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 arguments  */ 
/* 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.
  
 
decc$set_reentrancy
 
Controls the type of reentrancy that reentrant Compaq C RTL routines 
will exhibit.
 
 
Format
#include <reentrancy.h>
int decc$set_reentrancy (int type);
 
  
 
Argument
type
The type of reentrancy desired. Use one of the following values:
  - C$C_MULTITHREAD --- Designed to be used in conjunction with
the DECthreads product. It performs DECthreads locking and never 
disables ASTs. DECthreads must be available on your system to use this 
form of reentrancy.
  
 - C$C_AST --- Uses the _BBSSI  (VAX ONLY) or
__TESTBITSSI  (ALPHA ONLY) built-in function to perform simple locking 
around critical sections of RTL code, and it may additionally disable 
asynchronous system traps (ASTs) in locked regions of code. This type 
of locking should be used when AST code contains calls to Compaq C RTL 
I/O routines, or when the user application disables ASTs.
  
 - C$C_TOLERANT --- Uses the _BBSSI  (VAX ONLY)
or __TESTBITSSI  (ALPHA ONLY) built-in function to perform simple 
locking around critical sections of RTL code, but ASTs are not 
disabled. This type of locking should be used when ASTs are used and 
must be delivered immediately. TOLERANT is the default reentrancy type.
  
 - C$C_NONE --- Gives optimal performance in
the Compaq C RTL, but does absolutely no locking around critical 
sections of RTL code. It should only be used in a single-threaded 
environment when there is no chance that the thread of execution will 
be interrupted by an AST that would call the Compaq C RTL.
  
The reentrancy type can be raised but never lowered. The ordering of 
reentrancy types from low to high is C$C_NONE, C$C_TOLERANT, C$C_AST 
and C$C_MULTITHREAD. For example, once an application is set to 
multithread, a call to set the reentrancy to AST is ignored. A call to
decc$set_reentrancy
 that attempts to lower the reentrancy type returns a value of --1.
  
 
Description
Use this function to change the type of reentrancy exhibited by 
reentrant routines.
decc$set_reentrancy
 must be called exclusively at the non-AST level.
 
In an application using DECthreads, DECthreads automatically sets the 
reentrancy to multithread.
  
 
Return Value
  
    | 
      type
     | 
    
      The type of reentrancy used before this call.
     | 
   
  
    | 
      --1
     | 
    
      The reentrancy was set to a lower type.
     | 
   
 
 
 
decc$to_vms
 
Converts UNIX style file specifications to OpenVMS file specifications.
 
 
Format
#include <unixlib.h>
int decc$to_vms (const char *unix_style_filespec, int 
(*action_routine)(char *unix_style_filespec, int 
type_of_file), int allow_wild, int 
no_directory);
 
  
 
Arguments
unix_style_filespec
The address of a null-terminated string containing a name in UNIX style 
file specification format.
action_routine
The address of a routine that accepts the following arguments:
  - A pointer to a null-terminated string that contains the UNIX style 
  file name to be translated to a valid OpenVMS file name
  
 - An integer that has one of the following values:
  
    | Value  | 
    Translation  | 
   
  
    | 
      0 (DECC$K_FOREIGN)
     | 
    
      A file on a remote system that is not running the OpenVMS or VAXELN 
      operating system.
     | 
   
  
    | 
      2 (DECC$K_DIRECTORY)
     | 
    
      The OpenVMS translation of the UNIX style file name is a directory.
     | 
   
  
    | 
      1 (DECC$K_FILE)
     | 
    
      The translation is a file.
     | 
   
 
     These values can be defined symbolically with the symbols 
    DECC$K_FOREIGN, DECC$K_DIRECTORY, and DECC$K_FILE. See the example for 
    more information.
  
If action_routine returns a nonzero value (TRUE), file 
translation continues. If it returns a 0 value (FALSE), no further file 
translation takes place.
 allow_wild
Either 0 or 1, passed by value. If a 0 is specified, wildcards found in 
unix_style_filespec are not expanded. Otherwise, wildcards are 
expanded and each one is passed to action_routine. Only 
expanded file names that correspond to existing OpenVMS files are 
included.
no_directory
An integer that has one of the following values:
  
    | Value  | 
    Translation  | 
   
  
    | 
      0
     | 
    
      Directory is not allowed.
     | 
   
  
    | 
      1
     | 
    
      Prevent expansion of the string as a directory name.
     | 
   
  
    | 
      2
     | 
    
      Forced to be a directory name.
     | 
   
 
 
 
Description
This routine converts the given UNIX style file specification into the 
equivalent OpenVMS file specification (in all uppercase letters). It 
allows you to specify UNIX style wildcards, which are translated into a 
list of corresponding OpenVMS files.
 
 
Return Value
  
    | 
      x
     | 
    
      The number of file names that result from the specified UNIX style file 
      specification.
     | 
   
 
 
 
Example
 
  
    
       
      
/* Translate "Unix" wildcard file names to VMS names    */ 
/* Define as a foreign command and provide the name     */ 
/* as an argument.                                      */ 
 
#include <unixlib.h> 
#include <stdio.h> 
int print_name(char *, int); 
int main(int argc, char *argv[]) 
{ 
    int number_found;           /* number of files found */ 
 
    printf("Translating: %s\n", argv[1]); 
 
    number_found = decc$to_vms(argv[1], print_name, 1, 0); 
    printf("%d files found\n", number_found); 
} 
 
/* action routine that prints name and type on each line */ 
 
int print_name(char *name, int type) 
{ 
    if (type == DECC$K_DIRECTORY) 
        printf("directory: %s\n", name); 
    else if (type == DECC$K_FOREIGN) 
        printf("remote non-VMS: %s\n", name); 
    else 
        printf("file:        %s\n", name); 
 
/* Translation continues as long as success status is returned */ 
    return (1); 
} 
 |   
This example shows how to use the
decc$to_vms
routine in Compaq C. It takes a UNIX style file specification 
argument and displays, in OpenVMS file specification format, the name 
of each existing file that matches it.
  
  
         | 
	 
	  | 
	 
		 
		 |