diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-17 21:41:51 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-17 21:41:51 +0000 |
commit | 487ca4806cc046076293cf6cc5fbba0db282bac7 (patch) | |
tree | 847b412ab5158dd7bdd7ed7e5a4cc3fbca94be32 /Build/source/texk/seetexk/seek.c | |
parent | a3d3111bfe26b8e5f5bc6049dfb2a4ca2edc7881 (diff) |
texk 1
git-svn-id: svn://tug.org/texlive/trunk@1485 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/seetexk/seek.c')
-rw-r--r-- | Build/source/texk/seetexk/seek.c | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/Build/source/texk/seetexk/seek.c b/Build/source/texk/seetexk/seek.c new file mode 100644 index 00000000000..64c8baa7037 --- /dev/null +++ b/Build/source/texk/seetexk/seek.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 1987, 1989 University of Maryland + * Department of Computer Science. All rights reserved. + * Permission to copy for any purpose is hereby granted + * so long as this copyright notice remains intact. + */ + +#ifndef lint +static char rcsid[] = "$Header: /usr/src/local/tex/local/mctex/lib/RCS/seek.c,v 3.1 89/08/22 21:59:04 chris Exp $"; +#endif + +/* + * SeekFile copies an input stdio file, if necessary, so that + * it produces a stdio file on which fseek() works properly. + * It returns NULL if this cannot be done; in that case, the + * input file is closed (or otherwise rendered worthless). + * + * CopyFile copies an input file unconditionally. (On non-Unix + * machines, it might `accidentally' not copy it.) + * + * On Unix machines, this means `if the input is a pipe or tty, + * copy it to a temporary file'. On other systems, all stdio files + * might happen to be seekable. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef KPATHSEA +#include <kpathsea/c-fopen.h> +#endif + +#include <stdio.h> +#include "types.h" /* for BSD_FILE_SYSTEM */ +#include "seek.h" + +#ifdef HAVE_PROTOTYPES +extern int MakeRWTempFile(char *); +#else +extern int MakeRWTempFile(); +#endif + +#ifdef EASY_BUT_NOT_GOOD + +FILE *CopyFile(f) FILE *f; { return (f); } +FILE *SeekFile(f) FILE *f; { return (f); } + +#else + +#include <errno.h> +#ifdef BSD_FILE_SYSTEM +#include <sys/param.h> /* want MAXBSIZE */ +#else +#include <sys/types.h> +#endif +#include <sys/stat.h> + +#ifndef KPATHSEA +long lseek(); +char *malloc(); + +extern int errno; +#endif + +/* + * Make and return a version of `f' on which fseek works (unconditionally). + * This code is somewhat Unix-specific. + */ +FILE * +CopyFile(f) + FILE *f; +{ + register int tf, n, ifd, w; + register char *p, *buf; + register int blksize; + struct stat st; + int e; +#ifdef MAXBSIZE +#define BSIZE MAXBSIZE +#else +#define BSIZE BUFSIZ +#endif + char stackbuf[BSIZE]; +#if defined(WIN32) || defined(MSDOS) || defined(__CYGWIN32__) + int orig_fdmode; +#endif + char *open_mode; + + /* get a read/write temp file which will vanish when closed */ + if ((tf = MakeRWTempFile(stackbuf)) < 0) { + e = errno; + (void) fclose(f); + errno = e; + return (NULL); + } + + /* compute buffer size and choose buffer */ + ifd = fileno(f); + buf = stackbuf; + blksize = sizeof stackbuf; +#ifdef BSD_FILE_SYSTEM + if (fstat(tf, &st) == 0 && st.st_blksize > blksize) { + /* + * The output block size is the important one, + * but the input block size is not irrelevant. + * + * This should actually compute the lcm, but we + * will rely on block sizes being powers of two + * (so that the larger is the lcm). + */ + blksize = st.st_blksize; + if (fstat(ifd, &st) == 0 && st.st_blksize > blksize) + blksize = st.st_blksize; + if ((buf = malloc((unsigned)blksize)) == NULL) { + buf = stackbuf; + blksize = sizeof stackbuf; + } + } +#endif + +#if defined(WIN32) || defined(MSDOS) || defined(__CYGWIN32__) + /* make sure we open the temp file in the same mode that + the original handle was open. */ + orig_fdmode = setmode(ifd, 0); + setmode(tf, orig_fdmode); +#endif + /* copy from input file to temp file */ + (void) lseek(ifd, 0L, 0); /* paranoia */ + while ((n = read(ifd, p = buf, blksize)) > 0) { + do { + if ((w = write(tf, p, n)) < 0) { + (void) close(tf); + (void) fclose(f); + return (NULL); + } + p += w; + } while ((n -= w) > 0); + } + e = errno; /* in case n < 0 */ + if (buf != stackbuf) + free(buf); + if (n < 0) { + (void) close(tf); + (void) fclose(f); + errno = e; + return (NULL); + } + + /* discard the input file, and rewind and open the temporary */ + (void) fclose(f); + (void) lseek(tf, 0L, 0); + errno = 0; +#if defined(WIN32) || defined(MSDOS) || defined(__CYGWIN32__) + open_mode = orig_fdmode == O_BINARY ? FOPEN_RBIN_MODE : "r"; +#else + open_mode = "r"; +#endif + if ((f = fdopen(tf, open_mode)) == NULL) { + if (errno == 0) + e = EMFILE; + (void) close(tf); + errno = e; + } + return (f); +} + +/* + * Copy an input file, but only if necessary. + */ +FILE *SeekFile(f) + FILE *f; +{ + int fd = fileno(f); + + return (lseek(fd, 0L, 1) >= 0 && !isatty(fd) ? f : CopyFile(f)); +} + +#endif /* EASY_BUT_NOT_GOOD */ |