blob: 2eed684b87865f46ce6039d1a22c3726795053b7 [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001/* vi:set ts=8 sts=4 sw=4:
2 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 * BeBox port Copyright 1997 by Olaf Seibert.
5 *
6 * Do ":help uganda" in Vim to read copying and usage conditions.
7 * Do ":help credits" in Vim to see a list of people who contributed.
8 * See README.txt for an overview of the Vim source code.
9 */
10/*
11 * os_beos.c Additional stuff for BeOS (rest is in os_unix.c)
12 */
13
14#include <float.h>
15#include <termios.h>
Bram Moolenaar82881492012-11-20 16:53:39 +010016#ifndef PROTO
17# include <kernel/OS.h>
18#endif
19
Bram Moolenaar071d4272004-06-13 20:20:40 +000020#include "vim.h"
21
22#if USE_THREAD_FOR_INPUT_WITH_TIMEOUT
23
24#ifdef PROTO /* making prototypes on Unix */
25#define sem_id int
26#define thread_id int
27#endif
28
29char_u charbuf;
30signed char charcount;
31sem_id character_present;
32sem_id character_wanted;
33thread_id read_thread_id;
34
35#define TRY_ABORT 0 /* This code does not work so turn it off. */
36
37#if TRY_ABORT
38 static void
39mostly_ignore(int sig)
40{
41}
42#endif
43
44 static long
45read_thread(void *dummy)
46{
47 signal(SIGINT, SIG_IGN);
48 signal(SIGQUIT, SIG_IGN);
49#if TRY_ABORT
50 signal(SIGUSR1, mostly_ignore);
51#endif
52
53 for (;;) {
54 if (acquire_sem(character_wanted) != B_NO_ERROR)
55 break;
56 charcount = read(read_cmd_fd, &charbuf, 1);
57 release_sem(character_present);
58 }
59
60 return 0;
61}
62
63 void
64beos_cleanup_read_thread(void)
65{
66 if (character_present > 0)
67 delete_sem(character_present);
68 character_present = 0;
69 if (read_thread_id > 0)
70 kill_thread(read_thread_id);
71 read_thread_id = 0;
72}
73
74#endif
75
76/*
77 * select() emulation. Hopefully, in DR9 there will be something
78 * useful supplied by the system. ... Alas, not. Not in AAPR, nor
79 * in PR or even PR2... R3 then maybe? I don't think so!
80 */
81
82 int
83beos_select(int nbits,
84 struct fd_set *rbits,
85 struct fd_set *wbits,
86 struct fd_set *ebits,
87 struct timeval *timeout)
88{
89 bigtime_t tmo;
90
91 if (nbits == 0) {
92 /* select is purely being used for delay */
93 snooze(timeout->tv_sec * 1e6 + timeout->tv_usec);
94 return 0;
95 }
96#if 0
97 /*
98 * This does not seem to work either. Reads here are not supposed to
99 * block indefinitely, yet they do. This is most annoying.
100 */
101 if (FD_ISSET(0, rbits)) {
102 char cbuf[1];
103 int count;
104 struct termios told;
105 struct termios tnew;
106 tcgetattr(0, &told);
107 tnew = told;
108 tnew.c_lflag &= ~ICANON;
109 tnew.c_cc[VMIN] = 0;
110 tnew.c_cc[VTIME] = timeout->tv_sec * 10 + timeout->tv_usec / 100000;
111 tcsetattr(0, TCSANOW, &tnew);
112
113 count = read(0, &cbuf, sizeof(cbuf));
114 tcsetattr(0, TCSANOW, &told);
115 if (count > 0) {
116 add_to_input_buf(&cbuf[0], count);
117 return 1;
118 }
119 return 0;
120 }
121#endif
122#if USE_THREAD_FOR_INPUT_WITH_TIMEOUT
123 /*
124 * Check if the operation is really on stdin...
125 */
126 if (FD_ISSET(read_cmd_fd, rbits))
127 {
128 int acquired;
129
130 /*
131 * Is this the first time through?
132 * Then start up the thread and initialise the semaphores.
133 */
134 if (character_present == 0) {
135 character_present = create_sem(0, "vim character_present");
136 character_wanted = create_sem(1, "vim character_wanted");
137 read_thread_id = spawn_thread(read_thread, "vim async read",
138 B_NORMAL_PRIORITY, NULL);
139 atexit(beos_cleanup_read_thread);
140 resume_thread(read_thread_id);
141 }
142
143 /* timeout == NULL means "indefinitely" */
144 if (timeout) {
145 tmo = timeout->tv_sec * 1e6 + timeout->tv_usec;
146 /* 0 means "don't wait, which is impossible to do exactly. */
147 if (tmo == 0)
148 tmo = 1.0;
149 }
150#if TRY_ABORT
151 release_sem(character_wanted);
152#endif
153 if (timeout)
154 acquired = acquire_sem_etc(character_present, 1, B_TIMEOUT, tmo);
155 else
156 acquired = acquire_sem(character_present);
157 if (acquired == B_NO_ERROR) {
158 if (charcount > 0) {
159 add_to_input_buf(&charbuf, 1);
160#if !TRY_ABORT
161 release_sem(character_wanted);
162#endif
163
164 return 1;
165 } else {
166#if !TRY_ABORT
167 release_sem(character_wanted);
168#endif
169
170 return 0;
171 }
172 }
173#if TRY_ABORT
174 else {
175 /*
176 * Timeout occurred. Break the read() call by sending
177 * a signal. Problem: it may be just read()ing it now.
178 * Therefore we still have to finish the handshake with
179 * the thread and maybe remember the character.
180 */
181 kill(read_thread_id, SIGUSR1);
182 /*
183 * If some other error occurred, don't hang now.
184 * (We will most likely hang later anyway...)
185 */
186 if (acquired == B_TIMED_OUT)
187 acquire_sem(character_present);
188 if (charcount > 0) {
189 add_to_input_buf(&charbuf, 1);
190 return 1;
191 }
192 return 0;
193 }
194#endif
195 }
196#endif
197
Bram Moolenaar071d4272004-06-13 20:20:40 +0000198 return 0;
199}
200