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