I am writing a more command for my class, and have it most of the way done, but with my current implimentation when I pipe stdin to my code it doesnt use my non-canonical/non echo settings I set for the terminal window. Do I need to specify a different terminal in order for this to work ? It works great when I just use the program on an file.
I will paste the code below
\#include <stdio.h>
\#include <stdlib.h>
\#include <sys/types.h>
\#include <sys/ioctl.h>
\#include <termios.h>
\#include <unistd.h>
\#include <sys/stat.h>
\#include <string.h>
\#define PAGELEN 24
\#define LINELEN 512
int FILE_SIZE = 0; //holds the global file size for my %'s
int READ_SIZE = 0;
int FIRST_READ = 0; //flag to decide wether to display first time info, or just %
void do_more\( FILE *fp, char *file_read,int\);
int see_more\(FILE *cmd, char *file_read,int\);
void cbreak\(struct termios tty\)
\{
tty.c_lflag = tty.c_lflag & ~\(ECHO | ECHOK | ICANON\);
tty.c_cc[VTIME] = 1;
tcsetattr\(0, TCSANOW, &tty\);
\}
int main\(int argc, char **argv\)
\{
FILE *fp;
struct termios tty, otty;
int i, j;
struct stat file_info; //buffer for file info
tcgetattr\(0, &otty\); // Get original tty settings and save them in otty
tty = otty;
cbreak\(tty\); //turns off echo and on non-canonical
if \( argc == 1 \)\{
fp = stdin;
do_more\( fp,argv[0],1 \);
\}else
while \( --argc \)\{
if \( \(fp = fopen\( *\+\+argv , "r" \)\) != NULL \)
\{
if \(stat\(argv[0],&file_info\) == -1\)\{ //error condition
perror\(argv[0]\);
\}else\{
FILE_SIZE = file\_info.st_size;
do_more\( fp,argv[0],0 \) ;
fclose\( fp \);
\}
\}
else
printf\("%s: No such file or directory.\\n",argv[0]\);
\}
tcsetattr\(0, TCSANOW, &otty\); // Reset to the original settings
return \(0\);
\}
void do_more( FILE *fp, char *file_read,int is_stdin)
{
char line[LINELEN];
int num\_of_lines = 0;
int see_more\(FILE *, char*,int\), reply;
FILE *fp_tty;
fp_tty = fopen\( "/dev/tty", "r" \); /* NEW: cmd stream */
if \( fp_tty == NULL \) /* if open fails */
exit\(1\); /* no use in running */
while \( fgets\( line, LINELEN, fp \) \)\{ /* more input */
if \( num\_of_lines == PAGELEN \) \{ /* full screen? */
reply = see\_more\(fp_tty, file\_read,is_stdin\); /* NEW: pass FILE * */
if \( reply == 0 \)\{ /* n: done */
printf\("\\n"\);
break;
\}
num\_of_lines -= reply; /* reset count */
\}
if \( fputs\( line, stdout \) == EOF \) /* show line */
exit\(1\); /* or die */
else
READ_SIZE \+= strlen\(line\); //adds the total
num\_of_lines\+\+; /* count it */
\}
}
int see_more(FILE *cmd, char file_read, int is_stdin) / NEW: accepts arg */
{
int c;
if (is_stdin == 0){
if (FIRST_READ == 0){
printf("\033[7m%s: %.1f%%\033[m",file_read,((float)READ_SIZE/(float)FILE_SIZE)100); / reverse on a vt100 */
FIRST_READ++;
}else
printf("\033[7m%.1f%%\033[m",((float)READ_SIZE/(float)FILE_SIZE)100); / reverse on a vt100 */
}else{
printf("\033[7mbytes %d\033[m",READ_SIZE);
}
while\( \(c=getc\(cmd\)\) != EOF \) // NEW: reads from tty
\{
if \( c == 'q' \) // q -> N
return 0;
if \( c == ' ' \) // ' ' => next p
return PAGELEN; // how many to show
if \( c == '\\n' \) // Enter key => 1 line
return 1;
\}
}