Mercurial > emacs
annotate src/unexenix.c @ 41882:f3bc5e440020
Resurrect the Hebrew category
settings for all Hebrew characters removed by the last change.
Add code for setting the Hebrew category of the Unicode Hebrew
characters. Set syntax entries for Hebrew punctuation characters.
author | Eli Zaretskii <eliz@gnu.org> |
---|---|
date | Fri, 07 Dec 2001 17:52:20 +0000 |
parents | ee40177f6c68 |
children | 23a1cea22d13 |
rev | line source |
---|---|
484 | 1 /* Unexec for Xenix. |
2 Note that the GNU project considers support for Xenix operation | |
3 a peripheral activity which should not be allowed to divert effort | |
4 from development of the GNU system. Changes in this code will be | |
5 installed when Xenix users send them in, but aside from that | |
6 we don't plan to think about it, or about whether other Emacs | |
7 maintenance might break it. | |
8 | |
5521
d1d144ed5b76
Don't declare sys_errlist; declare strerror instead.
Roland McGrath <roland@gnu.org>
parents:
4696
diff
changeset
|
9 Copyright (C) 1988, 1994 Free Software Foundation, Inc. |
484 | 10 |
11 This file is part of GNU Emacs. | |
12 | |
13 GNU Emacs is free software; you can redistribute it and/or modify | |
14 it under the terms of the GNU General Public License as published by | |
5521
d1d144ed5b76
Don't declare sys_errlist; declare strerror instead.
Roland McGrath <roland@gnu.org>
parents:
4696
diff
changeset
|
15 the Free Software Foundation; either version 2, or (at your option) |
484 | 16 any later version. |
17 | |
18 GNU Emacs is distributed in the hope that it will be useful, | |
19 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 GNU General Public License for more details. | |
22 | |
23 You should have received a copy of the GNU General Public License | |
24 along with GNU Emacs; see the file COPYING. If not, write to | |
14186
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
5521
diff
changeset
|
25 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
5521
diff
changeset
|
26 Boston, MA 02111-1307, USA. */ |
484 | 27 |
28 | |
29 | |
30 /* | |
31 On 80386 Xenix, segmentation screws prevent us from modifying the text | |
32 segment at all. We basically just plug a new value for "data segment | |
33 size" into the countless headers and copy the other records straight | |
34 through. The data segment is ORG'ed at the xs_rbase value of the data | |
35 segment's xseg record (always @ 0x1880000, thanks to the "sophisticated | |
36 memory management hardware" of the chip) and extends to sbrk(0), exactly. | |
37 This code is afraid to malloc (should it be?), and alloca has to be the | |
38 wimpy, malloc-based version; consequently, data is usually copied in | |
39 smallish chunks. | |
40 | |
41 gb@entity.com | |
42 */ | |
43 | |
4696
1fc792473491
Include <config.h> instead of "config.h".
Roland McGrath <roland@gnu.org>
parents:
3591
diff
changeset
|
44 #include <config.h> |
484 | 45 #include <sys/types.h> |
46 #include <fcntl.h> | |
47 #include <sys/file.h> | |
48 #include <sys/stat.h> | |
49 #include <stdio.h> | |
50 #include <varargs.h> | |
51 #include <a.out.h> | |
52 | |
53 static void fatal_unexec (); | |
54 | |
55 #define READ(_fd, _buffer, _size, _error_message, _error_arg) \ | |
56 errno = EEOF; \ | |
57 if (read(_fd, _buffer, _size) != _size) \ | |
58 fatal_unexec(_error_message, _error_arg); | |
59 | |
60 #define WRITE(_fd, _buffer, _size, _error_message, _error_arg) \ | |
61 if (write(_fd, _buffer, _size) != _size) \ | |
62 fatal_unexec(_error_message, _error_arg); | |
63 | |
64 #define SEEK(_fd, _position, _error_message, _error_arg) \ | |
65 errno = EEOF; \ | |
66 if (lseek(_fd, _position, L_SET) != _position) \ | |
67 fatal_unexec(_error_message, _error_arg); | |
68 | |
69 extern int errno; | |
5521
d1d144ed5b76
Don't declare sys_errlist; declare strerror instead.
Roland McGrath <roland@gnu.org>
parents:
4696
diff
changeset
|
70 extern char *strerror (); |
484 | 71 #define EEOF -1 |
72 | |
73 #ifndef L_SET | |
74 #define L_SET 0 | |
75 #endif | |
76 | |
77 /* Should check the magic number of the old executable; | |
78 not yet written. */ | |
79 check_exec (x) | |
80 struct xexec *x; | |
81 { | |
82 } | |
83 | |
84 | |
85 unexec (new_name, a_name, data_start, bss_start, entry_address) | |
86 char *new_name, *a_name; | |
87 unsigned data_start, bss_start, entry_address; | |
88 { | |
89 char *sbrk (), *datalim = sbrk (0), *data_org; | |
90 long segpos, textseen, textpos, textlen, datapos, datadiff, datalen; | |
91 | |
92 struct xexec u_xexec, /* a.out header */ | |
93 *u_xexecp = &u_xexec; | |
94 struct xext u_xext, /* extended header */ | |
95 *u_xextp = &u_xext; | |
96 struct xseg u_xseg, /* segment table entry */ | |
97 *u_xsegp = &u_xseg; | |
98 int i, nsegs, isdata = 0, infd, outfd; | |
99 | |
100 infd = open (a_name, O_RDONLY, 0); | |
101 if (infd < 0) fatal_unexec ("opening %s", a_name); | |
102 | |
103 outfd = creat (new_name, 0666); | |
104 if (outfd < 0) fatal_unexec ("creating %s", new_name); | |
105 | |
106 READ (infd, u_xexecp, sizeof (struct xexec), | |
107 "error reading %s", a_name); | |
108 check_exec (u_xexecp); | |
109 READ (infd, u_xextp, sizeof (struct xext), | |
110 "error reading %s", a_name); | |
111 segpos = u_xextp->xe_segpos; | |
112 nsegs = u_xextp->xe_segsize / sizeof (struct xseg); | |
113 SEEK (infd, segpos, "seek error on %s", a_name); | |
114 for (i = 0; i < nsegs; i ++) | |
115 { | |
116 READ (infd, u_xsegp, sizeof (struct xseg), | |
117 "error reading %s", a_name); | |
118 switch (u_xsegp->xs_type) | |
119 { | |
120 case XS_TTEXT: | |
121 { | |
122 if (i == 0) | |
123 { | |
124 textpos = u_xsegp->xs_filpos; | |
125 textlen = u_xsegp->xs_psize; | |
126 break; | |
127 } | |
128 fatal_unexec ("invalid text segment in %s", a_name); | |
129 } | |
130 case XS_TDATA: | |
131 { | |
132 if (i == 1) | |
133 { | |
134 datapos = u_xsegp->xs_filpos; | |
135 datalen = datalim - (data_org = (char *)(u_xsegp->xs_rbase)); | |
136 datadiff = datalen - u_xsegp->xs_psize; | |
137 break; | |
138 } | |
139 fatal_unexec ("invalid data segment in %s", a_name); | |
140 } | |
141 default: | |
142 { | |
143 if (i > 1) break; | |
144 fatal_unexec ("invalid segment record in %s", a_name); | |
145 } | |
146 } | |
147 } | |
148 u_xexecp->x_data = datalen; | |
149 u_xexecp->x_bss = 0; | |
150 WRITE (outfd, u_xexecp, sizeof (struct xexec), | |
151 "error writing %s", new_name); | |
152 WRITE (outfd, u_xextp, sizeof (struct xext), | |
153 "error writing %s", new_name); | |
154 SEEK (infd, segpos, "seek error on %s", a_name); | |
155 SEEK (outfd, segpos, "seek error on %s", new_name); | |
156 | |
157 /* Copy the text segment record verbatim. */ | |
158 | |
159 copyrec (infd, outfd, sizeof (struct xseg), a_name, new_name); | |
160 | |
161 /* Read, modify, write the data segment record. */ | |
162 | |
163 READ (infd, u_xsegp, sizeof (struct xseg), | |
164 "error reading %s", a_name); | |
165 u_xsegp->xs_psize = u_xsegp->xs_vsize = datalen; | |
166 u_xsegp->xs_attr &= (~XS_AITER & ~XS_ABSS); | |
167 WRITE (outfd, u_xsegp, sizeof (struct xseg), | |
168 "error writing %s", new_name); | |
169 | |
170 /* Now copy any additional segment records, adjusting their | |
171 file position field */ | |
172 | |
173 for (i = 2; i < nsegs; i++) | |
174 { | |
175 READ (infd, u_xsegp, sizeof (struct xseg), | |
176 "error reading %s", a_name); | |
177 u_xsegp->xs_filpos += datadiff; | |
178 WRITE (outfd, u_xsegp, sizeof (struct xseg), | |
179 "error writing %s", new_name); | |
180 } | |
181 | |
182 SEEK (infd, textpos, "seek error on %s", a_name); | |
183 SEEK (outfd, textpos, "seek error on %s", new_name); | |
184 copyrec (infd, outfd, textlen, a_name, new_name); | |
185 | |
186 SEEK (outfd, datapos, "seek error on %s", new_name); | |
187 WRITE (outfd, data_org, datalen, | |
188 "write error on %s", new_name); | |
189 | |
190 for (i = 2, segpos += (2 * sizeof (struct xseg)); | |
191 i < nsegs; | |
192 i++, segpos += sizeof (struct xseg)) | |
193 { | |
194 SEEK (infd, segpos, "seek error on %s", a_name); | |
195 READ (infd, u_xsegp, sizeof (struct xseg), | |
196 "read error on %s", a_name); | |
197 SEEK (infd, u_xsegp->xs_filpos, "seek error on %s", a_name); | |
198 /* We should be at eof in the output file here, but we must seek | |
199 because the xs_filpos and xs_psize fields in symbol table | |
200 segments are inconsistent. */ | |
201 SEEK (outfd, u_xsegp->xs_filpos + datadiff, "seek error on %s", new_name); | |
202 copyrec (infd, outfd, u_xsegp->xs_psize, a_name, new_name); | |
203 } | |
204 close (infd); | |
205 close (outfd); | |
206 mark_x (new_name); | |
207 return 0; | |
208 } | |
209 | |
210 copyrec (infd, outfd, len, in_name, out_name) | |
211 int infd, outfd, len; | |
212 char *in_name, *out_name; | |
213 { | |
214 char buf[BUFSIZ]; | |
215 int chunk; | |
216 | |
217 while (len) | |
218 { | |
219 chunk = BUFSIZ; | |
220 if (chunk > len) | |
221 chunk = len; | |
222 READ (infd, buf, chunk, "error reading %s", in_name); | |
223 WRITE (outfd, buf, chunk, "error writing %s", out_name); | |
224 len -= chunk; | |
225 } | |
226 } | |
227 | |
228 /* | |
229 * mark_x | |
230 * | |
3591
507f64624555
Apply typo patches from Paul Eggert.
Jim Blandy <jimb@redhat.com>
parents:
484
diff
changeset
|
231 * After successfully building the new a.out, mark it executable |
484 | 232 */ |
233 static | |
234 mark_x (name) | |
235 char *name; | |
236 { | |
237 struct stat sbuf; | |
238 int um = umask (777); | |
239 umask (um); | |
240 if (stat (name, &sbuf) < 0) | |
241 fatal_unexec ("getting protection on %s", name); | |
242 sbuf.st_mode |= 0111 & ~um; | |
243 if (chmod (name, sbuf.st_mode) < 0) | |
244 fatal_unexec ("setting protection on %s", name); | |
245 } | |
246 | |
247 static void | |
248 fatal_unexec (s, va_alist) | |
249 va_dcl | |
250 { | |
251 va_list ap; | |
252 if (errno == EEOF) | |
253 fputs ("unexec: unexpected end of file, ", stderr); | |
254 else | |
5521
d1d144ed5b76
Don't declare sys_errlist; declare strerror instead.
Roland McGrath <roland@gnu.org>
parents:
4696
diff
changeset
|
255 fprintf (stderr, "unexec: %s, ", strerror (errno)); |
484 | 256 va_start (ap); |
257 _doprnt (s, ap, stderr); | |
258 fputs (".\n", stderr); | |
259 exit (1); | |
260 } |