#include <sys/types.h>
#include "file64.h"
#include <stdio.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <sys/file.h>
#include "stdiom.h"
#define ALWAYS_LARGE_OPEN 1
#define LARGE_OPEN (_FILE_OFFSET_BITS == 64)
static FILE *
_endopen(const char *file, const char *mode, FILE *iop, int largefile)
{
int plus, oflag, fd;
if (iop == NULL || file == NULL || file[0] == '\0')
return (NULL);
plus = (mode[1] == '+');
switch (mode[0]) {
case 'w':
oflag = (plus ? O_RDWR : O_WRONLY) | O_TRUNC | O_CREAT;
break;
case 'a':
oflag = (plus ? O_RDWR : O_WRONLY) | O_CREAT;
break;
case 'r':
oflag = plus ? O_RDWR : O_RDONLY;
break;
default:
return (NULL);
}
if (largefile) {
fd = open64(file, oflag, 0666);
} else {
fd = open(file, oflag, 0666);
}
if (fd < 0)
return (NULL);
iop->_cnt = 0;
#ifdef _LP64
iop->_file = fd;
#else
if (fd <= _FILE_FD_MAX) {
SET_FILE(iop, fd);
} else if (_file_set(iop, fd, mode) != 0) {
(void) close(fd);
return (NULL);
}
#endif
iop->_flag = plus ? _IORW : (mode[0] == 'r') ? _IOREAD : _IOWRT;
if (mode[0] == 'a') {
if ((lseek64(fd, 0L, SEEK_END)) < 0) {
(void) close(fd);
return (NULL);
}
}
iop->_base = iop->_ptr = NULL;
return (iop);
}
FILE *
fopen(const char *file, const char *mode)
{
FILE *iop;
FILE *rc;
iop = _findiop();
rc = _endopen(file, mode, iop, LARGE_OPEN);
if (rc == NULL && iop != NULL)
iop->_flag = 0;
return (rc);
}
#if !defined(_LP64)
FILE *
fopen64(const char *file, const char *mode)
{
FILE *iop;
FILE *rc;
iop = _findiop();
rc = _endopen(file, mode, iop, ALWAYS_LARGE_OPEN);
if (rc == NULL && iop != NULL)
iop->_flag = 0;
return (rc);
}
#endif
FILE *
freopen(const char *file, const char *mode, FILE *iop)
{
(void) fclose(iop);
return (_endopen(file, mode, iop, LARGE_OPEN));
}
#if !defined(_LP64)
FILE *
freopen64(const char *file, const char *mode, FILE *iop)
{
(void) fclose(iop);
return (_endopen(file, mode, iop, ALWAYS_LARGE_OPEN));
}
#endif