|
|
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.