aboutsummaryrefslogtreecommitdiffstats
path: root/src/mac.c
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu2006-09-08 08:17:58 +0000
committerYAMAMOTO Mitsuharu2006-09-08 08:17:58 +0000
commit3e51e9ac8ea02708ce46926e1d23af9f528e42dd (patch)
treedb98533ede42286d0d2e74a944ec9122f3af6cb1 /src/mac.c
parentdbcdba77e6d0b3ce23ceeba55ac6a1b3e25e3898 (diff)
downloademacs-3e51e9ac8ea02708ce46926e1d23af9f528e42dd.tar.gz
emacs-3e51e9ac8ea02708ce46926e1d23af9f528e42dd.zip
[!MAC_OSX] Don't include keyboard.h.
[!MAC_OSX] (select): Try detect_input_pending before ReceiveNextEvent in the same BLOCK_INPUT block, in case that some input has already been read asynchronously. Pretend to be interrupted by a signal if some input is available. [MAC_OSX] (select_and_poll_event, sys_select): Likewise. (SELECT_POLLING_PERIOD_USEC) [SELECT_USE_CFSOCKET]: Change to 100000. Now used for ReceiveNextEvent timeout instead of select timeout. (EVENT_CLASS_SOCK) [SELECT_USE_CFSOCKET]: Remove macro. [SELECT_USE_CFSOCKET] (socket_callback): Add non-blocking connect support. Quit event loop. [MAC_OSX] (sys_select) [SELECT_USE_CFSOCKET]: Add non-blocking connect support. Reuse previously allocated CFRunLoopSource. (Fmac_process_hi_command) [TARGET_API_MAC_CARBON]: New function. (syms_of_mac) [TARGET_API_MAC_CARBON]: Defsubr it.
Diffstat (limited to 'src/mac.c')
-rw-r--r--src/mac.c454
1 files changed, 240 insertions, 214 deletions
diff --git a/src/mac.c b/src/mac.c
index 67fd5e4f5e0..714ca400e19 100644
--- a/src/mac.c
+++ b/src/mac.c
@@ -2413,75 +2413,69 @@ sys_fopen (const char *name, const char *mode)
2413} 2413}
2414 2414
2415 2415
2416#include "keyboard.h" 2416extern Boolean mac_wait_next_event P_ ((EventRecord *, UInt32, Boolean));
2417extern Boolean mac_wait_next_event (EventRecord *, UInt32, Boolean);
2418 2417
2419int 2418int
2420select (n, rfds, wfds, efds, timeout) 2419select (n, rfds, wfds, efds, timeout)
2421 int n; 2420 int nfds;
2422 SELECT_TYPE *rfds; 2421 SELECT_TYPE *rfds, *wfds, *efds;
2423 SELECT_TYPE *wfds; 2422 EMACS_TIME *timeout;
2424 SELECT_TYPE *efds;
2425 struct timeval *timeout;
2426{ 2423{
2427 OSStatus err; 2424 OSStatus err = noErr;
2428#if TARGET_API_MAC_CARBON
2429 EventTimeout timeout_sec =
2430 (timeout
2431 ? (EMACS_SECS (*timeout) * kEventDurationSecond
2432 + EMACS_USECS (*timeout) * kEventDurationMicrosecond)
2433 : kEventDurationForever);
2434
2435 BLOCK_INPUT;
2436 err = ReceiveNextEvent (0, NULL, timeout_sec, kEventLeaveInQueue, NULL);
2437 UNBLOCK_INPUT;
2438#else /* not TARGET_API_MAC_CARBON */
2439 EventRecord e;
2440 UInt32 sleep_time = EMACS_SECS (*timeout) * 60 +
2441 ((EMACS_USECS (*timeout) * 60) / 1000000);
2442 2425
2443 /* Can only handle wait for keyboard input. */ 2426 /* Can only handle wait for keyboard input. */
2444 if (n > 1 || wfds || efds) 2427 if (nfds > 1 || wfds || efds)
2445 return -1; 2428 return -1;
2446 2429
2447 /* Also return true if an event other than a keyDown has occurred. 2430 /* Try detect_input_pending before ReceiveNextEvent in the same
2448 This causes kbd_buffer_get_event in keyboard.c to call 2431 BLOCK_INPUT block, in case that some input has already been read
2449 read_avail_input which in turn calls XTread_socket to poll for 2432 asynchronously. */
2450 these events. Otherwise these never get processed except but a 2433 BLOCK_INPUT;
2451 very slow poll timer. */ 2434 if (!detect_input_pending ())
2452 if (mac_wait_next_event (&e, sleep_time, false)) 2435 {
2453 err = noErr; 2436#if TARGET_API_MAC_CARBON
2454 else 2437 EventTimeout timeoutval =
2455 err = -9875; /* eventLoopTimedOutErr */ 2438 (timeout
2439 ? (EMACS_SECS (*timeout) * kEventDurationSecond
2440 + EMACS_USECS (*timeout) * kEventDurationMicrosecond)
2441 : kEventDurationForever);
2442
2443 if (timeoutval == 0.0)
2444 err = eventLoopTimedOutErr;
2445 else
2446 err = ReceiveNextEvent (0, NULL, timeoutval,
2447 kEventLeaveInQueue, NULL);
2448#else /* not TARGET_API_MAC_CARBON */
2449 EventRecord e;
2450 UInt32 sleep_time = EMACS_SECS (*timeout) * 60 +
2451 ((EMACS_USECS (*timeout) * 60) / 1000000);
2452
2453 if (sleep_time == 0)
2454 err = -9875; /* eventLoopTimedOutErr */
2455 else
2456 {
2457 if (mac_wait_next_event (&e, sleep_time, false))
2458 err = noErr;
2459 else
2460 err = -9875; /* eventLoopTimedOutErr */
2461 }
2456#endif /* not TARGET_API_MAC_CARBON */ 2462#endif /* not TARGET_API_MAC_CARBON */
2463 }
2464 UNBLOCK_INPUT;
2457 2465
2458 if (FD_ISSET (0, rfds)) 2466 if (err == noErr)
2459 if (err == noErr) 2467 {
2460 return 1; 2468 /* Pretend that `select' is interrupted by a signal. */
2461 else 2469 detect_input_pending ();
2462 { 2470 errno = EINTR;
2463 FD_ZERO (rfds); 2471 return -1;
2464 return 0; 2472 }
2465 }
2466 else 2473 else
2467 if (err == noErr) 2474 {
2468 { 2475 if (rfds)
2469 if (input_polling_used ()) 2476 FD_ZERO (rfds);
2470 {
2471 /* It could be confusing if a real alarm arrives while
2472 processing the fake one. Turn it off and let the
2473 handler reset it. */
2474 extern void poll_for_input_1 P_ ((void));
2475 int old_poll_suppress_count = poll_suppress_count;
2476 poll_suppress_count = 1;
2477 poll_for_input_1 ();
2478 poll_suppress_count = old_poll_suppress_count;
2479 }
2480 errno = EINTR;
2481 return -1;
2482 }
2483 else
2484 return 0; 2477 return 0;
2478 }
2485} 2479}
2486 2480
2487 2481
@@ -4904,6 +4898,30 @@ On successful conversion, return the result string, else return nil. */)
4904 4898
4905 return result; 4899 return result;
4906} 4900}
4901
4902DEFUN ("mac-process-hi-command", Fmac_process_hi_command, Smac_process_hi_command, 1, 1, 0,
4903 doc: /* Send a HI command whose ID is COMMAND-ID to the command chain.
4904COMMAND-ID must be a 4-character string. Some common command IDs are
4905defined in the Carbon Event Manager. */)
4906 (command_id)
4907 Lisp_Object command_id;
4908{
4909 OSStatus err;
4910 HICommand command;
4911
4912 bzero (&command, sizeof (HICommand));
4913 command.commandID = mac_get_code_from_arg (command_id , 0);
4914
4915 BLOCK_INPUT;
4916 err = ProcessHICommand (&command);
4917 UNBLOCK_INPUT;
4918
4919 if (err != noErr)
4920 error ("HI command (command ID: '%s') not handled.", SDATA (command_id));
4921
4922 return Qnil;
4923}
4924
4907#endif /* TARGET_API_MAC_CARBON */ 4925#endif /* TARGET_API_MAC_CARBON */
4908 4926
4909 4927
@@ -4944,23 +4962,22 @@ extern int noninteractive;
4944 -> Use `select'. 4962 -> Use `select'.
4945 2. Sockets are not involved. 4963 2. Sockets are not involved.
4946 -> Use ReceiveNextEvent. 4964 -> Use ReceiveNextEvent.
4947 3. [If SELECT_USE_CFSOCKET is defined] 4965 3. [If SELECT_USE_CFSOCKET is set]
4948 Only the window event channel and socket read channels are 4966 Only the window event channel and socket read/write channels are
4949 involved, and timeout is not too short (greater than 4967 involved, and timeout is not too short (greater than
4950 SELECT_TIMEOUT_THRESHHOLD_RUNLOOP seconds). 4968 SELECT_TIMEOUT_THRESHHOLD_RUNLOOP seconds).
4951 -> Create CFSocket for each socket and add it into the current 4969 -> Create CFSocket for each socket and add it into the current
4952 event RunLoop so that a `ready-to-read' event can be posted 4970 event RunLoop so that the current event loop gets quit when
4953 to the event queue that is also used for window events. Then 4971 the socket becomes ready. Then ReceiveNextEvent can wait for
4954 ReceiveNextEvent can wait for both kinds of inputs. 4972 both kinds of inputs.
4955 4. Otherwise. 4973 4. Otherwise.
4956 -> Periodically poll the window input channel while repeatedly 4974 -> Periodically poll the window input channel while repeatedly
4957 executing `select' with a short timeout 4975 executing `select' with a short timeout
4958 (SELECT_POLLING_PERIOD_USEC microseconds). */ 4976 (SELECT_POLLING_PERIOD_USEC microseconds). */
4959 4977
4960#define SELECT_POLLING_PERIOD_USEC 20000 4978#define SELECT_POLLING_PERIOD_USEC 100000
4961#ifdef SELECT_USE_CFSOCKET 4979#if SELECT_USE_CFSOCKET
4962#define SELECT_TIMEOUT_THRESHOLD_RUNLOOP 0.2 4980#define SELECT_TIMEOUT_THRESHOLD_RUNLOOP 0.2
4963#define EVENT_CLASS_SOCK 'Sock'
4964 4981
4965static void 4982static void
4966socket_callback (s, type, address, data, info) 4983socket_callback (s, type, address, data, info)
@@ -4970,196 +4987,208 @@ socket_callback (s, type, address, data, info)
4970 const void *data; 4987 const void *data;
4971 void *info; 4988 void *info;
4972{ 4989{
4973 EventRef event; 4990 int fd = CFSocketGetNative (s);
4991 SELECT_TYPE *ofds = (SELECT_TYPE *)info;
4974 4992
4975 CreateEvent (NULL, EVENT_CLASS_SOCK, 0, 0, kEventAttributeNone, &event); 4993 if ((type == kCFSocketReadCallBack && FD_ISSET (fd, &ofds[0]))
4976 PostEventToQueue (GetCurrentEventQueue (), event, kEventPriorityStandard); 4994 || (type == kCFSocketConnectCallBack && FD_ISSET (fd, &ofds[1])))
4977 ReleaseEvent (event); 4995 QuitEventLoop (GetCurrentEventLoop ());
4978} 4996}
4979#endif /* SELECT_USE_CFSOCKET */ 4997#endif /* SELECT_USE_CFSOCKET */
4980 4998
4981static int 4999static int
4982select_and_poll_event (n, rfds, wfds, efds, timeout) 5000select_and_poll_event (nfds, rfds, wfds, efds, timeout)
4983 int n; 5001 int nfds;
4984 SELECT_TYPE *rfds; 5002 SELECT_TYPE *rfds, *wfds, *efds;
4985 SELECT_TYPE *wfds; 5003 EMACS_TIME *timeout;
4986 SELECT_TYPE *efds;
4987 struct timeval *timeout;
4988{ 5004{
4989 int r; 5005 OSStatus err = noErr;
4990 OSStatus err; 5006 int r = 0;
4991 5007
4992 r = select (n, rfds, wfds, efds, timeout); 5008 /* Try detect_input_pending before ReceiveNextEvent in the same
4993 if (r != -1) 5009 BLOCK_INPUT block, in case that some input has already been read
5010 asynchronously. */
5011 BLOCK_INPUT;
5012 if (!detect_input_pending ())
4994 { 5013 {
4995 BLOCK_INPUT; 5014 EMACS_TIME select_timeout;
4996 err = ReceiveNextEvent (0, NULL, kEventDurationNoWait, 5015 EventTimeout timeoutval =
4997 kEventLeaveInQueue, NULL); 5016 (timeout
4998 UNBLOCK_INPUT; 5017 ? (EMACS_SECS (*timeout) * kEventDurationSecond
4999 if (err == noErr) 5018 + EMACS_USECS (*timeout) * kEventDurationMicrosecond)
5019 : kEventDurationForever);
5020
5021 EMACS_SET_SECS_USECS (select_timeout, 0, 0);
5022 r = select (nfds, rfds, wfds, efds, &select_timeout);
5023 if (timeoutval == 0.0)
5024 err = eventLoopTimedOutErr;
5025 else if (r == 0)
5000 { 5026 {
5001 FD_SET (0, rfds); 5027#if USE_CG_DRAWING
5002 r++; 5028 mac_prepare_for_quickdraw (NULL);
5029#endif
5030 err = ReceiveNextEvent (0, NULL, timeoutval,
5031 kEventLeaveInQueue, NULL);
5003 } 5032 }
5004 } 5033 }
5005 return r; 5034 UNBLOCK_INPUT;
5006}
5007 5035
5008#if MAC_OS_X_VERSION_MAX_ALLOWED < 1020 5036 if (r != 0)
5009#undef SELECT_INVALIDATE_CFSOCKET 5037 return r;
5010#endif 5038 else if (err == noErr)
5039 {
5040 /* Pretend that `select' is interrupted by a signal. */
5041 detect_input_pending ();
5042 errno = EINTR;
5043 return -1;
5044 }
5045 else
5046 return 0;
5047}
5011 5048
5012int 5049int
5013sys_select (n, rfds, wfds, efds, timeout) 5050sys_select (nfds, rfds, wfds, efds, timeout)
5014 int n; 5051 int nfds;
5015 SELECT_TYPE *rfds; 5052 SELECT_TYPE *rfds, *wfds, *efds;
5016 SELECT_TYPE *wfds; 5053 EMACS_TIME *timeout;
5017 SELECT_TYPE *efds;
5018 struct timeval *timeout;
5019{ 5054{
5020 OSStatus err; 5055 OSStatus err = noErr;
5021 int i, r; 5056 int r;
5022 EMACS_TIME select_timeout; 5057 EMACS_TIME select_timeout;
5058 SELECT_TYPE ofds[3];
5023 5059
5024 if (inhibit_window_system || noninteractive 5060 if (inhibit_window_system || noninteractive
5025 || rfds == NULL || !FD_ISSET (0, rfds)) 5061 || rfds == NULL || !FD_ISSET (0, rfds))
5026 return select (n, rfds, wfds, efds, timeout); 5062 return select (nfds, rfds, wfds, efds, timeout);
5027 5063
5028 FD_CLR (0, rfds); 5064 FD_CLR (0, rfds);
5065 ofds[0] = *rfds;
5029 5066
5030 if (wfds == NULL && efds == NULL) 5067 if (wfds)
5031 { 5068 ofds[1] = *wfds;
5032 int nsocks = 0; 5069 else
5033 SELECT_TYPE orfds = *rfds; 5070 FD_ZERO (&ofds[1]);
5034 5071
5035 EventTimeout timeout_sec = 5072 if (efds)
5073 ofds[2] = *efds;
5074 else
5075 {
5076 int maxfd;
5077 EventTimeout timeoutval =
5036 (timeout 5078 (timeout
5037 ? (EMACS_SECS (*timeout) * kEventDurationSecond 5079 ? (EMACS_SECS (*timeout) * kEventDurationSecond
5038 + EMACS_USECS (*timeout) * kEventDurationMicrosecond) 5080 + EMACS_USECS (*timeout) * kEventDurationMicrosecond)
5039 : kEventDurationForever); 5081 : kEventDurationForever);
5040 5082
5041 for (i = 1; i < n; i++) 5083 for (maxfd = nfds - 1; maxfd > 0; maxfd--)
5042 if (FD_ISSET (i, rfds)) 5084 if (FD_ISSET (maxfd, rfds) || (wfds && FD_ISSET (maxfd, wfds)))
5043 nsocks++; 5085 break;
5044 5086
5045 if (nsocks == 0) 5087 if (maxfd == 0)
5046 { 5088 return select_and_poll_event (nfds, rfds, wfds, efds, timeout);
5047 BLOCK_INPUT;
5048 err = ReceiveNextEvent (0, NULL, timeout_sec,
5049 kEventLeaveInQueue, NULL);
5050 UNBLOCK_INPUT;
5051 if (err == noErr)
5052 {
5053 FD_SET (0, rfds);
5054 return 1;
5055 }
5056 else
5057 return 0;
5058 }
5059 5089
5060#if USE_CG_DRAWING
5061 mac_prepare_for_quickdraw (NULL);
5062#endif
5063 /* Avoid initial overhead of RunLoop setup for the case that 5090 /* Avoid initial overhead of RunLoop setup for the case that
5064 some input is already available. */ 5091 some input is already available. */
5065 EMACS_SET_SECS_USECS (select_timeout, 0, 0); 5092 EMACS_SET_SECS_USECS (select_timeout, 0, 0);
5066 r = select_and_poll_event (n, rfds, wfds, efds, &select_timeout); 5093 r = select_and_poll_event (nfds, rfds, wfds, efds, &select_timeout);
5067 if (r != 0 || timeout_sec == 0.0) 5094 if (r != 0 || timeoutval == 0.0)
5068 return r; 5095 return r;
5069 5096
5070 *rfds = orfds; 5097 *rfds = ofds[0];
5098 if (wfds)
5099 *wfds = ofds[1];
5071 5100
5072#ifdef SELECT_USE_CFSOCKET 5101#if SELECT_USE_CFSOCKET
5073 if (timeout_sec > 0 && timeout_sec <= SELECT_TIMEOUT_THRESHOLD_RUNLOOP) 5102 if (timeoutval > 0 && timeoutval <= SELECT_TIMEOUT_THRESHOLD_RUNLOOP)
5074 goto poll_periodically; 5103 goto poll_periodically;
5075 5104
5076 { 5105 /* Try detect_input_pending before ReceiveNextEvent in the same
5077 CFRunLoopRef runloop = 5106 BLOCK_INPUT block, in case that some input has already been
5078 (CFRunLoopRef) GetCFRunLoopFromEventLoop (GetCurrentEventLoop ()); 5107 read asynchronously. */
5079 EventTypeSpec specs[] = {{EVENT_CLASS_SOCK, 0}}; 5108 BLOCK_INPUT;
5080#ifdef SELECT_INVALIDATE_CFSOCKET 5109 if (!detect_input_pending ())
5081 CFSocketRef *shead, *s; 5110 {
5082#else 5111 int minfd, fd;
5083 CFRunLoopSourceRef *shead, *s; 5112 CFRunLoopRef runloop =
5084#endif 5113 (CFRunLoopRef) GetCFRunLoopFromEventLoop (GetCurrentEventLoop ());
5085 5114 static CFSocketContext context;
5086 BLOCK_INPUT; 5115 static CFMutableDictionaryRef sources;
5087 5116
5088#ifdef SELECT_INVALIDATE_CFSOCKET 5117 context.info = ofds;
5089 shead = xmalloc (sizeof (CFSocketRef) * nsocks); 5118 if (sources == NULL)
5090#else 5119 sources =
5091 shead = xmalloc (sizeof (CFRunLoopSourceRef) * nsocks); 5120 CFDictionaryCreateMutable (NULL, 0, NULL,
5092#endif 5121 &kCFTypeDictionaryValueCallBacks);
5093 s = shead; 5122
5094 for (i = 1; i < n; i++) 5123 for (minfd = 1; minfd < maxfd; minfd++)
5095 if (FD_ISSET (i, rfds)) 5124 if (FD_ISSET (minfd, rfds) || (wfds && FD_ISSET (minfd, wfds)))
5096 { 5125 break;
5097 CFSocketRef socket =
5098 CFSocketCreateWithNative (NULL, i, kCFSocketReadCallBack,
5099 socket_callback, NULL);
5100 CFRunLoopSourceRef source =
5101 CFSocketCreateRunLoopSource (NULL, socket, 0);
5102
5103#ifdef SELECT_INVALIDATE_CFSOCKET
5104 CFSocketSetSocketFlags (socket, 0);
5105#endif
5106 CFRunLoopAddSource (runloop, source, kCFRunLoopDefaultMode);
5107#ifdef SELECT_INVALIDATE_CFSOCKET
5108 CFRelease (source);
5109 *s = socket;
5110#else
5111 CFRelease (socket);
5112 *s = source;
5113#endif
5114 s++;
5115 }
5116 5126
5117 err = ReceiveNextEvent (0, NULL, timeout_sec, kEventLeaveInQueue, NULL); 5127 for (fd = minfd; fd <= maxfd; fd++)
5128 if (FD_ISSET (fd, rfds) || (wfds && FD_ISSET (fd, wfds)))
5129 {
5130 void *key = (void *) fd;
5131 CFRunLoopSourceRef source =
5132 (CFRunLoopSourceRef) CFDictionaryGetValue (sources, key);
5133
5134 if (source == NULL)
5135 {
5136 CFSocketRef socket =
5137 CFSocketCreateWithNative (NULL, fd,
5138 (kCFSocketReadCallBack
5139 | kCFSocketConnectCallBack),
5140 socket_callback, &context);
5141
5142 if (socket == NULL)
5143 continue;
5144 source = CFSocketCreateRunLoopSource (NULL, socket, 0);
5145 CFRelease (socket);
5146 if (source == NULL)
5147 continue;
5148 CFDictionaryAddValue (sources, key, source);
5149 CFRelease (source);
5150 }
5151 CFRunLoopAddSource (runloop, source, kCFRunLoopDefaultMode);
5152 }
5118 5153
5119 do 5154#if USE_CG_DRAWING
5120 { 5155 mac_prepare_for_quickdraw (NULL);
5121 --s;
5122#ifdef SELECT_INVALIDATE_CFSOCKET
5123 CFSocketInvalidate (*s);
5124#else
5125 CFRunLoopRemoveSource (runloop, *s, kCFRunLoopDefaultMode);
5126#endif 5156#endif
5127 CFRelease (*s); 5157 err = ReceiveNextEvent (0, NULL, timeoutval,
5128 } 5158 kEventLeaveInQueue, NULL);
5129 while (s != shead);
5130
5131 xfree (shead);
5132 5159
5133 if (err) 5160 for (fd = minfd; fd <= maxfd; fd++)
5134 { 5161 if (FD_ISSET (fd, rfds) || (wfds && FD_ISSET (fd, wfds)))
5135 FD_ZERO (rfds); 5162 {
5136 r = 0; 5163 void *key = (void *) fd;
5137 } 5164 CFRunLoopSourceRef source =
5138 else 5165 (CFRunLoopSourceRef) CFDictionaryGetValue (sources, key);
5139 {
5140 FlushEventsMatchingListFromQueue (GetCurrentEventQueue (),
5141 GetEventTypeCount (specs),
5142 specs);
5143 EMACS_SET_SECS_USECS (select_timeout, 0, 0);
5144 r = select_and_poll_event (n, rfds, wfds, efds, &select_timeout);
5145 }
5146 5166
5147 UNBLOCK_INPUT; 5167 CFRunLoopRemoveSource (runloop, source, kCFRunLoopDefaultMode);
5168 }
5169 }
5170 UNBLOCK_INPUT;
5148 5171
5149 return r; 5172 if (err == noErr || err == eventLoopQuitErr)
5150 } 5173 {
5174 EMACS_SET_SECS_USECS (select_timeout, 0, 0);
5175 return select_and_poll_event (nfds, rfds, wfds, efds,
5176 &select_timeout);
5177 }
5178 else
5179 {
5180 FD_ZERO (rfds);
5181 if (wfds)
5182 FD_ZERO (wfds);
5183 return 0;
5184 }
5151#endif /* SELECT_USE_CFSOCKET */ 5185#endif /* SELECT_USE_CFSOCKET */
5152 } 5186 }
5153 5187
5154 poll_periodically: 5188 poll_periodically:
5155 { 5189 {
5156 EMACS_TIME end_time, now, remaining_time; 5190 EMACS_TIME end_time, now, remaining_time;
5157 SELECT_TYPE orfds = *rfds, owfds, oefds;
5158 5191
5159 if (wfds)
5160 owfds = *wfds;
5161 if (efds)
5162 oefds = *efds;
5163 if (timeout) 5192 if (timeout)
5164 { 5193 {
5165 remaining_time = *timeout; 5194 remaining_time = *timeout;
@@ -5172,15 +5201,15 @@ sys_select (n, rfds, wfds, efds, timeout)
5172 EMACS_SET_SECS_USECS (select_timeout, 0, SELECT_POLLING_PERIOD_USEC); 5201 EMACS_SET_SECS_USECS (select_timeout, 0, SELECT_POLLING_PERIOD_USEC);
5173 if (timeout && EMACS_TIME_LT (remaining_time, select_timeout)) 5202 if (timeout && EMACS_TIME_LT (remaining_time, select_timeout))
5174 select_timeout = remaining_time; 5203 select_timeout = remaining_time;
5175 r = select_and_poll_event (n, rfds, wfds, efds, &select_timeout); 5204 r = select_and_poll_event (nfds, rfds, wfds, efds, &select_timeout);
5176 if (r != 0) 5205 if (r != 0)
5177 return r; 5206 return r;
5178 5207
5179 *rfds = orfds; 5208 *rfds = ofds[0];
5180 if (wfds) 5209 if (wfds)
5181 *wfds = owfds; 5210 *wfds = ofds[1];
5182 if (efds) 5211 if (efds)
5183 *efds = oefds; 5212 *efds = ofds[2];
5184 5213
5185 if (timeout) 5214 if (timeout)
5186 { 5215 {
@@ -5190,12 +5219,8 @@ sys_select (n, rfds, wfds, efds, timeout)
5190 } 5219 }
5191 while (!timeout || EMACS_TIME_LT (now, end_time)); 5220 while (!timeout || EMACS_TIME_LT (now, end_time));
5192 5221
5193 FD_ZERO (rfds); 5222 EMACS_SET_SECS_USECS (select_timeout, 0, 0);
5194 if (wfds) 5223 return select_and_poll_event (nfds, rfds, wfds, efds, &select_timeout);
5195 FD_ZERO (wfds);
5196 if (efds)
5197 FD_ZERO (efds);
5198 return 0;
5199 } 5224 }
5200} 5225}
5201 5226
@@ -5387,6 +5412,7 @@ syms_of_mac ()
5387#if TARGET_API_MAC_CARBON 5412#if TARGET_API_MAC_CARBON
5388 defsubr (&Smac_get_preference); 5413 defsubr (&Smac_get_preference);
5389 defsubr (&Smac_code_convert_string); 5414 defsubr (&Smac_code_convert_string);
5415 defsubr (&Smac_process_hi_command);
5390#endif 5416#endif
5391 5417
5392 defsubr (&Smac_set_file_creator); 5418 defsubr (&Smac_set_file_creator);