2769 |
extern int inhibit_window_system; |
extern int inhibit_window_system; |
2770 |
extern int noninteractive; |
extern int noninteractive; |
2771 |
|
|
2772 |
|
#include "blockinput.h" |
2773 |
|
|
2774 |
/* When Emacs is started from the Finder, SELECT always immediately |
/* When Emacs is started from the Finder, SELECT always immediately |
2775 |
returns as if input is present when file descriptor 0 is polled for |
returns as if input is present when file descriptor 0 is polled for |
2776 |
input. Strangely, when Emacs is run as a GUI application from the |
input. Strangely, when Emacs is run as a GUI application from the |
2778 |
the system call SELECT corrects this discrepancy. */ |
the system call SELECT corrects this discrepancy. */ |
2779 |
int |
int |
2780 |
sys_select (n, rfds, wfds, efds, timeout) |
sys_select (n, rfds, wfds, efds, timeout) |
2781 |
int n; |
int n; |
2782 |
SELECT_TYPE *rfds; |
SELECT_TYPE *rfds; |
2783 |
SELECT_TYPE *wfds; |
SELECT_TYPE *wfds; |
2784 |
SELECT_TYPE *efds; |
SELECT_TYPE *efds; |
2785 |
struct timeval *timeout; |
struct timeval *timeout; |
2786 |
{ |
{ |
2787 |
if (!inhibit_window_system && rfds && FD_ISSET (0, rfds)) |
OSErr err; |
2788 |
return 1; |
EMACS_TIME end_time, now, remaining_time; |
2789 |
else if (inhibit_window_system || noninteractive || |
|
2790 |
(timeout && (EMACS_SECS(*timeout)==0) && |
if (inhibit_window_system || noninteractive |
2791 |
(EMACS_USECS(*timeout)==0))) |
|| rfds == NULL || !FD_ISSET (0, rfds)) |
2792 |
return select(n, rfds, wfds, efds, timeout); |
return select (n, rfds, wfds, efds, timeout); |
2793 |
else |
|
2794 |
|
if (wfds == NULL && efds == NULL) |
2795 |
{ |
{ |
2796 |
EMACS_TIME end_time, now; |
int i; |
|
|
|
|
EMACS_GET_TIME (end_time); |
|
|
if (timeout) |
|
|
EMACS_ADD_TIME (end_time, end_time, *timeout); |
|
2797 |
|
|
2798 |
do |
for (i = 1; i < n; i++) |
2799 |
{ |
if (FD_ISSET (i, rfds)) |
2800 |
int r; |
break; |
2801 |
EMACS_TIME one_second; |
if (i == n) |
2802 |
SELECT_TYPE orfds; |
{ |
2803 |
|
EventTimeout timeout_sec = |
2804 |
FD_ZERO (&orfds); |
(timeout |
2805 |
if (rfds) |
? (EMACS_SECS (*timeout) * kEventDurationSecond |
2806 |
|
+ EMACS_USECS (*timeout) * kEventDurationMicrosecond) |
2807 |
|
: kEventDurationForever); |
2808 |
|
|
2809 |
|
BLOCK_INPUT; |
2810 |
|
err = ReceiveNextEvent (0, NULL, timeout_sec, |
2811 |
|
kEventLeaveInQueue, NULL); |
2812 |
|
UNBLOCK_INPUT; |
2813 |
|
if (err == noErr) |
2814 |
{ |
{ |
2815 |
orfds = *rfds; |
FD_ZERO (rfds); |
2816 |
|
FD_SET (0, rfds); |
2817 |
|
return 1; |
2818 |
} |
} |
2819 |
|
else |
2820 |
|
return 0; |
2821 |
|
} |
2822 |
|
} |
2823 |
|
|
2824 |
EMACS_SET_SECS (one_second, 1); |
if (timeout) |
2825 |
EMACS_SET_USECS (one_second, 0); |
{ |
2826 |
|
remaining_time = *timeout; |
2827 |
if (timeout && EMACS_TIME_LT(*timeout, one_second)) |
EMACS_GET_TIME (now); |
2828 |
one_second = *timeout; |
EMACS_ADD_TIME (end_time, now, remaining_time); |
2829 |
|
} |
2830 |
if ((r = select (n, &orfds, wfds, efds, &one_second)) > 0) |
FD_CLR (0, rfds); |
2831 |
|
do |
2832 |
|
{ |
2833 |
|
EMACS_TIME select_timeout; |
2834 |
|
SELECT_TYPE orfds = *rfds; |
2835 |
|
int r; |
2836 |
|
|
2837 |
|
EMACS_SET_SECS_USECS (select_timeout, 0, 20000); |
2838 |
|
|
2839 |
|
if (timeout && EMACS_TIME_LT (remaining_time, select_timeout)) |
2840 |
|
select_timeout = remaining_time; |
2841 |
|
|
2842 |
|
r = select (n, &orfds, wfds, efds, &select_timeout); |
2843 |
|
BLOCK_INPUT; |
2844 |
|
err = ReceiveNextEvent (0, NULL, kEventDurationNoWait, |
2845 |
|
kEventLeaveInQueue, NULL); |
2846 |
|
UNBLOCK_INPUT; |
2847 |
|
if (r > 0) |
2848 |
|
{ |
2849 |
|
*rfds = orfds; |
2850 |
|
if (err == noErr) |
2851 |
{ |
{ |
2852 |
*rfds = orfds; |
FD_SET (0, rfds); |
2853 |
return r; |
r++; |
2854 |
} |
} |
2855 |
|
return r; |
2856 |
|
} |
2857 |
|
else if (err == noErr) |
2858 |
|
{ |
2859 |
|
FD_ZERO (rfds); |
2860 |
|
FD_SET (0, rfds); |
2861 |
|
return 1; |
2862 |
|
} |
2863 |
|
|
2864 |
mac_check_for_quit_char(); |
if (timeout) |
2865 |
|
{ |
2866 |
EMACS_GET_TIME (now); |
EMACS_GET_TIME (now); |
2867 |
EMACS_SUB_TIME (now, end_time, now); |
EMACS_SUB_TIME (remaining_time, end_time, now); |
2868 |
} |
} |
|
while (!timeout || !EMACS_TIME_NEG_P (now)); |
|
|
|
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
#undef read |
|
|
int sys_read (fds, buf, nbyte) |
|
|
int fds; |
|
|
char *buf; |
|
|
unsigned int nbyte; |
|
|
{ |
|
|
SELECT_TYPE rfds; |
|
|
EMACS_TIME one_second; |
|
|
int r; |
|
|
|
|
|
/* Use select to block on IO while still checking for quit_char */ |
|
|
if (!inhibit_window_system && !noninteractive && |
|
|
! (fcntl(fds, F_GETFL, 0) & O_NONBLOCK)) |
|
|
{ |
|
|
FD_ZERO (&rfds); |
|
|
FD_SET (fds, &rfds); |
|
|
if (sys_select (fds+1, &rfds, 0, 0, NULL) < 0) |
|
|
return -1; |
|
2869 |
} |
} |
2870 |
|
while (!timeout || EMACS_TIME_LT (now, end_time)); |
2871 |
|
|
2872 |
return read (fds, buf, nbyte); |
return 0; |
2873 |
} |
} |
2874 |
|
|
|
|
|
2875 |
/* Set up environment variables so that Emacs can correctly find its |
/* Set up environment variables so that Emacs can correctly find its |
2876 |
support files when packaged as an application bundle. Directories |
support files when packaged as an application bundle. Directories |
2877 |
placed in /usr/local/share/emacs/<emacs-version>/, /usr/local/bin, |
placed in /usr/local/share/emacs/<emacs-version>/, /usr/local/bin, |