Mercurial > emacs
view src/unexnext.c @ 83431:76396de7f50a
Rename `struct device' to `struct terminal'. Rename some terminal-related functions similarly.
* src/termhooks.h (struct device): Rename to `terminal'. Rename member
`next_device' to `next_terminal'.
(device_list): Rename to `terminal_list'.
(FRAME_DEVICE): Rename to `FRAME_TERMINAL'.
(DEVICE_TERMINAL_CODING): Rename to `TERMINAL_TERMINAL_CODING'.
(TERMINAL_KEYBOARD_CODING): Rename to `TERMINAL_KEYBOARD_CODING'.
(DEVICE_ACTIVE_P): Rename to `TERMINAL_ACTIVE_P'.
Update declarations and macro definitions.
* src/termchar.h (tty_display_info): Rename member `device' to `terminal'.
(FRAME_TTY): Update for renames.
* src/xterm.h (x_display_info): Rename member `device' to `terminal'.
* src/frame.h (frame): Rename `device' member to `terminal'.
(FRAME_KBOARD, FRAME_LIVE_P, Qdevice, Qdisplay_live_p):
Update for renames.
* src/lisp.h (set_process_environment): Rename to `set_global_environment'.
(device): Rename to `terminal'.
* src/dispextern.h: Update declarations and macro definitions.
* src/terminal.c (device_list): Rename to `terminal_list'.
(next_device_id): Rename to `next_terminal_id'.
(initial_device): Rename to `initial_terminal'.
(get_device): Rename to `get_terminal'.
(create_device): Rename to `create_terminal'.
(mark_devices): Rename to `mark_terminals'.
(delete_device): Rename to `delete_terminal'.
(Fdelete_display): Rename to `Fdelete_terminal'.
(Fframe_terminal): Move here from frame.c.
(Fdisplay_live_p): Rename to `Fterminal_live_p'.
(Fdisplay_list): Rename to `Fterminal_list'.
(Fdisplay_name): Rename to `Fterminal_name'.
(init_initial_device): Rename to `init_initial_terminal'.
(delete_initial_device): Rename to `delete_initial_terminal'.
(ring_bell, update_begin, update_end, set_terminal_window)
(cursor_to, raw_cursor_to, clear_to_end, clear_frame)
(clear_end_of_line, write_glyphs, insert_glyphs, delete_glyphs)
(ins_del_lines, get_terminal_param, store_terminal_param)
(Fterminal_parameters, Fterminal_parameter)
(Fmodify_terminal_parameters, Fset_terminal_parameter)
(syms_of_terminal): Update for renames.
* src/term.c (get_tty_device): Rename to `get_tty_terminal'. Update.
(Fdisplay_tty_type): Rename to `Ftty_type'.
(Fdisplay_controlling_tty_p): Rename to `Fcontrolling_tty_p'.
(delete_tty, tty_set_terminal_modes, tty_reset_terminal_modes)
(Ftty_display_color_p, Ftty_display_color_cells, get_named_tty)
(Ftty_no_underline, Fsuspend_tty, Fresume_tty, create_tty_output)
(init_tty, maybe_fatal, delete_tty, syms_of_term): Update for rename.
* src/frame.c (Qdevice): Rename to `Qterminal'.
(Qdisplay_live_p): Rename to `Qterminal_live_p'.
(terminal_frame_count): Rename to `tty_frame_count'.
(Fframe_display): Move to terminal.c, rename to `Fframe_terminal'.
(make_frame_without_minibuffer, make_initial_frame)
(make_terminal_frame, Fmodify_frame_parameters)
(do_switch_frame, Fdelete_frame, Fmouse_position)
(Fmouse_pixel_position, Fraise_frame, Flower_frame)
(Fredirect_frame_focus, set_term_frame_name, syms_of_frame):
Update for renames.
* src/xdisp.c (message2_nolog, message3_nolog, redisplay_internal)
(set_vertical_scroll_bar, redisplay_window, check_x_display_info)
(x_set_scroll_bar_foreground, x_set_scroll_bar_background)
(Fx_create_frame, Fxw_display_color_p, Fx_display_grayscale_p)
(Fx_display_pixel_width, Fx_display_pixel_height)
(Fx_display_planes, Fx_display_color_cells)
(Fx_server_max_request_size, Fx_server_vendor, Fx_server_version)
(Fx_display_screens, Fx_display_mm_height, Fx_display_mm_width)
(Fx_display_backing_store, Fx_display_visual_class)
(Fx_display_save_under, Fx_close_connection, x_create_tip_frame):
Update for renames.
* xterm.c (handle_one_xevent): Initialize `f' to NULL.
(x_delete_device): Rename to `x_delete_terminal'.
(x_create_device): Rename to `x_create_terminal'.
(XTset_terminal_modes, XTreset_terminal_modes)
(XTread_socket, x_connection_closed, x_term_init)
(x_term_init, x_delete_display): Update for renames.
* src/dispnew.c (Fredraw_frame, Fsend_string_to_terminal)
(Fsend_string_to_terminal, init_display): Update for renames.
* src/keyboard.c (push_frame_kboard, pop_kboard, pop_kboard)
(kbd_buffer_get_event, read_avail_input, tty_read_avail_input)
(interrupt_signal, Fset_output_flow_control)
(Fset_input_meta_mode, Fset_quit_char, delete_kboard)
(syms_of_keyboard): Update for renames.
* src/alloc.c (mark_devices): Update declaration.
(Fgarbage_collect): Update for renames.
* src/coding.c (Fset_terminal_coding_system_internal)
(Fterminal_coding_system4)
(Fset_keyboard_coding_system_internal)
(Fkeyboard_coding_system): Update for renames.
* src/data.c (Fterminal_local_value, Fset_terminal_local_value):
Update for renames.
* src/minibuf.c (read_minibuf): Update for renames.
* src/sysdep.c (init_sys_modes, reset_sys_modes): Update for renames.
* xselect.c (x_handle_selection_clear): Update for renames.
* lisp/files.el (save-buffers-kill-display): Rename to `save-buffers-kill-terminal'.
(save-buffers-kill-terminal, ctl-x-map): Update for renames.
* frame.el (make-frame): Rename 'device frame parameter to 'terminal. Update.
(frames-on-display-list, framep-on-display, suspend-frame): Update for renames.
(selected-display): Rename to `selected-terminal'.
* server.el (server-save-buffers-kill-display): Rename to
`server-save-buffers-kill-terminal'.
(server-delete-client, server-handle-delete-frame)
(server-handle-suspend-tty, server-process-filter)
(server-switch-buffer): Update for renames.
* startup.el (normal-splash-screen, normal-splash-screen): Update for renames.
* talk.el (talk): Update for renames.
* termdev.el (terminal-id): Update for renames.
* xt-mouse.el (turn-on-xterm-mouse-tracking-on-terminal)
(turn-off-xterm-mouse-tracking-on-terminal)
(xterm-mouse-handle-delete-frame): Update for renames.
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-471
author | Karoly Lorentey <lorentey@elte.hu> |
---|---|
date | Thu, 29 Dec 2005 18:20:26 +0000 |
parents | a0d1312ede66 |
children | 3bd95f4f2941 2d92f5c9d6ae |
line wrap: on
line source
/* Dump Emacs in macho format. Copyright (C) 1990, 1993, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Written by Bradley Taylor (btaylor@next.com). This file is part of GNU Emacs. GNU Emacs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #undef __STRICT_BSD__ #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <mach/mach.h> #include <mach-o/loader.h> #include <mach-o/reloc.h> #include <sys/file.h> #include <sys/stat.h> #include <unistd.h> /* Instead of unistd.h, this used to include libc.h. "Nelson H. F. Beebe" <beebe@math.utah.edu> says that doesn't work in system version 3.3. */ int malloc_cookie; /* * Kludge: we don't expect any program data beyond VM_HIGHDATA * What is really needed is a way to find out from malloc() which * pages it vm_allocated and write only those out into the data segment. * * This kludge may break when we stop using fixed virtual address * shared libraries. Actually, emacs will probably continue working, but be * much larger on disk than it needs to be (because non-malloced data will * be in the file). */ static const unsigned VM_HIGHDATA = 0x2000000; typedef struct region_t { vm_address_t address; vm_size_t size; vm_prot_t protection; vm_prot_t max_protection; vm_inherit_t inheritance; boolean_t shared; port_t object_name; vm_offset_t offset; } region_t; static void grow( struct load_command ***the_commands, unsigned *the_commands_len ) { if (*the_commands == NULL) { *the_commands_len = 1; *the_commands = malloc(sizeof(*the_commands)); } else { (*the_commands_len)++; *the_commands = realloc(*the_commands, (*the_commands_len * sizeof(**the_commands))); } } static void save_command( struct load_command *command, struct load_command ***the_commands, unsigned *the_commands_len ) { struct load_command **tmp; grow(the_commands, the_commands_len); tmp = &(*the_commands)[*the_commands_len - 1]; *tmp = malloc(command->cmdsize); bcopy(command, *tmp, command->cmdsize); } static void fatal_unexec(char *format, ...) { va_list ap; va_start(ap, format); fprintf(stderr, "unexec: "); vfprintf(stderr, format, ap); fprintf(stderr, "\n"); va_end(ap); } static int read_macho( int fd, struct mach_header *the_header, struct load_command ***the_commands, unsigned *the_commands_len ) { struct load_command command; struct load_command *buf; int i; int size; if (read(fd, the_header, sizeof(*the_header)) != sizeof(*the_header)) { fatal_unexec("cannot read macho header"); return (0); } for (i = 0; i < the_header->ncmds; i++) { if (read(fd, &command, sizeof(struct load_command)) != sizeof(struct load_command)) { fatal_unexec("cannot read macho load command header"); return (0); } size = command.cmdsize - sizeof(struct load_command); if (size < 0) { fatal_unexec("bogus load command size"); return (0); } buf = malloc(command.cmdsize); buf->cmd = command.cmd; buf->cmdsize = command.cmdsize; if (read(fd, ((char *)buf + sizeof(struct load_command)), size) != size) { fatal_unexec("cannot read load command data"); return (0); } save_command(buf, the_commands, the_commands_len); } return (1); } static int filldatagap( vm_address_t start_address, vm_size_t *size, vm_address_t end_address ) { vm_address_t address; vm_size_t gapsize; address = (start_address + *size); gapsize = end_address - address; *size += gapsize; if (vm_allocate(task_self(), &address, gapsize, FALSE) != KERN_SUCCESS) { fatal_unexec("cannot vm_allocate"); return (0); } return (1); } static int get_data_region( vm_address_t *address, vm_size_t *size ) { region_t region; kern_return_t ret; struct section *sect; sect = (struct section *) getsectbyname(SEG_DATA, SECT_DATA); region.address = 0; *address = 0; for (;;) { ret = vm_region(task_self(), ®ion.address, ®ion.size, ®ion.protection, ®ion.max_protection, ®ion.inheritance, ®ion.shared, ®ion.object_name, ®ion.offset); if (ret != KERN_SUCCESS || region.address >= VM_HIGHDATA) { break; } if (*address != 0) { if (region.address > *address + *size) { if (!filldatagap(*address, size, region.address)) { return (0); } } *size += region.size; } else { if (region.address == sect->addr) { *address = region.address; *size = region.size; } } region.address += region.size; } return (1); } static char * my_malloc( vm_size_t size ) { vm_address_t address; if (vm_allocate(task_self(), &address, size, TRUE) != KERN_SUCCESS) { return (NULL); } return ((char *)address); } static void my_free( char *buf, vm_size_t size ) { vm_deallocate(task_self(), (vm_address_t)buf, size); } static int unexec_doit( int infd, int outfd ) { int i; struct load_command **the_commands = NULL; unsigned the_commands_len; struct mach_header the_header; int fgrowth = 0; int fdatastart; int fdatasize; int size; struct stat st; char *buf; vm_address_t data_address; vm_size_t data_size; vm_size_t vmaddr_growth = 0; vm_size_t dataseg_vmaddr, dataseg_vmend; struct segment_command *segment; #ifdef NS_TARGET unsigned long extreloff = 0; unsigned long nextrel = 0; struct dysymtab_command *dysymtab; struct relocation_info reloc_info; #endif if (!read_macho(infd, &the_header, &the_commands, &the_commands_len)) { return (0); } malloc_cookie = malloc_freezedry (); if (!get_data_region(&data_address, &data_size)) { return (0); } /* * DO NOT USE MALLOC IN THIS SECTION */ { /* * Fix offsets */ for (i = 0; i < the_commands_len; i++) { switch (the_commands[i]->cmd) { case LC_SEGMENT: segment = ((struct segment_command *) the_commands[i]); if (strcmp(segment->segname, SEG_DATA) == 0) { fdatastart = segment->fileoff; fdatasize = segment->filesize; fgrowth = (data_size - segment->filesize); segment->vmsize = data_size; segment->filesize = data_size; dataseg_vmaddr = segment->vmaddr; dataseg_vmend = segment->vmaddr + segment->vmsize; vmaddr_growth = segment->vmaddr + segment->vmsize; } else { ((struct segment_command *)the_commands[i])->fileoff += fgrowth; } if( strcmp( segment->segname, SEG_LINKEDIT ) == 0 ) { segment->vmaddr = vmaddr_growth; } break; case LC_SYMTAB: ((struct symtab_command *) the_commands[i])->symoff += fgrowth; ((struct symtab_command *) the_commands[i])->stroff += fgrowth; break; case LC_SYMSEG: ((struct symseg_command *) the_commands[i])->offset += fgrowth; break; #ifdef NS_TARGET case LC_DYSYMTAB: dysymtab = ((struct dysymtab_command *)the_commands[i]); extreloff = dysymtab->extreloff; nextrel = dysymtab->nextrel; dysymtab->indirectsymoff += fgrowth; dysymtab->extreloff += fgrowth; break; #endif default: break; } } /* * Write header */ if (write(outfd, &the_header, sizeof(the_header)) != sizeof(the_header)) { fatal_unexec("cannot write output file"); return (0); } /* * Write commands */ for (i = 0; i < the_commands_len; i++) { if (write(outfd, the_commands[i], the_commands[i]->cmdsize) != the_commands[i]->cmdsize) { fatal_unexec("cannot write output file"); return (0); } } /* * Write original text */ if (lseek(infd, the_header.sizeofcmds + sizeof(the_header), L_SET) < 0) { fatal_unexec("cannot seek input file"); return (0); } size = fdatastart - (sizeof(the_header) + the_header.sizeofcmds); buf = my_malloc(size); if (read(infd, buf, size) != size) { my_free(buf, size); fatal_unexec("cannot read input file"); } if (write(outfd, buf, size) != size) { my_free(buf, size); fatal_unexec("cannot write output file"); return (0); } my_free(buf, size); /* * Write new data */ if (write(outfd, (char *)data_address, data_size) != data_size) { fatal_unexec("cannot write output file"); return (0); } } /* * OKAY TO USE MALLOC NOW */ /* * Write rest of file */ fstat(infd, &st); if (lseek(infd, fdatasize, L_INCR) < 0) { fatal_unexec("cannot seek input file"); return (0); } size = st.st_size - lseek(infd, 0, L_INCR); buf = malloc(size); if (read(infd, buf, size) != size) { free(buf); fatal_unexec("cannot read input file"); return (0); } if (write(outfd, buf, size) != size) { free(buf); fatal_unexec("cannot write output file"); return (0); } free(buf); #ifdef NS_TARGET /* * Fix up relocation entries in the data segment. */ if (lseek(infd, extreloff, L_SET) < 0) { fatal_unexec("cannot seek input file"); return (0); } for (i = 0; i < nextrel; i++) { long zeroval = 0; if (read(infd, &reloc_info, sizeof (reloc_info)) != sizeof (reloc_info)) { fatal_unexec("cannot read input file"); return (0); } if (reloc_info.r_address >= dataseg_vmaddr && reloc_info.r_address < dataseg_vmend) { if (lseek (outfd, fdatastart + reloc_info.r_address - dataseg_vmaddr, L_SET) < 0 ) { fatal_unexec("cannot seek input file"); return (0); } switch (reloc_info.r_length) { case 0: if (write(outfd, &zeroval, 1) != 1) { fatal_unexec("cannot write output file"); return (0); } break; case 1: if (write(outfd, &zeroval, 2) != 2) { fatal_unexec("cannot write output file"); return (0); } break; case 2: if (write(outfd, &zeroval, 4) != 4) { fatal_unexec("cannot write output file"); return (0); } break; } } } #endif return (1); } void unexec( char *outfile, char *infile ) { int infd; int outfd; char tmpbuf[L_tmpnam]; char *tmpfile; infd = open(infile, O_RDONLY, 0); if (infd < 0) { fatal_unexec("cannot open input file `%s'", infile); exit(1); } tmpnam(tmpbuf); tmpfile = rindex(tmpbuf, '/'); if (tmpfile == NULL) { tmpfile = tmpbuf; } else { tmpfile++; } outfd = open(tmpfile, O_WRONLY|O_TRUNC|O_CREAT, 0755); if (outfd < 0) { close(infd); fatal_unexec("cannot open tmp file `%s'", tmpfile); exit(1); } if (!unexec_doit(infd, outfd)) { close(infd); close(outfd); unlink(tmpfile); exit(1); } close(infd); close(outfd); if (rename(tmpfile, outfile) < 0) { unlink(tmpfile); fatal_unexec("cannot rename `%s' to `%s'", tmpfile, outfile); exit(1); } } /* arch-tag: 9796bdc3-c050-417a-b2f5-4cfd31032634 (do not change this comment) */