| 
     
 
 
  
 
  
 
  
 
  
 
  
 
  
 
          | 
     
| Updated: 11 December 1998 | 
 
 
OpenVMS Programming Concepts Manual
| Previous | Contents | Index | 
The SYS$DISMOU system service allows a process to dismount a volume or volume set. When you call SYS$DISMOU, you must specify a device name. If the volume mounted on the device is part of a fully mounted volume set, and you do not specify flags, the whole volume set is dismounted.
The following example illustrates a call to SYS$DISMOU. The call dismounts the volume set mounted in the previous example.
      
 
    $DESCRIPTOR(dev1_desc,"DRA4:"); 
   .
   .
   .
        status = SYS$DISMOU(&dev1_desc); /* devnam - device */ 
   .
   .
   .
 
 | 
Initializing a volume writes a label on the volume, sets protection and ownership for the volume, formats the volume (depending on the device type), and overwrites data already on the volume.
You interactively initialize a volume from the DCL command stream using 
the INITIALIZE command. A process can programmatically initialize a 
volume using the Initialize Volume (SYS$INIT_VOL) system service.
11.18.2.1 Calling the Initialize Volume System Service
You must specify a device name and a new volume name when you call the SYS$INIT_VOL system service. You can also use the itmlst argument of $INIT_VOL to specify options for the initialization. For example, you can specify that data compaction should be performed by specifying the INIT$_COMPACTION item code. See the OpenVMS System Services Reference Manual for more information on initialization options.
Before initializing the volume with SYS$INIT_VOL, be sure you have placed the volume on the device and started the device (by pressing the START or LOAD button).
The default format for files on disk volumes is called Files-11 On-Disk Structure Level 2. Files-11 On-Disk Structure Level 1 format, available on VAX systems, is used by other Compaq operating systems, including RSX-11M, RSX-11M-PLUS, RSX-11D, and IAS, but is not supported on Alpha systems. For more information, see the OpenVMS System Manager's Manual.
Here are two examples of calling SYS$INIT_VOL programmatically: one from a C program and one from a BASIC program.
The following example illustrates a call to SYS$INIT_VOL from DEC C:
      
 
#include <descrip.h> 
#include <initdef.h> 
#include <lib$routines.h> 
#include <starlet.h> 
#include <stsdef.h> 
 
struct item_descrip_3 
{ 
    unsigned short buffer_size; 
    unsigned short item_code; 
    void *buffer_address; 
    unsigned short *return_length; 
}; 
 
main () 
{ 
    unsigned long 
        density_code, 
        status; 
    $DESCRIPTOR(drive_dsc, "MUA0:"); 
    $DESCRIPTOR(label_dsc, "USER01"); 
    struct 
    { 
        struct item_descrip_3 density_item; 
        long terminator; 
    } init_itmlst; 
 
    /* 
    ** Initialize the input item list. 
    */ 
 
    density_code = INIT$K_DENSITY_6250_BPI; 
    init_itmlst.density_item.buffer_size = 4; 
    init_itmlst.density_item.item_code = INIT$_DENSITY; 
    init_itmlst.density_item.buffer_address = &density_code; 
 
    init_itmlst.terminator = 0; 
 
    /* 
    ** Initialize the volume. 
    */ 
 
    status = SYS$INIT_VOL (&drive_dsc, &label_dsc, &init_itmlst); 
 
    /* 
    ** Report an error if one occurred. 
    */ 
 
    if (!$VMS_STATUS_SUCCESS (status )) 
        LIB$STOP (status); 
} 
 
 | 
The following example illustrates a call to SYS$INIT_VOL from VAX BASIC:
      
 
OPTION TYPE = EXPLICIT 
 
%INCLUDE '$INITDEF' %FROM %LIBRARY 
 
EXTERNAL LONG FUNCTION SYS$INIT_VOL 
 
RECORD ITEM_DESC 
        VARIANT 
        CASE 
            WORD BUFLEN 
            WORD ITMCOD 
            LONG BUFADR 
            LONG LENADR 
        CASE 
            LONG TERMINATOR 
        END VARIANT 
END RECORD 
 
DECLARE LONG RET_STATUS, & 
    ITEM_DESC INIT_ITMLST(2) 
 
! Initialize the input item list. 
 
INIT_ITMLST(0)::ITMCOD = INIT$_READCHECK 
INIT_ITMLST(1)::TERMINATOR = 0 
 
! Initialize the volume. 
 
RET_STATUS = SYS$INIT_VOL ("DJA21:" BY DESC, "USERVOLUME" BY DESC, 
INIT_ITMLST() BY REF) 
 
 | 
