Re: Strange pager (less, more) behavior




On Wed, 29 Mar 2006 07:28:12 +0200, Kasper Dupont wrote:

I don't think above piece of code is the reason for the
problem, but maybe you are doing something else wrong.
Could you post the source for the smallest program which
produce the problem?


Here's a quick-and-dirty 'cat' clone that produces the problem:


[start]
/* mycat.c */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <unistd.h>

static FILE *openfile (const char *filename,
const char *mode,
FILE *defaultfile)
{
FILE *f;
if (!filename || strcmp (filename, "-") == 0)
{
if (defaultfile)
return defaultfile;
else
{
fprintf (stderr, "openfile: no default file\n");
return NULL;
}
}
else if (!(f = fopen (filename, mode)))
return NULL;
else
return f;
}

static int closefile (FILE *f,
const char *filename)
{
int rc;
if (f == stdin ||
f == stdout ||
f == stderr)
return 0;
else
{
if ((rc = fclose (f)) != 0)
{
if (filename)
perror (filename);
}
return rc;
}
}

static int copy_file (const char *infilename,
FILE *outfile,
const int verbose)
{
FILE *infile;
char inrec[1024+1];
int rc = 0, close_rc;

if (!(infile = openfile (infilename, "r", NULL)))
return 1;
if (verbose)
{
fflush (stdout);
fprintf (stderr, "[%s]\n", infilename);
}
while (fgets (inrec, sizeof (inrec), infile))
{
fputs (inrec, outfile);
}
if (!feof (infile))
{
perror (infilename);
rc = 1;
}
close_rc = closefile (infile, infilename);
if (close_rc != 0 && rc == 0)
rc = close_rc;
return rc;
}

int main (int argc,
char *argv[])
{
char *ourname;
FILE *outfile;
char *outfilename = "-";
int rc, close_rc;
int verbose = 0;
int ch, error = 0;

ourname = argv[0];
optind = 1;
while (!error &&
(ch = getopt (argc, argv, "o:v")) != EOF)
{
switch (ch)
{
case 'o':
outfilename = optarg;
break;
case 'v':
++verbose;
break;
default:
error = 1;
break;
}
}
argc -= optind;
argv += optind;
if (error)
{
fprintf (stderr, "usage: %s [-v] [-o file] [file...]\n",
ourname);
return EXIT_FAILURE;
}
if (!(outfile = openfile (outfilename, "w", stdout)))
return EXIT_FAILURE;
if (argc)
{
rc = 0;
for (; argc; rc == 0 && --argc, ++argv)
rc = copy_file (*argv, outfile, verbose);
}
else
rc = copy_file ("-", outfile, verbose);
close_rc = closefile (outfile, outfilename);
if (close_rc != 0 && rc == 0)
rc = close_rc;
return (rc == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
[end]

I apologize for the length of this program, but I wanted to include
openfile() and closefile() functions that are somewhat similar to the
ones I actually use.

I've recreated my problem using this command line (run in a
directory with 71 .c files):

$ ./mycat *.c | less

As with my other programs, 'less' is stuck waiting on tcsetattr()
as called from raw_mode().

Dave
--
Dave Ulrick
Email: d-ulrick@xxxxxxx
Web: http://www.niu.edu/~ulrick/
.



Relevant Pages