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