Mercurial > hg > xemacs-beta
annotate src/sysdep.c @ 5127:a9c41067dd88 ben-lisp-object
more cleanups, terminology clarification, lots of doc work
-------------------- ChangeLog entries follow: --------------------
man/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* internals/internals.texi (Introduction to Allocation):
* internals/internals.texi (Integers and Characters):
* internals/internals.texi (Allocation from Frob Blocks):
* internals/internals.texi (lrecords):
* internals/internals.texi (Low-level allocation):
Rewrite section on allocation of Lisp objects to reflect the new
reality. Remove references to nonexistent XSETINT and XSETCHAR.
modules/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* postgresql/postgresql.c (allocate_pgconn):
* postgresql/postgresql.c (allocate_pgresult):
* postgresql/postgresql.h (struct Lisp_PGconn):
* postgresql/postgresql.h (struct Lisp_PGresult):
* ldap/eldap.c (allocate_ldap):
* ldap/eldap.h (struct Lisp_LDAP):
Same changes as in src/ dir. See large log there in ChangeLog,
but basically:
ALLOC_LISP_OBJECT -> ALLOC_NORMAL_LISP_OBJECT
LISP_OBJECT_HEADER -> NORMAL_LISP_OBJECT_HEADER
../hlo/src/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* alloc.c:
* alloc.c (old_alloc_sized_lcrecord):
* alloc.c (very_old_free_lcrecord):
* alloc.c (copy_lisp_object):
* alloc.c (zero_sized_lisp_object):
* alloc.c (zero_nonsized_lisp_object):
* alloc.c (lisp_object_storage_size):
* alloc.c (free_normal_lisp_object):
* alloc.c (FREE_FIXED_TYPE_WHEN_NOT_IN_GC):
* alloc.c (ALLOC_FROB_BLOCK_LISP_OBJECT):
* alloc.c (Fcons):
* alloc.c (noseeum_cons):
* alloc.c (make_float):
* alloc.c (make_bignum):
* alloc.c (make_bignum_bg):
* alloc.c (make_ratio):
* alloc.c (make_ratio_bg):
* alloc.c (make_ratio_rt):
* alloc.c (make_bigfloat):
* alloc.c (make_bigfloat_bf):
* alloc.c (size_vector):
* alloc.c (make_compiled_function):
* alloc.c (Fmake_symbol):
* alloc.c (allocate_extent):
* alloc.c (allocate_event):
* alloc.c (make_key_data):
* alloc.c (make_button_data):
* alloc.c (make_motion_data):
* alloc.c (make_process_data):
* alloc.c (make_timeout_data):
* alloc.c (make_magic_data):
* alloc.c (make_magic_eval_data):
* alloc.c (make_eval_data):
* alloc.c (make_misc_user_data):
* alloc.c (Fmake_marker):
* alloc.c (noseeum_make_marker):
* alloc.c (size_string_direct_data):
* alloc.c (make_uninit_string):
* alloc.c (make_string_nocopy):
* alloc.c (mark_lcrecord_list):
* alloc.c (alloc_managed_lcrecord):
* alloc.c (free_managed_lcrecord):
* alloc.c (sweep_lcrecords_1):
* alloc.c (malloced_storage_size):
* buffer.c (allocate_buffer):
* buffer.c (compute_buffer_usage):
* buffer.c (DEFVAR_BUFFER_LOCAL_1):
* buffer.c (nuke_all_buffer_slots):
* buffer.c (common_init_complex_vars_of_buffer):
* buffer.h (struct buffer_text):
* buffer.h (struct buffer):
* bytecode.c:
* bytecode.c (make_compiled_function_args):
* bytecode.c (size_compiled_function_args):
* bytecode.h (struct compiled_function_args):
* casetab.c (allocate_case_table):
* casetab.h (struct Lisp_Case_Table):
* charset.h (struct Lisp_Charset):
* chartab.c (fill_char_table):
* chartab.c (Fmake_char_table):
* chartab.c (make_char_table_entry):
* chartab.c (copy_char_table_entry):
* chartab.c (Fcopy_char_table):
* chartab.c (put_char_table):
* chartab.h (struct Lisp_Char_Table_Entry):
* chartab.h (struct Lisp_Char_Table):
* console-gtk-impl.h (struct gtk_device):
* console-gtk-impl.h (struct gtk_frame):
* console-impl.h (struct console):
* console-msw-impl.h (struct Lisp_Devmode):
* console-msw-impl.h (struct mswindows_device):
* console-msw-impl.h (struct msprinter_device):
* console-msw-impl.h (struct mswindows_frame):
* console-msw-impl.h (struct mswindows_dialog_id):
* console-stream-impl.h (struct stream_console):
* console-stream.c (stream_init_console):
* console-tty-impl.h (struct tty_console):
* console-tty-impl.h (struct tty_device):
* console-tty.c (allocate_tty_console_struct):
* console-x-impl.h (struct x_device):
* console-x-impl.h (struct x_frame):
* console.c (allocate_console):
* console.c (nuke_all_console_slots):
* console.c (DEFVAR_CONSOLE_LOCAL_1):
* console.c (common_init_complex_vars_of_console):
* data.c (make_weak_list):
* data.c (make_weak_box):
* data.c (make_ephemeron):
* database.c:
* database.c (struct Lisp_Database):
* database.c (allocate_database):
* database.c (finalize_database):
* device-gtk.c (allocate_gtk_device_struct):
* device-impl.h (struct device):
* device-msw.c:
* device-msw.c (mswindows_init_device):
* device-msw.c (msprinter_init_device):
* device-msw.c (finalize_devmode):
* device-msw.c (allocate_devmode):
* device-tty.c (allocate_tty_device_struct):
* device-x.c (allocate_x_device_struct):
* device.c:
* device.c (nuke_all_device_slots):
* device.c (allocate_device):
* dialog-msw.c (handle_question_dialog_box):
* elhash.c:
* elhash.c (struct Lisp_Hash_Table):
* elhash.c (finalize_hash_table):
* elhash.c (make_general_lisp_hash_table):
* elhash.c (Fcopy_hash_table):
* elhash.h (htentry):
* emacs.c (main_1):
* eval.c:
* eval.c (size_multiple_value):
* event-stream.c (finalize_command_builder):
* event-stream.c (allocate_command_builder):
* event-stream.c (free_command_builder):
* event-stream.c (event_stream_generate_wakeup):
* event-stream.c (event_stream_resignal_wakeup):
* event-stream.c (event_stream_disable_wakeup):
* event-stream.c (event_stream_wakeup_pending_p):
* events.h (struct Lisp_Timeout):
* events.h (struct command_builder):
* extents-impl.h:
* extents-impl.h (struct extent_auxiliary):
* extents-impl.h (struct extent_info):
* extents-impl.h (set_extent_no_chase_aux_field):
* extents-impl.h (set_extent_no_chase_normal_field):
* extents.c:
* extents.c (gap_array_marker):
* extents.c (gap_array):
* extents.c (extent_list_marker):
* extents.c (extent_list):
* extents.c (stack_of_extents):
* extents.c (gap_array_make_marker):
* extents.c (extent_list_make_marker):
* extents.c (allocate_extent_list):
* extents.c (SLOT):
* extents.c (mark_extent_auxiliary):
* extents.c (allocate_extent_auxiliary):
* extents.c (attach_extent_auxiliary):
* extents.c (size_gap_array):
* extents.c (finalize_extent_info):
* extents.c (allocate_extent_info):
* extents.c (uninit_buffer_extents):
* extents.c (allocate_soe):
* extents.c (copy_extent):
* extents.c (vars_of_extents):
* extents.h:
* faces.c (allocate_face):
* faces.h (struct Lisp_Face):
* faces.h (struct face_cachel):
* file-coding.c:
* file-coding.c (finalize_coding_system):
* file-coding.c (sizeof_coding_system):
* file-coding.c (Fcopy_coding_system):
* file-coding.h (struct Lisp_Coding_System):
* file-coding.h (MARKED_SLOT):
* fns.c (size_bit_vector):
* font-mgr.c:
* font-mgr.c (finalize_fc_pattern):
* font-mgr.c (print_fc_pattern):
* font-mgr.c (Ffc_pattern_p):
* font-mgr.c (Ffc_pattern_create):
* font-mgr.c (Ffc_name_parse):
* font-mgr.c (Ffc_name_unparse):
* font-mgr.c (Ffc_pattern_duplicate):
* font-mgr.c (Ffc_pattern_add):
* font-mgr.c (Ffc_pattern_del):
* font-mgr.c (Ffc_pattern_get):
* font-mgr.c (fc_config_create_using):
* font-mgr.c (fc_strlist_to_lisp_using):
* font-mgr.c (fontset_to_list):
* font-mgr.c (Ffc_config_p):
* font-mgr.c (Ffc_config_up_to_date):
* font-mgr.c (Ffc_config_build_fonts):
* font-mgr.c (Ffc_config_get_cache):
* font-mgr.c (Ffc_config_get_fonts):
* font-mgr.c (Ffc_config_set_current):
* font-mgr.c (Ffc_config_get_blanks):
* font-mgr.c (Ffc_config_get_rescan_interval):
* font-mgr.c (Ffc_config_set_rescan_interval):
* font-mgr.c (Ffc_config_app_font_add_file):
* font-mgr.c (Ffc_config_app_font_add_dir):
* font-mgr.c (Ffc_config_app_font_clear):
* font-mgr.c (size):
* font-mgr.c (Ffc_config_substitute):
* font-mgr.c (Ffc_font_render_prepare):
* font-mgr.c (Ffc_font_match):
* font-mgr.c (Ffc_font_sort):
* font-mgr.c (finalize_fc_config):
* font-mgr.c (print_fc_config):
* font-mgr.h:
* font-mgr.h (struct fc_pattern):
* font-mgr.h (XFC_PATTERN):
* font-mgr.h (struct fc_config):
* font-mgr.h (XFC_CONFIG):
* frame-gtk.c (allocate_gtk_frame_struct):
* frame-impl.h (struct frame):
* frame-msw.c (mswindows_init_frame_1):
* frame-x.c (allocate_x_frame_struct):
* frame.c (nuke_all_frame_slots):
* frame.c (allocate_frame_core):
* gc.c:
* gc.c (GC_CHECK_NOT_FREE):
* glyphs.c (finalize_image_instance):
* glyphs.c (allocate_image_instance):
* glyphs.c (Fcolorize_image_instance):
* glyphs.c (allocate_glyph):
* glyphs.c (unmap_subwindow_instance_cache_mapper):
* glyphs.c (register_ignored_expose):
* glyphs.h (struct Lisp_Image_Instance):
* glyphs.h (struct Lisp_Glyph):
* glyphs.h (struct glyph_cachel):
* glyphs.h (struct expose_ignore):
* gui.c (allocate_gui_item):
* gui.h (struct Lisp_Gui_Item):
* keymap.c (struct Lisp_Keymap):
* keymap.c (make_keymap):
* lisp.h:
* lisp.h (struct Lisp_String_Direct_Data):
* lisp.h (struct Lisp_String_Indirect_Data):
* lisp.h (struct Lisp_Vector):
* lisp.h (struct Lisp_Bit_Vector):
* lisp.h (DECLARE_INLINE_LISP_BIT_VECTOR):
* lisp.h (struct weak_box):
* lisp.h (struct ephemeron):
* lisp.h (struct weak_list):
* lrecord.h:
* lrecord.h (struct lrecord_implementation):
* lrecord.h (MC_ALLOC_CALL_FINALIZER):
* lrecord.h (struct lcrecord_list):
* lstream.c (finalize_lstream):
* lstream.c (sizeof_lstream):
* lstream.c (Lstream_new):
* lstream.c (Lstream_delete):
* lstream.h (struct lstream):
* marker.c:
* marker.c (finalize_marker):
* marker.c (compute_buffer_marker_usage):
* mule-charset.c:
* mule-charset.c (make_charset):
* mule-charset.c (compute_charset_usage):
* objects-impl.h (struct Lisp_Color_Instance):
* objects-impl.h (struct Lisp_Font_Instance):
* objects-tty-impl.h (struct tty_color_instance_data):
* objects-tty-impl.h (struct tty_font_instance_data):
* objects-tty.c (tty_initialize_color_instance):
* objects-tty.c (tty_initialize_font_instance):
* objects.c (finalize_color_instance):
* objects.c (Fmake_color_instance):
* objects.c (finalize_font_instance):
* objects.c (Fmake_font_instance):
* objects.c (reinit_vars_of_objects):
* opaque.c:
* opaque.c (sizeof_opaque):
* opaque.c (make_opaque_ptr):
* opaque.c (free_opaque_ptr):
* opaque.h:
* opaque.h (Lisp_Opaque):
* opaque.h (Lisp_Opaque_Ptr):
* print.c (printing_unreadable_lcrecord):
* print.c (external_object_printer):
* print.c (debug_p4):
* process.c (finalize_process):
* process.c (make_process_internal):
* procimpl.h (struct Lisp_Process):
* rangetab.c (Fmake_range_table):
* rangetab.c (Fcopy_range_table):
* rangetab.h (struct Lisp_Range_Table):
* scrollbar.c:
* scrollbar.c (create_scrollbar_instance):
* scrollbar.c (compute_scrollbar_instance_usage):
* scrollbar.h (struct scrollbar_instance):
* specifier.c (finalize_specifier):
* specifier.c (sizeof_specifier):
* specifier.c (set_specifier_caching):
* specifier.h (struct Lisp_Specifier):
* specifier.h (struct specifier_caching):
* symeval.h:
* symeval.h (SYMBOL_VALUE_MAGIC_P):
* symeval.h (DEFVAR_SYMVAL_FWD):
* symsinit.h:
* syntax.c (init_buffer_syntax_cache):
* syntax.h (struct syntax_cache):
* toolbar.c:
* toolbar.c (allocate_toolbar_button):
* toolbar.c (update_toolbar_button):
* toolbar.h (struct toolbar_button):
* tooltalk.c (struct Lisp_Tooltalk_Message):
* tooltalk.c (make_tooltalk_message):
* tooltalk.c (struct Lisp_Tooltalk_Pattern):
* tooltalk.c (make_tooltalk_pattern):
* ui-gtk.c:
* ui-gtk.c (allocate_ffi_data):
* ui-gtk.c (emacs_gtk_object_finalizer):
* ui-gtk.c (allocate_emacs_gtk_object_data):
* ui-gtk.c (allocate_emacs_gtk_boxed_data):
* ui-gtk.h:
* window-impl.h (struct window):
* window-impl.h (struct window_mirror):
* window.c (finalize_window):
* window.c (allocate_window):
* window.c (new_window_mirror):
* window.c (mark_window_as_deleted):
* window.c (make_dummy_parent):
* window.c (compute_window_mirror_usage):
* window.c (compute_window_usage):
Overall point of this change and previous ones in this repository:
(1) Introduce new, clearer terminology: everything other than int
or char is a "record" object, which comes in two types: "normal
objects" and "frob-block objects". Fix up all places that
referred to frob-block objects as "simple", "basic", etc.
(2) Provide an advertised interface for doing operations on Lisp
objects, including creating new types, that is clean and
consistent in its naming, uses the above-referenced terms and
avoids referencing "lrecords", "old lcrecords", etc., which should
hide under the surface.
(3) Make the size_in_bytes and finalizer methods take a
Lisp_Object rather than a void * for consistency with other methods.
(4) Separate finalizer method into finalizer and disksaver, so
that normal finalize methods don't have to worry about disksaving.
Other specifics:
(1) Renaming:
LISP_OBJECT_HEADER -> NORMAL_LISP_OBJECT_HEADER
ALLOC_LISP_OBJECT -> ALLOC_NORMAL_LISP_OBJECT
implementation->basic_p -> implementation->frob_block_p
ALLOCATE_FIXED_TYPE_AND_SET_IMPL -> ALLOC_FROB_BLOCK_LISP_OBJECT
*FCCONFIG*, wrap_fcconfig -> *FC_CONFIG*, wrap_fc_config
*FCPATTERN*, wrap_fcpattern -> *FC_PATTERN*, wrap_fc_pattern
(the last two changes make the naming of these macros consistent
with the naming of all other macros, since the objects are named
fc-config and fc-pattern with a hyphen)
(2) Lots of documentation fixes in lrecord.h.
(3) Eliminate macros for copying, freeing, zeroing objects, getting
their storage size. Instead, new functions:
zero_sized_lisp_object()
zero_nonsized_lisp_object()
lisp_object_storage_size()
free_normal_lisp_object()
(copy_lisp_object() already exists)
LISP_OBJECT_FROB_BLOCK_P() (actually a macro)
Eliminated:
free_lrecord()
zero_lrecord()
copy_lrecord()
copy_sized_lrecord()
old_copy_lcrecord()
old_copy_sized_lcrecord()
old_zero_lcrecord()
old_zero_sized_lcrecord()
LISP_OBJECT_STORAGE_SIZE()
COPY_SIZED_LISP_OBJECT()
COPY_SIZED_LCRECORD()
COPY_LISP_OBJECT()
ZERO_LISP_OBJECT()
FREE_LISP_OBJECT()
(4) Catch the remaining places where lrecord stuff was used directly
and use the advertised interface, e.g. alloc_sized_lrecord() ->
ALLOC_SIZED_LISP_OBJECT().
(5) Make certain statically-declared pseudo-objects
(buffer_local_flags, console_local_flags) have their lheader
initialized correctly, so things like copy_lisp_object() can work
on them. Make extent_auxiliary_defaults a proper heap object
Vextent_auxiliary_defaults, and make extent auxiliaries dumpable
so that this object can be dumped. allocate_extent_auxiliary()
now just creates the object, and attach_extent_auxiliary()
creates an extent auxiliary and attaches to an extent, like the
old allocate_extent_auxiliary().
(6) Create EXTENT_AUXILIARY_SLOTS macro, similar to the foo-slots.h
files but in a macro instead of a file. The purpose is to avoid
duplication when iterating over all the slots in an extent auxiliary.
Use it.
(7) In lstream.c, don't zero out object after allocation because
allocation routines take care of this.
(8) In marker.c, fix a mistake in computing marker overhead.
(9) In print.c, clean up printing_unreadable_lcrecord(),
external_object_printer() to avoid lots of ifdef NEW_GC's.
(10) Separate toolbar-button allocation into a separate
allocate_toolbar_button() function for use in the example code
in lrecord.h.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Fri, 05 Mar 2010 04:08:17 -0600 |
parents | d4f666cda5e6 |
children | 308d34e9f07d |
rev | line source |
---|---|
428 | 1 /* Interfaces to system-dependent kernel and library entries. |
2 Copyright (C) 1985-1988, 1992-1995 Free Software Foundation, Inc. | |
3 Copyright (C) 1995 Tinker Systems. | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
4 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2010 Ben Wing. |
428 | 5 |
6 This file is part of XEmacs. | |
7 | |
8 XEmacs is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
10 Free Software Foundation; either version 2, or (at your option) any | |
11 later version. | |
12 | |
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with XEmacs; see the file COPYING. If not, write to | |
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
21 Boston, MA 02111-1307, USA. */ | |
22 | |
771 | 23 |
428 | 24 /* Synched up with: FSF 19.30 except for some Windows-NT crap. */ |
25 | |
771 | 26 /* Authorship: |
27 | |
28 Current primary author: Various | |
29 | |
30 Originally from FSF. Major changes at various times. | |
31 Substantially cleaned up by Ben Wing, Dec. 1994 / Jan. 1995. | |
32 SIGIO stuff ripped apart and redone by Ben Wing. (during 19.14 devel?) | |
33 Signal stuff totally redone by Ben Wing. (during 19.14 devel? that would | |
34 be Dec 1995 - Apr 1996.) | |
35 Controlling terminal stuff redone by Ben Wing for 19.13. | |
36 System call encapsulation stuff written by Ben Wing for 19.12. (1995) | |
37 Ripped up and redone avoiding preprocessor tricks Aug - Sep 2001 during | |
38 Mule-on-Windows development. | |
39 */ | |
428 | 40 |
41 #include <config.h> | |
42 #include "lisp.h" | |
43 | |
44 /* ------------------------------- */ | |
45 /* basic includes */ | |
46 /* ------------------------------- */ | |
47 | |
800 | 48 |
49 #include "buffer.h" | |
872 | 50 #include "device-impl.h" |
800 | 51 #include "events.h" |
52 #include "frame.h" | |
53 #include "process.h" | |
54 #include "redisplay.h" | |
55 #include "sysdep.h" | |
56 #include "window.h" | |
57 | |
428 | 58 #ifdef HAVE_TTY |
872 | 59 #include "console-tty-impl.h" |
428 | 60 #else |
61 #endif /* HAVE_TTY */ | |
62 | |
872 | 63 #include "console-stream-impl.h" |
442 | 64 #ifdef WIN32_NATIVE |
771 | 65 #include "syswindows.h" |
428 | 66 #endif |
67 | |
800 | 68 #include "sysdir.h" |
69 #include "sysfile.h" | |
70 #include "sysproc.h" | |
71 #include "syspwd.h" | |
859 | 72 #include "syssignal.h" |
800 | 73 #include "systime.h" |
74 #include "systty.h" | |
75 #include "syswait.h" | |
76 | |
77 #include <setjmp.h> | |
78 | |
79 | |
428 | 80 /* ------------------------------- */ |
81 /* TTY definitions */ | |
82 /* ------------------------------- */ | |
83 | |
84 #ifdef USG | |
85 #include <sys/utsname.h> | |
86 #endif /* USG */ | |
87 | |
88 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */ | |
89 #ifndef LPASS8 | |
90 #define LPASS8 0 | |
91 #endif | |
92 | |
93 #ifndef HAVE_H_ERRNO | |
94 int h_errno; | |
95 #endif | |
96 | |
97 #ifdef HAVE_TTY | |
98 | |
99 static int baud_convert[] = | |
100 #ifdef BAUD_CONVERT | |
101 BAUD_CONVERT; | |
102 #else | |
103 { | |
104 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200, | |
105 1800, 2400, 4800, 9600, 19200, 38400 | |
106 }; | |
107 #endif | |
108 | |
109 #endif | |
110 | |
111 | |
112 /************************************************************************/ | |
113 /* subprocess control */ | |
114 /************************************************************************/ | |
115 | |
853 | 116 #ifdef NEED_SYNC_PROCESS_CODE |
117 | |
118 /* True iff we are about to fork off a synchronous process or if we | |
119 are waiting for it. */ | |
120 volatile int synch_process_alive; | |
121 | |
122 /* Nonzero => this is a string explaining death of synchronous subprocess. */ | |
123 const char *synch_process_death; | |
124 | |
125 /* If synch_process_death is zero, | |
126 this is exit code of synchronous subprocess. */ | |
127 int synch_process_retcode; | |
128 | |
129 #endif /* NEED_SYNC_PROCESS_CODE */ | |
130 | |
428 | 131 #ifdef HAVE_TTY |
132 | |
133 #ifdef SIGTSTP | |
134 | |
135 /* Arrange for character C to be read as the next input from | |
136 the terminal. */ | |
137 void | |
2311 | 138 stuff_char (struct console *con, |
139 #ifdef TIOCSTI | |
140 int c | |
141 #else | |
142 int UNUSED (c) | |
143 #endif | |
144 ) | |
428 | 145 { |
146 int input_fd; | |
147 | |
148 assert (CONSOLE_TTY_P (con)); | |
149 input_fd = CONSOLE_TTY_DATA (con)->infd; | |
150 /* Should perhaps error if in batch mode */ | |
151 #ifdef TIOCSTI | |
152 ioctl (input_fd, TIOCSTI, &c); | |
153 #else /* no TIOCSTI */ | |
563 | 154 invalid_operation ("Cannot stuff terminal input characters in this version of Unix.", Qunbound); |
428 | 155 #endif /* no TIOCSTI */ |
156 } | |
157 | |
158 #endif /* SIGTSTP */ | |
159 | |
160 #endif /* HAVE_TTY */ | |
161 | |
162 void | |
2311 | 163 set_exclusive_use ( |
164 #ifdef FIOCLEX | |
165 int fd | |
166 #else | |
167 int UNUSED (fd) | |
168 #endif | |
169 ) | |
428 | 170 { |
171 #ifdef FIOCLEX | |
172 ioctl (fd, FIOCLEX, 0); | |
173 #endif | |
174 /* Ok to do nothing if this feature does not exist */ | |
175 } | |
176 | |
177 void | |
2340 | 178 set_descriptor_non_blocking ( |
179 #if defined (STRIDE) || (defined (pfa) && defined (HAVE_PTYS)) || defined (AIX) || defined (F_SETFL) | |
180 int fd | |
181 #else | |
182 int UNUSED (fd) | |
183 #endif | |
184 ) | |
428 | 185 { |
186 /* Stride people say it's a mystery why this is needed | |
187 as well as the O_NDELAY, but that it fails without this. */ | |
188 /* For AIX: Apparently need this for non-blocking reads on sockets. | |
189 It seems that O_NONBLOCK applies only to FIFOs? From | |
190 lowry@watson.ibm.com (Andy Lowry). */ | |
191 /* #### Should this be conditionalized on FIONBIO? */ | |
872 | 192 #if defined (STRIDE) || (defined (pfa) && defined (HAVE_PTYS)) || defined (AIX) |
428 | 193 { |
194 int one = 1; | |
195 ioctl (fd, FIONBIO, &one); | |
196 } | |
197 #endif | |
198 | |
199 #ifdef F_SETFL | |
200 fcntl (fd, F_SETFL, O_NONBLOCK); | |
201 #endif | |
202 } | |
203 | |
853 | 204 #ifdef NEED_SYNC_PROCESS_CODE /* #### Used only on super-ancient systems */ |
205 | |
206 static void | |
814 | 207 wait_for_termination (int pid) |
428 | 208 { |
209 /* #### With the new improved SIGCHLD handling stuff, there is much | |
210 less danger of race conditions and some of the comments below | |
211 don't apply. This should be updated. */ | |
212 | |
4759
aa5ed11f473b
Remove support for obsolete systems. See xemacs-patches message with ID
Jerry James <james@xemacs.org>
parents:
3700
diff
changeset
|
213 #if defined (HAVE_WAITPID) |
428 | 214 /* Note that, whenever any subprocess terminates (asynch. or synch.), |
215 the SIGCHLD handler will be called and it will call wait(). Thus | |
216 we cannot just call wait() ourselves, and we can't block SIGCHLD | |
217 and then call wait(), because then if an asynch. process dies | |
218 while we're waiting for our synch. process, Emacs will never | |
219 notice that the asynch. process died. | |
220 | |
221 So, the general approach we take is to repeatedly block until a | |
222 signal arrives, and then check if our process died using kill | |
223 (pid, 0). (We could also check the value of `synch_process_alive', | |
224 since the SIGCHLD handler will reset that and we know that we're | |
225 only being called on synchronous processes, but this approach is | |
226 safer. I don't trust the proper delivery of SIGCHLD. | |
227 | |
228 Note also that we cannot use any form of waitpid(). A loop with | |
229 WNOHANG will chew up CPU time; better to use sleep(). A loop | |
230 without WNOWAIT will screw up the SIGCHLD handler (actually this | |
231 is not true, if you duplicate the exit-status-reaping code; see | |
232 below). A loop with WNOWAIT will result in a race condition if | |
233 the process terminates between the process-status check and the | |
234 call to waitpid(). */ | |
235 | |
236 /* Formerly, immediate_quit was set around this function call, but | |
237 that could lead to problems if the QUIT happened when SIGCHLD was | |
238 blocked -- it would remain blocked. Yet another reason why | |
239 immediate_quit is a bad idea. In any case, there is no reason to | |
240 resort to this because either the SIGIO or the SIGALRM will stop | |
241 the block in EMACS_WAIT_FOR_SIGNAL(). */ | |
242 | |
243 /* Apparently there are bugs on some systems with the second method | |
244 used below (the EMACS_BLOCK_SIGNAL method), whereby zombie | |
245 processes get left around. It appears in those cases that the | |
246 SIGCHLD handler is never getting invoked. It's not clear whether | |
247 this is an Emacs bug or a kernel bug or both: on HPUX this | |
248 problem is observed only with XEmacs, but under Solaris 2.4 all | |
249 sorts of different programs have problems with zombies. The | |
250 method we use here does not require a working SIGCHLD (but will | |
251 not break if it is working), and should be safe. */ | |
252 /* | |
253 We use waitpid(), contrary to the remarks above. There is no | |
254 race condition, because the three situations when sigchld_handler | |
255 is invoked should be handled OK: | |
256 | |
257 - handler invoked before waitpid(): In this case, subprocess | |
258 status will be set by sigchld_handler. waitpid() here will | |
259 return -1 with errno set to ECHILD, which is a valid exit | |
260 condition. | |
261 | |
262 - handler invoked during waitpid(): as above, except that errno | |
263 here will be set to EINTR. This will cause waitpid() to be | |
264 called again, and this time it will exit with ECHILD. | |
265 | |
266 - handler invoked after waitpid(): The following code will reap | |
267 the subprocess. In the handler, wait() will return -1 because | |
268 there is no child to reap, and the handler will exit without | |
269 modifying child subprocess status. */ | |
270 int ret, status; | |
271 | |
272 /* Because the SIGCHLD handler can potentially reap the synchronous | |
273 subprocess, we should take care of that. */ | |
274 | |
275 /* Will stay in the do loop as long as: | |
276 1. Process is alive | |
277 2. Ctrl-G is not pressed */ | |
278 do | |
279 { | |
280 QUIT; | |
281 ret = waitpid (pid, &status, 0); | |
282 /* waitpid returns 0 if the process is still alive. */ | |
283 } | |
284 while (ret == 0 || (ret == -1 && errno == EINTR)); | |
285 | |
286 if (ret == pid) /* Success */ | |
287 /* Set synch process globals. This is can also happen | |
288 in sigchld_handler, and that code is duplicated. */ | |
289 { | |
290 synch_process_alive = 0; | |
291 if (WIFEXITED (status)) | |
292 synch_process_retcode = WEXITSTATUS (status); | |
293 else if (WIFSIGNALED (status)) | |
294 synch_process_death = signal_name (WTERMSIG (status)); | |
295 } | |
296 /* On exiting the loop, ret will be -1, with errno set to ECHILD if | |
297 the child has already been reaped, e.g. in the signal handler. */ | |
298 | |
299 /* Otherwise, we've had some error condition here. | |
300 Per POSIX, the only other possibilities are: | |
301 - EFAULT (bus error accessing arg 2) or | |
302 - EINVAL (incorrect arguments), | |
303 which are both program bugs. | |
304 | |
305 Since implementations may add their own error indicators on top, | |
306 we ignore it by default. */ | |
307 #elif defined (EMACS_BLOCK_SIGNAL) && !defined (BROKEN_WAIT_FOR_SIGNAL) && defined (SIGCHLD) | |
308 while (1) | |
309 { | |
310 static int wait_debugging = 0; /* Set nonzero to make following | |
311 function work under dbx (at least for bsd). */ | |
312 QUIT; | |
313 if (wait_debugging) | |
314 return; | |
315 | |
316 EMACS_BLOCK_SIGNAL (SIGCHLD); | |
317 /* Block SIGCHLD from happening during this check, | |
318 to avoid race conditions. */ | |
319 if (kill (pid, 0) < 0) | |
320 { | |
321 EMACS_UNBLOCK_SIGNAL (SIGCHLD); | |
322 return; | |
323 } | |
324 else | |
325 /* WARNING: Whatever this macro does *must* not allow SIGCHLD | |
326 to happen between the time that it's reenabled and when we | |
327 begin to block. Otherwise we may end up blocking for a | |
328 signal that has already arrived and isn't coming again. | |
329 Can you say "race condition"? | |
330 | |
331 I assume that the system calls sigpause() or sigsuspend() | |
332 to provide this atomicness. If you're getting hangs in | |
333 sigpause()/sigsuspend(), then your OS doesn't implement | |
334 this properly (this applies under hpux9, for example). | |
335 Try defining BROKEN_WAIT_FOR_SIGNAL. */ | |
336 EMACS_WAIT_FOR_SIGNAL (SIGCHLD); | |
337 } | |
853 | 338 #else /* not HAVE_WAITPID and (not EMACS_BLOCK_SIGNAL or BROKEN_WAIT_FOR_SIGNAL) */ |
428 | 339 /* This approach is kind of cheesy but is guaranteed(?!) to work |
340 for all systems. */ | |
341 while (1) | |
342 { | |
343 QUIT; | |
344 if (kill (pid, 0) < 0) | |
345 return; | |
771 | 346 stop_interrupts (); |
347 sleep (1); | |
348 start_interrupts (); | |
428 | 349 } |
350 #endif /* OS features */ | |
351 } | |
352 | |
853 | 353 #endif /* NEED_SYNC_PROCESS_CODE */ |
428 | 354 |
355 /* | |
356 * flush any pending output | |
357 * (may flush input as well; it does not matter the way we use it) | |
358 */ | |
359 | |
360 void | |
2286 | 361 flush_pending_output ( |
362 #if !defined (HAVE_TERMIOS) && (defined (TCFLSH) || defined (TIOCFLUSH)) | |
363 int channel | |
364 #else | |
365 int UNUSED (channel) | |
366 #endif | |
367 ) | |
428 | 368 { |
369 #ifdef HAVE_TERMIOS | |
370 /* If we try this, we get hit with SIGTTIN, because | |
371 the child's tty belongs to the child's pgrp. */ | |
372 #elif defined (TCFLSH) | |
373 ioctl (channel, TCFLSH, 1); | |
374 #elif defined (TIOCFLUSH) | |
375 int zero = 0; | |
376 /* 3rd arg should be ignored | |
377 but some 4.2 kernels actually want the address of an int | |
378 and nonzero means something different. */ | |
379 ioctl (channel, TIOCFLUSH, &zero); | |
380 #endif | |
381 } | |
382 | |
442 | 383 #ifndef WIN32_NATIVE |
428 | 384 /* Set up the terminal at the other end of a pseudo-terminal that |
385 we will be controlling an inferior through. | |
386 It should not echo or do line-editing, since that is done | |
387 in Emacs. No padding needed for insertion into an Emacs buffer. */ | |
388 | |
389 void | |
390 child_setup_tty (int out) | |
391 { | |
392 struct emacs_tty s; | |
430 | 393 emacs_get_tty (out, &s); |
428 | 394 |
395 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS) | |
396 assert (isatty(out)); | |
397 s.main.c_oflag |= OPOST; /* Enable output postprocessing */ | |
398 s.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL on output */ | |
513 | 399 |
400 { | |
401 /* Disable all output delays. */ | |
402 tcflag_t delay_mask = 0; | |
428 | 403 #ifdef NLDLY |
513 | 404 delay_mask |= NLDLY; |
405 #endif | |
406 #ifdef CRDLY | |
407 delay_mask |= CRDLY; | |
408 #endif | |
409 #ifdef TABDLY | |
410 delay_mask |= TABDLY; /* Also disables tab expansion (Posix). */ | |
411 #endif | |
412 #ifdef BSDLY | |
413 delay_mask |= BSDLY; | |
414 #endif | |
415 #ifdef VTDLY | |
416 delay_mask |= VTDLY; | |
428 | 417 #endif |
513 | 418 #ifdef FFDLY |
419 delay_mask |= FFDLY; | |
420 #endif | |
421 s.main.c_oflag &= ~delay_mask; | |
422 } | |
423 | |
424 #ifdef OXTABS | |
425 /* Posix defines the TAB3 value for TABDLY to mean: expand tabs to spaces. | |
426 On those systems tab expansion would be disabled by the above code. | |
427 BSD systems use an independent flag, OXTABS. */ | |
428 s.main.c_oflag &= ~OXTABS; /* Disable tab expansion */ | |
429 #endif | |
430 | |
428 | 431 s.main.c_lflag &= ~ECHO; /* Disable echo */ |
432 s.main.c_lflag |= ISIG; /* Enable signals */ | |
433 #ifdef IUCLC | |
434 s.main.c_iflag &= ~IUCLC; /* Disable downcasing on input. */ | |
435 #endif | |
436 #ifdef OLCUC | |
437 s.main.c_oflag &= ~OLCUC; /* Disable upcasing on output. */ | |
438 #endif | |
513 | 439 |
428 | 440 #if defined (CSIZE) && defined (CS8) |
441 s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */ | |
442 #endif | |
443 #ifdef ISTRIP | |
444 s.main.c_iflag &= ~ISTRIP; /* Don't strip 8th bit on input */ | |
445 #endif | |
446 #if 0 | |
447 /* Unnecessary as long as ICANON is set */ | |
448 s.main.c_cc[VMIN] = 1; /* minimum number of characters to accept */ | |
449 s.main.c_cc[VTIME] = 0; /* wait forever for at least 1 character */ | |
450 #endif /* 0 */ | |
451 | |
452 s.main.c_lflag |= ICANON; /* Enable erase/kill and eof processing */ | |
453 s.main.c_cc[VEOF] = 04; /* ensure that EOF is Control-D */ | |
454 s.main.c_cc[VERASE] = _POSIX_VDISABLE; /* disable erase processing */ | |
455 s.main.c_cc[VKILL] = _POSIX_VDISABLE; /* disable kill processing */ | |
456 | |
457 #ifdef HPUX | |
458 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */ | |
459 #endif /* HPUX */ | |
460 | |
461 #ifdef AIX | |
462 #ifndef IBMR2AIX | |
463 /* AIX enhanced edit loses NULs, so disable it. */ | |
464 s.main.c_line = 0; | |
465 s.main.c_iflag &= ~ASCEDIT; | |
466 #endif /* IBMR2AIX */ | |
467 /* Also, PTY overloads NUL and BREAK. | |
468 don't ignore break, but don't signal either, so it looks like NUL. | |
469 This really serves a purpose only if running in an XTERM window | |
470 or via TELNET or the like, but does no harm elsewhere. */ | |
471 s.main.c_iflag &= ~IGNBRK; | |
472 s.main.c_iflag &= ~BRKINT; | |
473 #endif /* AIX */ | |
474 #ifdef SIGNALS_VIA_CHARACTERS | |
475 /* TTY `special characters' are used in process_send_signal | |
476 so set them here to something useful. */ | |
477 s.main.c_cc[VQUIT] = '\\'&037; /* Control-\ */ | |
478 s.main.c_cc[VINTR] = 'C' &037; /* Control-C */ | |
479 s.main.c_cc[VSUSP] = 'Z' &037; /* Control-Z */ | |
480 #else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */ | |
481 /* TTY `special characters' work better as signals, so disable | |
482 character forms */ | |
483 s.main.c_cc[VQUIT] = _POSIX_VDISABLE; | |
484 s.main.c_cc[VINTR] = _POSIX_VDISABLE; | |
485 s.main.c_cc[VSUSP] = _POSIX_VDISABLE; | |
486 s.main.c_lflag &= ~ISIG; | |
487 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */ | |
488 s.main.c_cc[VEOL] = _POSIX_VDISABLE; | |
489 #if defined (CBAUD) | |
440 | 490 /* <mdiers> #### This is not portable. ### |
428 | 491 POSIX does not specify CBAUD, and 4.4BSD does not have it. |
492 Instead, POSIX suggests to use cfset{i,o}speed(). | |
493 [cf. D. Lewine, POSIX Programmer's Guide, Chapter 8: Terminal | |
494 I/O, O'Reilly 1991] */ | |
495 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */ | |
496 #else | |
497 /* <mdiers> What to do upon failure? Just ignoring rc is probably | |
498 not acceptable, is it? */ | |
499 if (cfsetispeed (&s.main, B9600) == -1) /* ignore */; | |
500 if (cfsetospeed (&s.main, B9600) == -1) /* ignore */; | |
501 #endif /* defined (CBAUD) */ | |
502 | |
503 #else /* not HAVE_TERMIO */ | |
504 | |
505 s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE | |
506 | CBREAK | TANDEM); | |
507 s.main.sg_flags |= LPASS8; | |
508 s.main.sg_erase = 0377; | |
509 s.main.sg_kill = 0377; | |
510 s.lmode = LLITOUT | s.lmode; /* Don't strip 8th bit */ | |
511 | |
512 #endif /* not HAVE_TERMIO */ | |
430 | 513 emacs_set_tty (out, &s, 0); |
428 | 514 } |
442 | 515 #endif /* WIN32_NATIVE */ |
428 | 516 |
517 | |
4759
aa5ed11f473b
Remove support for obsolete systems. See xemacs-patches message with ID
Jerry James <james@xemacs.org>
parents:
3700
diff
changeset
|
518 #if !defined (SIGTSTP) |
428 | 519 |
520 #define SIG_PARAM_TYPE int | |
521 | |
522 /* Record a signal code and the handler for it. */ | |
523 struct save_signal | |
524 { | |
525 int code; | |
872 | 526 RETSIGTYPE (XCDECL * handler) (SIG_PARAM_TYPE); |
428 | 527 }; |
528 | |
529 static void | |
530 save_signal_handlers (struct save_signal *saved_handlers) | |
531 { | |
532 while (saved_handlers->code) | |
533 { | |
534 saved_handlers->handler | |
872 | 535 = (RETSIGTYPE (XCDECL *) (SIG_PARAM_TYPE)) EMACS_SIGNAL (saved_handlers->code, SIG_IGN); |
428 | 536 saved_handlers++; |
537 } | |
538 } | |
539 | |
540 static void | |
541 restore_signal_handlers (struct save_signal *saved_handlers) | |
542 { | |
543 while (saved_handlers->code) | |
544 { | |
613 | 545 EMACS_SIGNAL (saved_handlers->code, saved_handlers->handler); |
428 | 546 saved_handlers++; |
547 } | |
548 } | |
549 | |
4760
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
550 /* Fork a subshell. */ |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
551 static void |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
552 sys_subshell (void) |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
553 { |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
554 Lisp_Object dir; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
555 Ibyte *str = 0; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
556 Bytecount len; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
557 struct gcpro gcpro1; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
558 Ibyte *sh = 0; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
559 Extbyte *shext; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
560 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
561 /* Use our buffer's default directory for the subshell. */ |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
562 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
563 /* Note: These calls are spread out to insure that the return values |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
564 of the calls (which may be newly-created strings) are properly |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
565 GC-protected. */ |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
566 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
567 GCPRO1 (dir); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
568 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
569 dir = current_buffer->directory; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
570 /* If the current dir has no terminating slash, we'll get undesirable |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
571 results, so put the slash back. */ |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
572 dir = Ffile_name_as_directory (dir); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
573 dir = Funhandled_file_name_directory (dir); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
574 dir = expand_and_dir_to_file (dir, Qnil); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
575 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
576 str = alloca_ibytes (XSTRING_LENGTH (dir) + 2); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
577 len = XSTRING_LENGTH (dir); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
578 memcpy (str, XSTRING_DATA (dir), len); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
579 if (!IS_ANY_SEP (str[len - 1])) |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
580 str[len++] = DIRECTORY_SEP; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
581 str[len] = 0; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
582 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
583 if (sh == 0) |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
584 sh = egetenv ("SHELL"); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
585 if (sh == 0) |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
586 sh = (Ibyte *) "sh"; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
587 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
588 PATHNAME_CONVERT_OUT (sh, shext); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
589 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
590 UNGCPRO; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
591 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
592 #ifdef WIN32_NATIVE |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
593 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
594 if (str) |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
595 qxe_chdir (str); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
596 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
597 /* Waits for process completion */ |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
598 if (XEUNICODE_P ? |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
599 _wspawnlp (_P_WAIT, (const wchar_t *) shext, |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
600 (const wchar_t *) shext, NULL) != 0 : |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
601 _spawnlp (_P_WAIT, shext, shext, NULL) != 0) |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
602 report_process_error ("Can't spawn subshell", Qunbound); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
603 else |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
604 return; /* we're done, no need to wait for termination */ |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
605 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
606 #else /* not WIN32_NATIVE */ |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
607 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
608 { |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
609 int pid; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
610 struct save_signal saved_handlers[5]; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
611 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
612 saved_handlers[0].code = SIGINT; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
613 saved_handlers[1].code = SIGQUIT; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
614 saved_handlers[2].code = SIGTERM; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
615 #ifdef SIGIO |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
616 saved_handlers[3].code = SIGIO; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
617 saved_handlers[4].code = 0; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
618 #else |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
619 saved_handlers[3].code = 0; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
620 #endif |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
621 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
622 pid = fork (); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
623 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
624 if (pid == -1) |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
625 report_process_error ("Can't spawn subshell", Qunbound); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
626 if (pid == 0) |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
627 { |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
628 if (str) |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
629 qxe_chdir (str); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
630 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
631 #if !defined (NO_SUBPROCESSES) |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
632 close_process_descs (); /* Close Emacs's pipes/ptys */ |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
633 #endif |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
634 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
635 #ifdef SET_EMACS_PRIORITY |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
636 if (emacs_priority != 0) |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
637 nice (-emacs_priority); /* Give the new shell the default priority */ |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
638 #endif |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
639 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
640 execlp (shext, shext, 0); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
641 retry_write (1, "Can't execute subshell", 22); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
642 _exit (1); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
643 } |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
644 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
645 save_signal_handlers (saved_handlers); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
646 synch_process_alive = 1; |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
647 wait_for_termination (pid); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
648 restore_signal_handlers (saved_handlers); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
649 } |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
650 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
651 #endif /* not WIN32_NATIVE */ |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
652 } |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
653 |
4759
aa5ed11f473b
Remove support for obsolete systems. See xemacs-patches message with ID
Jerry James <james@xemacs.org>
parents:
3700
diff
changeset
|
654 #endif /* !defined (SIGTSTP) */ |
428 | 655 |
656 | |
657 | |
658 /* Suspend the Emacs process; give terminal to its superior. */ | |
659 void | |
660 sys_suspend (void) | |
661 { | |
662 #if defined (SIGTSTP) | |
663 { | |
664 int pgrp = EMACS_GET_PROCESS_GROUP (); | |
665 EMACS_KILLPG (pgrp, SIGTSTP); | |
666 } | |
667 | |
4759
aa5ed11f473b
Remove support for obsolete systems. See xemacs-patches message with ID
Jerry James <james@xemacs.org>
parents:
3700
diff
changeset
|
668 #else /* No SIGTSTP */ |
4760
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
669 |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
670 /* On a system where suspending is not implemented, |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
671 instead fork a subshell and let it talk directly to the terminal |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
672 while we wait. */ |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
673 sys_subshell (); |
217abcf015c4
sys_subshell() is needed for WIndows native builds
Vin Shelton <acs@xemacs.org>
parents:
4759
diff
changeset
|
674 |
428 | 675 #endif |
676 } | |
677 | |
678 /* Suspend a process if possible; give terminal to its superior. */ | |
679 void | |
2340 | 680 sys_suspend_process ( |
681 #ifdef SIGTSTP | |
682 int process | |
683 #else | |
684 int UNUSED (process) | |
685 #endif | |
686 ) | |
428 | 687 { |
688 /* I don't doubt that it is possible to suspend processes on | |
4759
aa5ed11f473b
Remove support for obsolete systems. See xemacs-patches message with ID
Jerry James <james@xemacs.org>
parents:
3700
diff
changeset
|
689 * VMS machines, but I don't know how to do it, so... |
428 | 690 */ |
691 #if defined (SIGTSTP) | |
692 kill(process, SIGTSTP); | |
693 #endif | |
694 } | |
695 | |
696 | |
697 /* Given FD, obtain pty buffer size. When no luck, a good guess is made, | |
442 | 698 so that the function works even when fd is not a pty. */ |
428 | 699 |
700 int | |
2340 | 701 get_pty_max_bytes ( |
702 #if defined (HAVE_FPATHCONF) && defined (_PC_MAX_CANON) | |
703 int fd | |
704 #else | |
705 int UNUSED (fd) | |
706 #endif | |
707 ) | |
428 | 708 { |
442 | 709 /* DEC OSF 4.0 fpathconf returns 255, but xemacs hangs on long shell |
710 input lines if we return 253. 252 is OK!. So let's leave a bit | |
711 of slack for the newline that xemacs will insert, and for those | |
712 inevitable vendor off-by-one-or-two-or-three bugs. */ | |
713 #define MAX_CANON_SLACK 10 | |
714 #define SAFE_MAX_CANON (127 - MAX_CANON_SLACK) | |
428 | 715 #if defined (HAVE_FPATHCONF) && defined (_PC_MAX_CANON) |
442 | 716 { |
717 int max_canon = fpathconf (fd, _PC_MAX_CANON); | |
718 #ifdef __hpux__ | |
719 /* HP-UX 10.20 fpathconf returns 768, but this results in | |
720 truncated input lines, while 255 works. */ | |
721 if (max_canon > 255) max_canon = 255; | |
428 | 722 #endif |
442 | 723 return (max_canon < 0 ? SAFE_MAX_CANON : |
724 max_canon > SAFE_MAX_CANON ? max_canon - MAX_CANON_SLACK : | |
725 max_canon); | |
726 } | |
727 #elif defined (_POSIX_MAX_CANON) | |
728 return (_POSIX_MAX_CANON > SAFE_MAX_CANON ? | |
729 _POSIX_MAX_CANON - MAX_CANON_SLACK : | |
730 _POSIX_MAX_CANON); | |
731 #else | |
732 return SAFE_MAX_CANON; | |
733 #endif | |
428 | 734 } |
735 | |
736 /* Figure out the eof character for the FD. */ | |
737 | |
867 | 738 Ibyte |
428 | 739 get_eof_char (int fd) |
740 { | |
867 | 741 const Ibyte ctrl_d = (Ibyte) '\004'; |
428 | 742 |
743 if (!isatty (fd)) | |
744 return ctrl_d; | |
745 #ifdef HAVE_TERMIOS | |
746 { | |
747 struct termios t; | |
748 tcgetattr (fd, &t); | |
749 #if 0 | |
750 /* What is the following line designed to do??? -mrb */ | |
647 | 751 if ((int) strlen ((const char *) t.c_cc) < (VEOF + 1)) |
428 | 752 return ctrl_d; |
753 else | |
867 | 754 return (Ibyte) t.c_cc[VEOF]; |
428 | 755 #endif |
867 | 756 return t.c_cc[VEOF] == _POSIX_VDISABLE ? ctrl_d : (Ibyte) t.c_cc[VEOF]; |
428 | 757 } |
758 #else /* ! HAVE_TERMIOS */ | |
759 /* On Berkeley descendants, the following IOCTL's retrieve the | |
760 current control characters. */ | |
761 #if defined (TIOCGETC) | |
762 { | |
763 struct tchars c; | |
764 ioctl (fd, TIOCGETC, &c); | |
867 | 765 return (Ibyte) c.t_eofc; |
428 | 766 } |
767 #else /* ! defined (TIOCGLTC) && defined (TIOCGETC) */ | |
768 /* On SYSV descendants, the TCGETA ioctl retrieves the current control | |
769 characters. */ | |
770 #ifdef TCGETA | |
771 { | |
772 struct termio t; | |
773 ioctl (fd, TCGETA, &t); | |
647 | 774 if ((int) strlen ((const char *) t.c_cc) < (VINTR + 1)) |
428 | 775 return ctrl_d; |
776 else | |
867 | 777 return (Ibyte) t.c_cc[VINTR]; |
428 | 778 } |
779 #else /* ! defined (TCGETA) */ | |
780 /* Rather than complain, we'll just guess ^D, which is what | |
781 * earlier emacsen always used. */ | |
782 return ctrl_d; | |
783 #endif /* ! defined (TCGETA) */ | |
784 #endif /* ! defined (TIOCGETC) */ | |
785 #endif /* ! defined (HAVE_TERMIOS) */ | |
786 } | |
787 | |
788 /* Set the logical window size associated with descriptor FD | |
789 to HEIGHT and WIDTH. This is used mainly with ptys. */ | |
790 | |
791 int | |
2340 | 792 set_window_size ( |
793 #if defined (TIOCSWINSZ) || defined (TIOCSSIZE) | |
794 int fd, int height, int width | |
795 #else | |
796 int UNUSED (fd), int UNUSED (height), int UNUSED (width) | |
797 #endif | |
798 ) | |
428 | 799 { |
800 #ifdef TIOCSWINSZ | |
801 | |
802 /* BSD-style. */ | |
803 struct winsize size; | |
804 size.ws_row = height; | |
805 size.ws_col = width; | |
806 | |
807 if (ioctl (fd, TIOCSWINSZ, &size) == -1) | |
808 return 0; /* error */ | |
809 else | |
810 return 1; | |
811 | |
812 #elif defined (TIOCSSIZE) | |
813 | |
814 /* SunOS - style. */ | |
815 struct ttysize size; | |
816 size.ts_lines = height; | |
817 size.ts_cols = width; | |
818 | |
819 if (ioctl (fd, TIOCGSIZE, &size) == -1) | |
820 return 0; | |
821 else | |
822 return 1; | |
823 #else | |
824 return -1; | |
825 #endif | |
826 } | |
827 | |
828 /* Set up the proper status flags for use of a pty. */ | |
829 | |
830 void | |
2340 | 831 setup_pty ( |
832 #ifdef TIOCPKT | |
833 int fd | |
834 #else | |
835 int UNUSED (fd) | |
836 #endif | |
837 ) | |
428 | 838 { |
839 #ifdef TIOCPKT | |
840 /* In some systems (Linux through 2.0.0, at least), packet mode doesn't | |
841 get cleared when a pty is closed, so we need to clear it here. | |
842 Linux pre2.0.13 contained an attempted fix for this (from Ted Ts'o, | |
843 tytso@mit.edu), but apparently it messed up rlogind and telnetd, so he | |
844 removed the fix in pre2.0.14. - dkindred@cs.cmu.edu | |
845 */ | |
846 { | |
847 int off = 0; | |
848 ioctl (fd, TIOCPKT, (char *)&off); | |
849 } | |
535 | 850 #endif /* TIOCPKT */ |
428 | 851 } |
852 | |
853 | |
854 /************************************************************************/ | |
855 /* TTY control */ | |
856 /************************************************************************/ | |
857 | |
858 /* ------------------------------------------------------ */ | |
859 /* get baud rate */ | |
860 /* ------------------------------------------------------ */ | |
861 | |
862 /* It really makes more sense for the baud-rate to be console-specific | |
863 and not device-specific, but it's (at least potentially) used for output | |
864 decisions. */ | |
865 | |
866 void | |
867 init_baud_rate (struct device *d) | |
868 { | |
869 if (DEVICE_WIN_P (d) || DEVICE_STREAM_P (d)) | |
870 { | |
871 DEVICE_BAUD_RATE (d) = 38400; | |
872 return; | |
873 } | |
874 | |
875 #ifdef HAVE_TTY | |
876 assert (DEVICE_TTY_P (d)); | |
877 { | |
647 | 878 struct console *con = XCONSOLE (DEVICE_CONSOLE (d)); |
428 | 879 int input_fd = CONSOLE_TTY_DATA (con)->infd; |
814 | 880 #ifdef HAVE_TERMIOS |
428 | 881 struct termios sg; |
882 | |
883 sg.c_cflag = B9600; | |
884 tcgetattr (input_fd, &sg); | |
885 DEVICE_TTY_DATA (d)->ospeed = cfgetospeed (&sg); | |
886 #elif defined (HAVE_TERMIO) | |
887 struct termio sg; | |
888 | |
889 sg.c_cflag = B9600; | |
890 # ifdef HAVE_TCATTR | |
891 tcgetattr (input_fd, &sg); | |
892 # else | |
893 ioctl (input_fd, TCGETA, &sg); | |
894 # endif | |
895 DEVICE_TTY_DATA (d)->ospeed = sg.c_cflag & CBAUD; | |
896 #else /* neither TERMIOS nor TERMIO */ | |
897 struct sgttyb sg; | |
898 | |
899 sg.sg_ospeed = B9600; | |
900 if (ioctl (input_fd, TIOCGETP, &sg) < 0) | |
2500 | 901 ABORT (); |
428 | 902 DEVICE_TTY_DATA (d)->ospeed = sg.sg_ospeed; |
903 #endif | |
904 } | |
905 | |
906 DEVICE_BAUD_RATE (d) = | |
907 (DEVICE_TTY_DATA (d)->ospeed < countof (baud_convert) | |
908 ? baud_convert[DEVICE_TTY_DATA (d)->ospeed] | |
909 : 9600); | |
910 | |
911 if (DEVICE_BAUD_RATE (d) == 0) | |
912 DEVICE_BAUD_RATE (d) = 1200; | |
913 #endif /* HAVE_TTY */ | |
914 } | |
915 | |
916 | |
917 /* ------------------------------------------------------ */ | |
918 /* SIGIO control */ | |
919 /* ------------------------------------------------------ */ | |
920 | |
853 | 921 #if defined (SIGIO) && !defined (BROKEN_SIGIO) |
428 | 922 |
923 static void | |
924 init_sigio_on_device (struct device *d) | |
925 { | |
926 int filedesc = DEVICE_INFD (d); | |
927 | |
928 #if defined (FIOSSAIOOWN) | |
929 { /* HPUX stuff */ | |
930 int owner = getpid (); | |
931 int ioctl_status; | |
932 if (DEVICE_TTY_P (d)) | |
933 { | |
934 ioctl_status = ioctl (filedesc, FIOGSAIOOWN, | |
935 &DEVICE_OLD_FCNTL_OWNER (d)); | |
936 ioctl_status = ioctl (filedesc, FIOSSAIOOWN, &owner); | |
937 } | |
938 #ifdef HAVE_WINDOW_SYSTEM | |
939 else if (!DEVICE_STREAM_P (d)) | |
940 { | |
941 ioctl_status = ioctl (filedesc, SIOCGPGRP, | |
942 &DEVICE_OLD_FCNTL_OWNER (d)); | |
943 ioctl_status = ioctl (filedesc, SIOCSPGRP, &owner); | |
944 } | |
945 #endif | |
946 } | |
947 #elif defined (F_SETOWN) && !defined (F_SETOWN_BUG) | |
948 DEVICE_OLD_FCNTL_OWNER (d) = fcntl (filedesc, F_GETOWN, 0); | |
949 fcntl (filedesc, F_SETOWN, getpid ()); | |
950 #endif | |
951 } | |
952 | |
953 static void | |
954 reset_sigio_on_device (struct device *d) | |
955 { | |
956 int filedesc = DEVICE_INFD (d); | |
957 | |
958 #if defined (FIOSSAIOOWN) | |
959 { /* HPUX stuff */ | |
960 int ioctl_status; | |
961 if (DEVICE_TTY_P (d)) | |
962 { | |
963 ioctl_status = ioctl (filedesc, FIOSSAIOOWN, | |
964 &DEVICE_OLD_FCNTL_OWNER (d)); | |
965 } | |
966 #ifdef HAVE_WINDOW_SYSTEM | |
967 else if (!DEVICE_STREAM_P (d)) | |
968 { | |
969 ioctl_status = ioctl (filedesc, SIOCSPGRP, | |
970 &DEVICE_OLD_FCNTL_OWNER (d)); | |
971 } | |
972 #endif | |
973 } | |
974 #elif defined (F_SETOWN) && !defined (F_SETOWN_BUG) | |
975 fcntl (filedesc, F_SETOWN, DEVICE_OLD_FCNTL_OWNER (d)); | |
976 #endif | |
977 } | |
978 | |
979 static void | |
980 request_sigio_on_device (struct device *d) | |
981 { | |
982 int filedesc = DEVICE_INFD (d); | |
983 | |
502 | 984 /* NOTE: It appears that Linux has its own mechanism for requesting |
985 SIGIO, using the F_GETSIG and F_SETSIG commands to fcntl(). | |
986 These let you pick which signal you want sent (not just SIGIO), | |
987 and if you do this, you get additional info which tells you which | |
988 file descriptor has input ready on it. The man page says: | |
989 | |
990 Using these mechanisms, a program can implement fully | |
991 asynchronous I/O without using select(2) or poll(2) most | |
992 of the time. | |
993 | |
994 The use of O_ASYNC, F_GETOWN, F_SETOWN is specific to BSD | |
995 and Linux. F_GETSIG and F_SETSIG are Linux-specific. | |
996 POSIX has asynchronous I/O and the aio_sigevent structure | |
997 to achieve similar things; these are also available in | |
998 Linux as part of the GNU C Library (Glibc). | |
999 | |
1000 But it appears that Linux also supports O_ASYNC, so I see no | |
1001 particular need to switch. --ben | |
1002 */ | |
1003 | |
4759
aa5ed11f473b
Remove support for obsolete systems. See xemacs-patches message with ID
Jerry James <james@xemacs.org>
parents:
3700
diff
changeset
|
1004 #if defined (I_SETSIG) && !defined (HPUX11) && !defined (LINUX) |
428 | 1005 { |
502 | 1006 int events = 0; |
428 | 1007 ioctl (filedesc, I_GETSIG, &events); |
1008 ioctl (filedesc, I_SETSIG, events | S_INPUT); | |
1009 } | |
502 | 1010 #elif defined (O_ASYNC) |
1011 /* Generally FASYNC and O_ASYNC are both defined, and both equal; | |
1012 but let's not depend on that. O_ASYNC appears to be more | |
1013 standard (at least the Linux include files think so), so | |
1014 check it first. */ | |
1015 fcntl (filedesc, F_SETFL, fcntl (filedesc, F_GETFL, 0) | O_ASYNC); | |
428 | 1016 #elif defined (FASYNC) |
1017 fcntl (filedesc, F_SETFL, fcntl (filedesc, F_GETFL, 0) | FASYNC); | |
1018 #elif defined (FIOSSAIOSTAT) | |
1019 { | |
1020 /* DG: Changed for HP-UX. HP-UX uses different IOCTLs for | |
1021 sockets and other devices for some bizarre reason. We guess | |
1022 that an X device is a socket, and tty devices aren't. We then | |
1023 use the following crud to do the appropriate thing. */ | |
1024 int on = 1; | |
1025 int ioctl_status; /* ####DG: check if IOCTL succeeds here. */ | |
1026 | |
1027 if (DEVICE_TTY_P (d)) | |
1028 { | |
1029 ioctl_status = ioctl (filedesc, FIOSSAIOSTAT, &on); | |
1030 } | |
1031 #ifdef HAVE_WINDOW_SYSTEM | |
1032 else if (!DEVICE_STREAM_P (d)) | |
1033 { | |
1034 ioctl_status = ioctl (filedesc, FIOASYNC, &on); | |
1035 } | |
1036 #endif | |
1037 } | |
1038 #elif defined (FIOASYNC) | |
1039 { | |
1040 int on = 1; | |
1041 ioctl (filedesc, FIOASYNC, &on); | |
1042 } | |
1043 #endif | |
1044 } | |
1045 | |
1046 static void | |
1047 unrequest_sigio_on_device (struct device *d) | |
1048 { | |
1049 int filedesc = DEVICE_INFD (d); | |
1050 | |
4759
aa5ed11f473b
Remove support for obsolete systems. See xemacs-patches message with ID
Jerry James <james@xemacs.org>
parents:
3700
diff
changeset
|
1051 #if defined (I_SETSIG) && !defined (HPUX11) && !defined (LINUX) |
428 | 1052 { |
502 | 1053 int events = 0; |
428 | 1054 ioctl (filedesc, I_GETSIG, &events); |
1055 ioctl (filedesc, I_SETSIG, events & ~S_INPUT); | |
1056 } | |
502 | 1057 #elif defined (O_ASYNC) |
1058 fcntl (filedesc, F_SETFL, fcntl (filedesc, F_GETFL, 0) & ~O_ASYNC); | |
428 | 1059 #elif defined (FASYNC) |
1060 fcntl (filedesc, F_SETFL, fcntl (filedesc, F_GETFL, 0) & ~FASYNC); | |
1061 #elif defined (FIOSSAIOSTAT) | |
1062 { | |
1063 /* DG: Changed for HP-UX. HP-UX uses different IOCTLs for | |
1064 sockets and other devices for some bizarre reason. We guess | |
1065 that an X device is a socket, and tty devices aren't. We then | |
1066 use the following crud to do the appropriate thing. */ | |
1067 | |
1068 int off = 0; | |
1069 int ioctl_status; | |
1070 | |
1071 /* See comment for request_sigio_on_device */ | |
1072 | |
1073 if (DEVICE_TTY_P (d)) | |
1074 { | |
1075 ioctl_status = ioctl (filedesc, FIOSSAIOSTAT, &off); | |
1076 } | |
1077 else | |
1078 { | |
1079 ioctl_status = ioctl (filedesc, FIOASYNC, &off); | |
1080 } | |
1081 } | |
1082 #elif defined (FIOASYNC) | |
1083 { | |
1084 int off = 0; | |
1085 ioctl (filedesc, FIOASYNC, &off); | |
1086 } | |
1087 #endif | |
1088 } | |
1089 | |
1090 void | |
1091 request_sigio (void) | |
1092 { | |
1093 Lisp_Object devcons, concons; | |
1094 | |
1095 DEVICE_LOOP_NO_BREAK (devcons, concons) | |
1096 { | |
1097 struct device *d; | |
1098 | |
1099 d = XDEVICE (XCAR (devcons)); | |
1100 | |
1101 if (!DEVICE_STREAM_P (d)) | |
1102 request_sigio_on_device (d); | |
1103 } | |
1104 } | |
1105 | |
1106 void | |
1107 unrequest_sigio (void) | |
1108 { | |
1109 Lisp_Object devcons, concons; | |
1110 | |
1111 DEVICE_LOOP_NO_BREAK (devcons, concons) | |
1112 { | |
1113 struct device *d; | |
1114 | |
1115 d = XDEVICE (XCAR (devcons)); | |
1116 | |
1117 if (!DEVICE_STREAM_P (d)) | |
1118 unrequest_sigio_on_device (d); | |
1119 } | |
1120 } | |
1121 | |
1122 #endif /* SIGIO */ | |
1123 | |
1124 /* ------------------------------------------------------ */ | |
1125 /* Changing Emacs's process group */ | |
1126 /* ------------------------------------------------------ */ | |
1127 | |
1128 /* Saving and restoring the process group of Emacs's terminal. */ | |
1129 | |
1130 /* On some systems, apparently (?!) Emacs must be in its own process | |
1131 group in order to receive SIGIO correctly. On other systems | |
1132 (e.g. Solaris), it's not required and doing it makes things | |
1133 get fucked up. So, we only do it when | |
1134 SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP is defined. Basically, | |
1135 this is only required for BSD 4.2 systems. (Actually, I bet | |
1136 we don't have to do this at all -- those systems also | |
1137 required interrupt input, which we don't support.) | |
1138 | |
1139 If Emacs was in its own process group (i.e. inherited_pgroup == | |
1140 getpid ()), then we know we're running under a shell with job | |
1141 control (Emacs would never be run as part of a pipeline). | |
1142 Everything is fine. | |
1143 | |
1144 If Emacs was not in its own process group, then we know we're | |
1145 running under a shell (or a caller) that doesn't know how to | |
1146 separate itself from Emacs (like sh). Emacs must be in its own | |
1147 process group in order to receive SIGIO correctly. In this | |
1148 situation, we put ourselves in our own pgroup, forcibly set the | |
1149 tty's pgroup to our pgroup, and make sure to restore and reinstate | |
1150 the tty's pgroup just like any other terminal setting. If | |
1151 inherited_group was not the tty's pgroup, then we'll get a | |
1152 SIGTTmumble when we try to change the tty's pgroup, and a CONT if | |
1153 it goes foreground in the future, which is what should happen. */ | |
1154 | |
1155 #ifdef SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP | |
1156 | |
442 | 1157 static pid_t inherited_pgroup; |
1158 static pid_t inherited_tty_pgroup; | |
428 | 1159 |
1160 #endif | |
1161 | |
1162 void | |
1163 munge_tty_process_group (void) | |
1164 { | |
1165 #ifdef SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP | |
1166 if (noninteractive) | |
1167 return; | |
1168 | |
1169 /* Only do this munging if we have a device on the controlling | |
1170 terminal. See the large comment below. */ | |
1171 | |
1172 if (CONSOLEP (Vcontrolling_terminal) && | |
1173 CONSOLE_LIVE_P (XCONSOLE (Vcontrolling_terminal))) | |
1174 { | |
1175 int fd = open ("/dev/tty", O_RDWR, 0); | |
442 | 1176 pid_t me = getpid (); |
428 | 1177 EMACS_BLOCK_SIGNAL (SIGTTOU); |
1178 EMACS_SET_TTY_PROCESS_GROUP (fd, &me); | |
1179 EMACS_UNBLOCK_SIGNAL (SIGTTOU); | |
771 | 1180 retry_close (fd); |
428 | 1181 } |
1182 #endif | |
1183 } | |
1184 | |
1185 /* Split off the foreground process group to Emacs alone. | |
1186 When we are in the foreground, but not started in our own process | |
1187 group, redirect the TTY to point to our own process group. We need | |
1188 to be in our own process group to receive SIGIO properly. */ | |
1189 static void | |
1190 munge_process_groups (void) | |
1191 { | |
1192 #ifdef SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP | |
1193 if (noninteractive) | |
1194 return; | |
1195 | |
1196 EMACS_SEPARATE_PROCESS_GROUP (); | |
1197 | |
1198 munge_tty_process_group (); | |
1199 #endif | |
1200 } | |
1201 | |
1202 void | |
1203 unmunge_tty_process_group (void) | |
1204 { | |
1205 #ifdef SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP | |
1206 { | |
1207 int fd = open ("/dev/tty", O_RDWR, 0); | |
1208 EMACS_BLOCK_SIGNAL (SIGTTOU); | |
1209 EMACS_SET_TTY_PROCESS_GROUP (fd, &inherited_tty_pgroup); | |
1210 EMACS_UNBLOCK_SIGNAL (SIGTTOU); | |
771 | 1211 retry_close (fd); |
428 | 1212 } |
1213 #endif | |
1214 } | |
1215 | |
1216 /* Set the tty to our original foreground group. | |
1217 Also restore the original process group (put us back into sh's | |
1218 process group), so that ^Z will suspend both us and sh. */ | |
1219 static void | |
1220 unmunge_process_groups (void) | |
1221 { | |
1222 #ifdef SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP | |
1223 if (noninteractive) | |
1224 return; | |
1225 | |
1226 unmunge_tty_process_group (); | |
1227 | |
1228 EMACS_SET_PROCESS_GROUP (inherited_pgroup); | |
1229 #endif | |
1230 } | |
1231 | |
1232 /* According to some old wisdom, we need to be in a separate process | |
1233 group for SIGIO to work correctly (at least on some systems ...). | |
1234 So go ahead and put ourselves into our own process group. This | |
1235 will fail if we're already in our own process group, but who cares. | |
1236 Also record whether we were in our own process group. (In general, | |
1237 we will already be in our own process group if we were started from | |
1238 a job-control shell like csh, but not if we were started from sh). | |
1239 | |
1240 If we succeeded in changing our process group, then we will no | |
1241 longer be in the foreground process group of our controlling | |
1242 terminal. Therefore, if we have a console open onto this terminal, | |
1243 we have to change the controlling terminal's foreground process | |
1244 group (otherwise we will get stopped with a SIGTTIN signal when | |
1245 attempting to read from the terminal). It's important, | |
1246 however, that we do this *only* when we have a console open onto | |
1247 the terminal. It's a decidedly bad idea to do so otherwise, | |
1248 especially if XEmacs was started from the background. */ | |
1249 | |
1250 void | |
1251 init_process_group (void) | |
1252 { | |
1253 #ifdef SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP | |
1254 if (! noninteractive) | |
1255 { | |
1256 int fd = open ("/dev/tty", O_RDWR, 0); | |
1257 inherited_pgroup = EMACS_GET_PROCESS_GROUP (); | |
1258 EMACS_GET_TTY_PROCESS_GROUP (fd, &inherited_tty_pgroup); | |
771 | 1259 retry_close (fd); |
428 | 1260 EMACS_SEPARATE_PROCESS_GROUP (); |
1261 } | |
1262 #endif | |
1263 } | |
1264 | |
1265 void | |
1266 disconnect_controlling_terminal (void) | |
1267 { | |
1268 # ifdef HAVE_SETSID | |
1269 /* Controlling terminals are attached to a session. | |
1270 Create a new session for us; it will have no controlling | |
1271 terminal. This also, of course, puts us in our own | |
1272 process group. */ | |
1273 setsid (); | |
1274 # else | |
1275 /* Put us in our own process group. */ | |
1276 EMACS_SEPARATE_PROCESS_GROUP (); | |
1277 # if defined (TIOCNOTTY) | |
1278 /* This is the older way of disconnecting the controlling | |
1279 terminal, on 4.3 BSD. We must open /dev/tty; using | |
1280 filedesc 0 is not sufficient because it could be | |
1281 something else (e.g. our stdin was redirected to | |
1282 another terminal). | |
1283 */ | |
1284 { | |
1285 int j = open ("/dev/tty", O_RDWR, 0); | |
1286 ioctl (j, TIOCNOTTY, 0); | |
771 | 1287 retry_close (j); |
428 | 1288 } |
1289 # endif /* TIOCNOTTY */ | |
1290 /* | |
1291 On systems without TIOCNOTTY and without | |
1292 setsid(), we don't need to do anything more to | |
1293 disconnect our controlling terminal. Here is | |
1294 what the man page for termio(7) from a SYSV 3.2 | |
1295 system says: | |
1296 | |
1297 "The first terminal file opened by the process group leader | |
1298 of a terminal file not already associated with a process | |
1299 group becomes the control terminal for that process group. | |
1300 The control terminal plays a special role in handling quit | |
1301 and interrupt signals, as discussed below. The control | |
1302 terminal is inherited by a child process during a fork(2). | |
1303 A process can break this association by changing its process | |
1304 group using setpgrp(2)." | |
1305 | |
1306 */ | |
1307 # endif /* not HAVE_SETSID */ | |
1308 } | |
1309 | |
1310 | |
1311 /* ------------------------------------------------------ */ | |
1312 /* Getting and setting emacs_tty structures */ | |
1313 /* ------------------------------------------------------ */ | |
1314 | |
1315 /* It's wrong to encase these into #ifdef HAVE_TTY because we need | |
1316 them for child TTY processes. */ | |
1317 /* However, this does break NT support while we don't do child TTY processes */ | |
442 | 1318 #ifndef WIN32_NATIVE |
428 | 1319 |
1320 /* Set *TC to the parameters associated with the terminal FD. | |
1321 Return zero if all's well, or -1 if we ran into an error we | |
1322 couldn't deal with. */ | |
1323 int | |
1324 emacs_get_tty (int fd, struct emacs_tty *settings) | |
1325 { | |
1326 /* Retrieve the primary parameters - baud rate, character size, etcetera. */ | |
1327 #ifdef HAVE_TCATTR | |
1328 /* We have those nifty POSIX tcmumbleattr functions. */ | |
1329 if (tcgetattr (fd, &settings->main) < 0) | |
1330 return -1; | |
1331 | |
1332 #elif defined HAVE_TERMIO | |
1333 /* The SYSV-style interface? */ | |
1334 if (ioctl (fd, TCGETA, &settings->main) < 0) | |
1335 return -1; | |
1336 | |
814 | 1337 #else |
428 | 1338 /* I give up - I hope you have the BSD ioctls. */ |
1339 if (ioctl (fd, TIOCGETP, &settings->main) < 0) | |
1340 return -1; | |
1341 #endif /* HAVE_TCATTR */ | |
1342 | |
1343 /* Suivant - Do we have to get struct ltchars data? */ | |
1344 #ifdef HAVE_LTCHARS | |
1345 if (ioctl (fd, TIOCGLTC, &settings->ltchars) < 0) | |
1346 return -1; | |
1347 #endif | |
1348 | |
1349 /* How about a struct tchars and a wordful of lmode bits? */ | |
1350 #ifdef HAVE_TCHARS | |
1351 if (ioctl (fd, TIOCGETC, &settings->tchars) < 0 | |
1352 || ioctl (fd, TIOCLGET, &settings->lmode) < 0) | |
1353 return -1; | |
1354 #endif | |
1355 | |
1356 /* We have survived the tempest. */ | |
1357 return 0; | |
1358 } | |
1359 | |
1360 /* Set the parameters of the tty on FD according to the contents of | |
1361 *SETTINGS. If FLUSHP is non-zero, we discard input. | |
430 | 1362 Return 0 if all went well, and -1 if anything failed. |
1363 #### All current callers use FLUSHP == 0. */ | |
428 | 1364 |
1365 int | |
1366 emacs_set_tty (int fd, struct emacs_tty *settings, int flushp) | |
1367 { | |
1368 /* Set the primary parameters - baud rate, character size, etcetera. */ | |
1369 #ifdef HAVE_TCATTR | |
1370 int i; | |
1371 /* We have those nifty POSIX tcmumbleattr functions. | |
1372 William J. Smith <wjs@wiis.wang.com> writes: | |
1373 "POSIX 1003.1 defines tcsetattr() to return success if it was | |
1374 able to perform any of the requested actions, even if some | |
1375 of the requested actions could not be performed. | |
1376 We must read settings back to ensure tty setup properly. | |
1377 AIX requires this to keep tty from hanging occasionally." */ | |
1378 /* This makes sure that we don't loop indefinitely in here. */ | |
1379 for (i = 0 ; i < 10 ; i++) | |
1380 if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0) | |
1381 { | |
1382 if (errno == EINTR) | |
1383 continue; | |
1384 else | |
1385 return -1; | |
1386 } | |
1387 else | |
1388 { | |
2957 | 1389 struct termios new_; |
428 | 1390 |
1391 /* Get the current settings, and see if they're what we asked for. */ | |
2957 | 1392 tcgetattr (fd, &new_); |
428 | 1393 /* We cannot use memcmp on the whole structure here because under |
1394 * aix386 the termios structure has some reserved field that may | |
1395 * not be filled in. | |
4759
aa5ed11f473b
Remove support for obsolete systems. See xemacs-patches message with ID
Jerry James <james@xemacs.org>
parents:
3700
diff
changeset
|
1396 * FIXME: Now that aix386 is gone, can we memcmp the whole structure? |
428 | 1397 */ |
2957 | 1398 if ( new_.c_iflag == settings->main.c_iflag |
1399 && new_.c_oflag == settings->main.c_oflag | |
1400 && new_.c_cflag == settings->main.c_cflag | |
1401 && new_.c_lflag == settings->main.c_lflag | |
1402 && memcmp(new_.c_cc, settings->main.c_cc, NCCS) == 0) | |
428 | 1403 break; |
1404 else | |
1405 continue; | |
1406 } | |
1407 #elif defined HAVE_TERMIO | |
1408 /* The SYSV-style interface? */ | |
1409 if (ioctl (fd, flushp ? TCSETAF : TCSETAW, &settings->main) < 0) | |
1410 return -1; | |
1411 | |
814 | 1412 #else |
428 | 1413 /* I give up - I hope you have the BSD ioctls. */ |
1414 if (ioctl (fd, (flushp) ? TIOCSETP : TIOCSETN, &settings->main) < 0) | |
1415 return -1; | |
1416 #endif /* HAVE_TCATTR */ | |
1417 | |
1418 /* Suivant - Do we have to get struct ltchars data? */ | |
1419 #ifdef HAVE_LTCHARS | |
1420 if (ioctl (fd, TIOCSLTC, &settings->ltchars) < 0) | |
1421 return -1; | |
1422 #endif | |
1423 | |
1424 /* How about a struct tchars and a wordful of lmode bits? */ | |
1425 #ifdef HAVE_TCHARS | |
1426 if (ioctl (fd, TIOCSETC, &settings->tchars) < 0 | |
1427 || ioctl (fd, TIOCLSET, &settings->lmode) < 0) | |
1428 return -1; | |
1429 #endif | |
1430 | |
1431 /* We have survived the tempest. */ | |
1432 return 0; | |
1433 } | |
1434 | |
442 | 1435 #endif /* WIN32_NATIVE */ |
428 | 1436 |
1437 /* ------------------------------------------------------ */ | |
1438 /* Initializing a device */ | |
1439 /* ------------------------------------------------------ */ | |
1440 | |
1441 #ifdef HAVE_TTY | |
1442 | |
1443 #if defined (TIOCGLTC) && defined (HAVE_LTCHARS) /* HAVE_LTCHARS */ | |
1444 static struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1}; | |
1445 #endif | |
1446 #ifdef TIOCGETC /* HAVE_TCHARS */ | |
1447 #ifdef HAVE_TCHARS | |
1448 static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1}; | |
1449 #endif | |
1450 #endif | |
1451 | |
1452 static void | |
1453 tty_init_sys_modes_on_device (struct device *d) | |
1454 { | |
1455 struct emacs_tty tty; | |
2286 | 1456 int input_fd; |
428 | 1457 struct console *con = XCONSOLE (DEVICE_CONSOLE (d)); |
1458 | |
1459 input_fd = CONSOLE_TTY_DATA (con)->infd; | |
1460 | |
430 | 1461 emacs_get_tty (input_fd, &CONSOLE_TTY_DATA (con)->old_tty); |
428 | 1462 tty = CONSOLE_TTY_DATA (con)->old_tty; |
1463 | |
1464 con->tty_erase_char = Qnil; | |
1465 | |
1466 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS) | |
1467 /* after all those years... */ | |
1468 con->tty_erase_char = make_char (tty.main.c_cc[VERASE]); | |
1469 tty.main.c_iflag |= (IGNBRK); /* Ignore break condition */ | |
1470 tty.main.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */ | |
1471 #ifdef ISTRIP | |
1472 tty.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */ | |
1473 #endif | |
1474 tty.main.c_lflag &= ~ECHO; /* Disable echo */ | |
1475 tty.main.c_lflag &= ~ICANON; /* Disable erase/kill processing */ | |
1476 #ifdef IEXTEN | |
1477 tty.main.c_lflag &= ~IEXTEN; /* Disable other editing characters. */ | |
1478 #endif | |
1479 tty.main.c_lflag |= ISIG; /* Enable signals */ | |
1480 if (TTY_FLAGS (con).flow_control) | |
1481 { | |
1482 tty.main.c_iflag |= IXON; /* Enable start/stop output control */ | |
1483 #ifdef IXANY | |
1484 tty.main.c_iflag &= ~IXANY; | |
1485 #endif /* IXANY */ | |
1486 } | |
1487 else | |
1488 tty.main.c_iflag &= ~IXON; /* Disable start/stop output control */ | |
1489 tty.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL | |
1490 on output */ | |
513 | 1491 |
1492 #if 0 | |
1493 /* We used to disable tab expansion here, but this is the user's decision. */ | |
1494 #if defined (TABDLY) && defined (TAB3) | |
1495 if ((tty.main.c_oflag & TABDLY) == TAB3) | |
1496 tty.main.c_oflag &= ~TABDLY; /* Disable tab expansion (Posix). */ | |
1497 #elif defined (OXTABS) | |
1498 tty.main.c_oflag &= ~OXTABS; /* Disable tab expansion (BSD). */ | |
1499 #endif | |
1500 #endif /* 0 */ | |
1501 | |
428 | 1502 #ifdef CS8 |
1503 if (TTY_FLAGS (con).meta_key) | |
1504 { | |
1505 tty.main.c_cflag |= CS8; /* allow 8th bit on input */ | |
1506 tty.main.c_cflag &= ~PARENB;/* Don't check parity */ | |
1507 } | |
1508 #endif | |
1509 if (CONSOLE_TTY_DATA (con)->controlling_terminal) | |
1510 { | |
1204 | 1511 tty.main.c_cc[VINTR] = /* C-g (usually) gives SIGINT */ |
2828 | 1512 event_to_character (CONSOLE_QUIT_EVENT (con), 0, 1); |
428 | 1513 /* Set up C-g for both SIGQUIT and SIGINT. |
1514 We don't know which we will get, but we handle both alike | |
1515 so which one it really gives us does not matter. */ | |
1204 | 1516 tty.main.c_cc[VQUIT] = tty.main.c_cc[VINTR]; |
428 | 1517 } |
1518 else | |
1519 { | |
1520 tty.main.c_cc[VINTR] = _POSIX_VDISABLE; | |
1521 tty.main.c_cc[VQUIT] = _POSIX_VDISABLE; | |
1522 } | |
1523 tty.main.c_cc[VMIN] = 1; /* Input should wait for at | |
1524 least 1 char */ | |
1525 tty.main.c_cc[VTIME] = 0; /* no matter how long that takes. */ | |
1526 #ifdef VSWTCH | |
1527 tty.main.c_cc[VSWTCH] = _POSIX_VDISABLE; /* Turn off shell layering use | |
1528 of C-z */ | |
1529 #endif /* VSWTCH */ | |
1530 /* There was some conditionalizing here on (mips or TCATTR), but | |
1531 I think that's wrong. There was one report of C-y (DSUSP) not being | |
1532 disabled on HP9000s700 systems, and this might fix it. */ | |
1533 #ifdef VSUSP | |
1534 tty.main.c_cc[VSUSP] = _POSIX_VDISABLE; /* Turn off mips handling of C-z. */ | |
1535 #endif /* VSUSP */ | |
1536 #ifdef V_DSUSP | |
1537 tty.main.c_cc[V_DSUSP] = _POSIX_VDISABLE; /* Turn off mips handling of C-y. */ | |
1538 #endif /* V_DSUSP */ | |
1539 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */ | |
1540 tty.main.c_cc[VDSUSP] = _POSIX_VDISABLE; | |
1541 #endif /* VDSUSP */ | |
1542 #ifdef VLNEXT | |
1543 tty.main.c_cc[VLNEXT] = _POSIX_VDISABLE; | |
1544 #endif /* VLNEXT */ | |
1545 #ifdef VREPRINT | |
1546 tty.main.c_cc[VREPRINT] = _POSIX_VDISABLE; | |
1547 #endif /* VREPRINT */ | |
1548 #ifdef VWERASE | |
1549 tty.main.c_cc[VWERASE] = _POSIX_VDISABLE; | |
1550 #endif /* VWERASE */ | |
1551 #ifdef VDISCARD | |
1552 tty.main.c_cc[VDISCARD] = _POSIX_VDISABLE; | |
1553 #endif /* VDISCARD */ | |
1554 #ifdef VSTART | |
1555 tty.main.c_cc[VSTART] = _POSIX_VDISABLE; | |
1556 #endif /* VSTART */ | |
1557 #ifdef VSTRT | |
1558 tty.main.c_cc[VSTRT] = _POSIX_VDISABLE; /* called VSTRT on some systems */ | |
1559 #endif /* VSTART */ | |
1560 #ifdef VSTOP | |
1561 tty.main.c_cc[VSTOP] = _POSIX_VDISABLE; | |
1562 #endif /* VSTOP */ | |
1563 | |
1564 #ifdef AIX | |
1565 #ifndef IBMR2AIX | |
1566 /* AIX enhanced edit loses NULs, so disable it. */ | |
1567 tty.main.c_line = 0; | |
1568 tty.main.c_iflag &= ~ASCEDIT; | |
1569 #else | |
1570 tty.main.c_cc[VSTRT] = 255; | |
1571 tty.main.c_cc[VSTOP] = 255; | |
1572 tty.main.c_cc[VSUSP] = 255; | |
1573 tty.main.c_cc[VDSUSP] = 255; | |
1574 #endif /* IBMR2AIX */ | |
1575 /* Also, PTY overloads NUL and BREAK. | |
1576 don't ignore break, but don't signal either, so it looks like NUL. | |
1577 This really serves a purpose only if running in an XTERM window | |
1578 or via TELNET or the like, but does no harm elsewhere. */ | |
1579 tty.main.c_iflag &= ~IGNBRK; | |
1580 tty.main.c_iflag &= ~BRKINT; | |
1581 #endif /* AIX */ | |
1582 #else /* if not HAVE_TERMIO */ | |
1583 con->tty_erase_char = make_char (tty.main.sg_erase); | |
1584 tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS); | |
1585 if (TTY_FLAGS (con).meta_key) | |
1586 tty.main.sg_flags |= ANYP; | |
1587 /* #### should we be using RAW mode here? */ | |
1588 tty.main.sg_flags |= /* interrupt_input ? RAW : */ CBREAK; | |
1589 #endif /* not HAVE_TERMIO */ | |
1590 | |
1591 /* If going to use CBREAK mode, we must request C-g to interrupt | |
1592 and turn off start and stop chars, etc. If not going to use | |
1593 CBREAK mode, do this anyway so as to turn off local flow | |
1594 control for user coming over network on 4.2; in this case, | |
1595 only t_stopc and t_startc really matter. */ | |
1596 #ifndef HAVE_TERMIO | |
1597 #ifdef HAVE_TCHARS | |
1598 /* Note: if not using CBREAK mode, it makes no difference how we | |
1599 set this */ | |
1600 tty.tchars = new_tchars; | |
2828 | 1601 tty.tchars.t_intrc = event_to_character (CONSOLE_QUIT_EVENT (con), 0, 1); |
428 | 1602 if (TTY_FLAGS (con).flow_control) |
1603 { | |
1604 tty.tchars.t_startc = '\021'; | |
1605 tty.tchars.t_stopc = '\023'; | |
1606 } | |
1607 | |
1608 tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | | |
1609 CONSOLE_TTY_DATA (con)->old_tty.lmode; | |
1610 #endif /* HAVE_TCHARS */ | |
1611 #endif /* not HAVE_TERMIO */ | |
1612 | |
1613 #ifdef HAVE_LTCHARS | |
1614 tty.ltchars = new_ltchars; | |
1615 #endif /* HAVE_LTCHARS */ | |
1616 | |
430 | 1617 emacs_set_tty (input_fd, &tty, 0); |
428 | 1618 |
1619 /* This code added to insure that, if flow-control is not to be used, | |
1620 we have an unlocked terminal at the start. */ | |
1621 | |
1622 #ifdef TCXONC | |
1623 if (!TTY_FLAGS (con).flow_control) ioctl (input_fd, TCXONC, 1); | |
1624 #endif | |
1625 #ifdef TIOCSTART | |
1626 if (!TTY_FLAGS (con).flow_control) ioctl (input_fd, TIOCSTART, 0); | |
1627 #endif | |
1628 | |
4759
aa5ed11f473b
Remove support for obsolete systems. See xemacs-patches message with ID
Jerry James <james@xemacs.org>
parents:
3700
diff
changeset
|
1629 #if defined (HAVE_TERMIOS) |
428 | 1630 #ifdef TCOON |
1631 if (!TTY_FLAGS (con).flow_control) tcflow (input_fd, TCOON); | |
1632 #endif | |
1633 #endif | |
4759
aa5ed11f473b
Remove support for obsolete systems. See xemacs-patches message with ID
Jerry James <james@xemacs.org>
parents:
3700
diff
changeset
|
1634 |
428 | 1635 set_tty_modes (con); |
1636 } | |
1637 | |
1638 #endif /* HAVE_TTY */ | |
1639 | |
1640 void | |
2340 | 1641 init_one_device ( |
1642 #if defined(HAVE_TTY) || (defined(SIGIO) && !defined(BROKEN_SIGIO)) | |
1643 struct device *d | |
1644 #else | |
1645 struct device *UNUSED (d) | |
1646 #endif | |
1647 ) | |
428 | 1648 { |
1649 #ifdef HAVE_TTY | |
1650 if (DEVICE_TTY_P (d)) | |
1651 tty_init_sys_modes_on_device (d); | |
1652 #endif | |
1653 #if defined(SIGIO) && !defined(BROKEN_SIGIO) | |
1654 if (!DEVICE_STREAM_P (d)) | |
1655 { | |
1656 init_sigio_on_device (d); | |
1657 request_sigio_on_device (d); | |
1658 } | |
1659 #endif | |
1660 } | |
1661 | |
1662 void | |
1663 init_one_console (struct console *con) | |
1664 { | |
1665 Lisp_Object devcons; | |
1666 | |
1667 CONSOLE_DEVICE_LOOP (devcons, con) | |
1668 { | |
1669 struct device *d = XDEVICE (XCAR (devcons)); | |
1670 | |
1671 init_one_device (d); | |
1672 } | |
1673 } | |
1674 | |
1675 void | |
1676 reinit_initial_console (void) | |
1677 { | |
1678 munge_process_groups (); | |
1679 if (CONSOLEP (Vcontrolling_terminal) && | |
1680 CONSOLE_LIVE_P (XCONSOLE (Vcontrolling_terminal))) | |
1681 init_one_console (XCONSOLE (Vcontrolling_terminal)); | |
1682 } | |
1683 | |
1684 | |
1685 /* ------------------------------------------------------ */ | |
1686 /* Other TTY functions */ | |
1687 /* ------------------------------------------------------ */ | |
1688 | |
1689 #ifdef HAVE_TTY | |
1690 | |
1691 #if 0 /* not currently used */ | |
1692 | |
1693 /* Return nonzero if safe to use tabs in output. | |
1694 At the time this is called, init_sys_modes has not been done yet. */ | |
1695 | |
1696 int | |
2340 | 1697 tabs_safe_p (struct device *USED_IF_TTY (d)) |
428 | 1698 { |
1699 #ifdef HAVE_TTY | |
1700 if (DEVICE_TTY_P (d)) | |
1701 { | |
1702 struct emacs_tty tty; | |
1703 | |
430 | 1704 emacs_get_tty (DEVICE_INFD (d), &tty); |
428 | 1705 return EMACS_TTY_TABS_OK (&tty); |
1706 } | |
1707 #endif | |
1708 return 1; | |
1709 } | |
1710 | |
1711 #endif /* 0 */ | |
1712 | |
1713 /* Get terminal size from system. | |
1714 Store number of lines into *heightp and width into *widthp. | |
1715 If zero or a negative number is stored, the value is not valid. */ | |
1716 | |
1717 void | |
1718 get_tty_device_size (struct device *d, int *widthp, int *heightp) | |
1719 { | |
1720 int input_fd = DEVICE_INFD (d); | |
1721 | |
1722 assert (DEVICE_TTY_P (d)); | |
1723 | |
1724 #ifdef TIOCGWINSZ | |
1725 { | |
1726 /* BSD-style. */ | |
1727 struct winsize size; | |
1728 | |
1729 if (ioctl (input_fd, TIOCGWINSZ, &size) == -1) | |
1730 *widthp = *heightp = 0; | |
1731 else | |
1732 { | |
1733 *widthp = size.ws_col; | |
1734 *heightp = size.ws_row; | |
1735 } | |
1736 } | |
1737 #elif defined TIOCGSIZE | |
1738 { | |
1739 /* SunOS - style. */ | |
1740 struct ttysize size; | |
1741 | |
1742 if (ioctl (input_fd, TIOCGSIZE, &size) == -1) | |
1743 *widthp = *heightp = 0; | |
1744 else | |
1745 { | |
1746 *widthp = size.ts_cols; | |
1747 *heightp = size.ts_lines; | |
1748 } | |
1749 } | |
1750 #else /* system doesn't know size */ | |
1751 | |
1752 *widthp = 0; | |
1753 *heightp = 0; | |
1754 | |
1755 #endif /* not !TIOCGWINSZ */ | |
1756 } | |
1757 | |
1758 #endif /* HAVE_TTY */ | |
1759 | |
1760 | |
1761 /* ------------------------------------------------------ */ | |
1762 /* Is device 8 bit ? */ | |
1763 /* ------------------------------------------------------ */ | |
1764 | |
1765 #ifdef HAVE_TTY | |
1766 | |
1767 int | |
1768 eight_bit_tty (struct device *d) | |
1769 { | |
1770 struct emacs_tty s; | |
1771 int input_fd; | |
1772 int eight_bit = 0; | |
1773 | |
1774 assert (DEVICE_TTY_P (d)); | |
1775 input_fd = DEVICE_INFD (d); | |
1776 | |
430 | 1777 emacs_get_tty (input_fd, &s); |
428 | 1778 |
1779 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS) | |
1780 eight_bit = (s.main.c_cflag & CSIZE) == CS8; | |
1781 #else | |
1782 eight_bit = 0; /* I don't know how to do it */ | |
1783 #endif | |
1784 return eight_bit; | |
1785 } | |
1786 | |
1787 #endif /* HAVE_TTY */ | |
1788 | |
1789 | |
1790 /* ------------------------------------------------------ */ | |
1791 /* Resetting a device */ | |
1792 /* ------------------------------------------------------ */ | |
1793 | |
1794 #ifdef HAVE_TTY | |
1795 | |
1796 /* Prepare the terminal for exiting Emacs; move the cursor to the | |
1797 bottom of the frame, turn off interrupt-driven I/O, etc. */ | |
1798 static void | |
1799 tty_reset_sys_modes_on_device (struct device *d) | |
1800 { | |
4759
aa5ed11f473b
Remove support for obsolete systems. See xemacs-patches message with ID
Jerry James <james@xemacs.org>
parents:
3700
diff
changeset
|
1801 #if defined (BSD) |
2286 | 1802 int output_fd; |
1803 #endif | |
1804 int input_fd; | |
428 | 1805 struct console *con = XCONSOLE (DEVICE_CONSOLE (d)); |
1806 | |
1807 input_fd = CONSOLE_TTY_DATA (con)->infd; | |
4759
aa5ed11f473b
Remove support for obsolete systems. See xemacs-patches message with ID
Jerry James <james@xemacs.org>
parents:
3700
diff
changeset
|
1808 #if defined (BSD) |
428 | 1809 output_fd = CONSOLE_TTY_DATA (con)->outfd; |
2286 | 1810 #endif |
428 | 1811 |
1812 tty_redisplay_shutdown (con); | |
1813 /* reset_tty_modes() flushes the connection at its end. */ | |
1814 reset_tty_modes (con); | |
1815 | |
1816 #if defined (BSD) | |
1817 /* Avoid possible loss of output when changing terminal modes. */ | |
1818 fsync (output_fd); | |
1819 #endif | |
1820 | |
430 | 1821 while (emacs_set_tty (input_fd, &CONSOLE_TTY_DATA (con)->old_tty, 0) |
428 | 1822 < 0 && errno == EINTR) |
1823 ; | |
1824 } | |
1825 | |
1826 #endif /* HAVE_TTY */ | |
1827 | |
1828 void | |
1829 reset_one_device (struct device *d) | |
1830 { | |
1831 #ifdef HAVE_TTY | |
1832 if (DEVICE_TTY_P (d)) | |
1833 tty_reset_sys_modes_on_device (d); | |
1834 else | |
1835 #endif | |
1836 if (DEVICE_STREAM_P (d)) | |
1837 fflush (CONSOLE_STREAM_DATA (XCONSOLE (DEVICE_CONSOLE (d)))->out); | |
1838 #if defined(SIGIO) && !defined(BROKEN_SIGIO) | |
1839 if (!DEVICE_STREAM_P (d)) | |
1840 { | |
1841 unrequest_sigio_on_device (d); | |
1842 reset_sigio_on_device (d); | |
1843 } | |
1844 #endif | |
1845 } | |
1846 | |
1847 void | |
1848 reset_one_console (struct console *con) | |
1849 { | |
1850 /* Note: this can be called during GC. */ | |
1851 Lisp_Object devcons; | |
1852 | |
1853 CONSOLE_DEVICE_LOOP (devcons, con) | |
1854 { | |
1855 struct device *d = XDEVICE (XCAR (devcons)); | |
1856 | |
1857 reset_one_device (d); | |
1858 } | |
1859 } | |
1860 | |
1861 void | |
1862 reset_all_consoles (void) | |
1863 { | |
1864 /* Note: this can be called during GC. */ | |
1865 Lisp_Object concons; | |
1866 | |
1867 CONSOLE_LOOP (concons) | |
1868 { | |
1869 struct console *con = XCONSOLE (XCAR (concons)); | |
1870 | |
1871 reset_one_console (con); | |
1872 } | |
1873 | |
1874 unmunge_process_groups (); | |
1875 } | |
1876 | |
1877 void | |
1878 reset_initial_console (void) | |
1879 { | |
1880 if (CONSOLEP (Vcontrolling_terminal) && | |
1881 CONSOLE_LIVE_P (XCONSOLE (Vcontrolling_terminal))) | |
1882 reset_one_console (XCONSOLE (Vcontrolling_terminal)); | |
1883 unmunge_process_groups (); | |
1884 } | |
1885 | |
1886 | |
1887 /************************************************************************/ | |
1888 /* limits of text/data segments */ | |
1889 /************************************************************************/ | |
1890 | |
801 | 1891 /* Need start_of_data() as much as possible now, for total_data_usage(); |
1892 but with PDUMP and WIN32_NATIVE, can't currently do it. */ | |
1330 | 1893 #if ! (defined (PDUMP) && defined (WIN32_NATIVE) && defined (SYSTEM_MALLOC)) |
428 | 1894 #define NEED_STARTS |
1895 #endif | |
1896 | |
1897 #ifdef NEED_STARTS | |
1898 /* Some systems that cannot dump also cannot implement these. */ | |
1899 | |
1900 /* | |
1901 * Return the address of the start of the text segment prior to | |
1902 * doing an unexec. After unexec the return value is undefined. | |
1903 * See crt0.c for further explanation and _start. | |
1904 * | |
1905 */ | |
1906 | |
801 | 1907 #if !defined (HAVE_TEXT_START) && !defined (PDUMP) |
440 | 1908 |
442 | 1909 EXTERN_C int _start (void); |
428 | 1910 |
1911 char * | |
1912 start_of_text (void) | |
1913 { | |
1914 #ifdef TEXT_START | |
442 | 1915 return (char *) TEXT_START; |
428 | 1916 #else |
442 | 1917 return (char *) _start; |
428 | 1918 #endif /* TEXT_START */ |
1919 } | |
440 | 1920 #endif /* !defined(HAVE_TEXT_START) && !defined(PDUMP) */ |
428 | 1921 |
1922 /* | |
1923 * Return the address of the start of the data segment prior to | |
1924 * doing an unexec. After unexec the return value is undefined. | |
442 | 1925 * See ecrt0.c for further information and definition of data_start. |
428 | 1926 * |
1927 * Apparently, on BSD systems this is etext at startup. On | |
1928 * USG systems (swapping) this is highly mmu dependent and | |
1929 * is also dependent on whether or not the program is running | |
1930 * with shared text. Generally there is a (possibly large) | |
1931 * gap between end of text and start of data with shared text. | |
1932 * | |
1933 * On Uniplus+ systems with shared text, data starts at a | |
1934 * fixed address. Each port (from a given oem) is generally | |
1935 * different, and the specific value of the start of data can | |
1936 * be obtained via the UniPlus+ specific "uvar" system call, | |
1937 * however the method outlined in crt0.c seems to be more portable. | |
1938 * | |
1939 * Probably what will have to happen when a USG unexec is available, | |
1940 * at least on UniPlus, is temacs will have to be made unshared so | |
1941 * that text and data are contiguous. Then once loadup is complete, | |
1942 * unexec will produce a shared executable where the data can be | |
1943 * at the normal shared text boundary and the startofdata variable | |
1944 * will be patched by unexec to the correct value. | |
1945 * | |
1946 */ | |
1947 | |
801 | 1948 #if defined (ORDINARY_LINK) && !defined (MINGW) |
428 | 1949 extern char **environ; |
1950 #endif | |
1951 | |
1952 void * | |
1953 start_of_data (void) | |
1954 { | |
1955 #ifdef DATA_START | |
1956 return ((char *) DATA_START); | |
1957 #else | |
452 | 1958 #if defined (ORDINARY_LINK) || defined(PDUMP) |
428 | 1959 /* |
1960 * This is a hack. Since we're not linking crt0.c or pre_crt0.c, | |
1961 * data_start isn't defined. We take the address of environ, which | |
1962 * is known to live at or near the start of the system crt0.c, and | |
1963 * we don't sweat the handful of bytes that might lose. | |
1964 */ | |
442 | 1965 #if defined (HEAP_IN_DATA) && !defined(PDUMP) |
428 | 1966 extern char* static_heap_base; |
1967 if (!initialized) | |
1968 return static_heap_base; | |
1969 #endif | |
801 | 1970 return ((char *) &environ); |
428 | 1971 #else |
1972 extern int data_start; | |
1973 return ((char *) &data_start); | |
1974 #endif /* ORDINARY_LINK */ | |
1975 #endif /* DATA_START */ | |
1976 } | |
1330 | 1977 #endif /* NEED_STARTS aka !(PDUMP && WIN32_NATIVE && SYSTEM_MALLOC) */ |
428 | 1978 |
801 | 1979 extern void *minimum_address_seen; /* from xmalloc() */ |
1980 extern void *maximum_address_seen; /* from xmalloc() */ | |
1981 | |
1982 Bytecount | |
1983 total_data_usage (void) | |
1984 { | |
1985 #ifdef NEED_STARTS | |
1986 void *data_start = start_of_data (); | |
1987 #else | |
1988 void *data_start = minimum_address_seen; | |
1989 #endif | |
854 | 1990 |
1315 | 1991 #ifndef WIN32_ANY |
814 | 1992 void *data_end = sbrk (0); |
801 | 1993 #else |
1994 void *data_end = maximum_address_seen; | |
1995 #endif | |
1996 | |
1997 /* Sanity checking -- the min determined by malloc() should always be | |
1998 greater than data start determined by other means. We could do the | |
1999 same check on the max, except that things like rel-alloc might | |
2000 invalidate it. */ | |
2001 if (minimum_address_seen && | |
2002 (char *) minimum_address_seen < (char *) data_start) | |
2003 data_start = minimum_address_seen; | |
2004 | |
2005 if (data_end < data_start) /* Huh?????????? */ | |
2006 data_end = maximum_address_seen; | |
2007 | |
2008 /* #### Doesn't seem to give good results on Windows; values are much | |
2009 higher than actual memory usage. How to fix??? */ | |
2010 return (char *) data_end - (char *) data_start; | |
2011 } | |
2012 | |
428 | 2013 |
2014 /************************************************************************/ | |
2015 /* get the system name */ | |
2016 /************************************************************************/ | |
2017 | |
2018 /* init_system_name sets up the string for the Lisp function | |
2019 system-name to return. */ | |
2020 | |
2021 extern Lisp_Object Vsystem_name; | |
2022 | |
2023 void | |
2024 init_system_name (void) | |
2025 { | |
442 | 2026 #if defined (WIN32_NATIVE) |
771 | 2027 Extbyte hostname[MAX_XETCHAR_SIZE * (MAX_COMPUTERNAME_LENGTH + 1)]; |
2028 DWORD size = sizeof (hostname) / XETCHAR_SIZE; | |
2029 qxeGetComputerName (hostname, &size); | |
2030 Vsystem_name = build_tstr_string (hostname); | |
428 | 2031 #elif !defined (HAVE_GETHOSTNAME) |
2032 struct utsname uts; | |
2033 uname (&uts); | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
2034 Vsystem_name = build_extstring (uts.nodename, Qunix_host_name_encoding); |
428 | 2035 #else /* HAVE_GETHOSTNAME */ |
647 | 2036 int hostname_size = 256; |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
2037 Extbyte *hostname = alloca_extbytes (hostname_size); |
428 | 2038 |
2039 /* Try to get the host name; if the buffer is too short, try | |
2040 again. Apparently, the only indication gethostname gives of | |
2041 whether the buffer was large enough is the presence or absence | |
2042 of a '\0' in the string. Eech. */ | |
2043 for (;;) | |
2044 { | |
2045 gethostname (hostname, hostname_size - 1); | |
2046 hostname[hostname_size - 1] = '\0'; | |
2047 | |
2048 /* Was the buffer large enough for the '\0'? */ | |
647 | 2049 if ((int) strlen (hostname) < (hostname_size - 1)) |
428 | 2050 break; |
2051 | |
2052 hostname_size <<= 1; | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
2053 hostname = alloca_extbytes (hostname_size); |
428 | 2054 } |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
2055 # if defined (HAVE_SOCKETS) |
428 | 2056 /* Turn the hostname into the official, fully-qualified hostname. |
2057 Don't do this if we're going to dump; this can confuse system | |
2058 libraries on some machines and make the dumped emacs core dump. */ | |
2059 if (initialized) | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
2060 /* !!#### Could fail if we have a 7-bit external encoding */ |
428 | 2061 if (!strchr (hostname, '.')) |
2062 { | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
2063 # if !(defined (HAVE_GETADDRINFO) && defined (HAVE_GETNAMEINFO)) |
428 | 2064 struct hostent *hp = NULL; |
2065 int count; | |
440 | 2066 # ifdef TRY_AGAIN |
428 | 2067 for (count = 0; count < 10; count++) |
2068 { | |
2069 h_errno = 0; | |
440 | 2070 # endif |
428 | 2071 /* Some systems can't handle SIGALARM/SIGIO in gethostbyname(). */ |
2072 stop_interrupts (); | |
2073 hp = gethostbyname (hostname); | |
2074 start_interrupts (); | |
440 | 2075 # ifdef TRY_AGAIN |
428 | 2076 if (! (hp == 0 && h_errno == TRY_AGAIN)) |
2077 break; | |
2078 Fsleep_for (make_int (1)); | |
2079 } | |
440 | 2080 # endif |
428 | 2081 if (hp) |
2082 { | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
2083 const Extbyte *fqdn = (const Extbyte *) hp->h_name; |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
2084 |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
2085 /* !!#### Could fail if we have a 7-bit external encoding */ |
428 | 2086 if (!strchr (fqdn, '.')) |
2087 { | |
2088 /* We still don't have a fully qualified domain name. | |
2089 Try to find one in the list of alternate names */ | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
2090 Extbyte **alias = hp->h_aliases; |
428 | 2091 while (*alias && !strchr (*alias, '.')) |
2092 alias++; | |
2093 if (*alias) | |
2094 fqdn = *alias; | |
2095 } | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
2096 hostname = alloca_extbytes (strlen (fqdn) + 1); |
428 | 2097 strcpy (hostname, fqdn); |
2098 } | |
440 | 2099 # else /* !(HAVE_GETADDRINFO && HAVE_GETNAMEINFO) */ |
2100 struct addrinfo hints, *res; | |
2101 | |
2102 xzero (hints); | |
2103 hints.ai_flags = AI_CANONNAME; | |
724 | 2104 #ifdef IPV6_CANONICALIZE |
440 | 2105 hints.ai_family = AF_UNSPEC; |
724 | 2106 #else |
2107 hints.ai_family = PF_INET; | |
2108 #endif | |
440 | 2109 hints.ai_socktype = SOCK_STREAM; |
2110 hints.ai_protocol = 0; | |
2111 if (!getaddrinfo (hostname, NULL, &hints, &res)) | |
2112 { | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
2113 hostname = alloca_extbytes (strlen (res->ai_canonname) + 1); |
440 | 2114 strcpy (hostname, res->ai_canonname); |
2115 | |
2116 freeaddrinfo (res); | |
2117 } | |
2118 # endif /* !(HAVE_GETADDRINFO && HAVE_GETNAMEINFO) */ | |
428 | 2119 } |
2120 # endif /* HAVE_SOCKETS */ | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
2121 Vsystem_name = build_extstring (hostname, Qunix_host_name_encoding); |
428 | 2122 #endif /* HAVE_GETHOSTNAME */ |
2123 { | |
867 | 2124 Ibyte *p; |
428 | 2125 Bytecount i; |
2126 | |
2127 for (i = 0, p = XSTRING_DATA (Vsystem_name); | |
2128 i < XSTRING_LENGTH (Vsystem_name); | |
2129 i++, p++) | |
2130 { | |
2131 if (*p == ' ' || *p == '\t') | |
2132 *p = '-'; | |
2133 } | |
2134 } | |
2135 } | |
2136 | |
2137 | |
2138 /************************************************************************/ | |
2139 /* Emulation of select() */ | |
2140 /************************************************************************/ | |
2141 | |
2142 #ifndef HAVE_SELECT | |
2143 | |
2144 ERROR: XEmacs requires a working select(). | |
2145 | |
2146 #endif /* not HAVE_SELECT */ | |
2147 | |
2148 | |
2149 /************************************************************************/ | |
2150 /* Emulation of signal stuff */ | |
2151 /************************************************************************/ | |
2152 | |
2153 /* BSD 4.1 crap deleted. 4.2 was released in 1983, for God's sake! I | |
2154 can't imagine that anyone is actually running that OS any more. | |
2155 You can't use X under it (I think) because there's no select(). | |
2156 Anyway, the signal stuff has all been changed. If someone wants to | |
2157 get this stuff working again, look in the FSF Emacs sources. */ | |
2158 | |
2159 /* POSIX signals support - DJB */ | |
2160 | |
2161 #ifdef HAVE_SIGPROCMASK | |
2162 | |
2163 /* #### Is there any reason this is static global rather than local? */ | |
2164 static struct sigaction new_action, old_action; | |
2165 | |
2166 signal_handler_t | |
613 | 2167 qxe_reliable_signal (int signal_number, signal_handler_t action) |
428 | 2168 { |
2169 #if 0 | |
2170 | |
2171 /* XEmacs works better if system calls are *not* restarted. | |
2172 This allows C-g to interrupt reads and writes, on most systems. | |
2173 | |
2174 #### Another possibility is to just longjmp() out of the signal | |
2175 handler. According to W.R. Stevens, this should be OK on all | |
2176 systems. However, I don't want to deal with the potential | |
2177 evil ramifications of this at this point. */ | |
2178 | |
2179 sigemptyset (&new_action.sa_mask); | |
2180 new_action.sa_handler = action; | |
2181 #if defined (SA_RESTART) | |
2182 /* Emacs mostly works better with restartable system services. If this | |
2183 * flag exists, we probably want to turn it on here. | |
2184 */ | |
2185 new_action.sa_flags = SA_RESTART; | |
2186 #else | |
2187 new_action.sa_flags = 0; | |
2188 #endif | |
2189 sigaction (signal_number, &new_action, &old_action); | |
2190 return (old_action.sa_handler); | |
2191 | |
2192 #else /* not 0 */ | |
2193 | |
2194 sigemptyset (&new_action.sa_mask); | |
2195 new_action.sa_handler = action; | |
2196 #if defined (SA_INTERRUPT) /* don't restart system calls, under SunOS */ | |
2197 new_action.sa_flags = SA_INTERRUPT; | |
2198 #else | |
2199 new_action.sa_flags = 0; | |
2200 #endif | |
2201 sigaction (signal_number, &new_action, &old_action); | |
2202 return (signal_handler_t) (old_action.sa_handler); | |
2203 | |
2204 #endif /* not 0 */ | |
2205 } | |
2206 | |
2207 #elif defined (HAVE_SIGBLOCK) | |
2208 | |
2209 /* We use sigvec() rather than signal() if we have it, because | |
2210 it lets us specify interruptible system calls. */ | |
2211 signal_handler_t | |
613 | 2212 qxe_reliable_signal (int signal_number, signal_handler_t action) |
428 | 2213 { |
2214 struct sigvec vec, ovec; | |
2215 | |
2216 vec.sv_handler = action; | |
2217 vec.sv_mask = 0; | |
2218 #ifdef SV_INTERRUPT /* don't restart system calls */ | |
2219 vec.sv_flags = SV_INTERRUPT; | |
2220 #else | |
2221 vec.sv_flags = 0; | |
2222 #endif | |
2223 | |
2224 sigvec (signal_number, &vec, &ovec); | |
2225 | |
2226 return (ovec.sv_handler); | |
2227 } | |
2228 | |
2229 #endif /* HAVE_SIGBLOCK (HAVE_SIGPROCMASK) */ | |
2230 | |
2231 | |
2232 /************************************************************************/ | |
2233 /* Emulation of strerror() and errno support */ | |
2234 /************************************************************************/ | |
2235 | |
2236 #ifndef HAVE_STRERROR | |
2237 | |
4759
aa5ed11f473b
Remove support for obsolete systems. See xemacs-patches message with ID
Jerry James <james@xemacs.org>
parents:
3700
diff
changeset
|
2238 #if !defined(__alpha) && !defined(MACH) && !defined(LINUX) && !defined(IRIX) && !defined(__NetBSD__) |
428 | 2239 /* Linux added here by Raymond L. Toy <toy@alydar.crd.ge.com> for XEmacs. */ |
2240 /* Irix added here by gparker@sni-usa.com for XEmacs. */ | |
2241 /* NetBSD added here by James R Grinter <jrg@doc.ic.ac.uk> for XEmacs */ | |
442 | 2242 extern const char *sys_errlist[]; |
428 | 2243 extern int sys_nerr; |
2244 #endif | |
2245 | |
2246 #ifdef __NetBSD__ | |
2247 extern char *sys_errlist[]; | |
2248 extern int sys_nerr; | |
2249 #endif | |
2250 | |
2251 | |
442 | 2252 const char * |
428 | 2253 strerror (int errnum) |
2254 { | |
2255 if (errnum >= 0 && errnum < sys_nerr) | |
2256 return sys_errlist[errnum]; | |
442 | 2257 return ((const char *) GETTEXT ("Unknown error")); |
428 | 2258 } |
2259 | |
2260 #endif /* ! HAVE_STRERROR */ | |
2261 | |
2262 | |
2263 /************************************************************************/ | |
2264 /* Encapsulations of system calls */ | |
2265 /************************************************************************/ | |
2266 | |
2267 /***************** low-level calls ****************/ | |
2268 | |
2269 /* | |
2270 * On USG systems the system calls are INTERRUPTIBLE by signals | |
2271 * that the user program has elected to catch. Thus the system call | |
2272 * must be retried in these cases. To handle this without massive | |
2273 * changes in the source code, we remap the standard system call names | |
2274 * to names for our own functions in sysdep.c that do the system call | |
2275 * with retries. Actually, for portability reasons, it is good | |
2276 * programming practice, as this example shows, to limit all actual | |
2277 * system calls to a single occurrence in the source. Sure, this | |
2278 * adds an extra level of function call overhead but it is almost | |
2279 * always negligible. Fred Fish, Unisoft Systems Inc. | |
2280 */ | |
2281 | |
2282 /* Ben sez: read Dick Gabriel's essay about the Worse Is Better | |
2283 approach to programming and its connection to the silly | |
2284 interruptible-system-call business. To find it, look on | |
2340 | 2285 Jamie's home page (http://www.jwz.org/doc/worse-is-better.html). */ |
428 | 2286 |
771 | 2287 #ifdef WIN32_NATIVE |
2288 | |
2289 static int | |
2290 underlying_open_1 (const Extbyte *path, int oflag, int mode) | |
2291 { | |
2292 if (XEUNICODE_P) | |
2293 return _wopen ((const wchar_t *) path, oflag, mode); | |
2294 else | |
2295 return _open (path, oflag, mode); | |
2296 } | |
2297 | |
2298 #endif /* WIN32_NATIVE */ | |
2299 | |
2367 | 2300 /* Just call open() with normal open() semantics, with some fixups for |
2301 problems under Windows. */ | |
771 | 2302 |
2303 static int | |
2304 underlying_open (const Extbyte *path, int oflag, int mode) | |
2305 { | |
2306 #ifdef WIN32_NATIVE | |
2307 { | |
2308 /* Try to open file without _O_CREAT, to be able to write to hidden | |
2309 and system files. Force all file handles to be | |
2310 non-inheritable. */ | |
2311 int res = underlying_open_1 (path, (oflag & ~_O_CREAT) | _O_NOINHERIT, | |
2312 mode); | |
2313 if (res >= 0) | |
2314 return res; | |
2315 return underlying_open_1 (path, oflag | _O_NOINHERIT, mode); | |
2316 } | |
2317 #else | |
2318 return open (path, oflag, mode); | |
2319 #endif /* WIN32_NATIVE */ | |
2320 } | |
2321 | |
2367 | 2322 static int |
2323 retry_open_1 (const Extbyte *path, int oflag, int mode) | |
428 | 2324 { |
440 | 2325 #ifdef INTERRUPTIBLE_OPEN |
428 | 2326 { |
2327 int rtnval; | |
771 | 2328 while ((rtnval = underlying_open (path, oflag, mode)) == -1 |
428 | 2329 && (errno == EINTR)) |
2330 DO_NOTHING; | |
2331 return rtnval; | |
2332 } | |
2333 #else | |
771 | 2334 return underlying_open (path, oflag, mode); |
428 | 2335 #endif |
2336 } | |
771 | 2337 |
2367 | 2338 /* A version of open() that retries when interrupted. Operates on |
2339 externally-encoded filenames. */ | |
2340 | |
2341 int XCDECL | |
2342 retry_open (const Extbyte *path, int oflag, ...) | |
2343 { | |
2344 int mode; | |
2345 va_list ap; | |
2346 | |
2347 va_start (ap, oflag); | |
2348 mode = va_arg (ap, int); | |
2349 va_end (ap); | |
2350 | |
2351 return retry_open_1 (path, oflag, mode); | |
2352 } | |
2353 | |
2354 #if defined (WIN32_NATIVE) && defined (WEXTTEXT_IS_WIDE) | |
2355 | |
2356 /* Like retry_open() but operate on Wexttext filenames. */ | |
2357 | |
2358 int XCDECL | |
2359 wext_retry_open (const Wexttext *path, int oflag, ...) | |
2360 { | |
2361 int mode; | |
2362 va_list ap; | |
2363 | |
2364 va_start (ap, oflag); | |
2365 mode = va_arg (ap, int); | |
2366 va_end (ap); | |
2367 | |
2368 if (!XEUNICODE_P) | |
2369 return retry_open_1 (WEXTTEXT_TO_MULTIBYTE (path), oflag, mode); | |
2370 else | |
2371 return retry_open_1 ((Extbyte *) path, oflag, mode); | |
2372 } | |
2373 | |
2374 #endif | |
2375 | |
771 | 2376 /* The basic external entry point to open(). Handles conversion to |
2377 external encoding, interruptions, etc. */ | |
2378 | |
872 | 2379 int XCDECL |
867 | 2380 qxe_open (const Ibyte *path, int oflag, ...) |
771 | 2381 { |
2382 Extbyte *pathout; | |
2383 int mode; | |
2384 va_list ap; | |
2385 | |
2386 va_start (ap, oflag); | |
2387 mode = va_arg (ap, int); | |
2388 va_end (ap); | |
2389 | |
2390 PATHNAME_CONVERT_OUT (path, pathout); | |
2391 return retry_open (pathout, oflag, mode); | |
2392 } | |
2393 | |
2394 /* Like qxe_open, only when open() is interrupted by EINTR, check for | |
428 | 2395 QUIT. This allows the callers of this function to be interrupted |
2396 with C-g when, say, reading from named pipes. However, this should | |
1123 | 2397 be used with caution, as it can run random Lisp code (although it |
2398 cannot GC). | |
428 | 2399 |
2400 This function will not function as expected on systems where open() | |
2401 is not interrupted by C-g. However, the worst that can happen is | |
2402 the fallback to simple open(). */ | |
2403 int | |
867 | 2404 qxe_interruptible_open (const Ibyte *path, int oflag, int mode) |
428 | 2405 { |
2406 /* This function can GC */ | |
771 | 2407 Extbyte *pathout; |
2408 | |
2409 PATHNAME_CONVERT_OUT (path, pathout); | |
428 | 2410 |
442 | 2411 #ifdef WIN32_NATIVE |
440 | 2412 /* Make all handles non-inheritable */ |
2413 oflag |= _O_NOINHERIT; | |
2414 #endif | |
2415 | |
428 | 2416 for (;;) |
2417 { | |
771 | 2418 int rtnval = underlying_open (pathout, oflag, mode); |
428 | 2419 if (!(rtnval == -1 && errno == EINTR)) |
2420 return rtnval; | |
2421 /* open() was interrupted. Was QUIT responsible? */ | |
2422 QUIT; | |
2423 } | |
2424 } | |
2425 | |
2426 int | |
771 | 2427 retry_close (int filedes) |
428 | 2428 { |
2429 #ifdef INTERRUPTIBLE_CLOSE | |
2430 int did_retry = 0; | |
2431 REGISTER int rtnval; | |
2432 | |
2433 while ((rtnval = close (filedes)) == -1 | |
2434 && (errno == EINTR)) | |
2435 did_retry = 1; | |
2436 | |
2437 /* If close is interrupted SunOS 4.1 may or may not have closed the | |
2438 file descriptor. If it did the second close will fail with | |
2439 errno = EBADF. That means we have succeeded. */ | |
2440 if (rtnval == -1 && did_retry && errno == EBADF) | |
2441 return 0; | |
2442 | |
2443 return rtnval; | |
2444 #else | |
2445 return close (filedes); | |
2446 #endif | |
2447 } | |
771 | 2448 |
2449 static ssize_t | |
2450 retry_read_1 (int fildes, void *buf, size_t nbyte, int allow_quit) | |
428 | 2451 { |
2452 ssize_t rtnval; | |
2453 | |
2454 /* No harm in looping regardless of the INTERRUPTIBLE_IO setting. */ | |
2455 while ((rtnval = read (fildes, buf, nbyte)) == -1 | |
2456 && (errno == EINTR)) | |
2457 { | |
2458 if (allow_quit) | |
853 | 2459 QUIT; |
428 | 2460 } |
2461 return rtnval; | |
2462 } | |
2463 | |
2464 ssize_t | |
771 | 2465 retry_read (int fildes, void *buf, size_t nbyte) |
428 | 2466 { |
771 | 2467 return retry_read_1 (fildes, buf, nbyte, 0); |
428 | 2468 } |
771 | 2469 |
2470 static ssize_t | |
2471 retry_write_1 (int fildes, const void *buf, size_t nbyte, int allow_quit) | |
428 | 2472 { |
2473 ssize_t bytes_written = 0; | |
442 | 2474 const char *b = (const char *) buf; |
428 | 2475 |
2476 /* No harm in looping regardless of the INTERRUPTIBLE_IO setting. */ | |
2477 while (nbyte > 0) | |
2478 { | |
2479 ssize_t rtnval = write (fildes, b, nbyte); | |
2480 | |
2481 if (allow_quit) | |
853 | 2482 QUIT; |
428 | 2483 |
2484 if (rtnval == -1) | |
2485 { | |
2486 if (errno == EINTR) | |
2487 continue; | |
2488 else | |
2489 return bytes_written ? bytes_written : -1; | |
2490 } | |
2491 b += rtnval; | |
2492 nbyte -= rtnval; | |
2493 bytes_written += rtnval; | |
2494 } | |
2495 return bytes_written; | |
2496 } | |
2497 | |
2498 ssize_t | |
771 | 2499 retry_write (int fildes, const void *buf, size_t nbyte) |
428 | 2500 { |
771 | 2501 return retry_write_1 (fildes, buf, nbyte, 0); |
428 | 2502 } |
771 | 2503 |
2504 /* Versions of read() and write() that allow quitting out of the actual | |
2505 I/O. We don't use immediate_quit (i.e. direct longjmp() out of the | |
2506 signal handler) because that's way too losing. | |
2507 | |
2508 (#### Actually, longjmp()ing out of the signal handler may not be | |
2509 as losing as I thought. See qxe_reliable_signal() in sysdep.c.) */ | |
2510 | |
2511 Bytecount | |
2512 read_allowing_quit (int fildes, void *buf, Bytecount size) | |
2513 { | |
2514 QUIT; | |
2515 return retry_read_1 (fildes, buf, size, 1); | |
2516 } | |
2517 | |
2518 Bytecount | |
2519 write_allowing_quit (int fildes, const void *buf, Bytecount size) | |
2520 { | |
2521 QUIT; | |
2522 return retry_write_1 (fildes, buf, size, 1); | |
2523 } | |
428 | 2524 |
2525 | |
2526 /**************** stdio calls ****************/ | |
2527 | |
2528 /* There is at least some evidence that the stdio calls are interruptible | |
2529 just like the normal system calls, at least on some systems. In any | |
2530 case, it doesn't hurt to encapsulate them. */ | |
2531 | |
2532 /* #### Should also encapsulate fflush(). | |
2533 #### Should conceivably encapsulate getchar() etc. What a pain! */ | |
2534 | |
2535 FILE * | |
2367 | 2536 retry_fopen (const Extbyte *path, const Ascbyte *mode) |
428 | 2537 { |
771 | 2538 #ifdef WIN32_NATIVE |
2539 int fd; | |
2540 int oflag; | |
2367 | 2541 const Ascbyte *mode_save = mode; |
771 | 2542 |
2543 /* Force all file handles to be non-inheritable. This is necessary to | |
2544 ensure child processes don't unwittingly inherit handles that might | |
2545 prevent future file access. */ | |
2546 | |
2547 if (mode[0] == 'r') | |
2548 oflag = O_RDONLY; | |
2549 else if (mode[0] == 'w' || mode[0] == 'a') | |
2550 oflag = O_WRONLY | O_CREAT | O_TRUNC; | |
2551 else | |
2552 return NULL; | |
2553 | |
2554 /* Only do simplistic option parsing. */ | |
2555 while (*++mode) | |
2556 if (mode[0] == '+') | |
2557 { | |
2558 oflag &= ~(O_RDONLY | O_WRONLY); | |
2559 oflag |= O_RDWR; | |
2560 } | |
2561 else if (mode[0] == 'b') | |
2562 { | |
2563 oflag &= ~O_TEXT; | |
2564 oflag |= O_BINARY; | |
2565 } | |
2566 else if (mode[0] == 't') | |
2567 { | |
2568 oflag &= ~O_BINARY; | |
2569 oflag |= O_TEXT; | |
2570 } | |
2571 else break; | |
2572 | |
2573 fd = underlying_open (path, oflag, 0644); | |
2574 if (fd < 0) | |
2575 return NULL; | |
2576 | |
2577 return _fdopen (fd, mode_save); | |
428 | 2578 #elif defined (INTERRUPTIBLE_OPEN) |
2579 { | |
2580 FILE *rtnval; | |
771 | 2581 while (!(rtnval = fopen (path, mode)) && (errno == EINTR)) |
428 | 2582 DO_NOTHING; |
2583 return rtnval; | |
2584 } | |
2585 #else | |
771 | 2586 return fopen (path, mode); |
2587 #endif /* defined (INTERRUPTIBLE_OPEN) */ | |
428 | 2588 } |
771 | 2589 |
2590 FILE * | |
2367 | 2591 qxe_fopen (const Ibyte *path, const Ascbyte *mode) |
771 | 2592 { |
2593 Extbyte *pathout; | |
2594 PATHNAME_CONVERT_OUT (path, pathout); | |
2595 return retry_fopen (pathout, mode); | |
2596 } | |
2597 | |
428 | 2598 int |
771 | 2599 retry_fclose (FILE *stream) |
428 | 2600 { |
2601 #ifdef INTERRUPTIBLE_CLOSE | |
2602 int rtnval; | |
2603 | |
2604 while ((rtnval = fclose (stream)) == EOF | |
2605 && (errno == EINTR)) | |
2606 ; | |
2607 return rtnval; | |
2608 #else | |
2609 return fclose (stream); | |
2610 #endif | |
2611 } | |
771 | 2612 |
428 | 2613 size_t |
771 | 2614 retry_fread (void *ptr, size_t size, size_t nitem, FILE *stream) |
428 | 2615 { |
2616 #ifdef INTERRUPTIBLE_IO | |
2617 size_t rtnval; | |
2618 size_t items_read = 0; | |
2619 char *b = (char *) ptr; | |
2620 | |
2621 while (nitem > 0) | |
2622 { | |
2623 rtnval = fread (b, size, nitem, stream); | |
2624 if (rtnval == 0) | |
2625 { | |
2626 if (ferror (stream) && errno == EINTR) | |
2627 continue; | |
2628 else | |
2629 return items_read; | |
2630 } | |
2631 b += size*rtnval; | |
2632 nitem -= rtnval; | |
2633 items_read += rtnval; | |
2634 } | |
2635 return (items_read); | |
2636 #else | |
2637 return fread (ptr, size, nitem, stream); | |
2638 #endif | |
2639 } | |
771 | 2640 |
428 | 2641 size_t |
771 | 2642 retry_fwrite (const void *ptr, size_t size, size_t nitem, FILE *stream) |
428 | 2643 { |
2644 #ifdef INTERRUPTIBLE_IO | |
2645 size_t rtnval; | |
2646 size_t items_written = 0; | |
442 | 2647 const char *b = (const char *) ptr; |
428 | 2648 |
2649 while (nitem > 0) | |
2650 { | |
2651 rtnval = fwrite (b, size, nitem, stream); | |
2652 if (rtnval == 0) | |
2653 { | |
2654 if (ferror (stream) && errno == EINTR) | |
2655 continue; | |
2656 else | |
2657 return items_written; | |
2658 } | |
2659 b += size*rtnval; | |
2660 nitem -= rtnval; | |
2661 items_written += rtnval; | |
2662 } | |
2663 return (items_written); | |
2664 #else | |
2665 return fwrite (ptr, size, nitem, stream); | |
2666 #endif | |
2667 } | |
2668 | |
2669 /********************* directory calls *******************/ | |
2670 | |
2671 int | |
867 | 2672 qxe_chdir (const Ibyte *path) |
428 | 2673 { |
771 | 2674 Extbyte *pathout; |
2675 PATHNAME_CONVERT_OUT (path, pathout); | |
442 | 2676 #ifdef WIN32_NATIVE |
771 | 2677 if (XEUNICODE_P) |
2678 return _wchdir ((const wchar_t *) pathout); | |
2679 else | |
2680 return _chdir (pathout); | |
428 | 2681 #else |
771 | 2682 return chdir (pathout); |
428 | 2683 #endif |
2684 } | |
771 | 2685 |
2686 int | |
2340 | 2687 qxe_mkdir (const Ibyte *path, |
2688 #ifdef WIN32_NATIVE | |
2689 mode_t UNUSED (mode) | |
2690 #else | |
2691 mode_t mode | |
2692 #endif | |
2693 ) | |
771 | 2694 { |
2695 Extbyte *pathout; | |
2696 PATHNAME_CONVERT_OUT (path, pathout); | |
2697 #ifdef WIN32_NATIVE | |
2698 if (XEUNICODE_P) | |
2699 return _wmkdir ((const wchar_t *) pathout); | |
2700 else | |
2701 return _mkdir (pathout); | |
2702 #else | |
2703 return mkdir (pathout, mode); | |
2704 #endif | |
2705 } | |
2706 | |
428 | 2707 DIR * |
867 | 2708 qxe_opendir (const Ibyte *filename) |
428 | 2709 { |
771 | 2710 #ifdef WIN32_NATIVE |
2711 return mswindows_opendir (filename); | |
2712 #else | |
428 | 2713 DIR *rtnval; |
771 | 2714 Extbyte *pathout; |
2715 PATHNAME_CONVERT_OUT (filename, pathout); | |
2716 | |
2717 while (!(rtnval = opendir (pathout)) | |
428 | 2718 && (errno == EINTR)) |
2719 ; | |
2720 return rtnval; | |
771 | 2721 #endif /* WIN32_NATIVE */ |
428 | 2722 } |
771 | 2723 |
428 | 2724 DIRENTRY * |
771 | 2725 qxe_readdir (DIR *dirp) |
428 | 2726 { |
771 | 2727 #ifdef WIN32_NATIVE |
2728 return mswindows_readdir (dirp); | |
2729 #else /* not WIN32_NATIVE */ | |
428 | 2730 DIRENTRY *rtnval; |
2731 | |
2732 /* Apparently setting errno is necessary on some systems? | |
2733 Maybe readdir() doesn't always set errno ?! */ | |
2734 while (!(errno = 0, rtnval = readdir (dirp)) | |
2735 && (errno == EINTR)) | |
2736 ; | |
2737 #ifndef MULE | |
2738 return rtnval; | |
2739 #else /* MULE */ | |
2740 if (rtnval == NULL) /* End of directory */ | |
2741 return NULL; | |
2742 { | |
442 | 2743 const Extbyte * const external_name = (const Extbyte *) rtnval->d_name; |
665 | 2744 Bytecount external_len = strlen (rtnval->d_name); |
867 | 2745 const Ibyte *internal_name; |
462 | 2746 Bytecount internal_len; |
513 | 2747 |
462 | 2748 TO_INTERNAL_FORMAT (DATA, (external_name, external_len), |
2749 ALLOCA, (internal_name, internal_len), | |
2750 Qfile_name); | |
2751 | |
2752 /* check for common case of ASCII filename */ | |
2753 if (internal_len == external_len && | |
2754 !memcmp (external_name, internal_name, internal_len)) | |
428 | 2755 return rtnval; |
2756 | |
2757 { /* Non-ASCII filename */ | |
867 | 2758 static Ibyte_dynarr *internal_DIRENTRY; |
428 | 2759 if (!internal_DIRENTRY) |
867 | 2760 internal_DIRENTRY = Dynarr_new (Ibyte); |
428 | 2761 else |
2762 Dynarr_reset (internal_DIRENTRY); | |
2763 | |
867 | 2764 Dynarr_add_many (internal_DIRENTRY, (Ibyte *) rtnval, |
428 | 2765 offsetof (DIRENTRY, d_name)); |
2766 | |
2767 | |
2768 Dynarr_add_many (internal_DIRENTRY, internal_name, internal_len); | |
444 | 2769 Dynarr_add (internal_DIRENTRY, '\0'); /* NUL-terminate */ |
4967 | 2770 return (DIRENTRY *) Dynarr_begin (internal_DIRENTRY); |
428 | 2771 } |
2772 } | |
2773 #endif /* MULE */ | |
771 | 2774 #endif /* WIN32_NATIVE */ |
428 | 2775 } |
771 | 2776 |
428 | 2777 int |
771 | 2778 qxe_closedir (DIR *dirp) |
428 | 2779 { |
771 | 2780 #ifdef WIN32_NATIVE |
2781 return mswindows_closedir (dirp); | |
2782 #else /* not WIN32_NATIVE */ | |
428 | 2783 int rtnval; |
2784 | |
2785 while ((rtnval = closedir (dirp)) == -1 | |
2786 && (errno == EINTR)) | |
2787 ; | |
2788 return rtnval; | |
771 | 2789 #endif /* WIN32_NATIVE */ |
428 | 2790 } |
771 | 2791 |
428 | 2792 int |
867 | 2793 qxe_rmdir (const Ibyte *path) |
771 | 2794 { |
2795 Extbyte *pathout; | |
2796 PATHNAME_CONVERT_OUT (path, pathout); | |
2797 #ifdef WIN32_NATIVE | |
2798 if (XEUNICODE_P) | |
2799 return _wrmdir ((const wchar_t *) pathout); | |
2800 else | |
2801 return _rmdir (pathout); | |
2802 #else | |
2803 return rmdir (pathout); | |
2804 #endif | |
2805 } | |
2806 | |
867 | 2807 Ibyte * |
771 | 2808 qxe_allocating_getcwd (void) |
428 | 2809 { |
771 | 2810 #ifdef HAVE_GETCWD |
2811 Bytecount cwdsize = 1024; | |
2812 Extbyte *cwd = xnew_array (Extbyte, cwdsize); | |
2813 | |
2814 /* Many getcwd()'s can take a NULL argument and malloc() the right amount | |
2815 of data, but this is non-standard. */ | |
2816 while (1) | |
2817 { | |
2818 #ifdef WIN32_NATIVE | |
2819 Extbyte *ret; | |
2820 | |
2821 if (XEUNICODE_P) | |
2822 ret = (Extbyte *) _wgetcwd ((wchar_t *) cwd, | |
2823 cwdsize / sizeof (wchar_t)); | |
2824 else | |
2825 ret = _getcwd (cwd, cwdsize); | |
2826 | |
2827 if (ret) | |
2828 { | |
867 | 2829 Ibyte *retin; |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
2830 retin = TSTR_TO_ITEXT_MALLOC (ret); |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
2831 xfree (cwd); |
771 | 2832 return retin; |
2833 } | |
2834 #else | |
2835 Extbyte *ret = getcwd (cwd, cwdsize); | |
2836 if (ret) | |
2837 { | |
867 | 2838 Ibyte *retin; |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
2839 retin = EXTERNAL_TO_ITEXT_MALLOC (ret, Qfile_name); |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
2840 xfree (cwd); |
771 | 2841 return retin; |
2842 } | |
2843 #endif /* WIN32_NATIVE */ | |
2844 | |
2845 if (errno == ERANGE) | |
2846 { | |
2847 cwdsize *= 2; | |
2848 XREALLOC_ARRAY (cwd, Extbyte, cwdsize); | |
2849 } | |
2850 else | |
2851 { | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
2852 xfree (cwd); |
771 | 2853 return NULL; |
2854 } | |
2855 } | |
2856 #else | |
4854 | 2857 Extbyte chingame_limitos_arbitrarios[PATH_MAX_TCHAR]; |
867 | 2858 Ibyte *ret2; |
771 | 2859 |
2860 if (!getwd (chingame_limitos_arbitrarios)) | |
2861 return 0; | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
2862 ret2 = EXTERNAL_TO_ITEXT_MALLOC (chingame_limitos_arbitrarios, Qfile_name); |
771 | 2863 return ret2; |
2864 #endif /* HAVE_GETCWD */ | |
428 | 2865 } |
2866 | |
2867 /***************** file-information calls ******************/ | |
2868 | |
2869 int | |
867 | 2870 qxe_access (const Ibyte *path, int mode) |
428 | 2871 { |
771 | 2872 #ifdef WIN32_NATIVE |
2873 return mswindows_access (path, mode); | |
2874 #else /* not WIN32_NATIVE */ | |
2875 Extbyte *pathout; | |
2876 PATHNAME_CONVERT_OUT (path, pathout); | |
2877 return access (pathout, mode); | |
2878 #endif /* WIN32_NATIVE */ | |
428 | 2879 } |
771 | 2880 |
2881 #if defined (HAVE_EACCESS) | |
428 | 2882 int |
867 | 2883 qxe_eaccess (const Ibyte *path, int mode) |
428 | 2884 { |
771 | 2885 Extbyte *pathout; |
2886 PATHNAME_CONVERT_OUT (path, pathout); | |
2887 return eaccess (pathout, mode); | |
428 | 2888 } |
771 | 2889 #endif /* defined (HAVE_EACCESS) */ |
2890 | |
428 | 2891 int |
867 | 2892 qxe_lstat (const Ibyte *path, struct stat *buf) |
428 | 2893 { |
771 | 2894 /* if system does not have symbolic links, it does not have lstat. |
2895 In that case, use ordinary stat instead. */ | |
2896 #ifndef S_IFLNK | |
2897 return qxe_stat (path, buf); | |
2526 | 2898 #elif defined (WIN32_NATIVE) |
2899 if (mswindows_shortcuts_are_symlinks) | |
2900 { | |
2901 /* We want to resolve the directory component and leave the rest | |
2902 alone. */ | |
2903 Ibyte *dirend = find_end_of_directory_component (path, qxestrlen (path)); | |
2904 Bytecount len; | |
2905 | |
2906 if (dirend != path) | |
2907 { | |
2908 Ibyte *resdir; | |
2909 Ichar lastch; | |
2910 DECLARE_EISTRING (resname); | |
2911 DECLARE_EISTRING (dir); | |
2912 | |
2913 eicpy_raw (dir, path, dirend - path); | |
2914 PATHNAME_RESOLVE_LINKS (eidata (dir), resdir); | |
2915 eicpy_rawz (resname, resdir); | |
2916 lastch = eigetch_char (resname, eicharlen (resname) - 1); | |
2917 if (!IS_DIRECTORY_SEP (lastch)) | |
2918 eicat_ch (resname, '\\'); | |
2919 eicat_rawz (resname, dirend); | |
2920 path = eidata (resname); | |
2921 } | |
2922 | |
2923 /* However, if what we are trying to stat is a link, we need to add | |
2924 the .LNK so that the actual file is statted. */ | |
2925 len = qxestrlen (path); | |
2926 if (len > 4 && qxestrcasecmp_ascii (path + len - 4, ".LNK")) | |
2927 { | |
2928 DECLARE_EISTRING (name2); | |
2929 Ibyte *resolved; | |
2930 | |
2931 eicpy_rawz (name2, path); | |
2932 eicat_ascii (name2, ".LNK"); | |
2933 resolved = mswindows_read_link (eidata (name2)); | |
2934 if (resolved) | |
2935 { | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
2936 xfree (resolved); |
2526 | 2937 return mswindows_stat (eidata (name2), buf); |
2938 } | |
2939 } | |
2940 } | |
2941 | |
2942 return mswindows_stat (path, buf); | |
771 | 2943 #else |
2944 Extbyte *pathout; | |
2945 PATHNAME_CONVERT_OUT (path, pathout); | |
2946 return lstat (pathout, buf); | |
2947 #endif | |
428 | 2948 } |
771 | 2949 |
2950 #if defined (HAVE_READLINK) | |
428 | 2951 int |
867 | 2952 qxe_readlink (const Ibyte *path, Ibyte *buf, size_t bufsiz) |
428 | 2953 { |
771 | 2954 int retval; |
2955 Extbyte *pathout; | |
2956 | |
2957 PATHNAME_CONVERT_OUT (path, pathout); | |
2958 retval = readlink (pathout, (char *) buf, bufsiz); | |
2959 if (retval < 0) | |
2960 return retval; | |
2961 { | |
867 | 2962 Ibyte *intbuf; |
771 | 2963 Bytecount tamanho; |
2964 | |
2965 TO_INTERNAL_FORMAT (DATA, (buf, retval), | |
2966 ALLOCA, (intbuf, tamanho), Qfile_name); | |
2967 /* the man page says this function does not null-terminate */ | |
2968 if (tamanho >= (Bytecount) bufsiz) | |
2969 tamanho = bufsiz; | |
2970 memcpy (buf, intbuf, tamanho); | |
2971 return tamanho; | |
2972 } | |
428 | 2973 } |
771 | 2974 #endif /* defined (HAVE_READLINK) */ |
2975 | |
432 | 2976 int |
771 | 2977 qxe_fstat (int fd, struct stat *buf) |
432 | 2978 { |
442 | 2979 #ifdef WIN32_NATIVE |
2980 return mswindows_fstat (fd, buf); | |
2981 #else | |
432 | 2982 return fstat (fd, buf); |
771 | 2983 #endif /* WIN32_NATIVE */ |
432 | 2984 } |
2985 | |
428 | 2986 int |
867 | 2987 qxe_stat (const Ibyte *path, struct stat *buf) |
428 | 2988 { |
442 | 2989 #ifdef WIN32_NATIVE |
2526 | 2990 Ibyte *resolved; |
2991 PATHNAME_RESOLVE_LINKS (path, resolved); | |
2992 return mswindows_stat (resolved, buf); | |
771 | 2993 #else /* not WIN32_NATIVE */ |
2994 Extbyte *pathout; | |
2995 PATHNAME_CONVERT_OUT (path, pathout); | |
2996 return stat (pathout, buf); | |
2997 #endif /* WIN32_NATIVE */ | |
428 | 2998 } |
2999 | |
771 | 3000 |
428 | 3001 /****************** file-manipulation calls *****************/ |
3002 | |
3003 int | |
867 | 3004 qxe_chmod (const Ibyte *path, mode_t mode) |
428 | 3005 { |
771 | 3006 Extbyte *pathout; |
3007 PATHNAME_CONVERT_OUT (path, pathout); | |
3008 #ifdef WIN32_NATIVE | |
3009 if (XEUNICODE_P) | |
3010 return _wchmod ((const wchar_t *) pathout, mode); | |
3011 else | |
3012 return _chmod (pathout, mode); | |
3013 #else | |
3014 return chmod (pathout, mode); | |
3015 #endif | |
428 | 3016 } |
771 | 3017 |
3018 #if defined (HAVE_LINK) | |
428 | 3019 int |
2957 | 3020 qxe_link (const Ibyte *existing, const Ibyte *new_) |
428 | 3021 { |
771 | 3022 #ifdef WIN32_NATIVE |
2957 | 3023 return mswindows_link (existing, new_); |
771 | 3024 #else /* not WIN32_NATIVE */ |
3025 Extbyte *existingout, *newout; | |
3026 PATHNAME_CONVERT_OUT (existing, existingout); | |
2957 | 3027 PATHNAME_CONVERT_OUT (new_, newout); |
771 | 3028 return link (existingout, newout); |
3029 #endif /* WIN32_NATIVE */ | |
428 | 3030 } |
771 | 3031 #endif /* defined (HAVE_LINK) */ |
3032 | |
428 | 3033 int |
2957 | 3034 qxe_rename (const Ibyte *old, const Ibyte *new_) |
428 | 3035 { |
442 | 3036 #ifdef WIN32_NATIVE |
2957 | 3037 return mswindows_rename (old, new_); |
771 | 3038 #else /* not WIN32_NATIVE */ |
3039 Extbyte *oldout, *newout; | |
3040 PATHNAME_CONVERT_OUT (old, oldout); | |
2957 | 3041 PATHNAME_CONVERT_OUT (new_, newout); |
771 | 3042 return rename (oldout, newout); |
442 | 3043 #endif /* WIN32_NATIVE */ |
428 | 3044 } |
771 | 3045 |
3046 #if defined (HAVE_SYMLINK) | |
428 | 3047 int |
867 | 3048 qxe_symlink (const Ibyte *name1, const Ibyte *name2) |
428 | 3049 { |
771 | 3050 Extbyte *name1out, *name2out; |
3051 PATHNAME_CONVERT_OUT (name1, name1out); | |
3052 PATHNAME_CONVERT_OUT (name2, name2out); | |
3053 return symlink (name1out, name2out); | |
428 | 3054 } |
771 | 3055 #endif /* defined (HAVE_SYMLINK) */ |
3056 | |
428 | 3057 int |
867 | 3058 qxe_unlink (const Ibyte *path) |
428 | 3059 { |
771 | 3060 #ifdef WIN32_NATIVE |
3061 return mswindows_unlink (path); | |
3062 #else /* not WIN32_NATIVE */ | |
3063 Extbyte *pathout; | |
3064 PATHNAME_CONVERT_OUT (path, pathout); | |
3065 return unlink (pathout); | |
3066 #endif /* WIN32_NATIVE */ | |
428 | 3067 } |
771 | 3068 |
3069 | |
3070 /****************** process calls *****************/ | |
3071 | |
428 | 3072 int |
867 | 3073 qxe_execve (const Ibyte *filename, Ibyte * const argv[], |
3074 Ibyte * const envp[]) | |
428 | 3075 { |
771 | 3076 int i, argc, envc; |
3077 Extbyte *pathext; | |
3078 Extbyte **new_argv; | |
3079 Extbyte **new_envp; | |
3080 | |
3081 PATHNAME_CONVERT_OUT (filename, pathext); | |
3082 | |
428 | 3083 for (argc = 0; argv[argc]; argc++) |
3084 ; | |
771 | 3085 new_argv = alloca_array (Extbyte *, argc + 1); |
428 | 3086 for (i = 0; i < argc; i++) |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3087 new_argv[i] = ITEXT_TO_EXTERNAL (argv[i], Qcommand_argument_encoding); |
428 | 3088 new_argv[argc] = NULL; |
771 | 3089 |
3090 for (envc = 0; envp[envc]; envc++) | |
3091 ; | |
3092 new_envp = alloca_array (Extbyte *, envc + 1); | |
3093 for (i = 0; i < envc; i++) | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3094 new_envp[i] = ITEXT_TO_EXTERNAL (envp[i], Qenvironment_variable_encoding); |
771 | 3095 new_envp[envc] = NULL; |
3096 | |
1318 | 3097 #if defined (WIN32_NATIVE) |
3098 if (XEUNICODE_P) | |
3099 return _wexecve ((const wchar_t *) pathext, | |
3100 (const wchar_t * const *) new_argv, | |
3101 (const wchar_t * const *) new_envp); | |
3102 #endif | |
771 | 3103 return execve (pathext, new_argv, new_envp); |
3104 } | |
3105 | |
3106 pid_t | |
3107 qxe_getpid (void) | |
3108 { | |
3109 #ifdef WIN32_NATIVE | |
3110 return abs (getpid ()); | |
3111 #else | |
3112 return getpid (); | |
3113 #endif | |
428 | 3114 } |
771 | 3115 |
3116 | |
3117 /****************** passwd calls *****************/ | |
3118 | |
3119 struct passwd cached_pwd; | |
3120 | |
3121 static struct passwd * | |
3122 copy_in_passwd (struct passwd *pwd) | |
3123 { | |
3124 if (!pwd) | |
3125 return NULL; | |
3126 | |
3127 if (cached_pwd.pw_name) | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3128 xfree (cached_pwd.pw_name); |
771 | 3129 if (cached_pwd.pw_passwd) |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3130 xfree (cached_pwd.pw_passwd); |
771 | 3131 if (cached_pwd.pw_gecos) |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3132 xfree (cached_pwd.pw_gecos); |
771 | 3133 if (cached_pwd.pw_dir) |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3134 xfree (cached_pwd.pw_dir); |
771 | 3135 if (cached_pwd.pw_shell) |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3136 xfree (cached_pwd.pw_shell); |
771 | 3137 |
3138 cached_pwd = *pwd; | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3139 |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3140 #define FROB(field, encoding) \ |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3141 do \ |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3142 { \ |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3143 if (cached_pwd.field) \ |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3144 cached_pwd.field = (CIbyte *) \ |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3145 EXTERNAL_TO_ITEXT_MALLOC (cached_pwd.field, encoding); \ |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3146 } while (0) |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3147 |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3148 FROB (pw_name, Quser_name_encoding); |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3149 FROB (pw_passwd, Quser_name_encoding); |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3150 FROB (pw_gecos, Quser_name_encoding); |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3151 FROB (pw_dir, Qfile_name); |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3152 FROB (pw_shell, Qfile_name); |
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3153 #undef FROB |
771 | 3154 return &cached_pwd; |
3155 } | |
3156 | |
3157 struct passwd * | |
867 | 3158 qxe_getpwnam (const Ibyte *name) |
771 | 3159 { |
3160 #ifdef WIN32_NATIVE | |
3161 /* Synthetic versions are defined in nt.c and already do conversion. */ | |
3162 return getpwnam (name); | |
3163 #else | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3164 Extbyte *nameext = ITEXT_TO_EXTERNAL (name, Quser_name_encoding); |
771 | 3165 |
3166 return copy_in_passwd (getpwnam (nameext)); | |
3167 #endif /* WIN32_NATIVE */ | |
3168 } | |
3169 | |
3170 struct passwd * | |
3171 qxe_getpwuid (uid_t uid) | |
3172 { | |
3173 #ifdef WIN32_NATIVE | |
3174 /* Synthetic versions are defined in nt.c and already do conversion. */ | |
3175 return getpwuid (uid); | |
3176 #else | |
3177 return copy_in_passwd (getpwuid (uid)); | |
3178 #endif /* WIN32_NATIVE */ | |
3179 } | |
3180 | |
3181 #ifndef WIN32_NATIVE | |
3182 | |
3183 struct passwd * | |
3184 qxe_getpwent (void) | |
3185 { | |
3186 /* No WIN32_NATIVE version of this. */ | |
3187 return copy_in_passwd (getpwent ()); | |
3188 } | |
3189 | |
3190 #endif /* not WIN32_NATIVE */ | |
3191 | |
3192 /****************** time calls *****************/ | |
3193 | |
867 | 3194 static Ibyte *ctime_static; |
3195 | |
3196 Ibyte * | |
771 | 3197 qxe_ctime (const time_t *t) |
3198 { | |
3199 Extbyte *str = (Extbyte *) ctime (t); | |
3200 if (!str) /* can happen on MS Windows */ | |
867 | 3201 return (Ibyte *) "Sun Jan 01 00:00:00 1970"; |
771 | 3202 if (ctime_static) |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3203 xfree (ctime_static); |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3204 ctime_static = EXTERNAL_TO_ITEXT_MALLOC (str, Qtime_function_encoding); |
771 | 3205 return ctime_static; |
3206 } | |
428 | 3207 |
1204 | 3208 |
912 | 3209 /************************************************************************/ |
3210 /* Emulation of missing functions from wchar.h */ | |
3211 /************************************************************************/ | |
3212 | |
3213 #ifndef HAVE_WCHAR_H | |
3214 size_t | |
2367 | 3215 wcslen (const wchar_t *s) |
912 | 3216 { |
3700 | 3217 const wchar_t *p = s; |
3648 | 3218 if (s == NULL) return NULL; |
912 | 3219 |
3220 while (*p++) | |
3221 ; | |
3222 | |
3223 return p - s; | |
3224 } | |
3225 #endif | |
1204 | 3226 |
3227 /************************************************************************/ | |
3228 /* Emulation of missing functions from string.h */ | |
3229 /************************************************************************/ | |
3230 | |
3231 #ifndef HAVE_STRLWR | |
3232 char * | |
3233 strlwr (char *s) | |
3234 { | |
3700 | 3235 REGISTER char *c; |
3648 | 3236 if (s == NULL) return NULL; |
1271 | 3237 |
3238 for (c = s; *c; c++) | |
1204 | 3239 { |
1271 | 3240 *c = tolower (*c); |
1204 | 3241 } |
1271 | 3242 return s; |
1204 | 3243 } |
3244 #endif | |
3245 | |
1271 | 3246 #ifndef HAVE_STRUPR |
1204 | 3247 char * |
3248 strupr (char *s) | |
3249 { | |
1271 | 3250 REGISTER char *c; |
3251 | |
3252 for (c = s; *c; c++) | |
1204 | 3253 { |
1271 | 3254 *c = toupper (*c); |
1204 | 3255 } |
1271 | 3256 return s; |
1204 | 3257 } |
3258 #endif | |
912 | 3259 |
428 | 3260 |
3261 /************************************************************************/ | |
3262 /* Emulations of missing system calls */ | |
3263 /************************************************************************/ | |
3264 | |
3265 /***** (these are primarily required for USG, it seems) *****/ | |
3266 | |
3267 /* | |
3268 * Emulate rename using unlink/link. Note that this is | |
3269 * only partially correct. Also, doesn't enforce restriction | |
3270 * that files be of same type (regular->regular, dir->dir, etc). | |
3271 */ | |
3272 | |
3273 #ifndef HAVE_RENAME | |
3274 int | |
771 | 3275 rename (const Extbyte *from, const Extbyte *to) |
428 | 3276 { |
3277 if (access (from, 0) == 0) | |
3278 { | |
3279 unlink (to); | |
3280 if (link (from, to) == 0) | |
3281 if (unlink (from) == 0) | |
3282 return (0); | |
3283 } | |
3284 return (-1); | |
3285 } | |
3286 #endif /* HAVE_RENAME */ | |
3287 | |
3288 #ifdef HPUX | |
3289 #ifndef HAVE_PERROR | |
3290 | |
3291 /* HPUX curses library references perror, but as far as we know | |
3292 it won't be called. Anyway this definition will do for now. */ | |
3293 | |
3294 perror (void) | |
3295 { | |
3296 } | |
3297 | |
3298 #endif /* not HAVE_PERROR */ | |
3299 #endif /* HPUX */ | |
3300 | |
3301 #ifndef HAVE_DUP2 | |
3302 | |
3303 /* | |
3304 * Emulate BSD dup2. First close newd if it already exists. | |
3305 * Then, attempt to dup oldd. If not successful, call dup2 recursively | |
3306 * until we are, then close the unsuccessful ones. | |
3307 */ | |
3308 | |
3309 int | |
3310 dup2 (int oldd, int newd) | |
3311 { | |
3312 int fd, ret; | |
3313 | |
771 | 3314 retry_close (newd); |
428 | 3315 |
3316 #ifdef F_DUPFD | |
3317 fd = fcntl (oldd, F_DUPFD, newd); | |
3318 if (fd != newd) | |
563 | 3319 signal_ferror_with_frob (Qfile_error, lisp_strerror (errno), |
3320 "can't dup2 (%i, %i)", oldd, newd); | |
428 | 3321 #else |
2957 | 3322 fd = dup (oldd); |
428 | 3323 if (fd == -1) |
3324 return -1; | |
2957 | 3325 if (fd == newd) |
3326 return newd; | |
3327 ret = dup2 (oldd, newd); | |
771 | 3328 retry_close (fd); |
428 | 3329 return ret; |
3330 #endif /* F_DUPFD */ | |
3331 } | |
3332 | |
3333 #endif /* not HAVE_DUP2 */ | |
3334 | |
3335 /* | |
3336 * Gettimeofday. Simulate as much as possible. Only accurate | |
3337 * to nearest second. Emacs doesn't use tzp so ignore it for now. | |
3338 */ | |
3339 | |
3340 #if !defined (HAVE_GETTIMEOFDAY) | |
3341 | |
3342 int | |
3343 gettimeofday (struct timeval *tp, struct timezone *tzp) | |
3344 { | |
3345 extern long time (); | |
3346 | |
3347 tp->tv_sec = time ((long *)0); | |
3348 tp->tv_usec = 0; | |
3349 if (tzp != 0) | |
3350 tzp->tz_minuteswest = -1; | |
3351 return (0); | |
3352 } | |
3353 | |
3354 #endif /* !HAVE_GETTIMEOFDAY */ | |
3355 | |
3356 /* No need to encapsulate utime and utimes explicitly because all | |
3357 access to those functions goes through the following. */ | |
3358 | |
3359 int | |
2340 | 3360 set_file_times ( |
3361 #if defined (WIN32_NATIVE) || defined (HAVE_UTIME) || defined (HAVE_UTIMES) | |
3362 Lisp_Object path, EMACS_TIME atime, EMACS_TIME mtime | |
3363 #else | |
3364 Lisp_Object UNUSED (path), EMACS_TIME UNUSED (atime), | |
3365 EMACS_TIME UNUSED (mtime) | |
3366 #endif | |
3367 ) | |
428 | 3368 { |
592 | 3369 #if defined (WIN32_NATIVE) |
460 | 3370 struct utimbuf utb; |
3371 utb.actime = EMACS_SECS (atime); | |
3372 utb.modtime = EMACS_SECS (mtime); | |
592 | 3373 return mswindows_utime (path, &utb); |
3374 #elif defined (HAVE_UTIME) | |
3375 struct utimbuf utb; | |
3376 Extbyte *filename; | |
3377 utb.actime = EMACS_SECS (atime); | |
3378 utb.modtime = EMACS_SECS (mtime); | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3379 LISP_PATHNAME_CONVERT_OUT (path, filename); |
460 | 3380 return utime (filename, &utb); |
3381 #elif defined (HAVE_UTIMES) | |
428 | 3382 struct timeval tv[2]; |
592 | 3383 Extbyte *filename; |
428 | 3384 tv[0] = atime; |
3385 tv[1] = mtime; | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3386 LISP_PATHNAME_CONVERT_OUT (path, filename); |
428 | 3387 return utimes (filename, tv); |
460 | 3388 #else |
3389 /* No file times setting function available. */ | |
3390 return -1; | |
3391 #endif | |
428 | 3392 } |
3393 | |
3394 /* */ | |
3395 | |
3396 static long ticks_per_second; | |
3397 static long orig_user_ticks, orig_system_ticks; | |
3398 EMACS_TIME orig_real_time; | |
3399 | |
3400 static int process_times_available; | |
3401 | |
3402 /* Return the relative user and system tick count. We try to | |
3403 maintain calculations in terms of integers as long as possible | |
3404 for increased accuracy. */ | |
3405 | |
3406 static int | |
2340 | 3407 get_process_times_1 ( |
3408 #if defined (CLOCKS_PER_SEC) || defined (_SC_CLK_TCK) || defined (CLK_TCK) && !defined(WIN32_NATIVE) | |
3409 long *user_ticks, long *system_ticks | |
3410 #else | |
3411 long *UNUSED (user_ticks), long *UNUSED (system_ticks) | |
3412 #endif | |
3413 ) | |
428 | 3414 { |
442 | 3415 #if defined (_SC_CLK_TCK) || defined (CLK_TCK) && !defined(WIN32_NATIVE) |
428 | 3416 /* We have the POSIX times() function available. */ |
777 | 3417 /* #### Perhaps we should just use a configure test for times()? */ |
428 | 3418 struct tms tttt; |
3419 times (&tttt); | |
3420 *user_ticks = (long) tttt.tms_utime; | |
3421 *system_ticks = (long) tttt.tms_stime; | |
3422 return 1; | |
3423 #elif defined (CLOCKS_PER_SEC) | |
3424 *user_ticks = (long) clock (); | |
3425 *system_ticks = 0; | |
3426 return 1; | |
3427 #else | |
3428 return 0; | |
3429 #endif | |
3430 } | |
3431 | |
3432 void | |
3433 init_process_times_very_early (void) | |
3434 { | |
3435 #if defined (_SC_CLK_TCK) | |
3436 ticks_per_second = sysconf (_SC_CLK_TCK); | |
3437 #elif defined (CLK_TCK) | |
3438 ticks_per_second = CLK_TCK; | |
3439 #elif defined (CLOCKS_PER_SEC) | |
3440 ticks_per_second = CLOCKS_PER_SEC; | |
3441 #endif | |
3442 | |
3443 process_times_available = get_process_times_1 (&orig_user_ticks, | |
3444 &orig_system_ticks); | |
3445 EMACS_GET_TIME (orig_real_time); | |
3446 } | |
3447 | |
3448 /* Return the user and system times used up by this process so far. */ | |
3449 void | |
3450 get_process_times (double *user_time, double *system_time, double *real_time) | |
3451 { | |
3452 EMACS_TIME curr_real_time; | |
3453 EMACS_TIME elapsed_time; | |
3454 long curr_user_ticks, curr_system_ticks; | |
3455 | |
3456 EMACS_GET_TIME (curr_real_time); | |
3457 EMACS_SUB_TIME (elapsed_time, curr_real_time, orig_real_time); | |
3458 *real_time = (EMACS_SECS (elapsed_time) | |
3459 + ((double) EMACS_USECS (elapsed_time)) / 1000000); | |
3460 if (get_process_times_1 (&curr_user_ticks, &curr_system_ticks)) | |
3461 { | |
3462 *user_time = (((double) (curr_user_ticks - orig_user_ticks)) | |
3463 / ticks_per_second); | |
3464 *system_time = (((double) (curr_system_ticks - orig_system_ticks)) | |
3465 / ticks_per_second); | |
3466 } | |
3467 else | |
3468 { | |
3469 /* A lame OS */ | |
3470 *user_time = *real_time; | |
3471 *system_time = 0; | |
3472 } | |
3473 } | |
3474 | |
3475 #ifndef HAVE_RANDOM | |
3476 #ifdef random | |
3477 #define HAVE_RANDOM | |
3478 #endif | |
3479 #endif | |
3480 | |
3481 /* Figure out how many bits the system's random number generator uses. | |
3482 `random' and `lrand48' are assumed to return 31 usable bits. | |
3483 BSD `rand' returns a 31 bit value but the low order bits are unusable; | |
3484 so we'll shift it and treat it like the 15-bit USG `rand'. */ | |
3485 | |
3486 #ifndef RAND_BITS | |
3487 # ifdef HAVE_RANDOM | |
3488 # define RAND_BITS 31 | |
3489 # else /* !HAVE_RANDOM */ | |
3490 # ifdef HAVE_LRAND48 | |
3491 # define RAND_BITS 31 | |
3492 # define random lrand48 | |
3493 # else /* !HAVE_LRAND48 */ | |
3494 # define RAND_BITS 15 | |
3495 # if RAND_MAX == 32767 | |
3496 # define random rand | |
3497 # else /* RAND_MAX != 32767 */ | |
3498 # if RAND_MAX == 2147483647 | |
3499 # define random() (rand () >> 16) | |
3500 # else /* RAND_MAX != 2147483647 */ | |
3501 # ifdef USG | |
3502 # define random rand | |
3503 # else | |
3504 # define random() (rand () >> 16) | |
3505 # endif /* !BSD */ | |
3506 # endif /* RAND_MAX != 2147483647 */ | |
3507 # endif /* RAND_MAX != 32767 */ | |
3508 # endif /* !HAVE_LRAND48 */ | |
3509 # endif /* !HAVE_RANDOM */ | |
3510 #endif /* !RAND_BITS */ | |
3511 | |
3512 void | |
3513 seed_random (long arg) | |
3514 { | |
3515 #ifdef HAVE_RANDOM | |
3516 srandom ((unsigned int)arg); | |
3517 #else | |
3518 # ifdef HAVE_LRAND48 | |
3519 srand48 (arg); | |
3520 # else | |
3521 srand ((unsigned int)arg); | |
3522 # endif | |
3523 #endif | |
1983 | 3524 #ifdef HAVE_BIGNUM |
3525 bignum_random_seed ((unsigned long) arg); | |
3526 #endif | |
428 | 3527 } |
3528 | |
3529 /* | |
3530 * Build a full Emacs-sized word out of whatever we've got. | |
3531 * This suffices even for a 64-bit architecture with a 15-bit rand. | |
3532 */ | |
3533 long | |
3534 get_random (void) | |
3535 { | |
3536 long val = random (); | |
2039 | 3537 #if INT_VALBITS > RAND_BITS |
428 | 3538 val = (val << RAND_BITS) ^ random (); |
2039 | 3539 #if INT_VALBITS > 2*RAND_BITS |
428 | 3540 val = (val << RAND_BITS) ^ random (); |
2039 | 3541 #if INT_VALBITS > 3*RAND_BITS |
428 | 3542 val = (val << RAND_BITS) ^ random (); |
2039 | 3543 #if INT_VALBITS > 4*RAND_BITS |
428 | 3544 val = (val << RAND_BITS) ^ random (); |
3545 #endif /* need at least 5 */ | |
3546 #endif /* need at least 4 */ | |
3547 #endif /* need at least 3 */ | |
3548 #endif /* need at least 2 */ | |
2039 | 3549 return val & (EMACS_INT) ((1UL << INT_VALBITS) - 1); |
428 | 3550 } |
3551 | |
3552 | |
3553 /************************************************************************/ | |
3554 /* Strings corresponding to defined signals */ | |
3555 /************************************************************************/ | |
3556 | |
2762 | 3557 #if (!defined(HAVE_DECL_SYS_SIGLIST) || !HAVE_DECL_SYS_SIGLIST ) && !defined (HAVE_SYS_SIGLIST) |
428 | 3558 |
442 | 3559 #if defined(WIN32_NATIVE) || defined(CYGWIN) |
3560 const char *sys_siglist[] = | |
428 | 3561 { |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3562 /* @@@begin-snarf@@@ */ |
428 | 3563 "bum signal!!", |
3564 "hangup", | |
3565 "interrupt", | |
3566 "quit", | |
3567 "illegal instruction", | |
3568 "trace trap", | |
3569 "iot instruction", | |
3570 "emt instruction", | |
3571 "floating point exception", | |
3572 "kill", | |
3573 "bus error", | |
3574 "segmentation violation", | |
3575 "bad argument to system call", | |
3576 "write on a pipe with no one to read it", | |
3577 "alarm clock", | |
3578 "software termination signal from kill", | |
3579 "status signal", | |
3580 "sendable stop signal not from tty", | |
3581 "stop signal from tty", | |
3582 "continue a stopped process", | |
3583 "child status has changed", | |
3584 "background read attempted from control tty", | |
3585 "background write attempted from control tty", | |
3586 "input record available at control tty", | |
3587 "exceeded CPU time limit", | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3588 "exceeded file size limit", |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3589 /* @@@end-snarf@@@ */ |
428 | 3590 }; |
3591 #endif | |
3592 | |
3593 #ifdef USG | |
3594 #ifdef AIX | |
442 | 3595 const char *sys_siglist[NSIG + 1] = |
428 | 3596 { |
3597 /* AIX has changed the signals a bit */ | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3598 /* @@@begin-snarf@@@ */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3599 "bogus signal", /* 0 */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3600 "hangup", /* 1 SIGHUP */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3601 "interrupt", /* 2 SIGINT */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3602 "quit", /* 3 SIGQUIT */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3603 "illegal instruction", /* 4 SIGILL */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3604 "trace trap", /* 5 SIGTRAP */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3605 "IOT instruction", /* 6 SIGIOT */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3606 "crash likely", /* 7 SIGDANGER */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3607 "floating point exception", /* 8 SIGFPE */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3608 "kill", /* 9 SIGKILL */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3609 "bus error", /* 10 SIGBUS */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3610 "segmentation violation", /* 11 SIGSEGV */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3611 "bad argument to system call", /* 12 SIGSYS */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3612 "write on a pipe with no one to read it", /* 13 SIGPIPE */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3613 "alarm clock", /* 14 SIGALRM */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3614 "software termination signal", /* 15 SIGTERM */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3615 "user defined signal 1", /* 16 SIGUSR1 */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3616 "user defined signal 2", /* 17 SIGUSR2 */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3617 "death of a child", /* 18 SIGCLD */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3618 "power-fail restart", /* 19 SIGPWR */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3619 "bogus signal", /* 20 */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3620 "bogus signal", /* 21 */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3621 "bogus signal", /* 22 */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3622 "bogus signal", /* 23 */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3623 "bogus signal", /* 24 */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3624 "LAN I/O interrupt", /* 25 SIGAIO */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3625 "PTY I/O interrupt", /* 26 SIGPTY */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3626 "I/O intervention required", /* 27 SIGIOINT */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3627 /* @@@end-snarf@@@ */ |
428 | 3628 0 |
3629 }; | |
3630 #else /* USG, not AIX */ | |
442 | 3631 const char *sys_siglist[NSIG + 1] = |
428 | 3632 { |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3633 /* @@@begin-snarf@@@ */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3634 "bogus signal", /* 0 */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3635 "hangup", /* 1 SIGHUP */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3636 "interrupt", /* 2 SIGINT */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3637 "quit", /* 3 SIGQUIT */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3638 "illegal instruction", /* 4 SIGILL */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3639 "trace trap", /* 5 SIGTRAP */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3640 "IOT instruction", /* 6 SIGIOT */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3641 "EMT instruction", /* 7 SIGEMT */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3642 "floating point exception", /* 8 SIGFPE */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3643 "kill", /* 9 SIGKILL */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3644 "bus error", /* 10 SIGBUS */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3645 "segmentation violation", /* 11 SIGSEGV */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3646 "bad argument to system call", /* 12 SIGSYS */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3647 "write on a pipe with no one to read it", /* 13 SIGPIPE */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3648 "alarm clock", /* 14 SIGALRM */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3649 "software termination signal", /* 15 SIGTERM */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3650 "user defined signal 1", /* 16 SIGUSR1 */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3651 "user defined signal 2", /* 17 SIGUSR2 */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3652 "death of a child", /* 18 SIGCLD */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3653 "power-fail restart", /* 19 SIGPWR */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3654 #ifdef sun |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3655 "window size changed", /* 20 SIGWINCH */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3656 "urgent socket condition", /* 21 SIGURG */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3657 "pollable event occurred", /* 22 SIGPOLL */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3658 "stop (cannot be caught or ignored)", /* 23 SIGSTOP */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3659 "user stop requested from tty", /* 24 SIGTSTP */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3660 "stopped process has been continued", /* 25 SIGCONT */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3661 "background tty read attempted", /* 26 SIGTTIN */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3662 "background tty write attempted", /* 27 SIGTTOU */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3663 "virtual timer expired", /* 28 SIGVTALRM */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3664 "profiling timer expired", /* 29 SIGPROF */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3665 "exceeded cpu limit", /* 30 SIGXCPU */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3666 "exceeded file size limit", /* 31 SIGXFSZ */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3667 "process's lwps are blocked", /* 32 SIGWAITING */ |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3668 "special signal used by thread library", /* 33 SIGLWP */ |
428 | 3669 #ifdef SIGFREEZE |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3670 "special signal used by CPR", /* 34 SIGFREEZE */ |
428 | 3671 #endif |
3672 #ifdef SIGTHAW | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3673 "special signal used by CPR", /* 35 SIGTHAW */ |
428 | 3674 #endif |
3675 #endif /* sun */ | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
3676 /* @@@end-snarf@@@ */ |
428 | 3677 0 |
3678 }; | |
3679 #endif /* not AIX */ | |
3680 #endif /* USG */ | |
3681 | |
2762 | 3682 #endif /* (!defined(HAVE_DECL_SYS_SIGLIST) || !HAVE_DECL_SYS_SIGLIST ) && !defined (HAVE_SYS_SIGLIST) */ |
428 | 3683 |
3684 | |
3685 /************************************************************************/ | |
3686 /* Directory routines for systems that don't have them */ | |
3687 /************************************************************************/ | |
3688 | |
3689 #ifdef SYSV_SYSTEM_DIR | |
3690 | |
3691 #include <dirent.h> | |
3692 | |
4759
aa5ed11f473b
Remove support for obsolete systems. See xemacs-patches message with ID
Jerry James <james@xemacs.org>
parents:
3700
diff
changeset
|
3693 #if !defined(HAVE_CLOSEDIR) |
428 | 3694 int |
3695 closedir (DIR *dirp) /* stream from opendir */ | |
3696 { | |
3697 int rtnval; | |
3698 | |
771 | 3699 rtnval = retry_close (dirp->dd_fd); |
428 | 3700 |
3701 /* Some systems (like Solaris) allocate the buffer and the DIR all | |
3702 in one block. Why in the world are we freeing this ourselves | |
3703 anyway? */ | |
3704 #if ! (defined (sun) && defined (USG5_4)) | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3705 xfree (dirp->dd_buf); /* directory block defined in <dirent.h> */ |
428 | 3706 #endif |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3707 xfree (dirp); |
428 | 3708 return (rtnval); |
3709 } | |
4759
aa5ed11f473b
Remove support for obsolete systems. See xemacs-patches message with ID
Jerry James <james@xemacs.org>
parents:
3700
diff
changeset
|
3710 #endif /* not HAVE_CLOSEDIR */ |
428 | 3711 #endif /* SYSV_SYSTEM_DIR */ |
3712 | |
3713 #ifdef NONSYSTEM_DIR_LIBRARY | |
3714 | |
3715 DIR * | |
442 | 3716 opendir (const char *filename) /* name of directory */ |
428 | 3717 { |
3718 DIR *dirp; /* -> malloc'ed storage */ | |
3719 int fd; /* file descriptor for read */ | |
3720 struct stat sbuf; /* result of fstat */ | |
3721 | |
771 | 3722 fd = open (filename, O_RDONLY); |
428 | 3723 if (fd < 0) |
3724 return 0; | |
3725 | |
3726 if (fstat (fd, &sbuf) < 0 | |
3727 || (sbuf.st_mode & S_IFMT) != S_IFDIR | |
3728 || (dirp = (DIR *) malloc (sizeof (DIR))) == 0) | |
3729 { | |
771 | 3730 retry_close (fd); |
428 | 3731 return 0; /* bad luck today */ |
3732 } | |
3733 | |
3734 dirp->dd_fd = fd; | |
3735 dirp->dd_loc = dirp->dd_size = 0; /* refill needed */ | |
3736 | |
3737 return dirp; | |
3738 } | |
3739 | |
3740 void | |
3741 closedir (DIR *dirp) /* stream from opendir */ | |
3742 { | |
771 | 3743 retry_close (dirp->dd_fd); |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
3744 xfree (dirp); |
428 | 3745 } |
3746 | |
3747 | |
3748 #define DIRSIZ 14 | |
3749 struct olddir | |
3750 { | |
3751 ino_t od_ino; /* inode */ | |
3752 char od_name[DIRSIZ]; /* filename */ | |
3753 }; | |
3754 | |
3755 static struct direct dir_static; /* simulated directory contents */ | |
3756 | |
3757 /* ARGUSED */ | |
3758 struct direct * | |
3759 readdir (DIR *dirp) /* stream from opendir */ | |
3760 { | |
3761 struct olddir *dp; /* -> directory data */ | |
3762 | |
3763 for (; ;) | |
3764 { | |
3765 if (dirp->dd_loc >= dirp->dd_size) | |
3766 dirp->dd_loc = dirp->dd_size = 0; | |
3767 | |
3768 if (dirp->dd_size == 0 /* refill buffer */ | |
771 | 3769 && (dirp->dd_size = |
3770 retry_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0) | |
428 | 3771 return 0; |
3772 | |
3773 dp = (struct olddir *) &dirp->dd_buf[dirp->dd_loc]; | |
3774 dirp->dd_loc += sizeof (struct olddir); | |
3775 | |
3776 if (dp->od_ino != 0) /* not deleted entry */ | |
3777 { | |
3778 dir_static.d_ino = dp->od_ino; | |
3779 strncpy (dir_static.d_name, dp->od_name, DIRSIZ); | |
3780 dir_static.d_name[DIRSIZ] = '\0'; | |
3781 dir_static.d_namlen = strlen (dir_static.d_name); | |
3782 dir_static.d_reclen = sizeof (struct direct) | |
3783 - MAXNAMLEN + 3 | |
3784 + dir_static.d_namlen - dir_static.d_namlen % 4; | |
3785 return &dir_static; /* -> simulated structure */ | |
3786 } | |
3787 } | |
3788 } | |
3789 | |
3790 | |
3791 #endif /* NONSYSTEM_DIR_LIBRARY */ | |
3792 | |
3793 | |
3794 /* mkdir and rmdir functions, for systems which don't have them. */ | |
3795 | |
3796 #ifndef HAVE_MKDIR | |
3797 /* | |
3798 * Written by Robert Rother, Mariah Corporation, August 1985. | |
3799 * | |
3800 * If you want it, it's yours. All I ask in return is that if you | |
3801 * figure out how to do this in a Bourne Shell script you send me | |
3802 * a copy. | |
3803 * sdcsvax!rmr or rmr@uscd | |
3804 * | |
3805 * Severely hacked over by John Gilmore to make a 4.2BSD compatible | |
3806 * subroutine. 11Mar86; hoptoad!gnu | |
3807 * | |
3808 * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir, | |
3809 * subroutine didn't return EEXIST. It does now. | |
3810 */ | |
3811 | |
3812 /* | |
3813 * Make a directory. | |
3814 */ | |
3815 #ifdef MKDIR_PROTOTYPE | |
3816 MKDIR_PROTOTYPE | |
3817 #else | |
3818 int | |
442 | 3819 mkdir (const char *dpath, int dmode) |
428 | 3820 #endif |
3821 { | |
3822 int cpid, status, fd; | |
3823 struct stat statbuf; | |
3824 | |
442 | 3825 if (stat (dpath, &statbuf) == 0) /* we do want stat() here */ |
428 | 3826 { |
3827 errno = EEXIST; /* Stat worked, so it already exists */ | |
3828 return -1; | |
3829 } | |
3830 | |
3831 /* If stat fails for a reason other than non-existence, return error */ | |
3832 if (errno != ENOENT) | |
3833 return -1; | |
3834 | |
3835 synch_process_alive = 1; | |
3836 switch (cpid = fork ()) | |
3837 { | |
3838 | |
3839 case -1: /* Error in fork() */ | |
3840 return -1; /* Errno is set already */ | |
3841 | |
3842 case 0: /* Child process */ | |
3843 { | |
3844 /* | |
3845 * Cheap hack to set mode of new directory. Since this | |
3846 * child process is going away anyway, we zap its umask. | |
3847 * ####, this won't suffice to set SUID, SGID, etc. on this | |
3848 * directory. Does anybody care? | |
3849 */ | |
3850 status = umask (0); /* Get current umask */ | |
3851 status = umask (status | (0777 & ~dmode)); /* Set for mkdir */ | |
771 | 3852 fd = open ("/dev/null", O_RDWR); |
428 | 3853 if (fd >= 0) |
3854 { | |
3855 if (fd != STDIN_FILENO) dup2 (fd, STDIN_FILENO); | |
3856 if (fd != STDOUT_FILENO) dup2 (fd, STDOUT_FILENO); | |
3857 if (fd != STDERR_FILENO) dup2 (fd, STDERR_FILENO); | |
3858 } | |
3859 execl ("/bin/mkdir", "mkdir", dpath, (char *) 0); | |
3860 _exit (-1); /* Can't exec /bin/mkdir */ | |
3861 } | |
3862 | |
3863 default: /* Parent process */ | |
3864 wait_for_termination (cpid); | |
3865 } | |
3866 | |
3867 if (synch_process_death != 0 || synch_process_retcode != 0) | |
3868 { | |
3869 errno = EIO; /* We don't know why, but */ | |
3870 return -1; /* /bin/mkdir failed */ | |
3871 } | |
3872 | |
3873 return 0; | |
3874 } | |
3875 #endif /* not HAVE_MKDIR */ | |
3876 | |
3877 #ifndef HAVE_RMDIR | |
3878 int | |
442 | 3879 rmdir (const char *dpath) |
428 | 3880 { |
3881 int cpid, status, fd; | |
3882 struct stat statbuf; | |
3883 | |
442 | 3884 if (stat (dpath, &statbuf) != 0) /* we do want stat() here */ |
428 | 3885 { |
3886 /* Stat just set errno. We don't have to */ | |
3887 return -1; | |
3888 } | |
3889 | |
3890 synch_process_alive = 1; | |
3891 switch (cpid = fork ()) | |
3892 { | |
3893 | |
3894 case -1: /* Error in fork() */ | |
3895 return (-1); /* Errno is set already */ | |
3896 | |
3897 case 0: /* Child process */ | |
771 | 3898 fd = open ("/dev/null", O_RDWR); |
428 | 3899 if (fd >= 0) |
3900 { | |
3901 if (fd != STDIN_FILENO) dup2 (fd, STDIN_FILENO); | |
3902 if (fd != STDOUT_FILENO) dup2 (fd, STDOUT_FILENO); | |
3903 if (fd != STDERR_FILENO) dup2 (fd, STDERR_FILENO); | |
3904 } | |
3905 execl ("/bin/rmdir", "rmdir", dpath, (char *) 0); | |
3906 _exit (-1); /* Can't exec /bin/mkdir */ | |
3907 | |
3908 default: /* Parent process */ | |
3909 wait_for_termination (cpid); | |
3910 } | |
3911 | |
3912 if (synch_process_death != 0 || | |
3913 synch_process_retcode != 0) | |
3914 { | |
3915 errno = EIO; /* We don't know why, but */ | |
3916 return -1; /* /bin/rmdir failed */ | |
3917 } | |
3918 | |
3919 return 0; | |
3920 } | |
3921 #endif /* !HAVE_RMDIR */ | |
3922 | |
3923 | |
3924 /************************************************************************/ | |
3925 /* Misc. SunOS crap */ | |
3926 /************************************************************************/ | |
3927 | |
3928 #ifdef USE_DL_STUBS | |
3929 | |
3930 /* These are included on Sunos 4.1 when we do not use shared libraries. | |
3931 X11 libraries may refer to these functions but (we hope) do not | |
3932 actually call them. */ | |
3933 | |
3934 void * | |
3935 dlopen (void) | |
3936 { | |
3937 return 0; | |
3938 } | |
3939 | |
3940 void * | |
3941 dlsym (void) | |
3942 { | |
3943 return 0; | |
3944 } | |
3945 | |
3946 int | |
3947 dlclose (void) | |
3948 { | |
3949 return -1; | |
3950 } | |
3951 | |
3952 #endif /* USE_DL_STUBS */ |