A simple launcher
As a workaround for buffering issue of TurtleEdit, I wrote a simple launcher to cheat your code into belief that it is running in a terminal.
Usage
Download the C code below, then compile it in Mac or Linux (unfortunately, there is no Windows version) as
cc -o run run.c
Copy or move the executable file (run) into your programming folder.
Next, select Settings in Run menu of TurtleEdit, and modify "command for execution" as
./run ./a.out
in case of C. For Ruby, for example, setting is something like
./run ruby %f
Once this is done, you need not modify codes seen in textbooks when you use TurtleEdit.
Code
/* a simple program launcher for TurtleEdit */ /* Yoshinori Hayakawa, Tohoku University */ /* 07-MAY-2014 */ /* most of this code is based on the exmaples in */ /* http://rachid.koucha.free.fr/tech_corner/pty_pdip.html */ /* */ #define _XOPEN_SOURCE #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sys/select.h> #include <unistd.h> #include <string.h> #include <signal.h> #include <termios.h> #include <sys/types.h> #include <sys/wait.h> #define BUFFLEN 1024 char **cmdargv = NULL ; char readbuf[BUFFLEN] ; int terminating ; void sigchld_handler(int); int main(int argc, char *argv[]) { int i,master,slave ; pid_t pid ; if (argc<=1) return 0 ; else { cmdargv = (char **) malloc(sizeof(char *)*argc) ; for (i=1 ; i<argc ; i++) { cmdargv[i-1] = argv[i] ; } cmdargv[argc-1]='\0' ; } master = open("/dev/ptmx", O_RDWR|O_NOCTTY); grantpt(master); unlockpt(master); slave = open(ptsname(master), O_RDWR); terminating = 0 ; if (pid=fork()) { /* parent */ fd_set fd_input ; int rc,k ; signal(SIGCHLD, sigchld_handler); close(slave) ; while (1) { FD_ZERO(&fd_input); FD_SET(0, &fd_input); FD_SET(master, &fd_input); rc = select(master + 1, &fd_input, NULL, NULL, NULL); switch(rc) { case -1 : exit(0); default : if (FD_ISSET(0, &fd_input)) { /* check stdin */ rc = read(0, readbuf, sizeof(readbuf)); if (rc > 0) { write(master, readbuf, rc); } else { if (rc < 0) { fprintf(stderr, "Error on read standard input\n"); exit(1); } } } if (FD_ISSET(master, &fd_input)) { /* check PTY */ rc = read(master, readbuf, sizeof(readbuf)); if (rc > 0) { write(1, readbuf, rc); } if (terminating) exit(0) ; } } } } else { /* child process */ struct termios term_setting ; close(master) ; dup2(slave,0) ; dup2(slave,1) ; dup2(slave,2) ; /* disable echo */ tcgetattr (0, &term_setting) ; term_setting.c_lflag &= ~ECHO; term_setting.c_cc[VEOF] = 0x04 ; // CTRL-D term_setting.c_cc[VERASE] = 0x08 ; // BACKSPACE term_setting.c_lflag |= ICANON ; tcsetattr (0, TCSAFLUSH, &term_setting) ; setsid() ; ioctl(0, TIOCSCTTY, 1); if (execvp(argv[1],cmdargv)==-1) { fprintf(stderr,"cannot execute %s\n",argv[1]) ; } _exit(0) ; } return 0 ; } void sigchld_handler(int x) { terminating = 1 ; }