7 * Function to save an executable copy of the current process's
16 #include <sys/types.h>
25 extern long lseek(); /* For lint */
26 extern int getpagesize();
29 static int copy_file();
30 static int pad_file();
34 util_save_image(char const *orig_file_name
, char const *save_file_name
)
36 int origFd
= -1, saveFd
= -1;
37 char *start_data
, *end_data
, *start_text
, *end_round
;
38 struct exec old_hdr
, new_hdr
;
40 int n
, page_size
, length_text
, length_data
;
42 if ((origFd
= open(orig_file_name
, 0)) < 0) {
43 perror(orig_file_name
);
44 (void) fprintf(stderr
, "Cannot open original a.out file\n");
48 if (fstat(origFd
, &old_stat
) < 0) {
49 perror(orig_file_name
);
50 (void) fprintf(stderr
, "Cannot stat original a.out file\n");
55 * Read the a.out header from the original file.
57 if (read(origFd
, (char *) &old_hdr
, sizeof(old_hdr
)) != sizeof(old_hdr
)) {
58 perror(orig_file_name
);
59 (void) fprintf(stderr
, "Cannot read original a.out header\n");
62 if (N_BADMAG(old_hdr
)) {
63 (void) fprintf(stderr
, "File %s has a bad magic number (%o)\n",
64 orig_file_name
, old_hdr
.a_magic
);
67 if (old_hdr
.a_magic
!= ZMAGIC
) {
68 (void) fprintf(stderr
, "File %s is not demand-paged\n", orig_file_name
);
73 * Open the output file.
75 if (access(save_file_name
, /* F_OK */ 0) == 0) {
76 (void) unlink(save_file_name
);
78 if ((saveFd
= creat(save_file_name
, 0777)) < 0) {
79 if (errno
== ETXTBSY
) {
80 (void) unlink(save_file_name
);
81 saveFd
= creat(save_file_name
, 0777);
84 perror(save_file_name
);
85 (void) fprintf(stderr
, "Cannot create save file.\n");
91 * Find out how far the data segment extends.
95 page_size
= getpagesize();
96 n
= ((((int) end_data
) + page_size
- 1) / page_size
) * page_size
;
97 end_round
= (char *) n
;
98 if (end_round
> end_data
) {
99 end_data
= sbrk(end_round
- end_data
);
104 length_text
= new_hdr
.a_text
;
105 start_data
= (char *) old_hdr
.a_text
;
106 length_data
= end_data
- start_data
;
109 start_text
= (char *) N_TXTADDR(old_hdr
) + sizeof(old_hdr
);
110 length_text
= old_hdr
.a_text
- sizeof(old_hdr
);
111 start_data
= (char *) N_DATADDR(old_hdr
);
112 length_data
= end_data
- start_data
;
114 new_hdr
.a_data
= end_data
- start_data
;
118 * First, the header plus enough pad to extend up to N_TXTOFF.
120 if (write(saveFd
, (char *) &new_hdr
, (int) sizeof(new_hdr
)) !=
123 (void) fprintf(stderr
, "Error while copying header.\n");
126 if (! pad_file(saveFd
, N_TXTOFF(old_hdr
) - sizeof(new_hdr
))) {
127 (void) fprintf(stderr
, "Error while padding.\n");
133 * Copy our text segment
135 if (write(saveFd
, start_text
, length_text
) != length_text
) {
137 (void) fprintf(stderr
, "Error while copying text segment.\n");
143 * Copy our data segment
145 if (write(saveFd
, start_data
, length_data
) != length_data
) {
147 (void) fprintf(stderr
, "Error while copying data segment.\n");
152 * Copy the symbol table and everything else.
153 * This takes us to the end of the original file.
155 (void) lseek(origFd
, (long) N_SYMOFF(old_hdr
), 0);
156 if (! copy_file(origFd
, saveFd
, old_stat
.st_size
- N_SYMOFF(old_hdr
))) {
157 (void) fprintf(stderr
, "Error while copying symbol table.\n");
160 (void) close(origFd
);
161 (void) close(saveFd
);
165 if (origFd
>= 0) (void) close(origFd
);
166 if (saveFd
>= 0) (void) close(saveFd
);
172 copy_file(inFd
, outFd
, nbytes
)
174 unsigned long nbytes
;
181 if (ntoread
> sizeof buf
) ntoread
= sizeof buf
;
182 if ((nread
= read(inFd
, buf
, ntoread
)) != ntoread
) {
186 if (write(outFd
, buf
, nread
) != nread
) {
198 pad_file(outFd
, nbytes
)
205 nzero
= (nbytes
> sizeof(buf
)) ? sizeof(buf
) : nbytes
;
208 nzero
= (nbytes
> sizeof(buf
)) ? sizeof(buf
) : nbytes
;
209 if (write(outFd
, buf
, nzero
) != nzero
) {
222 util_save_image(char const *orig_file_name
, char const *save_file_name
)
224 (void) fprintf(stderr
,
225 "util_save_image: not implemented on your operating system\n");