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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
#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 <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#ifdef PG_PPU
#define GROTER groter_
#define GRWTER grwter_
#define GRCTER grcter_
#define GRPTER grpter_
#else
#define GROTER groter
#define GRWTER grwter
#define GRCTER grcter
#define GRPTER grpter
#endif
/* 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)
*/
int GROTER(cdev, ldev, cdev_len)
char *cdev; int *ldev;
int cdev_len;
{
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, 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(fd)
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(fd, cbuf, lbuf, cbuf_len)
int *fd; char *cbuf; int *lbuf; int cbuf_len;
{
int nwritten = write (*fd, 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(fd, cprom, lprom, cbuf, lbuf, cprom_len, cbuf_len)
int *fd; char *cprom; int *lprom; char *cbuf; int *lbuf;
int cprom_len; int cbuf_len;
{
char *buff = 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, 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;
}
|