annotate src/unexnext.c @ 4413:5a00cec8e9b0

(fill-region-as-paragraph): When we take one word after the fill column, don't stop at period with just one space. When checking whether at beginning of line, if no fill prefix, ignore intervening whitespace.
author Richard M. Stallman <rms@gnu.org>
date Mon, 02 Aug 1993 05:55:56 +0000
parents b70f4760d769
children cec168152d88
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1349
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
1 /* Dump Emacs in macho format.
2660
b70f4760d769 Changes for Emacs 19 from Thorsten Ohl <ohl@chico.harvard.edu>:
Jim Blandy <jimb@redhat.com>
parents: 1349
diff changeset
2 Copyright (C) 1990, 1993 Free Software Foundation, Inc.
1349
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
3 Written by Bradley Taylor (btaylor@next.com).
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
4
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
5 This file is part of GNU Emacs.
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
6
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
7 GNU Emacs is free software; you can redistribute it and/or modify
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
8 it under the terms of the GNU General Public License as published by
2660
b70f4760d769 Changes for Emacs 19 from Thorsten Ohl <ohl@chico.harvard.edu>:
Jim Blandy <jimb@redhat.com>
parents: 1349
diff changeset
9 the Free Software Foundation; either version 2, or (at your option)
1349
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
10 any later version.
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
11
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
12 GNU Emacs is distributed in the hope that it will be useful,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
15 GNU General Public License for more details.
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
16
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
18 along with GNU Emacs; see the file COPYING. If not, write to
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
20
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
21
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
22 #undef __STRICT_BSD__
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
23
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
24 #include <stdio.h>
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
25 #include <stdlib.h>
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
26 #include <stdarg.h>
2660
b70f4760d769 Changes for Emacs 19 from Thorsten Ohl <ohl@chico.harvard.edu>:
Jim Blandy <jimb@redhat.com>
parents: 1349
diff changeset
27 #include <mach/mach.h>
b70f4760d769 Changes for Emacs 19 from Thorsten Ohl <ohl@chico.harvard.edu>:
Jim Blandy <jimb@redhat.com>
parents: 1349
diff changeset
28 #include <mach-o/loader.h>
1349
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
29 #include <sys/file.h>
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
30 #include <sys/stat.h>
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
31 #include <libc.h>
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
32
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
33
2660
b70f4760d769 Changes for Emacs 19 from Thorsten Ohl <ohl@chico.harvard.edu>:
Jim Blandy <jimb@redhat.com>
parents: 1349
diff changeset
34 int malloc_cookie;
1349
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
35
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
36 /*
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
37 * Kludge: we don't expect any program data beyond VM_HIGHDATA
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
38 * What is really needed is a way to find out from malloc() which
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
39 * pages it vm_allocated and write only those out into the data segment.
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
40 *
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
41 * This kludge may break when we stop using fixed virtual address
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
42 * shared libraries. Actually, emacs will probably continue working, but be
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
43 * much larger on disk than it needs to be (because non-malloced data will
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
44 * be in the file).
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
45 */
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
46 static const unsigned VM_HIGHDATA = 0x2000000;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
47
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
48 typedef struct region_t {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
49 vm_address_t address;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
50 vm_size_t size;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
51 vm_prot_t protection;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
52 vm_prot_t max_protection;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
53 vm_inherit_t inheritance;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
54 boolean_t shared;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
55 port_t object_name;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
56 vm_offset_t offset;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
57 } region_t;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
58
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
59
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
60 static void
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
61 grow(
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
62 struct load_command ***the_commands,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
63 unsigned *the_commands_len
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
64 )
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
65 {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
66 if (*the_commands == NULL) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
67 *the_commands_len = 1;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
68 *the_commands = malloc(sizeof(*the_commands));
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
69 } else {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
70 (*the_commands_len)++;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
71 *the_commands = realloc(*the_commands,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
72 (*the_commands_len *
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
73 sizeof(**the_commands)));
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
74 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
75 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
76
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
77
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
78 static void
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
79 save_command(
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
80 struct load_command *command,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
81 struct load_command ***the_commands,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
82 unsigned *the_commands_len
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
83 )
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
84 {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
85 struct load_command **tmp;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
86
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
87 grow(the_commands, the_commands_len);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
88 tmp = &(*the_commands)[*the_commands_len - 1];
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
89 *tmp = malloc(command->cmdsize);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
90 bcopy(command, *tmp, command->cmdsize);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
91 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
92
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
93 static void
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
94 fatal_unexec(char *format, ...)
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
95 {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
96 va_list ap;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
97
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
98 va_start(ap, format);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
99 fprintf(stderr, "unexec: ");
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
100 vfprintf(stderr, format, ap);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
101 fprintf(stderr, "\n");
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
102 va_end(ap);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
103 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
104
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
105 static int
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
106 read_macho(
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
107 int fd,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
108 struct mach_header *the_header,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
109 struct load_command ***the_commands,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
110 unsigned *the_commands_len
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
111 )
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
112 {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
113 struct load_command command;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
114 struct load_command *buf;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
115 int i;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
116 int size;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
117
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
118 if (read(fd, the_header, sizeof(*the_header)) != sizeof(*the_header)) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
119 fatal_unexec("cannot read macho header");
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
120 return (0);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
121 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
122 for (i = 0; i < the_header->ncmds; i++) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
123 if (read(fd, &command, sizeof(struct load_command)) !=
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
124 sizeof(struct load_command)) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
125 fatal_unexec("cannot read macho load command header");
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
126 return (0);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
127 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
128 size = command.cmdsize - sizeof(struct load_command);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
129 if (size < 0) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
130 fatal_unexec("bogus load command size");
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
131 return (0);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
132 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
133 buf = malloc(command.cmdsize);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
134 buf->cmd = command.cmd;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
135 buf->cmdsize = command.cmdsize;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
136 if (read(fd, ((char *)buf +
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
137 sizeof(struct load_command)),
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
138 size) != size) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
139 fatal_unexec("cannot read load command data");
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
140 return (0);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
141 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
142 save_command(buf, the_commands, the_commands_len);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
143 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
144 return (1);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
145 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
146
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
147 static int
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
148 filldatagap(
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
149 vm_address_t start_address,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
150 vm_size_t *size,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
151 vm_address_t end_address
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
152 )
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
153 {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
154 vm_address_t address;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
155 vm_size_t gapsize;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
156
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
157 address = (start_address + *size);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
158 gapsize = end_address - address;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
159 *size += gapsize;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
160 if (vm_allocate(task_self(), &address, gapsize,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
161 FALSE) != KERN_SUCCESS) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
162 fatal_unexec("cannot vm_allocate");
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
163 return (0);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
164 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
165 return (1);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
166 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
167
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
168 static int
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
169 get_data_region(
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
170 vm_address_t *address,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
171 vm_size_t *size
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
172 )
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
173 {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
174 region_t region;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
175 kern_return_t ret;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
176 struct section *sect;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
177
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
178 sect = getsectbyname(SEG_DATA, SECT_DATA);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
179 region.address = 0;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
180 *address = 0;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
181 for (;;) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
182 ret = vm_region(task_self(),
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
183 &region.address,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
184 &region.size,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
185 &region.protection,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
186 &region.max_protection,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
187 &region.inheritance,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
188 &region.shared,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
189 &region.object_name,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
190 &region.offset);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
191 if (ret != KERN_SUCCESS || region.address >= VM_HIGHDATA) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
192 break;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
193 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
194 if (*address != 0) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
195 if (region.address > *address + *size) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
196 if (!filldatagap(*address, size,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
197 region.address)) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
198 return (0);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
199 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
200 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
201 *size += region.size;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
202 } else {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
203 if (region.address == sect->addr) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
204 *address = region.address;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
205 *size = region.size;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
206 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
207 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
208 region.address += region.size;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
209 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
210 return (1);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
211 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
212
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
213 static char *
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
214 my_malloc(
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
215 vm_size_t size
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
216 )
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
217 {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
218 vm_address_t address;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
219
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
220 if (vm_allocate(task_self(), &address, size, TRUE) != KERN_SUCCESS) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
221 return (NULL);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
222 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
223 return ((char *)address);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
224 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
225
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
226 static void
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
227 my_free(
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
228 char *buf,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
229 vm_size_t size
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
230 )
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
231 {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
232 vm_deallocate(task_self(), (vm_address_t)buf, size);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
233 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
234
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
235 static int
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
236 unexec_doit(
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
237 int infd,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
238 int outfd
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
239 )
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
240 {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
241 int i;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
242 struct load_command **the_commands = NULL;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
243 unsigned the_commands_len;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
244 struct mach_header the_header;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
245 int fgrowth;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
246 int fdatastart;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
247 int fdatasize;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
248 int size;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
249 struct stat st;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
250 char *buf;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
251 vm_address_t data_address;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
252 vm_size_t data_size;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
253
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
254 struct segment_command *segment;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
255
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
256 if (!read_macho(infd, &the_header, &the_commands, &the_commands_len)) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
257 return (0);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
258 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
259
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
260
2660
b70f4760d769 Changes for Emacs 19 from Thorsten Ohl <ohl@chico.harvard.edu>:
Jim Blandy <jimb@redhat.com>
parents: 1349
diff changeset
261 malloc_cookie = malloc_freezedry ();
1349
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
262 if (!get_data_region(&data_address, &data_size)) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
263 return (0);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
264 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
265
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
266
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
267 /*
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
268 * DO NOT USE MALLOC IN THIS SECTION
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
269 */
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
270 {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
271 /*
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
272 * Fix offsets
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
273 */
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
274 for (i = 0; i < the_commands_len; i++) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
275 switch (the_commands[i]->cmd) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
276 case LC_SEGMENT:
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
277 segment = ((struct segment_command *)
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
278 the_commands[i]);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
279 if (strcmp(segment->segname, SEG_DATA) == 0) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
280 fdatastart = segment->fileoff;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
281 fdatasize = segment->filesize;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
282 fgrowth = (data_size -
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
283 segment->filesize);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
284 segment->vmsize = data_size;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
285 segment->filesize = data_size;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
286 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
287 break;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
288 case LC_SYMTAB:
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
289 ((struct symtab_command *)
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
290 the_commands[i])->symoff += fgrowth;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
291 ((struct symtab_command *)
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
292 the_commands[i])->stroff += fgrowth;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
293 break;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
294 case LC_SYMSEG:
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
295 ((struct symseg_command *)
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
296 the_commands[i])->offset += fgrowth;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
297 break;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
298 default:
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
299 break;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
300 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
301 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
302
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
303 /*
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
304 * Write header
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
305 */
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
306 if (write(outfd, &the_header,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
307 sizeof(the_header)) != sizeof(the_header)) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
308 fatal_unexec("cannot write output file");
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
309 return (0);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
310 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
311
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
312 /*
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
313 * Write commands
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
314 */
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
315 for (i = 0; i < the_commands_len; i++) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
316 if (write(outfd, the_commands[i],
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
317 the_commands[i]->cmdsize) !=
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
318 the_commands[i]->cmdsize) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
319 fatal_unexec("cannot write output file");
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
320 return (0);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
321 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
322 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
323
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
324 /*
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
325 * Write original text
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
326 */
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
327 if (lseek(infd, the_header.sizeofcmds + sizeof(the_header),
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
328 L_SET) < 0) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
329 fatal_unexec("cannot seek input file");
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
330 return (0);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
331 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
332 size = fdatastart - (sizeof(the_header) +
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
333 the_header.sizeofcmds);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
334 buf = my_malloc(size);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
335 if (read(infd, buf, size) != size) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
336 my_free(buf, size);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
337 fatal_unexec("cannot read input file");
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
338 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
339 if (write(outfd, buf, size) != size) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
340 my_free(buf, size);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
341 fatal_unexec("cannot write output file");
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
342 return (0);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
343 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
344 my_free(buf, size);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
345
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
346
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
347 /*
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
348 * Write new data
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
349 */
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
350 if (write(outfd, (char *)data_address,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
351 data_size) != data_size) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
352 fatal_unexec("cannot write output file");
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
353 return (0);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
354 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
355
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
356 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
357
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
358 /*
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
359 * OKAY TO USE MALLOC NOW
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
360 */
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
361
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
362 /*
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
363 * Write rest of file
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
364 */
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
365 fstat(infd, &st);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
366 if (lseek(infd, fdatasize, L_INCR) < 0) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
367 fatal_unexec("cannot seek input file");
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
368 return (0);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
369 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
370 size = st.st_size - lseek(infd, 0, L_INCR);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
371
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
372 buf = malloc(size);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
373 if (read(infd, buf, size) != size) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
374 free(buf);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
375 fatal_unexec("cannot read input file");
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
376 return (0);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
377 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
378 if (write(outfd, buf, size) != size) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
379 free(buf);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
380 fatal_unexec("cannot write output file");
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
381 return (0);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
382 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
383 free(buf);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
384 return (1);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
385 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
386
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
387 void
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
388 unexec(
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
389 char *outfile,
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
390 char *infile
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
391 )
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
392 {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
393 int infd;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
394 int outfd;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
395 char tmpbuf[L_tmpnam];
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
396 char *tmpfile;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
397
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
398 infd = open(infile, O_RDONLY, 0);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
399 if (infd < 0) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
400 fatal_unexec("cannot open input file `%s'", infile);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
401 exit(1);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
402 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
403
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
404 tmpnam(tmpbuf);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
405 tmpfile = rindex(tmpbuf, '/');
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
406 if (tmpfile == NULL) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
407 tmpfile = tmpbuf;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
408 } else {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
409 tmpfile++;
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
410 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
411 outfd = open(tmpfile, O_WRONLY|O_TRUNC|O_CREAT, 0755);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
412 if (outfd < 0) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
413 close(infd);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
414 fatal_unexec("cannot open tmp file `%s'", tmpfile);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
415 exit(1);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
416 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
417 if (!unexec_doit(infd, outfd)) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
418 close(infd);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
419 close(outfd);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
420 unlink(tmpfile);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
421 exit(1);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
422 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
423 close(infd);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
424 close(outfd);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
425 if (rename(tmpfile, outfile) < 0) {
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
426 unlink(tmpfile);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
427 fatal_unexec("cannot rename `%s' to `%s'", tmpfile, outfile);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
428 exit(1);
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
429 }
5f7b21303f10 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
430 }