X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/c4ea52a64fc91467e6952d6dc32962b7ca7f940b..8030369ccb5c871d3ce11b96c220f318bc741ed8:/src/sysdep.c diff --git a/src/sysdep.c b/src/sysdep.c index 92f12df5da..206ecca427 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -1,5 +1,6 @@ /* Interfaces to system-dependent kernel and library entries. - Copyright (C) 1985, 86, 87, 88, 93, 94, 95 Free Software Foundation, Inc. + Copyright (C) 1985, 86,87,88,93,94,95, 1999, 2000, 2001 + Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -18,68 +19,55 @@ along with GNU Emacs; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifdef HAVE_CONFIG_H +#include +#endif #include #include - -#include -#ifdef STDC_HEADERS -#include +#ifdef HAVE_UNISTD_H +#include #endif #include "lisp.h" +/* Including stdlib.h isn't necessarily enough to get srandom + declared, e.g. without __USE_XOPEN_EXTENDED with glibc 2. */ +#ifdef HAVE_RANDOM +#if 0 /* It turns out that defining _OSF_SOURCE in osf5-0.h gets + random prototyped as returning `int'. It looks to me as + though the best way to DTRT is to prefer the rand48 functions + (per libc.info). -- fx */ +extern long int random P_ ((void)); +#endif +#if 0 /* Don't prototype srandom; it takes an unsigned argument on + some systems, and an unsigned long on others, like FreeBSD + 4.1. */ +extern void srandom P_ ((unsigned int)); +#endif +#endif + #include "blockinput.h" #undef NULL -#ifdef macintosh -#ifdef __MRC__ -__sigfun sys_signal (int signal, __sigfun signal_func); -#elif __MWERKS__ -__signal_func_ptr sys_signal (int signal, __signal_func_ptr signal_func); -#else -You lose!!! -#endif +#ifdef MAC_OS8 +/* It is essential to include stdlib.h so that this file picks up + the correct definitions of rand, srand, and RAND_MAX. + Otherwise random numbers will not work correctly. */ +#include + #ifndef subprocesses /* Nonzero means delete a process right away if it exits (process.c). */ static int delete_exited_processes; #endif -#ifndef HAVE_X_WINDOWS -/* Search path for bitmap files (xfns.c). */ -Lisp_Object Vx_bitmap_file_path; -#endif -#endif /* macintosh */ - -#define min(x,y) ((x) > (y) ? (y) : (x)) - -/* In this file, open, read and write refer to the system calls, - not our sugared interfaces sys_open, sys_read and sys_write. - Contrariwise, for systems where we use the system calls directly, - define sys_read, etc. here as aliases for them. */ -#ifndef read -#define sys_read read -#define sys_write write -#endif /* `read' is not a macro */ - -#undef read -#undef write +#endif /* MAC_OS8 */ #ifdef WINDOWSNT -#define read _read -#define write _write +#define read sys_read +#define write sys_write #include -extern int errno; -#endif /* not WINDOWSNT */ - -#ifndef close -#define sys_close close -#else -#undef close +#ifndef NULL +#define NULL 0 #endif - -#ifndef open -#define sys_open open -#else /* `open' is a macro */ -#undef open -#endif /* `open' is a macro */ +#endif /* not WINDOWSNT */ /* Does anyone other than VMS need this? */ #ifndef fwrite @@ -88,10 +76,6 @@ extern int errno; #undef fwrite #endif -#ifndef HAVE_H_ERRNO -extern int h_errno; -#endif - #include #include #include @@ -102,6 +86,17 @@ extern int h_errno; #include #endif +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_SETPGID +#if !defined (USG) || defined (BSD_PGRPS) +#undef setpgrp +#define setpgrp setpgid +#endif +#endif + /* Get SI_SRPC_DOMAIN, if it is available. */ #ifdef HAVE_SYS_SYSTEMINFO_H #include @@ -119,9 +114,11 @@ extern unsigned start __asm__ ("start"); #endif #endif +#ifndef USE_CRT_DLL #ifndef errno extern int errno; #endif +#endif #ifdef VMS #include @@ -172,7 +169,6 @@ extern int errno; #if defined (USG) || defined (DGUX) #include -#include #ifndef MEMORY_IN_STRING_H #include #endif @@ -189,6 +185,7 @@ extern int errno; extern int quit_char; +#include "keyboard.h" #include "frame.h" #include "window.h" #include "termhooks.h" @@ -226,10 +223,6 @@ struct utimbuf { #endif #endif -#ifndef VFORK_RETURN_TYPE -#define VFORK_RETURN_TYPE int -#endif - /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */ #ifndef LPASS8 #define LPASS8 0 @@ -249,18 +242,18 @@ static int baud_convert[] = }; #endif +#ifdef HAVE_SPEED_T +#include +#else #if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T) -extern short ospeed; #else -#if defined (HAVE_TERMIOS_H) && defined (LINUX) +#if defined (HAVE_TERMIOS_H) && defined (GNU_LINUX) #include -/* HJL's version of libc is said to need this on the Alpha. - On the other hand, DEC OSF1 on the Alpha needs ospeed to be a short. */ -extern speed_t ospeed; -#else -extern short ospeed; #endif #endif +#endif + +int emacs_ospeed; /* The file descriptor for Emacs's input terminal. Under Unix, this is normally zero except when using X; @@ -274,6 +267,10 @@ void hft_init (); void hft_reset (); #endif +/* Temporary used by `sigblock' when defined in terms of signprocmask. */ + +SIGMASKTYPE sigprocmask_set; + /* Specify a different file descriptor for further input operations. */ @@ -350,32 +347,32 @@ void init_baud_rate () { if (noninteractive) - ospeed = 0; + emacs_ospeed = 0; else { #ifdef INIT_BAUD_RATE INIT_BAUD_RATE (); #else #ifdef DOS_NT - ospeed = 15; + emacs_ospeed = 15; #else /* not DOS_NT */ #ifdef VMS struct sensemode sg; SYS$QIOW (0, input_fd, IO$_SENSEMODE, &sg, 0, 0, &sg.class, 12, 0, 0, 0, 0 ); - ospeed = sg.xmit_baud; + emacs_ospeed = sg.xmit_baud; #else /* not VMS */ #ifdef HAVE_TERMIOS struct termios sg; sg.c_cflag = B9600; tcgetattr (input_fd, &sg); - ospeed = cfgetospeed (&sg); + emacs_ospeed = cfgetospeed (&sg); #if defined (USE_GETOBAUD) && defined (getobaud) /* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */ - if (ospeed == 0) - ospeed = getobaud (sg.c_cflag); + if (emacs_ospeed == 0) + emacs_ospeed = getobaud (sg.c_cflag); #endif #else /* neither VMS nor TERMIOS */ #ifdef HAVE_TERMIO @@ -387,14 +384,14 @@ init_baud_rate () #else ioctl (input_fd, TCGETA, &sg); #endif - ospeed = sg.c_cflag & CBAUD; + emacs_ospeed = sg.c_cflag & CBAUD; #else /* neither VMS nor TERMIOS nor TERMIO */ struct sgttyb sg; sg.sg_ospeed = B9600; if (ioctl (input_fd, TIOCGETP, &sg) < 0) abort (); - ospeed = sg.sg_ospeed; + emacs_ospeed = sg.sg_ospeed; #endif /* not HAVE_TERMIO */ #endif /* not HAVE_TERMIOS */ #endif /* not VMS */ @@ -402,8 +399,8 @@ init_baud_rate () #endif /* not INIT_BAUD_RATE */ } - baud_rate = (ospeed < sizeof baud_convert / sizeof baud_convert[0] - ? baud_convert[ospeed] : 9600); + baud_rate = (emacs_ospeed < sizeof baud_convert / sizeof baud_convert[0] + ? baud_convert[emacs_ospeed] : 9600); if (baud_rate == 0) baud_rate = 1200; } @@ -481,14 +478,16 @@ wait_for_termination (pid) break; wait (0); #else /* neither BSD_SYSTEM nor UNIPLUS: random sysV */ -#ifdef POSIX_SIGNALS /* would this work for LINUX as well? */ +#ifdef POSIX_SIGNALS /* would this work for GNU/Linux as well? */ sigblock (sigmask (SIGCHLD)); - if (0 > kill (pid, 0)) + errno = 0; + if (kill (pid, 0) == -1 && errno == ESRCH) { sigunblock (sigmask (SIGCHLD)); break; } - sigpause (SIGEMPTYMASK); + + sigsuspend (&empty_mask); #else /* not POSIX_SIGNALS */ #ifdef HAVE_SYSV_SIGPAUSE sighold (SIGCHLD); @@ -587,6 +586,13 @@ child_setup_tty (out) #endif s.main.c_lflag &= ~ECHO; /* Disable echo */ s.main.c_lflag |= ISIG; /* Enable signals */ +#if 0 /* This causes bugs in (for instance) telnet to certain sites. */ + s.main.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */ +#ifdef INLCR /* Just being cautious, since I can't check how + widespread INLCR is--rms. */ + s.main.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */ +#endif +#endif #ifdef IUCLC s.main.c_iflag &= ~IUCLC; /* Disable downcasing on input. */ #endif @@ -753,12 +759,10 @@ sys_suspend () /* Fork a subshell. */ +#ifndef MAC_OS8 void sys_subshell () { -#ifdef macintosh - error ("Can't spawn subshell"); -#else #ifndef VMS #ifdef DOS_NT /* Demacs 1.1.2 91/10/20 Manabu Higashida */ int st; @@ -791,9 +795,9 @@ sys_subshell () goto xyzzy; dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil); - str = (unsigned char *) alloca (XSTRING (dir)->size + 2); - len = XSTRING (dir)->size; - bcopy (XSTRING (dir)->data, str, len); + str = (unsigned char *) alloca (SCHARS (dir) + 2); + len = SCHARS (dir); + bcopy (SDATA (dir), str, len); if (str[len - 1] != '/') str[len++] = '/'; str[len] = 0; xyzzy: @@ -834,7 +838,7 @@ sys_subshell () #ifdef SET_EMACS_PRIORITY { - extern int emacs_priority; + extern EMACS_INT emacs_priority; if (emacs_priority < 0) nice (-emacs_priority); @@ -842,8 +846,23 @@ sys_subshell () #endif #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */ - st = system (sh); - chdir (oldwd); + { + char *epwd = getenv ("PWD"); + char old_pwd[MAXPATHLEN+1+4]; + + /* If PWD is set, pass it with corrected value. */ + if (epwd) + { + strcpy (old_pwd, epwd); + if (str[len - 1] == '/') + str[len - 1] = '\0'; + setenv ("PWD", str, 1); + } + st = system (sh); + chdir (oldwd); + if (epwd) + putenv (old_pwd); /* restore previous value */ + } #if 0 /* This is also reported if last command executed in subshell failed, KFS */ if (st) report_file_error ("Can't execute subshell", Fcons (build_string (sh), Qnil)); @@ -875,8 +894,8 @@ sys_subshell () restore_signal_handlers (saved_handlers); synch_process_alive = 0; #endif /* !VMS */ -#endif /* !macintosh */ } +#endif /* !MAC_OS8 */ static void save_signal_handlers (saved_handlers) @@ -1286,25 +1305,15 @@ init_sys_modes () { struct emacs_tty tty; -#ifdef macintosh - Vwindow_system = intern ("mac"); - Vwindow_system_version = make_number (1); - -/* cus-start.el complains if delete-exited-processes and x-bitmap-file-path not defined */ +#ifdef MAC_OS8 +/* cus-start.el complains if delete-exited-processes is not defined */ #ifndef subprocesses DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes, - "*Non-nil means delete processes immediately when they exit.\n\ -nil means don't delete them until `list-processes' is run."); + doc: /* *Non-nil means delete processes immediately when they exit. +nil means don't delete them until `list-processes' is run. */); delete_exited_processes = 0; #endif - -#ifndef HAVE_X_WINDOWS - DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path, - "List of directories to search for bitmap files for X."); - Vx_bitmap_file_path = decode_env_path ((char *) 0, "."); -#endif - -#endif /* not macintosh */ +#endif /* MAC_OS8 */ #ifdef VMS #if 0 @@ -1777,6 +1786,8 @@ set_window_size (fd, height, width) void reset_sys_modes () { + struct frame *sf; + if (noninteractive) { fflush (stdout); @@ -1796,10 +1807,11 @@ reset_sys_modes () ) return; #endif - cursor_to (FRAME_HEIGHT (selected_frame) - 1, 0); - clear_end_of_line (FRAME_WIDTH (selected_frame)); + sf = SELECTED_FRAME (); + cursor_to (FRAME_HEIGHT (sf) - 1, 0); + clear_end_of_line (FRAME_WIDTH (sf)); /* clear_end_of_line may move the cursor */ - cursor_to (FRAME_HEIGHT (selected_frame) - 1, 0); + cursor_to (FRAME_HEIGHT (sf) - 1, 0); #if defined (IBMR2AIX) && defined (AIXHFT) { /* HFT devices normally use ^J as a LF/CR. We forced it to @@ -1895,7 +1907,7 @@ setup_pty (fd) Since the latter lossage is more benign, we may as well lose that way. -- cph */ #ifdef FIONBIO -#ifdef SYSV_PTYS +#if defined(SYSV_PTYS) || defined(UNIX98_PTYS) { int on = 1; ioctl (fd, FIONBIO, &on); @@ -1999,9 +2011,9 @@ kbd_input_ast () if (c >= 0) { struct input_event e; - e.kind = ascii_keystroke; + e.kind = ASCII_KEYSTROKE_EVENT; XSETINT (e.code, c); - XSETFRAME (e.frame_or_window, selected_frame); + e.frame_or_window = selected_frame; kbd_buffer_store_event (&e); } if (input_available_clear_time) @@ -2030,7 +2042,7 @@ wait_for_kbd_input () /* No timing error: wait for flag to be set. */ set_waiting_for_input (0); SYS$WFLOR (input_ef, input_eflist); - clear_waiting_for_input (0); + clear_waiting_for_input (); if (!detect_input_pending ()) /* Check for subprocess input availability */ { @@ -2045,7 +2057,7 @@ wait_for_kbd_input () { update_mode_lines++; prepare_menu_bars (); - redisplay_preserve_echo_area (); + redisplay_preserve_echo_area (18); } } } @@ -2179,6 +2191,7 @@ unrequest_sigio () * */ +#if !(defined (__NetBSD__) && defined (__ELF__)) #ifndef HAVE_TEXT_START char * start_of_text () @@ -2196,6 +2209,7 @@ start_of_text () #endif /* TEXT_START */ } #endif /* not HAVE_TEXT_START */ +#endif /* * Return the address of the start of the data segment prior to @@ -2223,6 +2237,7 @@ start_of_text () * */ +#ifndef start_of_data char * start_of_data () { @@ -2245,44 +2260,8 @@ start_of_data () #endif /* ORDINARY_LINK */ #endif /* DATA_START */ } +#endif /* start_of_data */ #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */ - -#ifndef CANNOT_DUMP -/* Some systems that cannot dump also cannot implement these. */ - -/* - * Return the address of the end of the text segment prior to - * doing an unexec. After unexec the return value is undefined. - */ - -char * -end_of_text () -{ -#ifdef TEXT_END - return ((char *) TEXT_END); -#else - extern int etext; - return ((char *) &etext); -#endif -} - -/* - * Return the address of the end of the data segment prior to - * doing an unexec. After unexec the return value is undefined. - */ - -char * -end_of_data () -{ -#ifdef DATA_END - return ((char *) DATA_END); -#else - extern int edata; - return ((char *) &edata); -#endif -} - -#endif /* not CANNOT_DUMP */ /* init_system_name sets up the string for the Lisp function system-name to return. */ @@ -2302,6 +2281,12 @@ extern Lisp_Object Vsystem_name; #endif /* not VMS */ #endif /* not BSD4_1 */ +#ifdef TRY_AGAIN +#ifndef HAVE_H_ERRNO +extern int h_errno; +#endif +#endif /* TRY_AGAIN */ + void init_system_name () { @@ -2369,7 +2354,9 @@ init_system_name () if (hp) { char *fqdn = (char *) hp->h_name; +#if 0 char *p; +#endif if (!index (fqdn, '.')) { @@ -2443,7 +2430,7 @@ init_system_name () #endif /* BSD4_1 */ { unsigned char *p; - for (p = XSTRING (Vsystem_name)->data; *p; p++) + for (p = SDATA (Vsystem_name); *p; p++) if (*p == ' ' || *p == '\t') *p = '-'; } @@ -2499,7 +2486,7 @@ sys_select (nfds, rfds, wfds, efds, timeout) SELECT_TYPE *rfds, *wfds, *efds; EMACS_TIME *timeout; { - int ravail = 0, old_alarm; + int ravail = 0; SELECT_TYPE orfds; int timeoutval; int *local_timeout; @@ -2509,7 +2496,6 @@ sys_select (nfds, rfds, wfds, efds, timeout) #else extern int process_tick, update_tick; #endif - SIGTYPE (*old_trap) (); unsigned char buf; #if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS) @@ -2592,10 +2578,12 @@ sys_select (nfds, rfds, wfds, efds, timeout) } if (*local_timeout == 0 || ravail != 0 || process_tick != update_tick) break; - old_alarm = alarm (0); - old_trap = signal (SIGALRM, select_alarm); + + turn_on_atimers (0); + signal (SIGALRM, select_alarm); select_alarmed = 0; alarm (SELECT_PAUSE); + /* Wait for a SIGALRM (or maybe a SIGTINT) */ while (select_alarmed == 0 && *local_timeout != 0 && process_tick == update_tick) @@ -2613,18 +2601,10 @@ sys_select (nfds, rfds, wfds, efds, timeout) pause (); } (*local_timeout) -= SELECT_PAUSE; - /* Reset the old alarm if there was one */ - alarm (0); - signal (SIGALRM, old_trap); - if (old_alarm != 0) - { - /* Reset or forge an interrupt for the original handler. */ - old_alarm -= SELECT_PAUSE; - if (old_alarm <= 0) - kill (getpid (), SIGALRM); /* Fake an alarm with the orig' handler */ - else - alarm (old_alarm); - } + + /* Reset the old alarm if there was one. */ + turn_on_atimers (1); + if (*local_timeout == 0) /* Stop on timer being cleared */ break; } @@ -2665,7 +2645,7 @@ read_input_waiting () kbd_buffer_store_event (&buf[i]); /* Don't look at input that follows a C-g too closely. This reduces lossage due to autorepeat on C-g. */ - if (buf[i].kind == ascii_keystroke + if (buf[i].kind == ASCII_KEYSTROKE_EVENT && buf[i].code == quit_char) break; } @@ -2676,8 +2656,8 @@ read_input_waiting () nread = read (fileno (stdin), buf, 1); /* Scan the chars for C-g and store them in kbd_buffer. */ - e.kind = ascii_keystroke; - XSETFRAME (e.frame_or_window, selected_frame); + e.kind = ASCII_KEYSTROKE_EVENT; + e.frame_or_window = selected_frame; e.modifiers = 0; for (i = 0; i < nread; i++) { @@ -2707,25 +2687,6 @@ read_input_waiting () #endif /* not MSDOS */ #ifdef BSD4_1 -/* - * Partially emulate 4.2 open call. - * open is defined as this in 4.1. - * - * - added by Michael Bloom @ Citicorp/TTI - * - */ - -int -sys_open (path, oflag, mode) - char *path; - int oflag, mode; -{ - if (oflag & O_CREAT) - return creat (path, mode); - else - return open (path, oflag); -} - void init_sigio (fd) int fd; @@ -2814,23 +2775,18 @@ sigbit (i) sigset_t empty_mask, full_mask; -void -init_signals () -{ - sigemptyset (&empty_mask); - sigfillset (&full_mask); -} - signal_handler_t sys_signal (int signal_number, signal_handler_t action) { struct sigaction new_action, old_action; sigemptyset (&new_action.sa_mask); new_action.sa_handler = action; -#ifdef SA_RESTART +#if defined (SA_RESTART) && ! defined (BROKEN_SA_RESTART) /* Emacs mostly works better with restartable system services. If this - * flag exists, we probably want to turn it on here. - */ + flag exists, we probably want to turn it on here. + However, on some systems this resets the timeout of `select' + which means that `select' never finishes if it keeps getting signals. + BROKEN_SA_RESTART is defined on those systems. */ new_action.sa_flags = SA_RESTART; #else new_action.sa_flags = 0; @@ -2883,6 +2839,185 @@ sys_sigsetmask (sigset_t new_mask) #endif /* POSIX_SIGNALS */ +#if !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED +static char *my_sys_siglist[NSIG]; +# ifdef sys_siglist +# undef sys_siglist +# endif +# define sys_siglist my_sys_siglist +#endif + +void +init_signals () +{ +#ifdef POSIX_SIGNALS + sigemptyset (&empty_mask); + sigfillset (&full_mask); +#endif + +#if !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED + if (! initialized) + { +# ifdef SIGABRT + sys_siglist[SIGABRT] = "Aborted"; +# endif +# ifdef SIGAIO + sys_siglist[SIGAIO] = "LAN I/O interrupt"; +# endif +# ifdef SIGALRM + sys_siglist[SIGALRM] = "Alarm clock"; +# endif +# ifdef SIGBUS + sys_siglist[SIGBUS] = "Bus error"; +# endif +# ifdef SIGCLD + sys_siglist[SIGCLD] = "Child status changed"; +# endif +# ifdef SIGCHLD + sys_siglist[SIGCHLD] = "Child status changed"; +# endif +# ifdef SIGCONT + sys_siglist[SIGCONT] = "Continued"; +# endif +# ifdef SIGDANGER + sys_siglist[SIGDANGER] = "Swap space dangerously low"; +# endif +# ifdef SIGDGNOTIFY + sys_siglist[SIGDGNOTIFY] = "Notification message in queue"; +# endif +# ifdef SIGEMT + sys_siglist[SIGEMT] = "Emulation trap"; +# endif +# ifdef SIGFPE + sys_siglist[SIGFPE] = "Arithmetic exception"; +# endif +# ifdef SIGFREEZE + sys_siglist[SIGFREEZE] = "SIGFREEZE"; +# endif +# ifdef SIGGRANT + sys_siglist[SIGGRANT] = "Monitor mode granted"; +# endif +# ifdef SIGHUP + sys_siglist[SIGHUP] = "Hangup"; +# endif +# ifdef SIGILL + sys_siglist[SIGILL] = "Illegal instruction"; +# endif +# ifdef SIGINT + sys_siglist[SIGINT] = "Interrupt"; +# endif +# ifdef SIGIO + sys_siglist[SIGIO] = "I/O possible"; +# endif +# ifdef SIGIOINT + sys_siglist[SIGIOINT] = "I/O intervention required"; +# endif +# ifdef SIGIOT + sys_siglist[SIGIOT] = "IOT trap"; +# endif +# ifdef SIGKILL + sys_siglist[SIGKILL] = "Killed"; +# endif +# ifdef SIGLOST + sys_siglist[SIGLOST] = "Resource lost"; +# endif +# ifdef SIGLWP + sys_siglist[SIGLWP] = "SIGLWP"; +# endif +# ifdef SIGMSG + sys_siglist[SIGMSG] = "Monitor mode data available"; +# endif +# ifdef SIGPHONE + sys_siglist[SIGWIND] = "SIGPHONE"; +# endif +# ifdef SIGPIPE + sys_siglist[SIGPIPE] = "Broken pipe"; +# endif +# ifdef SIGPOLL + sys_siglist[SIGPOLL] = "Pollable event occurred"; +# endif +# ifdef SIGPROF + sys_siglist[SIGPROF] = "Profiling timer expired"; +# endif +# ifdef SIGPTY + sys_siglist[SIGPTY] = "PTY I/O interrupt"; +# endif +# ifdef SIGPWR + sys_siglist[SIGPWR] = "Power-fail restart"; +# endif +# ifdef SIGQUIT + sys_siglist[SIGQUIT] = "Quit"; +# endif +# ifdef SIGRETRACT + sys_siglist[SIGRETRACT] = "Need to relinguish monitor mode"; +# endif +# ifdef SIGSAK + sys_siglist[SIGSAK] = "Secure attention"; +# endif +# ifdef SIGSEGV + sys_siglist[SIGSEGV] = "Segmentation violation"; +# endif +# ifdef SIGSOUND + sys_siglist[SIGSOUND] = "Sound completed"; +# endif +# ifdef SIGSTOP + sys_siglist[SIGSTOP] = "Stopped (signal)"; +# endif +# ifdef SIGSTP + sys_siglist[SIGSTP] = "Stopped (user)"; +# endif +# ifdef SIGSYS + sys_siglist[SIGSYS] = "Bad argument to system call"; +# endif +# ifdef SIGTERM + sys_siglist[SIGTERM] = "Terminated"; +# endif +# ifdef SIGTHAW + sys_siglist[SIGTHAW] = "SIGTHAW"; +# endif +# ifdef SIGTRAP + sys_siglist[SIGTRAP] = "Trace/breakpoint trap"; +# endif +# ifdef SIGTSTP + sys_siglist[SIGTSTP] = "Stopped (user)"; +# endif +# ifdef SIGTTIN + sys_siglist[SIGTTIN] = "Stopped (tty input)"; +# endif +# ifdef SIGTTOU + sys_siglist[SIGTTOU] = "Stopped (tty output)"; +# endif +# ifdef SIGURG + sys_siglist[SIGURG] = "Urgent I/O condition"; +# endif +# ifdef SIGUSR1 + sys_siglist[SIGUSR1] = "User defined signal 1"; +# endif +# ifdef SIGUSR2 + sys_siglist[SIGUSR2] = "User defined signal 2"; +# endif +# ifdef SIGVTALRM + sys_siglist[SIGVTALRM] = "Virtual timer expired"; +# endif +# ifdef SIGWAITING + sys_siglist[SIGWAITING] = "Process's LWPs are blocked"; +# endif +# ifdef SIGWINCH + sys_siglist[SIGWINCH] = "Window size changed"; +# endif +# ifdef SIGWIND + sys_siglist[SIGWIND] = "SIGWIND"; +# endif +# ifdef SIGXCPU + sys_siglist[SIGXCPU] = "CPU time limit exceeded"; +# endif +# ifdef SIGXFSZ + sys_siglist[SIGXFSZ] = "File size limit exceeded"; +# endif + } +#endif /* !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED */ +} + #ifndef HAVE_RANDOM #ifdef random #define HAVE_RANDOM @@ -3090,27 +3225,25 @@ strerror (errnum) #endif /* not WINDOWSNT */ #endif /* ! HAVE_STRERROR */ -#ifdef INTERRUPTIBLE_OPEN - int -/* VARARGS 2 */ -sys_open (path, oflag, mode) - char *path; +emacs_open (path, oflag, mode) + const char *path; int oflag, mode; { register int rtnval; + +#ifdef BSD4_1 + if (oflag & O_CREAT) + return creat (path, mode); +#endif while ((rtnval = open (path, oflag, mode)) == -1 && (errno == EINTR)); return (rtnval); } -#endif /* INTERRUPTIBLE_OPEN */ - -#ifdef INTERRUPTIBLE_CLOSE - int -sys_close (fd) +emacs_close (fd) int fd; { int did_retry = 0; @@ -3129,12 +3262,8 @@ sys_close (fd) return rtnval; } -#endif /* INTERRUPTIBLE_CLOSE */ - -#ifdef INTERRUPTIBLE_IO - int -sys_read (fildes, buf, nbyte) +emacs_read (fildes, buf, nbyte) int fildes; char *buf; unsigned int nbyte; @@ -3147,9 +3276,9 @@ sys_read (fildes, buf, nbyte) } int -sys_write (fildes, buf, nbyte) +emacs_write (fildes, buf, nbyte) int fildes; - char *buf; + const char *buf; unsigned int nbyte; { register int rtnval, bytes_written; @@ -3174,22 +3303,6 @@ sys_write (fildes, buf, nbyte) } return (bytes_written); } - -#endif /* INTERRUPTIBLE_IO */ - -#ifndef HAVE_VFORK -#ifndef WINDOWSNT -/* - * Substitute fork for vfork on USG flavors. - */ - -VFORK_RETURN_TYPE -vfork () -{ - return (fork ()); -} -#endif /* not WINDOWSNT */ -#endif /* not HAVE_VFORK */ #ifdef USG /* @@ -3207,93 +3320,6 @@ vfork () * always negligible. Fred Fish, Unisoft Systems Inc. */ -#ifndef HAVE_SYS_SIGLIST -char *sys_siglist[NSIG + 1] = -{ -#ifdef AIX -/* AIX has changed the signals a bit */ - "bogus signal", /* 0 */ - "hangup", /* 1 SIGHUP */ - "interrupt", /* 2 SIGINT */ - "quit", /* 3 SIGQUIT */ - "illegal instruction", /* 4 SIGILL */ - "trace trap", /* 5 SIGTRAP */ - "IOT instruction", /* 6 SIGIOT */ - "crash likely", /* 7 SIGDANGER */ - "floating point exception", /* 8 SIGFPE */ - "kill", /* 9 SIGKILL */ - "bus error", /* 10 SIGBUS */ - "segmentation violation", /* 11 SIGSEGV */ - "bad argument to system call", /* 12 SIGSYS */ - "write on a pipe with no one to read it", /* 13 SIGPIPE */ - "alarm clock", /* 14 SIGALRM */ - "software termination signum", /* 15 SIGTERM */ - "user defined signal 1", /* 16 SIGUSR1 */ - "user defined signal 2", /* 17 SIGUSR2 */ - "death of a child", /* 18 SIGCLD */ - "power-fail restart", /* 19 SIGPWR */ - "bogus signal", /* 20 */ - "bogus signal", /* 21 */ - "bogus signal", /* 22 */ - "bogus signal", /* 23 */ - "bogus signal", /* 24 */ - "LAN I/O interrupt", /* 25 SIGAIO */ - "PTY I/O interrupt", /* 26 SIGPTY */ - "I/O intervention required", /* 27 SIGIOINT */ -#ifdef AIXHFT - "HFT grant", /* 28 SIGGRANT */ - "HFT retract", /* 29 SIGRETRACT */ - "HFT sound done", /* 30 SIGSOUND */ - "HFT input ready", /* 31 SIGMSG */ -#endif -#else /* not AIX */ - "bogus signal", /* 0 */ - "hangup", /* 1 SIGHUP */ - "interrupt", /* 2 SIGINT */ - "quit", /* 3 SIGQUIT */ - "illegal instruction", /* 4 SIGILL */ - "trace trap", /* 5 SIGTRAP */ - "IOT instruction", /* 6 SIGIOT */ - "EMT instruction", /* 7 SIGEMT */ - "floating point exception", /* 8 SIGFPE */ - "kill", /* 9 SIGKILL */ - "bus error", /* 10 SIGBUS */ - "segmentation violation", /* 11 SIGSEGV */ - "bad argument to system call", /* 12 SIGSYS */ - "write on a pipe with no one to read it", /* 13 SIGPIPE */ - "alarm clock", /* 14 SIGALRM */ - "software termination signum", /* 15 SIGTERM */ - "user defined signal 1", /* 16 SIGUSR1 */ - "user defined signal 2", /* 17 SIGUSR2 */ - "death of a child", /* 18 SIGCLD */ - "power-fail restart", /* 19 SIGPWR */ -#ifdef sun - "window size change", /* 20 SIGWINCH */ - "urgent socket condition", /* 21 SIGURG */ - "pollable event occurred", /* 22 SIGPOLL */ - "stop (cannot be caught or ignored)", /* 23 SIGSTOP */ - "user stop requested from tty", /* 24 SIGTSTP */ - "stopped process has been continued", /* 25 SIGCONT */ - "background tty read attempted", /* 26 SIGTTIN */ - "background tty write attempted", /* 27 SIGTTOU */ - "virtual timer expired", /* 28 SIGVTALRM */ - "profiling timer expired", /* 29 SIGPROF */ - "exceeded cpu limit", /* 30 SIGXCPU */ - "exceeded file size limit", /* 31 SIGXFSZ */ - "process's lwps are blocked", /* 32 SIGWAITING */ - "special signal used by thread library", /* 33 SIGLWP */ -#ifdef SIGFREEZE - "Special Signal Used By CPR", /* 34 SIGFREEZE */ -#endif -#ifdef SIGTHAW - "Special Signal Used By CPR", /* 35 SIGTHAW */ -#endif -#endif /* sun */ -#endif /* not AIX */ - 0 - }; -#endif /* HAVE_SYS_SIGLIST */ - /* * Warning, this function may not duplicate 4.2 action properly * under error conditions. @@ -3316,7 +3342,10 @@ getwd (pathname) BLOCK_INPUT; /* getcwd uses malloc */ spath = npath = getcwd ((char *) 0, MAXPATHLEN); if (spath == 0) - return spath; + { + UNBLOCK_INPUT; + return spath; + } /* On Altos 3068, getcwd can return @hostname/dir, so discard up to first slash. Should be harmless on other systems. */ while (*npath && *npath != '/') @@ -3381,12 +3410,10 @@ dup2 (oldd, newd) { register int fd, ret; - sys_close (newd); + emacs_close (newd); #ifdef F_DUPFD - fd = fcntl (oldd, F_DUPFD, newd); - if (fd != newd) - error ("can't dup2 (%i,%i) : %s", oldd, newd, strerror (errno)); + return fcntl (oldd, F_DUPFD, newd); #else fd = dup (old); if (fd == -1) @@ -3394,7 +3421,7 @@ dup2 (oldd, newd) if (fd == new) return new; ret = dup2 (old,new); - sys_close (fd); + emacs_close (fd); return ret; #endif } @@ -3447,80 +3474,6 @@ croak (badfunc) #endif /* USG */ -#ifdef DGUX - -char *sys_siglist[NSIG + 1] = -{ - "null signal", /* 0 SIGNULL */ - "hangup", /* 1 SIGHUP */ - "interrupt", /* 2 SIGINT */ - "quit", /* 3 SIGQUIT */ - "illegal instruction", /* 4 SIGILL */ - "trace trap", /* 5 SIGTRAP */ - "abort termination", /* 6 SIGABRT */ - "SIGEMT", /* 7 SIGEMT */ - "floating point exception", /* 8 SIGFPE */ - "kill", /* 9 SIGKILL */ - "bus error", /* 10 SIGBUS */ - "segmentation violation", /* 11 SIGSEGV */ - "bad argument to system call", /* 12 SIGSYS */ - "write on a pipe with no reader", /* 13 SIGPIPE */ - "alarm clock", /* 14 SIGALRM */ - "software termination signal", /* 15 SIGTERM */ - "user defined signal 1", /* 16 SIGUSR1 */ - "user defined signal 2", /* 17 SIGUSR2 */ - "child stopped or terminated", /* 18 SIGCLD */ - "power-fail restart", /* 19 SIGPWR */ - "window size changed", /* 20 SIGWINCH */ - "undefined", /* 21 */ - "pollable event occurred", /* 22 SIGPOLL */ - "sendable stop signal not from tty", /* 23 SIGSTOP */ - "stop signal from tty", /* 24 SIGSTP */ - "continue a stopped process", /* 25 SIGCONT */ - "attempted background tty read", /* 26 SIGTTIN */ - "attempted background tty write", /* 27 SIGTTOU */ - "undefined", /* 28 */ - "undefined", /* 29 */ - "undefined", /* 30 */ - "undefined", /* 31 */ - "undefined", /* 32 */ - "socket (TCP/IP) urgent data arrival", /* 33 SIGURG */ - "I/O is possible", /* 34 SIGIO */ - "exceeded cpu time limit", /* 35 SIGXCPU */ - "exceeded file size limit", /* 36 SIGXFSZ */ - "virtual time alarm", /* 37 SIGVTALRM */ - "profiling time alarm", /* 38 SIGPROF */ - "undefined", /* 39 */ - "file record locks revoked", /* 40 SIGLOST */ - "undefined", /* 41 */ - "undefined", /* 42 */ - "undefined", /* 43 */ - "undefined", /* 44 */ - "undefined", /* 45 */ - "undefined", /* 46 */ - "undefined", /* 47 */ - "undefined", /* 48 */ - "undefined", /* 49 */ - "undefined", /* 50 */ - "undefined", /* 51 */ - "undefined", /* 52 */ - "undefined", /* 53 */ - "undefined", /* 54 */ - "undefined", /* 55 */ - "undefined", /* 56 */ - "undefined", /* 57 */ - "undefined", /* 58 */ - "undefined", /* 59 */ - "undefined", /* 60 */ - "undefined", /* 61 */ - "undefined", /* 62 */ - "undefined", /* 63 */ - "notification message in mess. queue", /* 64 SIGDGNOTIFY */ - 0 -}; - -#endif /* DGUX */ - /* Directory routines for systems that don't have them. */ #ifdef SYSV_SYSTEM_DIR @@ -3535,7 +3488,7 @@ closedir (dirp) { int rtnval; - rtnval = sys_close (dirp->dd_fd); + rtnval = emacs_close (dirp->dd_fd); /* Some systems (like Solaris) allocate the buffer and the DIR all in one block. Why in the world are we freeing this ourselves @@ -3560,16 +3513,16 @@ opendir (filename) register int fd; /* file descriptor for read */ struct stat sbuf; /* result of fstat */ - fd = sys_open (filename, 0); + fd = emacs_open (filename, O_RDONLY, 0); if (fd < 0) return 0; BLOCK_INPUT; if (fstat (fd, &sbuf) < 0 || (sbuf.st_mode & S_IFMT) != S_IFDIR - || (dirp = (DIR *) malloc (sizeof (DIR))) == 0) + || (dirp = (DIR *) xmalloc (sizeof (DIR))) == 0) { - sys_close (fd); + emacs_close (fd); UNBLOCK_INPUT; return 0; /* bad luck today */ } @@ -3585,7 +3538,7 @@ void closedir (dirp) register DIR *dirp; /* stream from opendir */ { - sys_close (dirp->dd_fd); + emacs_close (dirp->dd_fd); xfree ((char *) dirp); } @@ -3619,7 +3572,7 @@ readdir (dirp) dirp->dd_loc = dirp->dd_size = 0; if (dirp->dd_size == 0 /* refill buffer */ - && (dirp->dd_size = sys_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0) + && (dirp->dd_size = emacs_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0) return 0; #ifndef VMS @@ -3697,7 +3650,7 @@ readdirver (dirp) int set_file_times (filename, atime, mtime) - char *filename; + const char *filename; EMACS_TIME atime, mtime; { #ifdef HAVE_UTIMES @@ -3772,7 +3725,7 @@ mkdir (dpath, dmode) */ status = umask (0); /* Get current umask */ status = umask (status | (0777 & ~dmode)); /* Set for mkdir */ - fd = sys_open ("/dev/null", 2); + fd = emacs_open ("/dev/null", O_RDWR, 0); if (fd >= 0) { dup2 (fd, 0); @@ -3818,7 +3771,7 @@ rmdir (dpath) return (-1); /* Errno is set already */ case 0: /* Child process */ - fd = sys_open ("/dev/null", 2); + fd = emacs_open ("/dev/null", O_RDWR, 0); if (fd >= 0) { dup2 (fd, 0); @@ -4237,6 +4190,7 @@ sys_getuid () return (getgid () << 16) | getuid (); } +#undef read int sys_read (fildes, buf, nbyte) int fildes; @@ -4276,6 +4230,7 @@ sys_write (fildes, buf, nbyte) * Thus we do this stupidity below. */ +#undef write int sys_write (fildes, buf, nbytes) int fildes; @@ -5319,1569 +5274,25 @@ bcmp (b1, b2, length) /* This could be a macro! */ } #endif /* no bcmp */ #endif /* not BSTRING */ - -/* All the Macintosh stuffs go here */ - -#ifdef macintosh - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* Convert a Mac pathname to Unix form. A Mac full pathname is one - that does not begin with a ':' and contains at least one ':'. A Mac - full pathname causes an '/' to be prepended to the Unix pathname. - The algorithm for the rest of the pathname is as follows: - For each segment between two ':', - if it is non-null, copy as is and then add a '/' at the end, - otherwise, insert a "../" into the Unix pathname. - Returns 1 if successful; 0 if fails. */ - -int -Mac2UnixPathname (const char *mfn, char *ufn, int ufnbuflen) + +#ifndef HAVE_STRSIGNAL +char * +strsignal (code) + int code; { - const char *p, *q, *pe; - - strcpy (ufn, ""); - - if (*mfn == '\0') - return 1; - - p = strchr (mfn, ':'); - if (p != 0 && p != mfn) /* full pathname */ - strcat (ufn, "/"); - - p = mfn; - if (*p == ':') - p++; - - pe = mfn + strlen (mfn); - while (p < pe) + char *signame = 0; + + if (0 <= code && code < NSIG) { - q = strchr (p, ':'); - if (q) - { - if (q == p) - { /* two consecutive ':' */ - if (strlen (ufn) + 3 >= ufnbuflen) - return 0; - strcat (ufn, "../"); - } - else - { - if (strlen (ufn) + (q - p) + 1 >= ufnbuflen) - return 0; - strncat (ufn, p, q - p); - strcat (ufn, "/"); - } - p = q + 1; - } - else - { - if (strlen (ufn) + (pe - p) >= ufnbuflen) - return 0; - strncat (ufn, p, pe - p); /* no separator for last one */ - p = pe; - } - } - - return 1; -} - -extern char *GetTempDirName (); - -/* Convert a Unix pathname to Mac form. Approximately reverse of the - above in algorithm. */ -int -Unix2MacPathname (const char *ufn, char *mfn, int mfnbuflen) -{ - const char *p, *q, *pe; - char expandedPathname[MAXPATHLEN+1]; - - strcpy (mfn, ""); - - if (*ufn == '\0') - return 1; - - p = ufn; - - /* Check for and handle volume names. Last comparison: strangely - somewhere `/.emacs' is passed. A temporary fix for now. */ - if (*p == '/' && strchr (p+1, '/') == NULL && strcmp (p, "/.emacs") != 0) - { - if (strlen (p) + 1 > mfnbuflen) - return 0; - strcpy (mfn, p+1); - strcat (mfn, ":"); - return 1; - } - - if (strncmp (p, "~emacs/", 7) == 0) - { /* expand to emacs dir found by InitEmacsPasswdDir */ - struct passwd *pw = getpwnam ("emacs"); - p += 7; - if (strlen (pw->pw_dir) + strlen (p) > MAXPATHLEN) - return 0; - strcpy (expandedPathname, pw->pw_dir); - strcat (expandedPathname, p); - p = expandedPathname; - /* Now p points to the pathname with emacs dir prefix. */ - } - else if (strncmp (p, "/tmp/", 5) == 0) - { - char *t = GetTempDirName (); - p += 5; - if (strlen (t) + strlen (p) > MAXPATHLEN) - return 0; - strcpy (expandedPathname, t); - strcat (expandedPathname, p); - p = expandedPathname; - /* Now p points to the pathname with emacs dir prefix. */ - } - else if (*p != '/') /* relative pathname */ - strcat (mfn, ":"); - - if (*p == '/') - p++; - - pe = p + strlen (p); - while (p < pe) - { - q = strchr (p, '/'); - if (q) - { - if (q - p == 2 && *p == '.' && *(p+1) == '.') - { - if (strlen (mfn) + 1 >= mfnbuflen) - return 0; - strcat (mfn, ":"); - } - else - { - if (strlen (mfn) + (q - p) + 1 >= mfnbuflen) - return 0; - strncat (mfn, p, q - p); - strcat (mfn, ":"); - } - p = q + 1; - } - else - { - if (strlen (mfn) + (pe - p) >= mfnbuflen) - return 0; - strncat (mfn, p, pe - p); - p = pe; - } - } - - return 1; -} - -/* The following functions with "sys_" prefix are stubs to Unix - functions that have already been implemented by CW or MPW. The - calls to them in Emacs source course are #define'd to call the sys_ - versions by the header files s-mac.h. In these stubs pathnames are - converted between their Unix and Mac forms. */ -/* Unix Epoch is Jan 1, 1970 while Mac Epoch is Jan 1, 1904: 66 years - + 17 leap days */ -#define MAC_UNIX_EPOCH_DIFF ((365L * 66 + 17) * 24 * 60 * 60) - -/* CW Epoch is Jan 1, 1900 (aaarghhhhh!); remember, 1900 is not a leap - year! */ -#define CW_UNIX_EPOCH_DIFF ((365L * 70 + 17) * 24 * 60 * 60) - -/* Define our own stat function for both MrC and CW. The reason for - doing this: "stat" is both the name of a struct and function name: - can't use the same trick like that for sys_open, sys_close, etc. to - redirect Emacs's calls to our own version that converts Unix style - filenames to Mac style filename because all sorts of compilation - errors will be generated if stat is #define'd to be sys_stat. */ - -int -stat (const char *path, struct stat *buf) -{ - char MacPathname[MAXPATHLEN+1]; - CInfoPBRec cipb; - - if (Unix2MacPathname (path, MacPathname, MAXPATHLEN+1) == 0) - return -1; - - c2pstr (MacPathname); - cipb.hFileInfo.ioNamePtr = MacPathname; - cipb.hFileInfo.ioVRefNum = 0; - cipb.hFileInfo.ioDirID = 0; - cipb.hFileInfo.ioFDirIndex = 0; /* set to 0 to get information about specific dir or file */ - - errno = PBGetCatInfo (&cipb, false); - if (errno == -43) /* -43: fnfErr defined in Errors.h */ - errno = ENOENT; - if (errno != noErr) - return -1; - - if (cipb.hFileInfo.ioFlAttrib & 0x10) - { /* bit 4 = 1 for directories */ - buf->st_mode = S_IFDIR | S_IREAD | S_IEXEC; - if (!(cipb.hFileInfo.ioFlAttrib & 0x1)) /* bit 1 = 1 for locked files/directories */ - buf->st_mode |= S_IWRITE; - buf->st_ino = cipb.dirInfo.ioDrDirID; - buf->st_dev = cipb.dirInfo.ioVRefNum; - buf->st_size = cipb.dirInfo.ioDrNmFls; /* size of dir = number of files and dirs */ - buf->st_atime = buf->st_mtime = cipb.dirInfo.ioDrMdDat - MAC_UNIX_EPOCH_DIFF; - buf->st_ctime = cipb.dirInfo.ioDrCrDat - MAC_UNIX_EPOCH_DIFF; - } - else - { - buf->st_mode = S_IFREG | S_IREAD; - if (!(cipb.hFileInfo.ioFlAttrib & 0x1)) /* bit 1 = 1 for locked files/directories */ - buf->st_mode |= S_IWRITE; - if (cipb.hFileInfo.ioFlFndrInfo.fdType == 'APPL') - buf->st_mode |= S_IEXEC; - buf->st_ino = cipb.hFileInfo.ioDirID; - buf->st_dev = cipb.hFileInfo.ioVRefNum; - buf->st_size = cipb.hFileInfo.ioFlLgLen; - buf->st_atime = buf->st_mtime = cipb.hFileInfo.ioFlMdDat - MAC_UNIX_EPOCH_DIFF; - buf->st_ctime = cipb.hFileInfo.ioFlCrDat - MAC_UNIX_EPOCH_DIFF; - } - buf->st_nlink = 1; - buf->st_uid = getuid (); - buf->st_gid = getgid (); - buf->st_rdev = 0; - - return 0; -} - -#if __MRC__ - -/* CW defines fstat in stat.mac.c while MPW does not provide this - function. Without the information of how to get from a file - descriptor in MPW StdCLib to a Mac OS file spec, it should be hard - to implement this function. Fortunately, there is only one place - where this function is called in our configuration: in fileio.c, - where only the st_dev and st_ino fields are used to determine - whether two fildes point to different i-nodes to prevent copying - a file onto itself equal. What we have here probably needs - improvement. */ -int -fstat (int fildes, struct stat *buf) -{ - buf->st_dev = 0; - buf->st_ino = fildes; - return 0; /* success */ -} - -#endif /* __MRC__ */ - -/* From Think Reference code example */ -int -mkdir (const char *dirname, int mode) -{ -#pragma unused (mode) - - HFileParam hfpb; - char MacPathname[MAXPATHLEN+1]; - - if (Unix2MacPathname (dirname, MacPathname, MAXPATHLEN+1) == 0) - return -1; - - c2pstr (MacPathname); - hfpb.ioNamePtr = MacPathname; - hfpb.ioVRefNum = 0; /*ignored unless name is invalid */ - hfpb.ioDirID = 0; /*parent is the root */ - - /* Just return the Mac OSErr code for now. */ - errno = PBDirCreate ((HParmBlkPtr) &hfpb, false); - return errno == noErr ? 0 : -1; -} - -int -rmdir (const char *dirname) -{ - HFileParam hfpb; - char MacPathname[MAXPATHLEN+1]; - - if (Unix2MacPathname (dirname, MacPathname, MAXPATHLEN+1) == 0) - return -1; - - c2pstr (MacPathname); - hfpb.ioNamePtr = MacPathname; - hfpb.ioVRefNum = 0; /*ignored unless name is invalid */ - hfpb.ioDirID = 0; /*parent is the root */ - - errno = PBHDelete ((HParmBlkPtr) &hfpb, false); - return errno == noErr ? 0 : -1; -} - -#ifdef __MRC__ - -/* No implementation yet. */ -int -execvp (const char *path, ...) -{ - return -1; -} - -#endif /* __MRC__ */ - -int -utime (const char *path, const struct utimbuf *times) -{ - char MacPathname[MAXPATHLEN+1]; - CInfoPBRec cipb; - - if (Unix2MacPathname (path, MacPathname, MAXPATHLEN+1) == 0) - return -1; - - c2pstr (MacPathname); - cipb.hFileInfo.ioNamePtr = MacPathname; - cipb.hFileInfo.ioVRefNum = 0; - cipb.hFileInfo.ioDirID = 0; - /* Set to 0 to get information about specific dir or file. */ - cipb.hFileInfo.ioFDirIndex = 0; - - errno = PBGetCatInfo (&cipb, false); - if (errno != noErr) - return -1; - - if (cipb.hFileInfo.ioFlAttrib & 0x10) - { /* bit 4 = 1 for directories */ - if (times) - cipb.dirInfo.ioDrMdDat = times->modtime + MAC_UNIX_EPOCH_DIFF; - else - GetDateTime (&cipb.dirInfo.ioDrMdDat); - } - else - { - if (times) - cipb.hFileInfo.ioFlMdDat = times->modtime + MAC_UNIX_EPOCH_DIFF; - else - GetDateTime (&cipb.hFileInfo.ioFlMdDat); - } - - errno = PBSetCatInfo (&cipb, false); - return errno == noErr ? 0 : -1; -} - -#define F_OK 0 -#define X_OK 1 -#define W_OK 2 - -/* Like stat, but test for access mode in hfpb.ioFlAttrib. */ -int -access (const char *path, int mode) -{ - char MacPathname[MAXPATHLEN+1]; - CInfoPBRec cipb; - - if (Unix2MacPathname (path, MacPathname, MAXPATHLEN+1) == 0) - return -1; - - c2pstr (MacPathname); - cipb.hFileInfo.ioNamePtr = MacPathname; - cipb.hFileInfo.ioVRefNum = 0; - cipb.hFileInfo.ioDirID = 0; - cipb.hFileInfo.ioFDirIndex = 0; /* set to 0 to get information about specific dir or file */ - - errno = PBGetCatInfo (&cipb, false); - if (errno != noErr) - return -1; - - if (mode == F_OK) /* got this far, file exists */ - return 0; - - if (mode & X_OK) - if (cipb.hFileInfo.ioFlAttrib & 0x10) /* path refers to a directory */ - return 0; - else - { - if (cipb.hFileInfo.ioFlFndrInfo.fdType == 'APPL') - return 0; - else - return -1; - } - - if (mode & W_OK) - return (cipb.hFileInfo.ioFlAttrib & 0x1) ? -1 : 0; /* don't allow if lock bit on */ - - return -1; -} - -#define DEV_NULL_FD 0x10000 - -#undef open -int -sys_open (const char *path, int oflag) -{ - char MacPathname[MAXPATHLEN+1]; - - if (strcmp (path, "/dev/null") == 0) - return DEV_NULL_FD; /* some bogus fd to be ignored in write */ - - if (Unix2MacPathname (path, MacPathname, MAXPATHLEN+1) == 0) - return -1; - else - return open (MacPathname, oflag); -} - -#undef creat -int -sys_creat (const char *path, mode_t mode) -{ - char MacPathname[MAXPATHLEN+1]; - - if (Unix2MacPathname (path, MacPathname, MAXPATHLEN+1) == 0) - return -1; - else - return creat (MacPathname, mode); -} - -#undef unlink -int -sys_unlink (const char *path) -{ - char MacPathname[MAXPATHLEN+1]; - - if (Unix2MacPathname (path, MacPathname, MAXPATHLEN+1) == 0) - return -1; - else - return unlink (MacPathname); -} - -#undef read -int -sys_read (int fildes, char *buf, int count) -{ - if (fildes == 0) - { /* if stdin, call (non-echoing) "getch" in console.h */ - if (MacKeyPending ()) - { /* don't wait for a key if none has been pressed */ - *buf = MacGetChar (); - return 1; - } - else - return 0; - } - else - return read (fildes, buf, count); -} - -#undef write -int -sys_write (int fildes, char *buf, int count) -{ - if (fildes == DEV_NULL_FD) - return count; - else - return write (fildes, buf, count); -} - -#undef rename -int -sys_rename (const char * old_name, const char * new_name) -{ - char MacOldName[MAXPATHLEN+1], MacNewName[MAXPATHLEN+1]; - - if (strcmp (old_name, new_name) == 0) - return 0; - - if (Unix2MacPathname (old_name, MacOldName, MAXPATHLEN+1) == 0) - return 1; - - if (Unix2MacPathname (new_name, MacNewName, MAXPATHLEN+1) == 0) - return 1; - - return rename (MacOldName, MacNewName); -} - -#undef fopen -extern FILE *fopen (const char *name, const char *mode); -FILE -sys_fopen (const char *name, const char *mode) -{ - char MacPathname[MAXPATHLEN+1]; - - if (Unix2MacPathname (name, MacPathname, MAXPATHLEN+1) == 0) - return 0; - else - return fopen (MacPathname, mode); -} - -#include - -long targetTicks = 0; - -#ifdef __MRC__ -__sigfun alarm_signal_func = (__sigfun) 0; -#elif __MWERKS__ -__signal_func_ptr alarm_signal_func = (__signal_func_ptr) 0; -#else -You lose!!! -#endif - -/* These functions simulate SIG_ALRM. The stub for function signal - stores the signal handler function in alarm_signal_func if a - SIG_ALRM is encountered. CheckAlarm is called in mac_read_socket, - which emacs calls periodically. A pending alarm is represented by - a non-zero targetTicks value. CheckAlarm calls the handler - function pointed to by alarm_signal_func if one has been set up and - an alarm is pending. */ -void -CheckAlarm () -{ - if (targetTicks && TickCount () > targetTicks) - { - targetTicks = 0; - if (alarm_signal_func) - (*alarm_signal_func)(SIGALRM); - } -} - -/* Called in sys_select to wait for an alarm signal to arrive. */ -int -pause () -{ - unsigned long finalTick; - - if (!targetTicks) /* no alarm pending */ - return -1; - - while (TickCount () <= targetTicks) - Delay (1UL, &finalTick); /* wait for 1/60 second before trying again */ - - targetTicks = 0; - if (alarm_signal_func) - (*alarm_signal_func)(SIGALRM); - - return 0; -} - -int -alarm (int seconds) -{ - long remaining = targetTicks ? (TickCount () - targetTicks) / 60 : 0; - - targetTicks = seconds ? TickCount () + 60 * seconds : 0; - - return (remaining < 0) ? 0 : (unsigned int) remaining; -} - -#undef signal -#ifdef __MRC__ -extern __sigfun signal (int signal, __sigfun signal_func); -__sigfun -sys_signal (int signal_num, __sigfun signal_func) -#elif __MWERKS__ -extern __signal_func_ptr signal (int signal, __signal_func_ptr signal_func); -__signal_func_ptr -sys_signal (int signal_num, __signal_func_ptr signal_func) -#else - You lose!!! -#endif -{ - if (signal_num != SIGALRM) - return signal (signal_num, signal_func); - else - { -#ifdef __MRC__ - __sigfun old_signal_func; -#elif __MWERKS__ - __signal_func_ptr old_signal_func; -#else - You lose!!! -#endif - old_signal_func = alarm_signal_func; - alarm_signal_func = signal_func; - return old_signal_func; - } -} - -/* The time functions adjust time values according to the difference - between the Unix and CW epoches. */ - -#undef gmtime -extern struct tm *gmtime (const time_t *); -struct tm -sys_gmtime (const time_t *timer) -{ - time_t unixTime = *timer + CW_UNIX_EPOCH_DIFF; - - return gmtime (&unixTime); -} - -#undef localtime -extern struct tm *localtime (const time_t *); -struct tm * -sys_localtime (const time_t *timer) -{ - time_t unixTime = *timer + CW_UNIX_EPOCH_DIFF; - - return localtime (&unixTime); -} - -#undef ctime -extern char *ctime (const time_t *); -char * -sys_ctime (const time_t *timer) -{ - time_t unixTime = *timer + CW_UNIX_EPOCH_DIFF; - - return ctime (&unixTime); -} - -#undef time -extern time_t time (time_t *); -time_t -sys_time (time_t *timer) -{ - time_t macTime = time (NULL) - CW_UNIX_EPOCH_DIFF; - - if (timer) - *timer = macTime; - - return macTime; -} - -/* no subprocesses, empty wait */ -int -wait (int pid) -{ - return 0; -} - -void -croak (char *badfunc) -{ - printf ("%s not yet implemented\r\n", badfunc); - exit (1); -} - -char * -index (const char * str, int chr) -{ - return strchr (str, chr); -} - -char *e[] = { 0 }; -char **environ = &e[0]; - -char * -mktemp (char *template) -{ - int len, k; - static seqnum = 0; - - len = strlen (template); - k = len - 1; - while (k >= 0 && template[k] == 'X') - k--; - - k++; /* make k index of first 'X' */ - - if (k < len) - { - /* Zero filled, number of digits equal to the number of X's. */ - sprintf (&template[k], "%0*d", len-k, seqnum++); - - return template; - } - else - return 0; -} - -/* Emulate getpwuid, getpwnam and others. */ - -#define PASSWD_FIELD_SIZE 256 - -static char myPasswdName[PASSWD_FIELD_SIZE]; -static char myPasswdDir[MAXPATHLEN+1]; - -static struct passwd myPasswd = -{ - myPasswdName, - myPasswdDir, -}; - -/* Initialized by main () in macterm.c to pathname of emacs directory. */ -char emacsPasswdDir[MAXPATHLEN+1]; - -void -InitEmacsPasswdDir () -{ - int found = false; - - if (getwd (emacsPasswdDir) && getwd (myPasswdDir)) - { - /* Need pathname of first ancestor that begins with `emacs' since - Mac emacs application is somewhere in the emacs-20.3 tree. */ - int len = strlen (emacsPasswdDir); - /* J points to the "/" following the directory name being compared. */ - int j = len - 1; - int i = j - 1; - while (i >= 0 && !found) - { - while (i >= 0 && emacsPasswdDir[i] != '/') - i--; - if (emacsPasswdDir[i] == '/' && i+5 < len) - found = (strncmp (&(emacsPasswdDir[i+1]), "emacs", 5) == 0); - if (found) - emacsPasswdDir[j+1] = '\0'; - else - { - j = i; - i = j - 1; - } - } - } - - if (!found) - { /* setting to "/" probably won't work, - but set it to something anyway. */ - strcpy (emacsPasswdDir, "/"); - strcpy (myPasswdDir, "/"); - } -} - -static struct passwd emacsPasswd = -{ - "emacs", - emacsPasswdDir, -}; - -static int myPasswdInited = 0; - -static void -InitMyPasswd () -{ - char **ownerName; - - /* Note: myPasswdDir initialized in InitEmacsPasswdDir to directory - where Emacs was started. */ - - ownerName = (char **) GetResource ('STR ',-16096); - if (ownerName) - { - HLock (ownerName); - BlockMove ((unsigned char *) *ownerName, - (unsigned char *) myPasswdName, *ownerName[0] + 1); - HUnlock (ownerName); - p2cstr ((unsigned char *) myPasswdName); - } - else - myPasswdName[0] = 0; -} - -struct passwd * -getpwuid (uid_t uid) -{ - if (!myPasswdInited) - { - InitMyPasswd (); - myPasswdInited = 1; - } - - return &myPasswd; -} - -struct passwd * -getpwnam (const char *name) -{ - if (strcmp (name, "emacs") == 0) - return &emacsPasswd; - - if (!myPasswdInited) - { - InitMyPasswd (); - myPasswdInited = 1; - } - - return &myPasswd; -} - -/* The functions fork, kill, sigsetmask, sigblock, request_sigio, - setpgrp, setpriority, and unrequest_sigio are defined to be empty - as in msdos.c. */ - -int -fork () -{ - return -1; -} - -int -kill (int x, int y) -{ - return -1; -} - -int -sigsetmask (int x) -{ - return 0; -} - -int -sigblock (int mask) -{ - return 0; -} - -void -request_sigio (void) -{ -} - -int -setpgrp () -{ - return 0; -} - -void -unrequest_sigio (void) -{ -} - -/* djgpp does not implement pipe either. */ -int -pipe (int _fildes[2]) -{ - errno = EACCES; - return -1; -} - -/* Hard and symbolic links. */ -int -symlink (const char *name1, const char *name2) -{ - errno = ENOENT; - return -1; -} - -int -link (const char *name1, const char *name2) -{ - errno = ENOENT; - return -1; -} - -int -lstat (const char *path, struct stat *sb) -{ - return stat (path, sb); -} - -int -readlink (const char *path, char *buf, int bufsiz) -{ - errno = ENOENT; - return -1; -} - -mode_t -umask (mode_t numask) -{ - static mode_t mask = 022; - mode_t oldmask = mask; - mask = numask; - return oldmask; -} - -int -chmod (const char *path, mode_t mode) -{ - /* say it always succeed for now */ - return 0; -} - -int -dup (int oldd) -{ -#ifdef __MRC__ - return fcntl (oldd, F_DUPFD, 0); -#elif __MWERKS__ - /* current implementation of fcntl in fcntl.mac.c simply returns old - descriptor */ - return fcntl (oldd, F_DUPFD); -#else -You lose!!! -#endif -} - -/* This is from the original sysdep.c. Emulate BSD dup2. First close - newd if it already exists. Then, attempt to dup oldd. If not - successful, call dup2 recursively until we are, then close the - unsuccessful ones. */ -int -dup2 (int oldd, int newd) -{ - int fd, ret; - - close (newd); - - fd = dup (oldd); - if (fd == -1) - return -1; - if (fd == newd) - return newd; - ret = dup2 (oldd, newd); - close (fd); - return ret; -} - -/* let it fail for now */ -char * -sbrk (int incr) -{ - return (char *) -1; -} - -int -fsync (int fd) -{ - return 0; -} - -int -ioctl (int d, int request, void *argp) -{ - return -1; -} - -#ifdef __MRC__ -int -isatty (int fildes) -{ - if (fildes >=0 && fildes <= 2) - return 1; - else - return 0; -} - -int -getgid () -{ - return 100; -} - -int -getegid () -{ - return 100; -} - -int -getuid () -{ - return 200; -} - -int -geteuid () -{ - return 200; -} - -unsigned int -sleep (unsigned int seconds) -{ - unsigned long finalTick; - - Delay (seconds * 60UL, &finalTick); - return (0); -} -#endif /* __MRC__ */ - -#ifdef __MWERKS__ -#undef getpid -int -getpid () -{ - return 9999; -} -#endif /* __MWERKS__ */ - -/* Return the path to the directory in which Emacs can create - temporary files. The MacOS "temporary items" directory cannot be - used because it removes the file written by a process when it - exits. In that sense it's more like "/dev/null" than "/tmp" (but - again not exactly). And of course Emacs needs to read back the - files written by its subprocesses. So here we write the files to a - directory "Emacs" in the Preferences Folder. This directory is - created if it does not exist. */ -static char * -GetTempDirName () -{ - static char *TempDirName = NULL; - short vRefNum; - long dirID; - OSErr err; - Str255 dirName, fullPath; - CInfoPBRec cpb; - char unixDirName[MAXPATHLEN+1]; - DIR *dir; - - /* Cache directory name with pointer TempDirName. - Look for it only the first time. */ - if (!TempDirName) - { - err = FindFolder (kOnSystemDisk, kPreferencesFolderType, - kCreateFolder, &vRefNum, &dirID); - if (err != noErr) - return NULL; - - *fullPath = '\0'; - cpb.dirInfo.ioNamePtr = dirName; - cpb.dirInfo.ioDrParID = dirID; - - /* Standard ref num to full path name loop */ - do { - cpb.dirInfo.ioVRefNum = vRefNum; - cpb.dirInfo.ioFDirIndex = -1; - cpb.dirInfo.ioDrDirID = cpb.dirInfo.ioDrParID; - - err = PBGetCatInfo (&cpb, false); - - p2cstr (dirName); - strcat (dirName, ":"); - if (strlen (fullPath) + strlen (dirName) <= MAXPATHLEN) - { - strcat (dirName, fullPath); - strcpy (fullPath, dirName); - } - else - return NULL; - } - while (cpb.dirInfo.ioDrDirID != fsRtDirID && err == noErr); - - if (strlen (fullPath) + 6 <= MAXPATHLEN) - strcat (fullPath, "Emacs:"); - else - return NULL; - - if (Mac2UnixPathname (fullPath, unixDirName, MAXPATHLEN+1) == 0) - return NULL; - - dir = opendir (unixDirName); /* check whether temp directory exists */ - if (dir) - closedir (dir); - else if (mkdir (unixDirName, 0700) != 0) /* create it if not */ - return NULL; - - TempDirName = (char *) malloc (strlen (unixDirName) + 1); - strcpy (TempDirName, unixDirName); - } - - return TempDirName; -} - -char * -getenv (const char * name) -{ - if (strcmp (name, "TERM") == 0) - return "vt100"; - else if (strcmp (name, "TERMCAP") == 0) - /* for debugging purpose when code was still outputting to dumb terminal */ - return "d0|vt100|vt100-am|vt100am|dec vt100:do=[do]:co#100:li#32:cl=[cl]:sf=[sf]:km:\ -:le=[le]:bs:am:cm=[cm-%d,%d]:nd=[nd]:up=[up]:ce=[ce]:cd=[cd]:so=[so]:se=[se]:\ -:us=[us]:ue=[ue]:md=[md]:mr=[mr]:mb=[mb]:me=[me]:is=[is]:\ -:rf=/usr/share/lib/tabset/vt100:rs=[rs]:ks=[ks]:ke=[ke]:\ -:ku=\\036:kd=\\037:kr=\\035:kl=\\034:kb=[kb]:ho=[ho]:k1=[k1]:k2=[k2]:k3=[k3]:k4=[k4]:\ -:pt:sr=[sr]:vt#3:xn:sc=[sc]:rc=[rc]:cs=[cs-%d,%d]"; - else if (strcmp (name, "TMPDIR") == 0) - return GetTempDirName (); - else - return (NULL); -} - -#ifdef __MRC__ -/* see Interfaces&Libraries:Interfaces:CIncludes:signal.h */ -char *sys_siglist[] = -{ - "Zero is not a signal!!!", - "Abort", /* 1 */ - "Interactive user interrupt", /* 2 */ "BAD", - "Floating point exception", /* 4 */ "BAD", "BAD", "BAD", - "Illegal instruction", /* 8 */ "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", - "Segment violation", /* 16 */ "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", "BAD", - "Terminal" /* 32 */ -}; -#elif __MWERKS__ -char *sys_siglist[] = -{ - "Zero is not a signal!!!", - "Abort", - "Floating point exception", - "Illegal instruction", - "Interactive user interrupt", - "Segment violation", - "Terminal" -}; +#ifdef VMS + signame = sys_errlist[code]; #else -You lose!!! -#endif - -#ifdef __MRC__ -#include - -int -uname (struct utsname *name) -{ - char **systemName; - systemName = GetString (-16413); /* IM - Resource Manager Reference */ - if (systemName) - { - BlockMove (*systemName, name->nodename, (*systemName)[0]+1); - p2cstr (name->nodename); - } - else - return -1; -} -#endif - -#include -#include - -/* Event class of HLE sent to subprocess. */ -const OSType kEmacsSubprocessSend = 'ESND'; -/* Event class of HLE sent back from subprocess. */ -const OSType kEmacsSubprocessReply = 'ERPY'; - -char * -mystrchr (char *s, char c) -{ - while (*s && *s != c) - { - if (*s == '\\') - s++; - s++; - } - - if (*s) - { - *s = '\0'; - return s; - } - else - return NULL; -} - -char * -mystrtok (char *s) -{ - while (*s) - s++; - - return s + 1; -} - -void -mystrcpy (char *to, char *from) -{ - while (*from) - { - if (*from == '\\') - from++; - *to++ = *from++; - } - *to = '\0'; -} - -/* Start a Mac subprocess. Arguments for it is passed in argv (null - terminated). The process should run with the default directory - "workdir", read input from "infn", and write output and error to - "outfn" and "errfn", resp. The Process Manager call - LaunchApplication is used to start the subprocess. We use high - level events as the mechanism to pass arguments to the subprocess - and to make Emacs wait for the subprocess to terminate and pass - back a result code. The bulk of the code here packs the arguments - into one message to be passed together with the high level event. - Emacs also sometimes starts a subprocess using a shell to perform - wildcard filename expansion. Since we don't really have a shell on - the Mac, this case is detected and the starting of the shell is - by-passed. We really need to add code here to do filename - expansion to support such functionality. */ -int -run_mac_command (argv, workdir, infn, outfn, errfn) - unsigned char **argv; - const char *workdir; - const char *infn, *outfn, errfn; -{ - char macappname[MAXPATHLEN+1], macworkdir[MAXPATHLEN+1]; - char macinfn[MAXPATHLEN+1], macoutfn[MAXPATHLEN+1], macerrfn[MAXPATHLEN+1]; - int paramlen, argc, newargc, j, retries; - char **newargv, *param, *p; - OSErr iErr; - FSSpec spec; - LaunchParamBlockRec lpbr; - EventRecord sendEvent, replyEvent; - RgnHandle cursorRegionHdl; - TargetID targ; - unsigned long refCon, len; - - if (Unix2MacPathname (workdir, macworkdir, MAXPATHLEN+1) == 0) - return -1; - if (Unix2MacPathname (infn, macinfn, MAXPATHLEN+1) == 0) - return -1; - if (Unix2MacPathname (outfn, macoutfn, MAXPATHLEN+1) == 0) - return -1; - if (Unix2MacPathname (errfn, macerrfn, MAXPATHLEN+1) == 0) - return -1; - - paramlen = strlen (macworkdir) + strlen (macinfn) + strlen (macoutfn) + strlen (macerrfn) + 4; - /* count nulls at end of strings */ - - argc = 0; - while (argv[argc]) - argc++; - - if (argc == 0) - return -1; - - /* If a subprocess is invoked with a shell, we receive 3 arguments of the form: - "/sh" "-c" "/ " */ - j = strlen (argv[0]); - if (j >= 3 && strcmp (argv[0]+j-3, "/sh") == 0 && argc == 3 && strcmp (argv[1], "-c") == 0) - { - char *command, *t, tempmacpathname[MAXPATHLEN+1]; - - /* The arguments for the command in argv[2] are separated by spaces. Count them and put - the count in newargc. */ - command = (char *) alloca (strlen (argv[2])+2); - strcpy (command, argv[2]); - if (command[strlen (command) - 1] != ' ') - strcat (command, " "); - - t = command; - newargc = 0; - t = mystrchr (t, ' '); - while (t) - { - newargc++; - t = mystrchr (t+1, ' '); - } - - newargv = (char **) alloca (sizeof (char *) * newargc); - - t = command; - for (j = 0; j < newargc; j++) - { - newargv[j] = (char *) alloca (strlen (t) + 1); - mystrcpy (newargv[j], t); - - t = mystrtok (t); - paramlen += strlen (newargv[j]) + 1; - } - - if (strncmp (newargv[0], "~emacs/", 7) == 0) - { - if (Unix2MacPathname (newargv[0], tempmacpathname, MAXPATHLEN+1) == 0) - return -1; - } - else - { /* sometimes Emacs call "sh" without a path for the command */ -#if 0 - char *t = (char *) alloca (strlen (newargv[0]) + 7 + 1); - strcpy (t, "~emacs/"); - strcat (t, newargv[0]); + /* Cast to suppress warning if the table has const char *. */ + signame = (char *) sys_siglist[code]; #endif - Lisp_Object path; - openp (Vexec_path, build_string (newargv[0]), EXEC_SUFFIXES, &path, 1); - - if (NILP (path)) - return -1; - if (Unix2MacPathname (XSTRING (path)->data, tempmacpathname, MAXPATHLEN+1) == 0) - return -1; - } - strcpy (macappname, tempmacpathname); - } - else - { - if (Unix2MacPathname (argv[0], macappname, MAXPATHLEN+1) == 0) - return -1; - - newargv = (char **) alloca (sizeof (char *) * argc); - newargc = argc; - for (j = 1; j < argc; j++) - { - if (strncmp (argv[j], "~emacs/", 7) == 0) - { - char *t = strchr (argv[j], ' '); - if (t) - { - char tempcmdname[MAXPATHLEN+1], tempmaccmdname[MAXPATHLEN+1]; - strncpy (tempcmdname, argv[j], t-argv[j]); - tempcmdname[t-argv[j]] = '\0'; - if (Unix2MacPathname (tempcmdname, tempmaccmdname, MAXPATHLEN+1) == 0) - return -1; - newargv[j] = (char *) alloca (strlen (tempmaccmdname) + strlen (t) + 1); - strcpy (newargv[j], tempmaccmdname); - strcat (newargv[j], t); - } - else - { - char tempmaccmdname[MAXPATHLEN+1]; - if (Unix2MacPathname (argv[j], tempmaccmdname, MAXPATHLEN+1) == 0) - return -1; - newargv[j] = (char *) alloca (strlen (tempmaccmdname)+1); - strcpy (newargv[j], tempmaccmdname); - } - } - else - newargv[j] = argv[j]; - paramlen += strlen (newargv[j]) + 1; - } - } - - /* After expanding all the arguments, we now know the length of the parameter block to be - sent to the subprocess as a message attached to the HLE. */ - param = (char *) malloc (paramlen + 1); - if (!param) - return -1; - - p = param; - *p++ = newargc; /* first byte of message contains number of arguments for command */ - strcpy (p, macworkdir); - p += strlen (macworkdir); - *p++ = '\0'; /* null terminate strings sent so it's possible to use strcpy over there */ - strcpy (p, macinfn); - p += strlen (macinfn); - *p++ = '\0'; - strcpy (p, macoutfn); - p += strlen (macoutfn); - *p++ = '\0'; - strcpy (p, macerrfn); - p += strlen (macerrfn); - *p++ = '\0'; - for (j = 1; j < newargc; j++) { - strcpy (p, newargv[j]); - p += strlen (newargv[j]); - *p++ = '\0'; - } - - c2pstr (macappname); - - iErr = FSMakeFSSpec (0, 0, macappname, &spec); - - if (iErr != noErr) { - free (param); - return -1; - } - - lpbr.launchBlockID = extendedBlock; - lpbr.launchEPBLength = extendedBlockLen; - lpbr.launchControlFlags = launchContinue + launchNoFileFlags; - lpbr.launchAppSpec = &spec; - lpbr.launchAppParameters = NULL; - - iErr = LaunchApplication (&lpbr); /* call the subprocess */ - if (iErr != noErr) { - free (param); - return -1; - } - - sendEvent.what = kHighLevelEvent; - sendEvent.message = kEmacsSubprocessSend; /* Event ID stored in "where" unused */ - - retries = 3; - do { /* OS may think current subprocess has terminated if previous one terminated recently */ - iErr = PostHighLevelEvent (&sendEvent, &lpbr.launchProcessSN, 0, param, paramlen + 1, receiverIDisPSN); - } - while (iErr == sessClosedErr && retries-- > 0); - - if (iErr != noErr) { - free (param); - return -1; - } - - cursorRegionHdl = NewRgn (); - - /* Wait for the subprocess to finish, when it will send us a ERPY high level event */ - while (1) - if (WaitNextEvent (highLevelEventMask, &replyEvent, 180, cursorRegionHdl) && replyEvent.message == kEmacsSubprocessReply) - break; - - /* The return code is sent through the refCon */ - iErr = AcceptHighLevelEvent (&targ, &refCon, NULL, &len); - if (iErr != noErr) { - DisposeHandle ((Handle) cursorRegionHdl); - free (param); - return -1; - } - - DisposeHandle ((Handle) cursorRegionHdl); - free (param); - - return refCon; -} - -DIR * -opendir (const char *dirname) -{ - char MacPathname[MAXPATHLEN+1]; - DIR *dirp; - CInfoPBRec cipb; - int len; - - dirp = (DIR *) malloc (sizeof (DIR)); - if (!dirp) - return 0; - - /* Handle special case when dirname is "/": sets up for readir to - get all mount volumes. */ - if (strcmp (dirname, "/") == 0) { - dirp->getting_volumes = 1; /* special all mounted volumes DIR struct */ - dirp->current_index = 1; /* index for first volume */ - return dirp; - } - - /* Handle typical cases: not accessing all mounted volumes. */ - if (Unix2MacPathname (dirname, MacPathname, MAXPATHLEN+1) == 0) - return 0; - - /* Emacs calls opendir without the trailing '/', Mac needs trailing ':' */ - len = strlen (MacPathname); - if (MacPathname[len - 1] != ':' && len < MAXPATHLEN) - strcat (MacPathname, ":"); - - c2pstr (MacPathname); - cipb.hFileInfo.ioNamePtr = MacPathname; /* using full pathname so vRefNum and dirID ignored */ - cipb.hFileInfo.ioVRefNum = 0; - cipb.hFileInfo.ioDirID = 0; - cipb.hFileInfo.ioFDirIndex = 0; /* set to 0 to get information about specific dir or file */ - - errno = PBGetCatInfo (&cipb, false); - if (errno != noErr) { - errno = ENOENT; - return 0; - } - - if (!(cipb.hFileInfo.ioFlAttrib & 0x10)) /* bit 4 = 1 for directories */ - return 0; /* not a directory */ - - dirp->dir_id = cipb.dirInfo.ioDrDirID; /* used later in readdir */ - dirp->getting_volumes = 0; - dirp->current_index = 1; /* index for first file/directory */ - - return dirp; -} - -int -closedir (DIR *dp) -{ - free (dp); - - return 0; -} - -struct dirent * -readdir (DIR *dp) -{ - HParamBlockRec HPBlock; - CInfoPBRec cipb; - static struct dirent s_dirent; - static Str255 s_name; - int done; - - /* Handle the root directory containing the mounted volumes. Call - PBHGetVInfo specifying an index to obtain the info for a volume. - PBHGetVInfo returns an error when it receives an index beyond the - last volume, at which time we should return a nil dirent struct - pointer. */ - if (dp->getting_volumes) { - HPBlock.volumeParam.ioNamePtr = s_name; - HPBlock.volumeParam.ioVRefNum = 0; - HPBlock.volumeParam.ioVolIndex = dp->current_index; - - errno = PBHGetVInfo (&HPBlock, false); - if (errno != noErr) { - errno = ENOENT; - return 0; - } - - p2cstr (s_name); - strcat (s_name, "/"); /* need "/" for stat to work correctly */ - - dp->current_index++; - - s_dirent.d_ino = cipb.dirInfo.ioDrDirID; - s_dirent.d_name = s_name; - - return &s_dirent; - } - else { - cipb.hFileInfo.ioVRefNum = 0; - cipb.hFileInfo.ioNamePtr = s_name; /* location to receive filename returned */ - - /* return only visible files */ - done = false; - while (!done) { - cipb.hFileInfo.ioDirID = dp->dir_id; /* directory ID found by opendir */ - cipb.hFileInfo.ioFDirIndex = dp->current_index; - - errno = PBGetCatInfo (&cipb, false); - if (errno != noErr) { - errno = ENOENT; - return 0; - } - - /* insist on an visibile entry */ - if (cipb.hFileInfo.ioFlAttrib & 0x10) /* directory? */ - done = !(cipb.dirInfo.ioDrUsrWds.frFlags & fInvisible); - else - done = !(cipb.hFileInfo.ioFlFndrInfo.fdFlags & fInvisible); - - dp->current_index++; - } - - p2cstr (s_name); - - s_dirent.d_ino = cipb.dirInfo.ioDrDirID; /* value unimportant: non-zero for valid file */ - s_dirent.d_name = s_name; - - return &s_dirent; - } -} - -char * -getwd (char *path) -{ - char MacPathname[MAXPATHLEN+1]; - Str255 directoryName; - OSErr errno; - CInfoPBRec cipb; - - MacPathname[0] = '\0'; - directoryName[0] = '\0'; - cipb.dirInfo.ioDrParID = 0; - cipb.dirInfo.ioNamePtr = directoryName; /* empty string = default directory */ - - do { - cipb.dirInfo.ioVRefNum = 0; - cipb.dirInfo.ioFDirIndex = -1; - cipb.dirInfo.ioDrDirID = cipb.dirInfo.ioDrParID; /* go up to parent each time */ - - errno = PBGetCatInfo (&cipb, false); - if (errno != noErr) { - errno = ENOENT; - return 0; } - p2cstr (directoryName); - strcat (directoryName, ":"); - strcat (directoryName, MacPathname); /* attach to front since going up directory tree */ - strcpy (MacPathname, directoryName); - } while (cipb.dirInfo.ioDrDirID != fsRtDirID); /* until volume's root directory */ - - if (Mac2UnixPathname (MacPathname, path, MAXPATHLEN+1) == 0) - return 0; - else - return path; + return signame; } +#endif /* HAVE_STRSIGNAL */ -#endif /* macintosh */