[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

Guide to OpenVMS File Applications


Previous Contents Index

4.2 Creating a File

After you select the creation characteristics for your file, you use the selected characteristics to create the file. You can create the file using one of the following:

  • Create service
  • Create/FDL utility
  • Convert utility
  • FDL$CREATE routine

4.2.1 Using the Create Service

The Create service creates a new data file assigning it the attributes you specify in the FAB and any applicable XABs. Note that where there is a conflict, the XAB fields override the FAB fields.

When you use the Create service to create a file, the file remains open until you explicitly close it.

If you set the create-if (CIF) bit in the FOP (file-processing options) field of the FAB, you can open an existing file with the Create service. If the file you try to create has the same name as an existing file, the Create service opens the existing file instead of creating the new file.

The Create service allows you to set file-creation characteristics and to create the file directly from your application program.

For more information about the Create service, see the OpenVMS Record Management Services Reference Manual.

4.2.2 Using the Create/FDL Utility

Unlike the Create service, using FDL to create a file is a two-step process. You must first create the FDL file using the Edit/FDL utility and then use another RMS utility or your application program to create the data file.

One of the utilities you can use to create a file is the Create/FDL utility (CREATE/FDL). CREATE/FDL creates an empty data file from the specifications in an existing FDL file. This feature allows you to use the Edit/FDL utility to create standard FDL files that describe commonly needed data files and then to use CREATE/FDL to create the data files as they are needed.

For example, to create an empty data file called CUSTRECS.DAT from the specifications in an FDL file called INDEXED.FDL, enter the following DCL command:


$ CREATE/FDL=INDEXED.FDL CUSTRECS.DAT

4.2.3 Using the Convert Utility

Another RMS utility that creates an output data file from the specifications in an FDL file is the Convert utility (CONVERT). However, instead of being empty, the new output file generally contains data records from the input file unless the input file was also empty. Note that the Convert utility processes relative files by sequentially reading records from the input file, then writing them to the output file. As a result the relative record numbers (RRN) change when the input file contains deleted or unused records.

If you want to use CONVERT to change the characteristics of a particular file, you can use a DCL command of the following form:


CONVERT/FDL=fdl-file input-file output-file

The CONVERT/FDL command creates a new file named by the output-file parameter and assigns the new file the characteristics specified in the FDL file.

For more information about populating data files with CONVERT, see Section 4.5.

4.2.4 Using the FDL$CREATE Routine

You can also create data files according to your specifications with the FDL$CREATE routine. FDL$CREATE is the FDL routine most likely to be called from a high-level language. It creates a file from an FDL specification and then closes the file.

The FDL$CREATE routine performs the same function as the Create/FDL utility, but it allows you to create data files from your application. However, it allows you to use only the creation-time features of RMS.

Example 4-4 shows how to call the FDL$CREATE routine from a Fortran program.

Example 4-4 Using the FDL$CREATE Routine in a Fortran Program

*       This program calls the FDL$CREATE routine.  It
*       creates an indexed output file named NEW_MASTER.DAT
*       from the specifications in the FDL file named
*       INDEXED.FDL.  You can also supply a default file name
*       and a result name (which receives the name of the created
*       file).  The program also returns all statistics.
*
        IMPLICIT        INTEGER*4       (A - Z)
        EXTERNAL        LIB$GET_LUN,    FDL$CREATE
        CHARACTER       IN_FILE*11      /'INDEXED.FDL'/,
        1               OUT_FILE*14     /'NEW_MASTER.DAT'/,
        1               DEF_FILE*11     /'DEFAULT.FDL'/,
        1               RES_FILE*50
        INTEGER*2       FIDBLK(3)       /0,0,0/
        I = 1
        STATUS = FDL$CREATE (IN_FILE,OUT_FILE,
                 DEF_FILE,RES_FILE,FIDBLK,,)
        IF (.NOT. STATUS) CALL LIB$STOP (%VAL(STATUS))
*
        STATUS=LIB$GET_LUN(LOG_UNIT)
        OPEN (UNIT=LOG_UNIT,FILE=RES_FILE,STATUS='OLD')
        CLOSE (UNIT=LOG_UNIT, STATUS='KEEP')
*
        WRITE (6,1000) (RES_FILE)
        WRITE (6,2000) (FIDBLK (I), I=1,3)
*
1000    FORMAT  (1X,'The result filename is: ',A50)
*
2000    FORMAT  (/1X,'FID-NUM: ',I5/,
        1         1X,'FID-SEQ: ',I5/,
        1         1X,'FID-RVN: ',I5)
*
        END

Example 4-5 shows how to call the FDL$CREATE routine from a COBOL program.

Example 4-5 Using the FDL$CREATE Routine from a COBOL Program

*        FDLCR.COB
*
*        This program calls the FDL$CREATE routine.  It creates
*        an indexed output file named NEW_MASTER.DAT from the
*        specifications in the FDL file named INDEXED.DAT.  You
*        can also supply a default file name and a result name
*        (that receives the name of the created file).  The
*        program also returns the FDL$CREATE statistics.
*
*        DATA NAMES:
*
*        OUT-REC    defines the output record
*        STATVALUE  receives the status value from the routine
*                   call
*        NORMAL     receives the value from SS$_NORMAL
*        FIDBLOCK   receives the FDL$CREATE statistics.  There
*                   are three:
*                   (1) file identification number (FID-NUM)
*                   (2) file sequence number       (FID-SEQ)
*                   (3) relative volume number     (RVN)
*        RESNAME    receives the name of the file that is created
*                   (the result file name)
*
IDENTIFICATION DIVISION.
PROGRAM-ID. FDL-CREATE-EXAMPLE.

ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. VAX
OBJECT-COMPUTER. VAX
INPUT-OUTPUT SECTION.
FILE-CONTROL.
        SELECT OUT-FILE ASSIGN TO 'NEWMASTER.DAT'.

DATA DIVISION.
FILE SECTION.
FD      OUT-FILE
        DATA RECORD IS OUT-REC.

01      OUT-REC.
        02      OUT-NUM     PIC X(4).
        02      OUT-NAME    PIC X(20).
        02      OUT-COLOR   PIC X(4).
        02      OUT-WEIGHT  PIC X(4).
        02      SUPL-NAME    PIC X(20).
        02      FILLER      PIC X(28).
WORKING-STORAGE SECTION.
01      MORE-DATA-FLAGS     PIC XXX     VALUE 'YES'.
        88      THERE-IS-DATA           VALUE 'YES'.
        88      THERE-IS-NO-DATA        VALUE 'NO '.

01      STATVALUE           PIC S9(9)   COMP.

01      FIDBLOCK            USAGE IS COMP.
        02      NUM         PIC S9(9)   VALUE 0.
        02      SEQ         PIC S9(9)   VALUE 0.
        02      RVN         PIC S9(9)   VALUE 0.

01      RESNAME             PIC X(50).

PROCEDURE DIVISION.
MAIN.
        PERFORM CREATE-FILE THRU DISPLAY-STATS.
        STOP RUN.

CREATE-FILE.
        CALL 'FDL$CREATE' USING BY DESCRIPTOR 'INDEXED.FDL'
                                BY DESCRIPTOR 'NEWMASTER.DAT'
                                BY DESCRIPTOR 'DEFAULT.DAT'
                                BY DESCRIPTOR RESNAME
                                BY REFERENCE FIDBLOCK
                                BY VALUE 0
                                BY VALUE 0
                                BY VALUE 0
                                BY VALUE 0
                                BY VALUE 0
                          GIVING STATVALUE.

        IF STATVALUE IS FAILURE
        CALL 'LIB$STOP' USING BY VALUE STATVALUE.

DISPLAY-STATS.
        DISPLAY 'The result filename is: ',RESNAME CONVERSION.
        DISPLAY 'FID number:             ',NUM CONVERSION.
        DISPLAY 'FID sequence:           ',SEQ CONVERSION.
        DISPLAY 'Volume number:          ',RVN CONVERSION.

4.3 Creating and Accessing Tagged Files

RMS supports the use of compound document text through the implementation of tagged files. The term compound documents refers to files that contain a number of integrated components including text, graphics, and scanned images.

Tagged files are made distinguishable by the RMS file attribute stored semantics. The value of the stored semantics attribute is called the file tag, and it specifies how file data is to be interpreted.

RMS support for compound document text requires that compound document files be tagged with the appropriate stored semantics values. These are binary values that can be up to 64 bytes long and can be expressed using hexadecimal notation. The hexadecimal value of the DDIF tag, for example, is 2B0C8773010301. The operating system lets you assign names to tag values so that DCL commands such as DIRECTORY/FULL and utilities such as FDL and ANALYZE/RMS_FILE display a more easily remembered mnemonic for the DDIF tag instead of the hexadecimal value.

Assigning a name to the tag also aids in using the /SEMANTICS qualifier with the DCL SET FILE command when you want to tag a file from the DCL interface. For example, you can use a command like the following:


$ SET FILE/SEMANTICS=DDIF MY.FILE

To assign a tag a name, you must have privileges to make appropriate entries in two system tables, RMS$SEMANTIC_TAGS and RMS$SEMANTIC_OBJECTS.

For example, the following DCL commands have been included in the system startup command file to assign the mnemonic DDIF to the hexadecimal value for a DDIF tag:


$ DEFINE/TABLE=RMS$SEMANTIC_TAGS DDIF 2B0C8773010301
$ DEFINE/TABLE=RMS$SEMANTIC_OBJECTS 2B0C8773010301 DDIF
With the appropriate DEFINE commands, you can assign mnemonics for other tags, including tags used with international program applications.

You can tag files through the DCL interface, the FDL interface, or from your program by way of the RMS interface. This section describes the implementation of tagged files through the RMS interface including:

  • Tagging files
  • Accessing tagged files
  • Preserving tags

4.3.1 Programming Interface for File Tagging

You can tag a file from the RMS interface by using the Create service in conjunction with an item XAB ($XABITM). See OpenVMS Record Management Services Reference Manual for more information about using the $XABITM macro.

Example 4-6 illustrates a BLISS--32 program that tags a DDIF file through the RMS interface. The tag value shown is a 7-byte hexadecimal number representing the code for the DDIF tag. The RMS program interface accepts only hexadecimal tag values.

To write to a tagged file, the application program must use a $XABITM macro to specify access semantics that match the file's stored semantics as established by a $XABITM macro. As shown in the example, the Create service tags the file and the Connect service specifies the appropriate access semantics.

Example 4-6 Tagging a File

MODULE TYPE$MAIN (
        IDENT = 'X-1',
        MAIN = MAIN,
        ADDRESSING_MODE (EXTERNAL=GENERAL)
        ) =
BEGIN
!
FORWARD ROUTINE
    MAIN : NOVALUE;                        ! Main routine
!
! INCLUDE FILES:
!
LIBRARY 'SYS$LIBRARY:LIB';
OWN
    NAM            : $NAM(),
    RETLEN,
    DDIF_TAG        : BLOCK[ 7, BYTE]
                INITIAL( BYTE( %X'2B', %X'0C', %X'87', %X'73', %X'01', %X'03', %X'01')),
    FAB_XABITM        :
                $xabitm
                  ( itemlist=
                        $ITMLST_UPLIT
                          (
                            (ITMCOD=XAB$_STORED_SEMANTICS,
                             BUFADR=DDIF_TAG,
                             BUFSIZ=%ALLOCATION(DDIF_TAG))
                          ),
                    mode = SETMODE),
    RAB_XABITM        :
                $xabitm
                  ( itemlist=
                        $ITMLST_UPLIT
                          (
                            (ITMCOD=XAB$_ACCESS_SEMANTICS,
                             BUFADR=DDIF_TAG,
                             BUFSIZ=%ALLOCATION(DDIF_TAG))
                          ),
                    mode = SETMODE),
    FAB         : $FAB( fnm = 'TAGGED-FILE.TEST',
                        nam = NAM,
                        mrs = 512,
                        rfm = FIX,
                        fac = <GET,PUT,UPD>,
                        xab = FAB_XABITM),
    REC             : BLOCK[512,BYTE],
    STATUS,
    RAB         : $RAB( xab = RAB_XABITM,
                        fab = FAB,
                        rsz = 512,
                        rbf = REC,
                        usz = 512,
                        ubf = REC),
    DESC            : BLOCK[8,BYTE] INITIAL(0);
ROUTINE MAIN : NOVALUE =
BEGIN
STATUS = $CREATE( FAB = FAB );
IF NOT .STATUS
THEN
    SIGNAL (.STATUS);
STATUS = $CONNECT( RAB = RAB );
IF NOT .STATUS
THEN
    SIGNAL (.STATUS);
STATUS = $CLOSE( FAB = FAB );
IF NOT .STATUS
THEN
    SIGNAL (.STATUS);
END;
END
ELUDOM

4.3.2 Accessing a Tagged File

This section details how RMS handles access to tagged files at the program level. When a program accesses a tagged file, RMS must determine whether and when to associate an RMS extension with the access. This is important to the programmer because an RMS extension can change the attributes of the accessed file.

RMS extensions are system images that perform specialized file or record operations within the context of RMS. Record management services can invoke an extension if specified conditions are met. Functions provided by an extension are only accessible through the record managment services and are generally transparent to the application.

An example of an RMS extension is the DDIF-to-ASCII text translator. RMS can call this extension to extract ASCII text from a DDIF file. The conditions that determine when this extension is called are described in this section.

A DDIF file is a sequentially organized file with 512-byte, fixed-length records. If the DDIF-to-ASCII RMS extension is used to extract text from a DDIF file, the accessed file appears as a sequentially organized file having variable-length records with a maximum record size of 2048 bytes and an implicit carriage return.

One consideration in determining whether an access requires the RMS extension is the type of access (FAB$B_FAC). When an application program opens a file through the RMS program interface, it must specify if it will be doing record I/O (default), block I/O (BIO), or mixed I/O (BRO) operations, where the program has the option of using either block I/O or record I/O for each access. For example, if block I/O operations are specified, RMS does not associate the RMS extension with the file access.

Another consideration is whether the program senses the tag when it opens a file. If the program does not sense the tag when it opens a DDIF file for record access, RMS associates the RMS extension with the file access during the Open service and returns the file attributes that have been modified by the extension.

The final consideration is the access semantics that the program specifies and the file's stored semantics (tag). If the program specifies block I/O (FAB$V_BIO) operations, RMS does not associate the RMS extension with the file access and the Open service returns the file's stored attributes to the accessing program regardless of whether the program senses tags.

4.3.2.1 File Accesses That Do Not Sense Tags

This section describes what happens when a program does not use a XABITM control block to sense a tag when it opens a file.

When a program opens a DDIF file for record operations and does not sense the tag, RMS assumes that the program wants to access text in the file. In this case, RMS associates the RMS extension with the file access, which provides file attributes that correspond to record-mode access.

When a program opens a DDIF file with the FAB$V_BRO option and does not sense the tag, any subsequent attempt to use block I/O fails. If the program specifies block I/O (FAB$V_BIO) when it invokes the Connect service, the operation fails because the file attributes returned at Open permit record access only. Similarly, if the program specifies the FAB$V_BRO option when it opens the file and then specifies mixed mode (block/record) operations by not specifying RAB$V_BIO at connect time, block operations such as READ and WRITE are disallowed.

4.3.2.2 File Accesses That Sense Tags

RMS does not associate the RMS extension with the file access as part of the Open service if a program opens a DDIF file and senses the stored semantics. This allows the program to specify access semantics with the Connect service. RMS returns the file attributes, including the stored semantics attribute (tag value), to the program as part of the Open service.

When the program subsequently invokes the Connect service, RMS uses the specified operations mode to determine its response. If the program specified FAB$V_BRO with the Open service and then specifies block I/O (RAB$V_BIO) when it invokes the Connect service, RMS does not associate the RMS extension with the file access.

But, if the program specifies record access or FAB$V_BRO when it opens the file and then decides to use record I/O when it invokes the Connect service, RMS compares the access semantics with the file's stored semantics to determine whether to associate the RMS extension with the file access. If the access semantics match the stored semantics, RMS does not associate the RMS extension with the file access. If the access semantics do not match the stored semantics, RMS associates the RMS extension with the file access. In this case, the program must use the Display service to obtain the modified file attributes. If RMS cannot find the appropriate RMS extension, the operation fails and the Connect service returns the EXTNOTFOU error message.

If the application program senses the file's stored semantics, RMS allows mixed-mode operations. In this case, mixed block and record operations are permitted because the application gets record mode file attributes and data from the RMS extension and block mode file attributes and data from the file.

Example 4-7 illustrates a BLISS--32 program that accesses a tagged file from an application program that does not use an RMS extension.

Example 4-7 Accessing a Tagged File

MODULE TYPE$MAIN (
        IDENT = 'X-1',
        MAIN = MAIN,
        ADDRESSING_MODE (EXTERNAL=GENERAL)
        ) =
BEGIN
!
FORWARD ROUTINE
    MAIN : NOVALUE;                        ! Main routine
!
! INCLUDE FILES:
!
LIBRARY 'SYS$LIBRARY:STARLET';
OWN
    NAM            : $NAM(),
    ITEM_BUFF   : BLOCK[ XAB$K_SEMANTICS_MAX_LEN,BYTE ],
    RETLEN,
    FAB_XABITM        :
                $xabitm
                  ( itemlist=
                        $ITMLST_UPLIT
                          ((ITMCOD=XAB$_STORED_SEMANTICS,
                             BUFADR=ITEM_BUFF,
                             BUFSIZ=XAB$K_SEMANTICS_MAX_LEN,
                             RETLEN=RETLEN)),
                    mode = SENSEMODE),
    RAB_ITEMLIST  : BLOCK[ ITM$S_ITEM + 4, BYTE ],
    RAB_XABITM    : $XABITM
                  ( itemlist=RAB_ITEMLIST,
                    mode=SETMODE ),
    FAB         : $FAB( fnm = 'TAGGED-FILE.TEST',
                        nam = NAM,
                        fac = <GET,PUT,UPD>,
                        xab = FAB_XABITM),
    REC             : BLOCK[512,BYTE],
    STATUS,
    RAB         : $RAB( xab = RAB_XABITM,
                        fab = FAB,
                        rsz = 512,
                        rbf = REC,
                        usz = 512,
                        ubf = REC),
    DESC            : BLOCK[8,BYTE] INITIAL(0);
ROUTINE MAIN : NOVALUE =
BEGIN
STATUS = $OPEN( FAB = FAB );
IF NOT .STATUS
THEN
    SIGNAL (.STATUS);
RAB_ITEMLIST[ ITM$W_BUFSIZ ] = .RETLEN;
RAB_ITEMLIST[ ITM$L_BUFADR ] = ITEM_BUFF;
RAB_ITEMLIST[ ITM$W_ITMCOD ] = XAB$_ACCESS_SEMANTICS;
STATUS = $CONNECT( RAB = RAB );
IF NOT .STATUS
THEN
    SIGNAL (.STATUS);
STATUS = $CLOSE( FAB = FAB );
IF NOT .STATUS
THEN
    SIGNAL (.STATUS);
END;
END
ELUDOM

4.3.3 Preserving Tags

In order to preserve the integrity of a tagged file that is being copied or transmitted, the tag must be preserved in the destination (output) file. The most efficient way to use the RMS interface for propagating tags involves a 2-step procedure:

  1. Open the source file (input) and sense the tag using a $XABITM macro with the item code XAB$_STORED_SEMANTICS, as shown in the following example:


       .
       .
       .
    ITEMLIST[ ITM$W_BUFSIZ ] = XAB$K_SEMANTICS_MAX_LEN;
    ITEMLIST[ ITM$L_BUFADR ] = ITEM_BUFF;
    ITEMLIST[ ITM$L_RETLEN ] = RETLEN;
    ITEMLIST[ ITM$W_ITMCOD ] = XAB$_STORED_SEMANTICS;
       .
       .
       .
    XABITM[ XAB$B_MODE ] = XAB$K_SENSEMODE;
    STATUS = $OPEN( FAB = FAB );
       .
       .
       .
    
  2. Create the destination (output) file and set the tag using a $XABITM macro with the item code XAB$_STORED_SEMANTICS:


       .
       .
       .
    IF .RETLEN GTR 0
    THEN
        BEGIN
        ITEMLIST[ ITM$W_ITMCOD ] = XAB$_STORED_SEMANTICS;
        ITEMLIST[ ITM$L_SIZE   ] = .RETLEN;
        XABITM[ XAB$B_MODE ] = XAB$K_SETMODE;
        END;
    
    STATUS = $CREATE( FAB = FAB );
       .
       .
       .
    END;
    END
    ELUDOM
    

4.4 Defining File Protection

You can protect a disk file in two ways:

  • UIC-based protection codes
  • Access control lists (ACLs)

4.4.1 UIC-Based Protection

You can protect the disk with UIC-based protect codes that are described in the OpenVMS Guide to System Security.

The owner UIC is normally the UIC of the person who created the file. The protection code indicates who is allowed access and what type of access they are permitted.

When you try to open a file, your UIC is compared to the owner UIC of the file. Depending on the relationship of the UICs, you might be classified under one or more of the following categories:

  • System
  • Owner
  • Group
  • World

Depending on your classification, you may be allowed or denied the following types of access:

Read Can examine, print, or copy a disk or tape file
Write Can modify or write to a disk or tape file
Execute Can execute a disk file that contains executable program images
Delete Can delete a disk file

You can specify the UIC-based protection value you need when the file is created if you use either an FDL specification or RMS directly.

After you create a file, you can change its UIC-based protection with the DCL command SET PROTECTION. For more information about the SET PROTECTION command, see the OpenVMS DCL Dictionary.

The previous list omits CONTROL access because it is never specified in the standard UIC-based protection code. However, CONTROL access can be specified in an ACL and is automatically granted to certain user categories when UIC-based protection is evaluated.

CONTROL access grants the accessor all the privileges of the object's actual owner. For more information, see the documentation related to OpenVMS security.


Previous Next Contents Index