When you are preparing output strings for a program, you may need to insert variable information into a string prior to output, or you may need to convert a numeric value to an ASCII string. The Formatted ASCII Output (SYS$FAO) system service performs these functions.
Input to the SYS$FAO system service consists of the following:
The following example shows a call to the SYS$FAO system service to format an output string for a SYS$QIOW macro. Complete details on how to use SYS$FAO, with additional examples, are provided in the description of the SYS$FAO system service in the OpenVMS System Services Reference Manual.
      
 
 
#include <descrip.h> 
#include <lib$routines.h> 
#include <ssdef.h> 
#include <starlet.h> 
#include <stdio.h> 
#include <stsdef.h> 
 
main() { 
 
        unsigned int status, faolen; 
        char faobuf[80]; 
        $DESCRIPTOR(faostr,"FILE !AS DOES NOT EXIST");    (1)
        $DESCRIPTOR(outbuf, faobuf);                      (2)
        $DESCRIPTOR(filespec,"DISK$USER:MYFILE.DAT");     (3)
 
        status = SYS$FAO( &faostr, &outlen, &outbuf, &filespec );  (4)
        if (!$VMS_STATUS_SUCCESS(status)) 
                LIB$SIGNAL(status); 
   .
   .
   .
        status = SYS$QIOW( ...faobuf, outlen, ... ); (5)
        if (!$VMS_STATUS_SUCCESS(status)) 
                LIB$SIGNAL(status); 
   .
   .
   .
} 
 | 
      FILE DISK$USER:MYFILE.DAT DOES NOT EXIST  | 
Mailboxes are virtual devices that can be used for communication among processes. You accomplish actual data transfer by using OpenVMS RMS or I/O services. When the Create Mailbox and Assign Channel (SYS$CREMBX) system service creates a mailbox, it also assigns a channel to it for use by the creating process. Other processes can then assign channels to the mailbox using either the SYS$CREMBX or SYS$ASSIGN system service.
The SYS$CREMBX system service creates the mailbox. The SYS$CREMBX system service identifies a mailbox by a user-specified logical name and assigns it an equivalence name. The equivalence name is a physical device name in the format MBAn, where n is a unit number. The equivalence name has the terminal attribute.
When another process assigns a channel to the mailbox with the SYS$CREMBX or SYS$ASSIGN system service, it can identify the mailbox by its logical name. The service automatically translates the logical name. The process can obtain the MBAn name by translating the logical name (with the SYS$TRNLNM system service), or it can call the Get Device/Volume Information (SYS$GETDVI) system service to obtain the unit number and the physical device name.
On VAX systems, channels assigned to mailboxes can be either bidirectional or unidirectional. Bidirectional channels (read/write) allow both SYS$QIO read and SYS$QIO write requests to be issued to the channel. Unidirectional channels (read-only or write-only) allow only a read request or a write request to the channel. The unidirectional channels and unidirectional $QIO function modifiers provide for greater synchronization between users of the mailbox.
On VAX systems, the Create Mailbox and Assign Channel (SYS$CREMBX) and Assign I/O Channel (SYS$ASSIGN) system services use the flags argument to enable unidirectional channels. If the flags argument is not specified or is zero, then the channel assigned to the mailbox is bidirectional (read/write). For more information, see the discussion and programming examples in the mailbox driver chapter in the OpenVMS I/O User's Reference Manual. Chapter 2 of this manual also discusses the use of mailboxes.
Mailboxes are either temporary or permanent. You need the user privileges TMPMBX and PRMMBX to create temporary and permanent mailboxes, respectively.
For a temporary mailbox, the SYS$CREMBX service enters the logical name and equivalence name in the logical name table LNM$TEMPORARY_MAILBOX. This logical name table name usually specifies the LNM$JOB logical name table name. The system deletes a temporary mailbox when no more channels are assigned to it.
For a permanent mailbox, the SYS$CREMBX service enters the logical name and equivalence name in the logical name table LNM$PERMANENT_MAILBOX. This logical name table name usually specifies the LNM$SYSTEM logical name table name. Permanent mailboxes continue to exist until they are specifically marked for deletion with the Delete Mailbox (SYS$DELMBX) system service.
The following example shows how processes can communicate by means of a mailbox:
      
 
/* Process ORION */ 
 
#include <descrip.h> 
#include <iodef.h> 
#include <lib$routines.h> 
#include <ssdef.h> 
#include <starlet.h> 
#include <stdio.h> 
#define MBXBUFSIZ 128 
#define MBXBUFQUO 384 
 
