|
|
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 distributed in the hope that it will be useful, ! 7: but WITHOUT ANY WARRANTY. No author or distributor ! 8: accepts responsibility to anyone for the consequences of using it ! 9: or for whether it serves any particular purpose or works at all, ! 10: unless he says so in writing. Refer to the GNU Emacs General Public ! 11: License for full details. ! 12: ! 13: Everyone is granted permission to copy, modify and redistribute ! 14: GNU Emacs, but only under the conditions described in the ! 15: GNU Emacs General Public License. A copy of this license is ! 16: supposed to have been given to you along with GNU Emacs so you ! 17: can know your rights and responsibilities. It should be in a ! 18: file named COPYING. Among other things, the copyright notice ! 19: and this notice must be preserved on all copies. */ ! 20: ! 21: /* Written by Mukesh Prasad. */ ! 22: ! 23: #ifdef VMS ! 24: ! 25: #include "config.h" ! 26: #include "lisp.h" ! 27: #include <rab.h> ! 28: #include <fab.h> ! 29: #include <rmsdef.h> ! 30: #include <secdef.h> ! 31: ! 32: /* RMS block size */ ! 33: #define BLOCKSIZE 512 ! 34: ! 35: /* Maximum number of bytes to be written in one RMS write. ! 36: * Must be a multiple of BLOCKSIZE. ! 37: */ ! 38: #define MAXWRITE (BLOCKSIZE * 30) ! 39: ! 40: /* This funniness is to ensure that sdata occurs alphabetically BEFORE the ! 41: $DATA psect and that edata occurs after ALL Emacs psects. This is ! 42: because the VMS linker sorts all psects in a cluster alphabetically ! 43: during the linking, unless you use the cluster_psect command. Emacs ! 44: uses the cluster command to group all Emacs psects into one cluster; ! 45: this keeps the dumped data separate from any loaded libraries. */ ! 46: ! 47: globaldef {"$D$ATA"} char sdata[512]; /* Start of saved data area */ ! 48: globaldef {"__DATA"} char edata[512]; /* End of saved data area */ ! 49: ! 50: /* Structure to write into first block of map file. ! 51: */ ! 52: ! 53: struct map_data ! 54: { ! 55: char * sdata; /* Start of data area */ ! 56: char * edata; /* End of data area */ ! 57: int datablk; /* Block in file to map data area from/to */ ! 58: }; ! 59: ! 60: static void fill_fab (), fill_rab (); ! 61: static int write_data (); ! 62: ! 63: extern char *start_of_data (); ! 64: extern int vms_out_initial; /* Defined in malloc.c */ ! 65: ! 66: /* Maps in the data and alloc area from the map file. ! 67: */ ! 68: ! 69: int ! 70: mapin_data (name) ! 71: char * name; ! 72: { ! 73: struct FAB fab; ! 74: struct RAB rab; ! 75: int status, size; ! 76: int inadr[2]; ! 77: struct map_data map_data; ! 78: ! 79: /* Open map file. */ ! 80: fab = cc$rms_fab; ! 81: fab.fab$b_fac = FAB$M_BIO|FAB$M_GET; ! 82: fab.fab$l_fna = name; ! 83: fab.fab$b_fns = strlen (name); ! 84: status = sys$open (&fab); ! 85: if (status != RMS$_NORMAL) ! 86: { ! 87: printf ("Map file not available, running bare Emacs....\n"); ! 88: return 0; /* Map file not available */ ! 89: } ! 90: /* Connect the RAB block */ ! 91: rab = cc$rms_rab; ! 92: rab.rab$l_fab = &fab; ! 93: rab.rab$b_rac = RAB$C_SEQ; ! 94: rab.rab$l_rop = RAB$M_BIO; ! 95: status = sys$connect (&rab); ! 96: if (status != RMS$_NORMAL) ! 97: lib$stop (status); ! 98: /* Read the header data */ ! 99: rab.rab$l_ubf = &map_data; ! 100: rab.rab$w_usz = sizeof (map_data); ! 101: rab.rab$l_bkt = 0; ! 102: status = sys$read (&rab); ! 103: if (status != RMS$_NORMAL) ! 104: lib$stop (status); ! 105: status = sys$close (&fab); ! 106: if (status != RMS$_NORMAL) ! 107: lib$stop (status); ! 108: if (map_data.sdata != start_of_data ()) ! 109: { ! 110: printf ("Start of data area has moved: cannot map in data.\n"); ! 111: return 0; ! 112: } ! 113: if (map_data.edata != edata) ! 114: { ! 115: printf ("End of data area has moved: cannot map in data.\n"); ! 116: return 0; ! 117: } ! 118: fab.fab$l_fop |= FAB$M_UFO; ! 119: status = sys$open (&fab); ! 120: if (status != RMS$_NORMAL) ! 121: lib$stop (status); ! 122: /* Map data area. */ ! 123: inadr[0] = map_data.sdata; ! 124: inadr[1] = map_data.edata; ! 125: status = sys$crmpsc (inadr, 0, 0, SEC$M_CRF | SEC$M_WRT, 0, 0, 0, ! 126: fab.fab$l_stv, 0, map_data.datablk, 0, 0); ! 127: if (! (status & 1)) ! 128: lib$stop (status); ! 129: } ! 130: ! 131: /* Writes the data and alloc area to the map file. ! 132: */ ! 133: mapout_data (into) ! 134: char * into; ! 135: { ! 136: struct FAB fab; ! 137: struct RAB rab; ! 138: int status; ! 139: struct map_data map_data; ! 140: int datasize, msize; ! 141: ! 142: if (vms_out_initial) ! 143: { ! 144: error ("Out of initial allocation. Must rebuild emacs with more memory (VMS_ALLOCATION_SIZE)."); ! 145: return 0; ! 146: } ! 147: map_data.sdata = start_of_data (); ! 148: map_data.edata = edata; ! 149: datasize = map_data.edata - map_data.sdata + 1; ! 150: map_data.datablk = 2 + (sizeof (map_data) + BLOCKSIZE - 1) / BLOCKSIZE; ! 151: /* Create map file. */ ! 152: fab = cc$rms_fab; ! 153: fab.fab$b_fac = FAB$M_BIO|FAB$M_PUT; ! 154: fab.fab$l_fna = into; ! 155: fab.fab$b_fns = strlen (into); ! 156: fab.fab$l_fop = FAB$M_CBT; ! 157: fab.fab$b_org = FAB$C_SEQ; ! 158: fab.fab$b_rat = 0; ! 159: fab.fab$b_rfm = FAB$C_VAR; ! 160: fab.fab$l_alq = 1 + map_data.datablk + ! 161: ((datasize + BLOCKSIZE - 1) / BLOCKSIZE); ! 162: status = sys$create (&fab); ! 163: if (status != RMS$_NORMAL) ! 164: { ! 165: error ("Could not create map file"); ! 166: return 0; ! 167: } ! 168: /* Connect the RAB block */ ! 169: rab = cc$rms_rab; ! 170: rab.rab$l_fab = &fab; ! 171: rab.rab$b_rac = RAB$C_SEQ; ! 172: rab.rab$l_rop = RAB$M_BIO; ! 173: status = sys$connect (&rab); ! 174: if (status != RMS$_NORMAL) ! 175: { ! 176: error ("RMS connect to map file failed"); ! 177: return 0; ! 178: } ! 179: /* Write the header */ ! 180: rab.rab$l_rbf = &map_data; ! 181: rab.rab$w_rsz = sizeof (map_data); ! 182: status = sys$write (&rab); ! 183: if (status != RMS$_NORMAL) ! 184: { ! 185: error ("RMS write (header) to map file failed"); ! 186: return 0; ! 187: } ! 188: if (! write_data (&rab, map_data.datablk, map_data.sdata, datasize)) ! 189: return 0; ! 190: status = sys$close (&fab); ! 191: if (status != RMS$_NORMAL) ! 192: { ! 193: error ("RMS close on map file failed"); ! 194: return 0; ! 195: } ! 196: return 1; ! 197: } ! 198: ! 199: static int ! 200: write_data (rab, firstblock, data, length) ! 201: struct RAB * rab; ! 202: char * data; ! 203: { ! 204: int status; ! 205: ! 206: rab->rab$l_bkt = firstblock; ! 207: while (length > 0) ! 208: { ! 209: rab->rab$l_rbf = data; ! 210: rab->rab$w_rsz = length > MAXWRITE ? MAXWRITE : length; ! 211: status = sys$write (rab, 0, 0); ! 212: if (status != RMS$_NORMAL) ! 213: { ! 214: error ("RMS write to map file failed"); ! 215: return 0; ! 216: } ! 217: data = &data[MAXWRITE]; ! 218: length -= MAXWRITE; ! 219: rab->rab$l_bkt = 0; ! 220: } ! 221: return 1; ! 222: } /* write_data */ ! 223: ! 224: #endif /* VMS */ ! 225:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.