Annotation of GNUtools/emacs/src/vmsmap.c, revision 1.1.1.1

1.1       root        1: /* VMS mapping of data and alloc arena for GNU Emacs.
                      2:    Copyright (C) 1986, 1987 Free Software Foundation, Inc.
                      3:    
                      4: This file is part of GNU Emacs.
                      5: 
                      6: GNU Emacs is free software; you can redistribute it and/or modify
                      7: it under the terms of the GNU General Public License as published by
                      8: the Free Software Foundation; either version 1, or (at your option)
                      9: any later version.
                     10: 
                     11: GNU Emacs is distributed in the hope that it will be useful,
                     12: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14: GNU General Public License for more details.
                     15: 
                     16: You should have received a copy of the GNU General Public License
                     17: along with GNU Emacs; see the file COPYING.  If not, write to
                     18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     19: 
                     20: /* Written by Mukesh Prasad.  */
                     21: 
                     22: #ifdef VMS
                     23: 
                     24: #include "config.h"
                     25: #include "lisp.h"
                     26: #include <rab.h>
                     27: #include <fab.h>
                     28: #include <rmsdef.h>
                     29: #include <secdef.h>
                     30: 
                     31: /* RMS block size */
                     32: #define        BLOCKSIZE       512
                     33: 
                     34: /* Maximum number of bytes to be written in one RMS write.
                     35:  * Must be a multiple of BLOCKSIZE.
                     36:  */
                     37: #define        MAXWRITE        (BLOCKSIZE * 30)
                     38: 
                     39: /* This funniness is to ensure that sdata occurs alphabetically BEFORE the
                     40:    $DATA psect and that edata occurs after ALL Emacs psects.  This is
                     41:    because the VMS linker sorts all psects in a cluster alphabetically
                     42:    during the linking, unless you use the cluster_psect command.  Emacs
                     43:    uses the cluster command to group all Emacs psects into one cluster;
                     44:    this keeps the dumped data separate from any loaded libraries. */
                     45: 
                     46: #ifdef __GNUC__
                     47: /* We need a large sdata array because otherwise the impure storage will end up
                     48:    in low memory, and this will screw up garbage collection (Emacs will not
                     49:    be able to tell the difference between a string length and an address).
                     50:    This array guarantees that the impure storage is at a sufficiently high
                     51:    address so that this problem will not occur. */
                     52: char sdata[8192] asm("_$$PsectAttributes_NOOVR$$$D$ATA") ;
                     53: char edata[512]  asm("_$$PsectAttributes_NOOVR$$__DATA") ;
                     54: #else
                     55: globaldef {"$D$ATA"} char sdata[512]; /* Start of saved data area */
                     56: globaldef {"__DATA"} char edata[512]; /* End of saved data area */
                     57: #endif
                     58: 
                     59: /* Structure to write into first block of map file.
                     60:  */
                     61: 
                     62: struct map_data
                     63: {
                     64:   char * sdata;                        /* Start of data area */
                     65:   char * edata;                        /* End of data area */
                     66:   int  datablk;                        /* Block in file to map data area from/to */
                     67: };
                     68: 
                     69: static void fill_fab (), fill_rab ();
                     70: static int write_data ();
                     71: 
                     72: extern char *start_of_data ();
                     73: extern int vms_out_initial;    /* Defined in malloc.c */
                     74: 
                     75: /* Maps in the data and alloc area from the map file.
                     76:  */
                     77: 
                     78: int
                     79: mapin_data (name)
                     80:      char * name;
                     81: {
                     82:   struct FAB fab;
                     83:   struct RAB rab;
                     84:   int status, size;
                     85:   int inadr[2];
                     86:   struct map_data map_data;
                     87: 
                     88: 
                     89:   /* Open map file. */
                     90:   fab = cc$rms_fab;
                     91:   fab.fab$b_fac = FAB$M_BIO|FAB$M_GET;
                     92:   fab.fab$l_fna = name;
                     93:   fab.fab$b_fns = strlen (name);
                     94:   status = sys$open (&fab);
                     95:   if (status != RMS$_NORMAL)
                     96:     {
                     97:       printf ("Map file not available, running bare Emacs....\n");
                     98:       return 0;                        /* Map file not available */
                     99:     }
                    100:   /* Connect the RAB block */
                    101:   rab = cc$rms_rab;
                    102:   rab.rab$l_fab = &fab;
                    103:   rab.rab$b_rac = RAB$C_SEQ;
                    104:   rab.rab$l_rop = RAB$M_BIO;
                    105:   status = sys$connect (&rab);
                    106:   if (status != RMS$_NORMAL)
                    107:     lib$stop (status);
                    108:   /* Read the header data */
                    109:   rab.rab$l_ubf = (char *) &map_data;
                    110:   rab.rab$w_usz = sizeof (map_data);
                    111:   rab.rab$l_bkt = 0;
                    112:   status = sys$read (&rab);
                    113:   if (status != RMS$_NORMAL)
                    114:     lib$stop (status);
                    115:   status = sys$close (&fab);
                    116:   if (status != RMS$_NORMAL)
                    117:     lib$stop (status);
                    118:   if (map_data.sdata != start_of_data ())
                    119:     {
                    120:       printf ("Start of data area has moved: cannot map in data.\n");
                    121:       return 0;
                    122:     }
                    123:   if (map_data.edata != edata)
                    124:     {
                    125:       printf ("End of data area has moved: cannot map in data.\n");
                    126:       return 0;
                    127:     }
                    128:   fab.fab$l_fop |= FAB$M_UFO;
                    129:   status = sys$open (&fab);
                    130:   if (status != RMS$_NORMAL)
                    131:     lib$stop (status);
                    132:   /* Map data area. */
                    133:   inadr[0] = (int) map_data.sdata;
                    134:   inadr[1] = (int) map_data.edata;
                    135:   status = sys$crmpsc (inadr, 0, 0, SEC$M_CRF | SEC$M_WRT, 0, 0, 0,
                    136:                       fab.fab$l_stv, 0, map_data.datablk, 0, 0);
                    137:   if (! (status & 1))
                    138:     lib$stop (status);
                    139: }
                    140: 
                    141: /* Writes the data and alloc area to the map file.
                    142:  */
                    143: mapout_data (into)
                    144:      char * into;
                    145: {
                    146:   struct FAB fab;
                    147:   struct RAB rab;
                    148:   int status;
                    149:   struct map_data map_data;
                    150:   int datasize, msize;
                    151:  
                    152:   if (vms_out_initial)
                    153:     {
                    154:       error ("Out of initial allocation. Must rebuild emacs with more memory (VMS_ALLOCATION_SIZE).");
                    155:       return 0;
                    156:     }
                    157:   map_data.sdata = start_of_data ();
                    158:   map_data.edata = edata;
                    159:   datasize = map_data.edata - map_data.sdata + 1;
                    160:   map_data.datablk = 2 + (sizeof (map_data) + BLOCKSIZE - 1) / BLOCKSIZE;
                    161:   /* Create map file. */
                    162:   fab = cc$rms_fab;
                    163:   fab.fab$b_fac = FAB$M_BIO|FAB$M_PUT;
                    164:   fab.fab$l_fna = into;
                    165:   fab.fab$b_fns = strlen (into);
                    166:   fab.fab$l_fop = FAB$M_CBT;
                    167:   fab.fab$b_org = FAB$C_SEQ;
                    168:   fab.fab$b_rat = 0;
                    169:   fab.fab$b_rfm = FAB$C_VAR;
                    170:   fab.fab$l_alq = 1 + map_data.datablk +
                    171:                      ((datasize + BLOCKSIZE - 1) / BLOCKSIZE);
                    172:   status = sys$create (&fab);
                    173:   if (status != RMS$_NORMAL)
                    174:     {
                    175:       error ("Could not create map file");
                    176:       return 0;
                    177:     }
                    178:   /* Connect the RAB block */
                    179:   rab = cc$rms_rab;
                    180:   rab.rab$l_fab = &fab;
                    181:   rab.rab$b_rac = RAB$C_SEQ;
                    182:   rab.rab$l_rop = RAB$M_BIO;
                    183:   status = sys$connect (&rab);
                    184:   if (status != RMS$_NORMAL)
                    185:     {
                    186:       error ("RMS connect to map file failed");
                    187:       return 0;
                    188:     }
                    189:   /* Write the header */
                    190:   rab.rab$l_rbf = (char *) &map_data;
                    191:   rab.rab$w_rsz = sizeof (map_data);
                    192:   status = sys$write (&rab);
                    193:   if (status != RMS$_NORMAL)
                    194:     {
                    195:       error ("RMS write (header) to map file failed");
                    196:       return 0;
                    197:     }
                    198:   if (! write_data (&rab, map_data.datablk, map_data.sdata, datasize))
                    199:     return 0;
                    200:   status = sys$close (&fab);
                    201:   if (status != RMS$_NORMAL)
                    202:     {
                    203:       error ("RMS close on map file failed");
                    204:       return 0;
                    205:     }
                    206:   return 1;
                    207: }
                    208: 
                    209: static int
                    210: write_data (rab, firstblock, data, length)
                    211:      struct RAB * rab;
                    212:      char * data;
                    213: {
                    214:   int status;
                    215:   
                    216:   rab->rab$l_bkt = firstblock;
                    217:   while (length > 0)
                    218:     {
                    219:       rab->rab$l_rbf = data;
                    220:       rab->rab$w_rsz = length > MAXWRITE ? MAXWRITE : length;
                    221:       status = sys$write (rab, 0, 0);
                    222:       if (status != RMS$_NORMAL)
                    223:        {
                    224:          error ("RMS write to map file failed");
                    225:          return 0;
                    226:        }
                    227:       data = &data[MAXWRITE];
                    228:       length -= MAXWRITE;
                    229:       rab->rab$l_bkt = 0;
                    230:     }
                    231:   return 1;
                    232: }                              /* write_data */
                    233: 
                    234: #endif /* VMS */
                    235: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.