/* I/O status block */ 
struct { 
                unsigned short iostat, iolen; 
                unsigned int remainder; 
}mbxiosb; 
 
 
main() { 
        void *p1, mbxast(); 
        char mbuffer[MBXBUFSIZ], prmflg=0; 
        unsigned short mbxchan, mbxiosb; 
        unsigned int status, outlen; 
        unsigned int mbuflen=MBXBUFSIZ, bufquo=MBXBUFQUO, promsk=0; 
        $DESCRIPTOR(mblognam,"GROUP100_MAILBOX"); 
 
/* Create a mailbox */ 
        status = SYS$CREMBX( prmflg,         /* Permanent or temporary */  (1)
                             &mbxchan,       /* chan - channel number */ 
                             mbuflen,        /* maxmsg - buffer length */ 
                             bufquo,         /* bufquo - quota */ 
                             promsk,         /* promsk - protection mask */ 
                             0,              /* acmode - access mode */ 
                             &mblognam,      /* lognam - mailbox logical name */ 
                             0);             /* flags -  options */ 
        if (!$VMS_STATUS_SUCCESS(status)) 
                LIB$SIGNAL(status); 
   .
   .
   .
/* Request I/O */ 
        status = SYS$QIO(0,               /* efn - event flag */   (2)
                          mbxchan,        /* chan - channel number */ 
                          IO$_READVBLK,   /* func - function modifier */ 
                          &mbxiosb,       /* iosb - I/O status block */ 
                          &mbxast,        /* astadr - AST routine */ 
                          &mbuffer,       /* p1 - output buffer */ 
                          mbuflen);       /* p2 - length of buffer */ 
        if (!$VMS_STATUS_SUCCESS(status)) 
                LIB$SIGNAL(status); 
   .
   .
   .
 
} 
 
void mbxast(void) {                                               (3)
 
        if (mbxiosb.iostat != SS$_NORMAL) 
 
        status = SYS$QIOW(..., &mbuffer, &outlen,...) 
        if (!$VMS_STATUS_SUCCESS(status)) 
                LIB$SIGNAL(status); 
 
        return; 
} 
 
 
/* Process Cygnus */ 
 
#include <descrip.h> 
#include <iodef.h> 
#include <lib$routines.h> 
#include <ssdef.h> 
#include <starlet.h> 
#include <stdio.h> 
#include <stsdef.h> 
#define MBXBUFSIZ 128 
 
main() { 
 
        unsigned short int mailchan; 
        unsigned int status, outlen; 
        char outbuf[MBXBUFSIZ]; 
        $DESCRIPTOR(mailbox,"GROUP100_MAILBOX"); 
 
        status = SYS$ASSIGN(&mailbox, &mailchan, 0, 0, 0);            (4)
        if (!$VMS_STATUS_SUCCESS(status)) 
                LIB$SIGNAL(status); 
   .
   .
   .
 
        status = SYS$QIOW(0, mailchan, 0, 0, 0, 0, &outbuf, outlen, 0, 0, 0, 0) 
        if (!$VMS_STATUS_SUCCESS(status)) 
                LIB$SIGNAL(status); 
   .
   .
   .
 
} 
 
 | 
The lognam argument to the SYS$CREMBX service specifies a descriptor that points to a character string for the mailbox name.
Translation of the lognam argument proceeds as follows:
For example, assume that you have made the following logical name assignment:
      $ DEFINE MBX$CHKPNT CHKPNT_001  | 
Assume also that your program contains the following statements:
      
        $DESCRIPTOR(mbxdesc,"CHKPNT"); 
   .
   .
   .
        status = SYS$CREMBX(...,&mbxdesc,...); 
 | 
The following logical name translation takes place:
Because further translation is unsuccessful, the logical name CHKPNT_001 is created with the equivalence name MBAn (n is a number assigned by the system).
There are two exceptions to the logical name translation method discussed in this section:
The system uses mailboxes for communication among system processes. All system mailbox messages contain, in the first word of the message, a constant that identifies the sender of the message. These constants have symbolic names (defined in the $MSGDEF macro) in the following format:
      MSG$_sender  | 
  
