- int stdin_read;
- int stdin_write;
-
- int control_read;
- int control_write;
-
- int size_read;
- int size_write;
-
- bool stdin_thread_initialized_p = false;
- THREADHANDLE stdin_thread;
- pthread_mutex_t stdin_mutex;
-}
-
-void safe_close(int fd)
-{
- if(close(fd) < 0)
- fatal_error("error closing fd",errno);
-}
-
-bool check_write(int fd, void *data, ssize_t size)
-{
- if(write(fd,data,size) == size)
- return true;
- else
- {
- if(errno == EINTR)
- return check_write(fd,data,size);
- else
- return false;
- }
-}
-
-void safe_write(int fd, void *data, ssize_t size)
-{
- if(!check_write(fd,data,size))
- fatal_error("error writing fd",errno);
-}
-
-void safe_write_nonblock(int fd, void *data, ssize_t size)
-{
- if(!check_write(fd,data,size) && errno != EAGAIN)
- fatal_error("error writing fd",errno);
-}
-
-bool safe_read(int fd, void *data, ssize_t size)
-{
- ssize_t bytes = read(fd,data,size);
- if(bytes < 0)
- {
- if(errno == EINTR)
- return safe_read(fd,data,size);
- else
- {
- fatal_error("error reading fd",errno);
- return false;
- }
- }
- else
- return (bytes == size);
-}
-
-void *stdin_loop(void *arg)
-{
- unsigned char buf[4096];
- bool loop_running = true;
-
- sigset_t mask;
- sigfillset(&mask);
- sigdelset(&mask, SIGUSR2);
- sigdelset(&mask, SIGTTIN);
- sigdelset(&mask, SIGTERM);
- sigdelset(&mask, SIGQUIT);
- pthread_sigmask(SIG_SETMASK, &mask, NULL);
-
- int unused;
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &unused);
- pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &unused);
-
- while(loop_running)
- {
- if(!safe_read(control_read,buf,1))
- break;
-
- if(buf[0] != 'X')
- fatal_error("stdin_loop: bad data on control fd",buf[0]);
-
- for(;;)
- {
- /* If we fep, the parent thread will grab stdin_mutex and send us
- SIGUSR2 to interrupt the read() call. */
- pthread_mutex_lock(&stdin_mutex);
- pthread_mutex_unlock(&stdin_mutex);
- ssize_t bytes = read(0,buf,sizeof(buf));
- if(bytes < 0)
- {
- if(errno == EINTR)
- continue;
- else
- {
- loop_running = false;
- break;
- }
- }
- else if(bytes >= 0)
- {
- safe_write(size_write,&bytes,sizeof(bytes));
-
- if(!check_write(stdin_write,buf,bytes))
- loop_running = false;
- break;
- }
- }
- }
-
- safe_close(stdin_write);
- safe_close(control_read);
-
- return NULL;
-}
-
-void factor_vm::open_console()
-{
- FACTOR_ASSERT(!stdin_thread_initialized_p);
- safe_pipe(&control_read,&control_write);
- safe_pipe(&size_read,&size_write);
- safe_pipe(&stdin_read,&stdin_write);
- stdin_thread = start_thread(stdin_loop,NULL);
- stdin_thread_initialized_p = true;
- pthread_mutex_init(&stdin_mutex, NULL);
+int stdin_read;
+int stdin_write;
+
+int control_read;
+int control_write;
+
+int size_read;
+int size_write;
+
+bool stdin_thread_initialized_p = false;
+THREADHANDLE stdin_thread;
+pthread_mutex_t stdin_mutex;
+}
+
+void safe_close(int fd) {
+ if (close(fd) < 0)
+ fatal_error("error closing fd", errno);
+}
+
+bool check_write(int fd, void* data, ssize_t size) {
+ if (write(fd, data, size) == size)
+ return true;
+ else {
+ if (errno == EINTR)
+ return check_write(fd, data, size);
+ else
+ return false;
+ }
+}
+
+void safe_write(int fd, void* data, ssize_t size) {
+ if (!check_write(fd, data, size))
+ fatal_error("error writing fd", errno);
+}
+
+void safe_write_nonblock(int fd, void* data, ssize_t size) {
+ if (!check_write(fd, data, size) && errno != EAGAIN)
+ fatal_error("error writing fd", errno);
+}
+
+bool safe_read(int fd, void* data, ssize_t size) {
+ ssize_t bytes = read(fd, data, size);
+ if (bytes < 0) {
+ if (errno == EINTR)
+ return safe_read(fd, data, size);
+ else {
+ fatal_error("error reading fd", errno);
+ return false;
+ }
+ } else
+ return (bytes == size);
+}
+
+void* stdin_loop(void* arg) {
+ unsigned char buf[4096];
+ bool loop_running = true;
+
+ sigset_t mask;
+ sigfillset(&mask);
+ sigdelset(&mask, SIGUSR2);
+ sigdelset(&mask, SIGTTIN);
+ sigdelset(&mask, SIGTERM);
+ sigdelset(&mask, SIGQUIT);
+ pthread_sigmask(SIG_SETMASK, &mask, NULL);
+
+ int unused;
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &unused);
+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &unused);
+
+ while (loop_running) {
+ if (!safe_read(control_read, buf, 1))
+ break;
+
+ if (buf[0] != 'X')
+ fatal_error("stdin_loop: bad data on control fd", buf[0]);
+
+ for (;;) {
+ /* If we fep, the parent thread will grab stdin_mutex and send us
+ SIGUSR2 to interrupt the read() call. */
+ pthread_mutex_lock(&stdin_mutex);
+ pthread_mutex_unlock(&stdin_mutex);
+ ssize_t bytes = read(0, buf, sizeof(buf));
+ if (bytes < 0) {
+ if (errno == EINTR)
+ continue;
+ else {
+ loop_running = false;
+ break;
+ }
+ } else if (bytes >= 0) {
+ safe_write(size_write, &bytes, sizeof(bytes));
+
+ if (!check_write(stdin_write, buf, bytes))
+ loop_running = false;
+ break;
+ }
+ }
+ }
+
+ safe_close(stdin_write);
+ safe_close(control_read);
+
+ return NULL;
+}
+
+void factor_vm::open_console() {
+ FACTOR_ASSERT(!stdin_thread_initialized_p);
+ safe_pipe(&control_read, &control_write);
+ safe_pipe(&size_read, &size_write);
+ safe_pipe(&stdin_read, &stdin_write);
+ stdin_thread = start_thread(stdin_loop, NULL);
+ stdin_thread_initialized_p = true;
+ pthread_mutex_init(&stdin_mutex, NULL);