#include "config.h"
#ifndef NON_UNIX_STDIO
#define _INCLUDE_POSIX_SOURCE
#define _INCLUDE_XOPEN_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#endif
#include "f2c.h"
#undef abs
#undef min
#undef max
#include <stdlib.h>
#include "fio.h"
#include "fmt.h"
unit f__units[MXUNIT];
int f__init;
cilist *f__elist;
icilist *f__svic;
flag f__reading;
flag f__cplus, f__cblank;
char *f__fmtbuf;
int f__fmtlen;
flag f__external;
int (*f__getn) (void);
void (*f__putn) (int);
int (*f__doed) (struct syl *, char *, ftnlen), (*f__doned) (struct syl *);
int (*f__dorevert) (void), (*f__donewrec) (void), (*f__doend) (void);
flag f__sequential;
flag f__formatted;
FILE *f__cf;
unit *f__curunit;
int f__recpos;
int f__cursor, f__hiwater, f__scale;
char *f__icptr;
char *F_err[] = {
"error in format",
"illegal unit number",
"formatted io not allowed",
"unformatted io not allowed",
"direct io not allowed",
"sequential io not allowed",
"can't backspace file",
"null file name",
"can't stat file",
"unit not connected",
"off end of record",
"truncation failed in endfile",
"incomprehensible list input",
"out of free space",
"unit not connected",
"read unexpected character",
"bad logical input field",
"bad variable type",
"bad namelist name",
"variable not in namelist",
"no end record",
"variable count incorrect",
"subscript for scalar variable",
"invalid array section",
"substring out of bounds",
"subscript out of bounds",
"can't read file",
"can't write file",
"'new' file exists",
"can't append to file",
"non-positive record number",
"I/O started while already doing I/O",
"Temporary file name (TMPDIR?) too long"
};
#define MAXERR (sizeof(F_err)/sizeof(char *)+100)
int
f__canseek (FILE * f)
{
#ifdef NON_UNIX_STDIO
return !isatty (fileno (f));
#else
struct stat x;
if (fstat (fileno (f), &x) < 0)
return (0);
#ifdef S_IFMT
switch (x.st_mode & S_IFMT)
{
case S_IFDIR:
case S_IFREG:
if (x.st_nlink > 0)
return (1);
else
return (0);
case S_IFCHR:
if (isatty (fileno (f)))
return (0);
return (1);
#ifdef S_IFBLK
case S_IFBLK:
return (1);
#endif
}
#else
#ifdef S_ISDIR
if (S_ISREG (x.st_mode) || S_ISDIR (x.st_mode))
{
if (x.st_nlink > 0)
return (1);
else
return (0);
}
if (S_ISCHR (x.st_mode))
{
if (isatty (fileno (f)))
return (0);
return (1);
}
if (S_ISBLK (x.st_mode))
return (1);
#else
Help ! How does fstat work on this system ?
#endif
#endif
return (0);
#endif
}
void
f__fatal (int n, char *s)
{
static int dead = 0;
if (n < 100 && n >= 0)
perror (s);
else if (n >= (int) MAXERR || n < -1)
{
fprintf (stderr, "%s: illegal error number %d\n", s, n);
}
else if (n == -1)
fprintf (stderr, "%s: end of file\n", s);
else
fprintf (stderr, "%s: %s\n", s, F_err[n - 100]);
if (dead)
{
fprintf (stderr, "(libf2c f__fatal already called, aborting.)");
abort ();
}
dead = 1;
if (f__init & 1)
{
if (f__curunit)
{
fprintf (stderr, "apparent state: unit %d ",
(int) (f__curunit - f__units));
fprintf (stderr, f__curunit->ufnm ? "named %s\n" : "(unnamed)\n",
f__curunit->ufnm);
}
else
fprintf (stderr, "apparent state: internal I/O\n");
if (f__fmtbuf)
fprintf (stderr, "last format: %.*s\n", f__fmtlen, f__fmtbuf);
fprintf (stderr, "lately %s %s %s %s",
f__reading ? "reading" : "writing",
f__sequential ? "sequential" : "direct",
f__formatted ? "formatted" : "unformatted",
f__external ? "external" : "internal");
}
f__init &= ~2;
sig_die (" IO", 1);
}
void
f_init (void)
{
unit *p;
if (f__init & 2)
f__fatal (131, "I/O recursion");
f__init = 1;
p = &f__units[0];
p->ufd = stderr;
p->useek = f__canseek (stderr);
p->ufmt = 1;
p->uwrt = 1;
p = &f__units[5];
p->ufd = stdin;
p->useek = f__canseek (stdin);
p->ufmt = 1;
p->uwrt = 0;
p = &f__units[6];
p->ufd = stdout;
p->useek = f__canseek (stdout);
p->ufmt = 1;
p->uwrt = 1;
}
int
f__nowreading (unit * x)
{
off_t loc;
int ufmt, urw;
extern char *f__r_mode[], *f__w_mode[];
if (x->urw & 1)
goto done;
if (!x->ufnm)
goto cantread;
ufmt = x->url ? 0 : x->ufmt;
loc = FTELL (x->ufd);
urw = 3;
if (!freopen (x->ufnm, f__w_mode[ufmt | 2], x->ufd))
{
urw = 1;
if (!freopen (x->ufnm, f__r_mode[ufmt], x->ufd))
{
cantread:
errno = 126;
return 1;
}
}
FSEEK (x->ufd, loc, SEEK_SET);
x->urw = urw;
done:
x->uwrt = 0;
return 0;
}
int
f__nowwriting (unit * x)
{
off_t loc;
int ufmt;
extern char *f__w_mode[];
if (x->urw & 2)
goto done;
if (!x->ufnm)
goto cantwrite;
ufmt = x->url ? 0 : x->ufmt;
if (x->uwrt == 3)
{
if (!(f__cf = x->ufd = freopen (x->ufnm, f__w_mode[ufmt], x->ufd)))
goto cantwrite;
x->urw = 2;
}
else
{
loc = FTELL (x->ufd);
if (!(f__cf = x->ufd = freopen (x->ufnm, f__w_mode[ufmt |= 2], x->ufd)))
{
x->ufd = NULL;
cantwrite:
errno = 127;
return (1);
}
x->urw = 3;
FSEEK (x->ufd, loc, SEEK_SET);
}
done:
x->uwrt = 1;
return 0;
}
int
err__fl (int f, int m, char *s)
{
if (!f)
f__fatal (m, s);
if (f__doend)
(*f__doend) ();
f__init &= ~2;
return errno = m;
}