/* ** COPYRIGHT (c) 1992, 1997, 1998 BY ** DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS. ** ALL RIGHTS RESERVED. ** ** THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ** ONLY IN ACCORDANCE OF THE TERMS OF SUCH LICENSE AND WITH THE ** INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER ** COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY ** OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY ** TRANSFERRED. ** ** THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE ** AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT ** CORPORATION. ** ** DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ** SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. */ /* **++ ** Facility: ** ** Examples ** ** Version: V1.3 ** ** Abstract: ** ** GBLSEC.C -- global section example code ** ** Creates a backing storage file, and maps a global section ** into process virtual address space (twice), and then shows ** basic section operations. ** ** Author: ** Stephen Hoffman ** ** Creation Date: 2-Jan-1990 ** ** Modification History: ** ** Stephen Hoffman remove unused "stubs" ** V1.1 27-Aug-1997 ** Stephen Hoffman added sys$updsecw calls. ** V1.2 07-Apr-1998 ** Stephen Hoffman added sys$updsecw calls. ** V1.3 04-Feb-2000 ** Stephen Hoffman added explicit cleanup via $dassgn. ** ** Build Instructions: ** ** $ CC/DECC/PREFIX=ALL GBLSEC ** $ LINK GBLSEC ** $ RUN GBLSEC ** **-- */ #include #include #include #include #include #include #include #include #include #include #define P0SPACE ((void*)0x0200) #define GBLSECMAX 10 /* // Open the specified file, using basic RMS calls... // (The FAB$M_UFO is typically used with backing storage files.) */ RmsFileOpen( struct FAB *fab, char *FileName, char *DefFileName ) { int RetStat; *fab = cc$rms_fab; fab->fab$l_alq = 10; fab->fab$b_fac = 0; fab->fab$l_fop = FAB$M_UFO | FAB$M_CIF; fab->fab$b_shr = FAB$M_UPI | FAB$M_SHRPUT | FAB$M_SHRGET | FAB$M_SHRUPD; fab->fab$l_fna = FileName; fab->fab$b_fns = strlen( FileName ); fab->fab$l_dna = DefFileName; fab->fab$b_dns = strlen( DefFileName ); /* // Create or open the specified file -- it is created if // not found, else it is opened. (See the FAB$M_CIF bit.) */ RetStat = sys$create( fab, 0, 0 ); if ( !$VMS_STATUS_SUCCESS( RetStat ) ) return RetStat; return RetStat; } main() { int RetStat; $DESCRIPTOR( SecDsc, "FACNAM_GLOBAL_SECTION_NAME" ); int i; unsigned short int Iosb[4]; void *InAdr1[2] = {P0SPACE,P0SPACE}; void *RetAdr1[2] = {NULL,NULL}; void *InAdr2[2] = {P0SPACE,P0SPACE}; void *RetAdr2[2] = {NULL,NULL}; void *InAdr3[2] = {P0SPACE,P0SPACE}; void *RetAdr3[2] = {NULL,NULL}; struct FAB Fab1, Fab2, Fab3; struct SecStructDef { int Gblsec[GBLSECMAX]; } *Sec1, *Sec2, *Sec3; /* // Create and open, and then map the global section... // Then overlay a structure onto the global section... */ RetStat = RmsFileOpen( &Fab1, "GBLSEC", "SYS$SCRATCH:.TMP" ); if (!$VMS_STATUS_SUCCESS( RetStat )) lib$signal( RetStat ); RetStat = sys$crmpsc( InAdr1, RetAdr1, PSL$C_USER, SEC$M_EXPREG | SEC$M_WRT | SEC$M_DZRO | SEC$M_GBL, &SecDsc, 0, 0, Fab1.fab$l_stv, 1, 0, 0, 0 ); if (!$VMS_STATUS_SUCCESS( RetStat )) lib$signal( RetStat ); Sec1 = RetAdr1[0]; /* // Create and open, and then map the global section. Again. // Then overlay a structure onto the global section... */ RetStat = RmsFileOpen( &Fab2, "GBLSEC", "SYS$SCRATCH:.TMP" ); if (!$VMS_STATUS_SUCCESS( RetStat )) lib$signal( RetStat ); RetStat = sys$crmpsc( InAdr2, RetAdr2, PSL$C_USER, SEC$M_EXPREG | SEC$M_WRT | SEC$M_GBL, &SecDsc, 0, 0, Fab2.fab$l_stv, 1, 0, 0, 0 ); if (!$VMS_STATUS_SUCCESS( RetStat )) lib$signal( RetStat ); Sec2 = RetAdr2[0]; /* // Now write some data into one "window"... And then read the // data back in from the other "window". */ for ( i = 0; i < GBLSECMAX; i++) Sec1->Gblsec[i] = i; printf( "Sec1->Gblsec is located at %p\n", RetAdr1[0] ); Sec1 = RetAdr1[0]; for ( i = 0; i < GBLSECMAX; i++) printf( " Sec1->Gblsec[%d] = %d\n", i, Sec1->Gblsec[i] ); printf( "Sec2->Gblsec is located at %p\n", RetAdr2[0] ); for ( i = 0; i < GBLSECMAX; i++) printf( " Sec2->Gblsec[%d] = %d\n", i, Sec2->Gblsec[i] ); /* // Now flush out the contents of the section to disk... // Twice. Once for each of the two ranges mapped in... */ RetStat = sys$updsecw( RetAdr1, NULL, PSL$C_USER, 0, 0, Iosb, NULL, NULL ); if (!$VMS_STATUS_SUCCESS( RetStat )) lib$signal( RetStat ); if (!$VMS_STATUS_SUCCESS( Iosb[0] )) lib$signal( Iosb[0] ); RetStat = sys$updsecw( RetAdr2, NULL, PSL$C_USER, 0, 0, Iosb, NULL, NULL ); if (!$VMS_STATUS_SUCCESS( RetStat )) lib$signal( RetStat ); if (!$VMS_STATUS_SUCCESS( Iosb[0] )) lib$signal( Iosb[0] ); /* // Now delete the section virtual address space range... */ RetStat = sys$deltva( RetAdr1, NULL, PSL$C_USER ); if (!$VMS_STATUS_SUCCESS( RetStat )) lib$signal( RetStat ); RetStat = sys$deltva( RetAdr2, NULL, PSL$C_USER ); if (!$VMS_STATUS_SUCCESS( RetStat )) lib$signal( RetStat ); /* // Now remap the second section, into the next available // address space. (This may well be in one of the same // virtual address ranges we just deleted.) */ RetStat = RmsFileOpen( &Fab3, "GBLSEC", "SYS$SCRATCH:.TMP" ); if (!$VMS_STATUS_SUCCESS( RetStat )) lib$signal( RetStat ); RetStat = sys$crmpsc( InAdr3, RetAdr3, PSL$C_USER, SEC$M_EXPREG | SEC$M_WRT | SEC$M_GBL, &SecDsc, 0, 0, Fab3.fab$l_stv, 1, 0, 0, 0 ); if (!$VMS_STATUS_SUCCESS( RetStat )) lib$signal( RetStat ); Sec3 = RetAdr3[0]; /* // And redisplay the contents of the section, as was // maintained by the backing storage file... */ printf( "Sec3->Gblsec is located at %p\n", RetAdr3[0] ); for ( i = 0; i < GBLSECMAX; i++) printf( " Sec3->Gblsec[%d] = %d\n", i, Sec3->Gblsec[i] ); /* // Close the channels to the file. Since we used the UFO option, // we cannot and do not use sys$close, we must use sys$dassgn... */ RetStat = sys$dassgn( Fab1.fab$l_stv ); if (!$VMS_STATUS_SUCCESS( RetStat )) lib$signal( RetStat ); RetStat = sys$dassgn( Fab2.fab$l_stv ); if (!$VMS_STATUS_SUCCESS( RetStat )) lib$signal( RetStat ); RetStat = sys$dassgn( Fab3.fab$l_stv ); if (!$VMS_STATUS_SUCCESS( RetStat )) lib$signal( RetStat ); return SS$_NORMAL; }