The symbolic names included in the $MSGDEF macro and their meanings are as follows:
| Symbolic Name | Meaning | 
|---|---|
| MSG$_TRMUNSOLIC | Unsolicited terminal data | 
| MSG$_CRUNSOLIC | Unsolicited card reader data | 
| MSG$_ABORT | Network partner aborted link | 
| MSG$_CONFIRM | Network connect confirm | 
| MSG$_CONNECT | Network inbound connect initiate | 
| MSG$_DISCON | Network partner disconnected | 
| MSG$_EXIT | Network partner exited prematurely | 
| MSG$_INTMSG | Network interrupt message; unsolicited data | 
| MSG$_PATHLOST | Network path lost to partner | 
| MSG$_PROTOCOL | Network protocol error | 
| MSG$_REJECT | Network connect reject | 
| MSG$_THIRDPARTY | Network third-party disconnect | 
| MSG$_TIMEOUT | Network connect timeout | 
| MSG$_NETSHUT | Network shutting down | 
| MSG$_NODEACC | Node has become accessible | 
| MSG$_NODEINACC | Node has become inaccessible | 
| MSG$_EVTAVL | Events available to DECnet Event Logger | 
| MSG$_EVTRCVCHG | Event receiver database change | 
| MSG$_INCDAT | Unsolicited incoming data available | 
| MSG$_RESET | Request to reset the virtual circuit | 
| MSG$_LINUP | PVC line up | 
| MSG$_LINDWN | PVC line down | 
| MSG$_EVTXMTCHG | Event transmitter database change | 
The remainder of the message contains variable information, depending on the system component that is sending the message.
The format of the variable information for each message type is 
documented with the system function that uses the mailbox.
11.20.3 Mailboxes for Process Termination Messages
When a process creates another process, it can specify the unit number of a mailbox as an argument to the Create Process ($CREPRC) system service. When you delete the created process, the system sends a message to the specified termination mailbox.
You cannot use a mailbox in memory shared by multiple processors as a 
process termination mailbox.
11.21 Example of Using I/O Services
In the following Fortran example, the first program, SEND.FOR, creates a mailbox named MAIL_BOX, writes data to it, and then indicates the end of the data by writing an end-of-file message.
The second program, RECEIVE.FOR, creates a mailbox with the same logical name, MAIL_BOX. It reads the messages from the mailbox into an array. It stops the read operations when a read operation generates an end-of-file message and the second longword of the I/O status block is nonzero. By checking that the I/O status block is nonzero, the second program confirms that the writing process sent the end-of-file message.
The processes use common event flag number 64 to ensure that SEND.FOR does not exit until RECEIVE.FOR has established a channel to the mailbox. (If RECEIVE.FOR executes first, an error occurs because SYS$ASSIGN cannot find the mailbox.)
      
 
                          SEND.FOR 
INTEGER STATUS 
 
! Name and channel number for mailbox 
CHARACTER*(*) MBX_NAME 
PARAMETER (MBX_NAME = 'MAIL_BOX') 
INTEGER*2 MBX_CHAN 
 
! Mailbox message 
CHARACTER*80 MBX_MESSAGE 
INTEGER LEN 
 
CHARACTER*80 MESSAGES (255) 
INTEGER MESSAGE_LEN (255) 
INTEGER MAX_MESSAGE 
PARAMETER (MAX_MESSAGE = 255) 
 
! I/O function codes and status block 
INCLUDE '($IODEF)' 
INTEGER*4 WRITE_CODE 
INTEGER*2 IOSTAT, 
2         MSG_LEN 
INTEGER READER_PID 
COMMON /IOBLOCK/ IOSTAT, 
2                MSG_LEN, 
2                READER_PID 
 
! System routines 
INTEGER SYS$CREMBX, 
2       SYS$ASCEFC, 
2       SYS$WAITFR, 
2       SYS$QIOW 
 
! Create the mailbox. 
STATUS = SYS$CREMBX (, 
2                    MBX_CHAN, 
2                    ,,,, 
2                    MBX_NAME) 
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) 
 
! Fill MESSAGES array 
                                . 
                                . 
                                . 
! Write the messages. 
DO I = 1, MAX_MESSAGE 
  WRITE_CODE = IO$_WRITEVBLK .OR. IO$M_NOW 
  MBX_MESSAGE = MESSAGES(I) 
  LEN = MESSAGE_LEN(I) 
  STATUS = SYS$QIOW (, 
2                    %VAL(MBX_CHAN),     ! Channel 
2                    %VAL(WRITE_CODE),   ! I/O code 
2                    IOSTAT,             ! Status block 
2                    ,, 
2                    %REF(MBX_MESSAGE),  ! P1 
2                    %VAL(LEN),,,,)      ! P2 
  IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) 
  IF (.NOT. IOSTAT) CALL LIB$SIGNAL (%VAL(STATUS)) 
END DO 
 
