1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
#ifndef _POSIX_SOURCE
#define _POSIX_SOURCE
#endif
/* Support routines for terminal I/O. This module defines the following
Fortran-callable routines: GROTER, GRCTER, GRWTER, GRPTER. */
#include <stdio.h>
#include <termios.h>
#include <fortran.h>
/* Open a channel to the device specified by 'cdev'.
*
* cdev I The name of the device to be opened
* ldev I Number of valid characters in cdev
* groter O The open channel number (-1 indicates an error)
*/
long int GROTER(_fcd cdev, int *ldev)
{
int fd; /* The returned file descriptor */
char name[64]; /* A copy of the given terminal device name */
/*
* Make a copy of the given file if there is sufficient room in name[].
*/
if(*ldev <= sizeof(name)-1) {
strncpy(name, _fcdtocp(cdev), *ldev);
name[*ldev] = '\0';
} else {
fprintf(stderr, "groter: Terminal file name too long.\n");
return -1;
};
/*
* Open the terminal.
*/
if((fd = open(name, 2)) == -1) {
perror(name);
return -1;
};
return fd;
}
/* Close a previously opened channel.
*
* fd I The channel number to be closed
*/
void GRCTER(int *fd)
{
close(*fd);
return;
}
/* Write lbuf bytes from cbuf to the channel fd. Data is written without
* any formating.
*
* fd I The channel number
* cbuf I Character array of data to be written
* lbuf I/O The number of bytes to write, set to zero on return
*/
void GRWTER(int *fd, _fcd cbuf, int *lbuf)
{
int nwritten = write (*fd, _fcdtocp(cbuf), *lbuf);
if (nwritten != *lbuf)
perror("Error writing to graphics device");
*lbuf = 0;
return;
}
/* Write prompt string on terminal and then read response. This version
* will try to read lbuf characters.
*
* fd I The channel number
* cprom I An optional prompt string
* lprom I Number of valid characters in cprom
* cbuf O Character array of data read
* lbuf I/O The number of bytes to read, on return number read
*/
void GRPTER(int *fd, _fcd cprom, int *lprom, _fcd cbuf, int *lbuf)
{
char *buff = _fcdtocp(cbuf); /* C pointer to FORTRAN string */
int ndone=0; /* The number of characters read */
struct termios term; /* Terminal mode flags */
/*
* Get the current set of terminal mode flags.
*/
if(tcgetattr(*fd, &term)==0) {
struct termios saveterm; /* Saved terminal attributes */
int ntry; /* The number of characters still to be read */
int nread; /* The number of characters read in one iteration */
/*
* Save the existing terminal mode flags to be restored later.
*/
saveterm = term;
/*
* Enable raw single character input.
*/
term.c_lflag &= ~ICANON;
term.c_cc[VMIN] = 1;
/*
* Install the new terminal flags after first waiting for all pending
* output to be delivered to the terminal and after discarding any
* lingering input.
*/
tcsetattr(*fd, TCSAFLUSH, &term);
/*
* Prompt for input.
*/
if(*lprom>0) write(*fd, _fcdtocp(cprom), *lprom);
/*
* Read up to 'ntry' characters from the terminal.
*/
ndone = 0;
ntry = *lbuf;
do {
nread = read(*fd, &buff[ndone], ntry);
ndone += nread;
ntry -= nread;
} while(nread>0 && ntry>0);
/*
* Restore the previous terminal mode flags.
*/
tcsetattr(*fd, TCSAFLUSH, &saveterm);
};
*lbuf=ndone;
return;
}
|