! Write end of file 
WRITE_CODE = IO$_WRITEOF .OR. IO$M_NOW 
STATUS = SYS$QIOW (, 
2                  %VAL(MBX_CHAN),     ! Channel 
2                  %VAL(WRITE_CODE),   ! End of file code 
2                  IOSTAT,             ! Status block 
2                  ,,,,,,,) 
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) 
IF (.NOT. IOSTAT) CALL LIB$SIGNAL (%VAL(IOSTAT)) 
                                . 
                                . 
                                . 
! Make sure cooperating process can read the information 
! by waiting for it to assign a channel to the mailbox. 
 
STATUS = SYS$ASCEFC (%VAL(64), 
2                    'CLUSTER',,) 
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) 
STATUS = SYS$WAITFR (%VAL(64)) 
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) 
 
END 
 
 
                        RECEIVE.FOR 
INTEGER STATUS 
 
INCLUDE '($IODEF)' 
INCLUDE '($SSDEF)' 
 
! Name and channel number for mailbox 
CHARACTER*(*) MBX_NAME 
PARAMETER (MBX_NAME = 'MAIL_BOX') 
INTEGER*2 MBX_CHAN 
 
! QIO function code 
INTEGER READ_CODE 
 
! Mailbox message 
CHARACTER*80 MBX_MESSAGE 
INTEGER*4    LEN 
 
! Message arrays 
CHARACTER*80 MESSAGES (255) 
INTEGER*4    MESSAGE_LEN (255) 
 
! I/O status block 
INTEGER*2 IOSTAT, 
2         MSG_LEN 
INTEGER READER_PID 
COMMON /IOBLOCK/ IOSTAT, 
2                MSG_LEN, 
2                READER_PID 
! System routines 
INTEGER SYS$ASSIGN, 
2       SYS$ASCEFC, 
2       SYS$SETEF, 
2       SYS$QIOW 
 
! Create the mailbox and let the other process know 
STATUS = SYS$ASSIGN (MBX_NAME, 
2                    MBX_CHAN,,,) 
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) 
STATUS = SYS$ASCEFC (%VAL(64), 
2                    'CLUSTER',,) 
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) 
STATUS = SYS$SETEF (%VAL(64)) 
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) 
 
! Read first message 
READ_CODE = IO$_READVBLK .OR. IO$M_NOW 
LEN = 80 
STATUS = SYS$QIOW (, 
2                  %VAL(MBX_CHAN),     ! Channel 
2                  %VAL(READ_CODE),    ! Function code 
2                  IOSTAT,             ! Status block 
2                  ,, 
2                  %REF(MBX_MESSAGE),  ! P1 
2                  %VAL(LEN),,,,)      ! P2 
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) 
IF ((.NOT. IOSTAT) .AND. 
2  (IOSTAT .NE. SS$_ENDOFFILE)) THEN 
  CALL LIB$SIGNAL (%VAL(IOSTAT)) 
ELSE IF (IOSTAT .NE. SS$_ENDOFFILE) THEN 
  I = 1 
  MESSAGES(I) = MBX_MESSAGE 
  MESSAGE_LEN(I) = MSG_LEN 
END IF 
 
! Read messages until cooperating process writes end-of-file 
DO WHILE (.NOT. ((IOSTAT .EQ. SS$_ENDOFFILE) .AND. 
2                (READER_PID .NE. 0))) 
 
  STATUS = SYS$QIOW (, 
2                    %VAL(MBX_CHAN),     ! Channel 
2                    %VAL(READ_CODE),    ! Function code 
2                    IOSTAT,             ! Status block 
2                    ,, 
2                    %REF(MBX_MESSAGE),  ! P1 
2                    %VAL(LEN),,,,)      ! P2 
 
   IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) 
   IF ((.NOT. IOSTAT) .AND. 
2     (IOSTAT .NE. SS$_ENDOFFILE)) THEN 
     CALL LIB$SIGNAL (%VAL(IOSTAT)) 
  ELSE IF (IOSTAT .NE. SS$_ENDOFFILE) THEN 
    I = I + 1 
    MESSAGES(I) = MBX_MESSAGE 
    MESSAGE_LEN(I) = MSG_LEN 
   END IF 
 
END DO 
                                . 
                                . 
                                . 
 | 
| Previous | Next | Contents | Index | 
 
 
 
  
 
  
 
  
 
  
 
  
 
  
      | 
 
           |  
     
|  
              
 
              
            Copyright © Compaq Computer Corporation 1998. All rights reserved. Legal |  
     
 
           
           
5841PRO_032.HTML
           
           
          |