Пример #1
0
size_t readbytes( b_file *io, char *buff, size_t len )
//====================================================
{
    size_t      bytes_read;
    size_t      total;
    size_t      amt;

    total = 0;
    amt = MAX_SYSIO_SIZE;
    while( len > 0 ) {
        if( amt > len )
            amt = len;
        bytes_read = posix_read( io->handle, buff, amt );
        if( bytes_read == READ_ERROR ) {
            FSetSysErr( io );
            return( READ_ERROR );
        } else if( bytes_read == 0 ) {
            if( total != 0 )
                break;
            FSetEof( io );
            return( READ_ERROR );
        }
        io->phys_offset += (unsigned long)bytes_read;
        total += bytes_read;
        buff += bytes_read;
        len -= bytes_read;
        if( bytes_read < amt ) {
            break;
        }
    }
    return( total );
}
Пример #2
0
static size_t GetVariableRec( b_file *io, char *b, size_t len )
//=============================================================
// Get a record from a file with "variable" records.
{
    size_t      tag_len;
    unsigned_32 tag;
    unsigned_32 save_tag;

    if( SysRead( io, (char *)(&tag), sizeof( unsigned_32 ) ) == READ_ERROR ) {
        return( 0 );
    }
    save_tag = tag;
    tag_len = tag & 0x7fffffff;
    if( tag_len > len ) {
        FSetTrunc( io );
        if( SysRead( io, b, len ) == READ_ERROR )
            return( 0 );
        if( SysSeek( io, (long)tag_len - (long)len, SEEK_CUR ) < 0 ) {
            FSetSysErr( io );
            return( 0 );
        }
    } else {
        if( SysRead( io, b, tag_len ) == READ_ERROR )
            return( 0 );
        len = tag_len;
    }
    if( SysRead( io, (char *)(&tag), sizeof( unsigned_32 ) ) == READ_ERROR )
        return( 0 );
    if( tag != save_tag ) {
        FSetErr( IO_BAD_RECORD, io );
        return( 0 );
    }
    return( len );
}
Пример #3
0
void    ReportNExist( ftnfile *fcb ) {
//====================================

// Set i/o error condition to "file not found".

    errno = ENOENT;
    FSetSysErr( fcb->fileptr );
}
Пример #4
0
b_file  *Openf( char *f, f_attrs attrs ) {
// Open a file.
    int         retc;
    long int    fpos;
#if defined( __WATCOMC__ ) || !defined( __UNIX__ )
    int         share;

    share = SH_COMPAT;
    if( attrs & S_DENYRW ) {
        share = SH_DENYRW;
    } else if( attrs & S_DENYWR ) {
        share = SH_DENYWR;
    } else if( attrs & S_DENYRD ) {
        share = SH_DENYRD;
    } else if( attrs & S_DENYNO ) {
        share = SH_DENYNO;
    }
#endif
    if( attrs & WRONLY ) {
        attrs |= WRITE_ONLY;
        if( attrs & APPEND ) {
            retc = sopen4( f, O_WRONLY | O_BINARY | O_CREAT, share, PMODE_RW );
        } else {
            retc = sopen4( f, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, share, PMODE_RW );
        }
    } else if( attrs & RDONLY ) {
        retc = sopen3( f, O_RDONLY | O_BINARY, share );
    } else { // if( attrs & RDWR ) {
        retc = sopen4( f, O_RDWR | O_BINARY | O_CREAT, share, PMODE_RW );
    }
    if( retc < 0 ) {
        FSetSysErr( NULL );
        return( NULL );
    }
    fpos = 0;
    if( attrs & APPEND ) {
        fpos = lseek( retc, 0, SEEK_END );
        if( fpos < 0 ) {
            FSetSysErr( NULL );
            close( retc );
            return( NULL );
        }
    }
    return( _AllocFile( retc, attrs, fpos ) );
}
Пример #5
0
b_file  *_AllocFile( int h, f_attrs attrs, long int fpos ) {
// Allocate file structure.
    b_file      *io;
    struct stat info;
    int         buff_size;

    if( fstat( h, &info ) == -1 ) {
        FSetSysErr( NULL );
        return( NULL );
    }
    attrs &= ~CREATION_MASK;
    if( S_ISCHR( info.st_mode ) ) {
        io = MEM_ALLOC( sizeof( a_file ) );
        // Turn off truncate just in case we turned it on by accident due to
        // a buggy NT dos box.  We NEVER want to truncate a device.
        attrs &= ~TRUNC_ON_WRITE;
        attrs |= CHAR_DEVICE;
    } else {
        attrs |= BUFFERED;
        buff_size = IOBufferSize;
        io = MEM_ALLOC( sizeof( b_file ) + IOBufferSize - MIN_BUFFER );
        if( ( io == NULL ) && ( IOBufferSize > MIN_BUFFER ) ) {
            // buffer is too big (low on memory) so use small buffer
            buff_size = MIN_BUFFER;
            io = MEM_ALLOC( sizeof( b_file ) );
        }
    }
    if( io == NULL ) {
        close( h );
        FSetErr( IO_NO_MEM, NULL );
    } else {
        if( attrs & CARRIAGE_CONTROL ) {
            attrs |= CC_NOLF;
        }
        io->attrs = attrs;
        io->handle = h;
        if( attrs & BUFFERED ) {
            io->b_curs = 0;
            io->read_len = 0;
            io->buff_size = buff_size;
            io->high_water = 0;
        }
        io->phys_offset = fpos;
        IOOk( io );
    }
    return( io );
}
Пример #6
0
void    Closef( b_file *io ) {
// Close a file.
    uint        cc_len;
    char        *cc;

    if( io->attrs & CARRIAGE_CONTROL ) {
        cc_len = FSetCC( io, ' ', &cc );
        if( SysWrite( io, cc, cc_len ) == -1 ) return;
    }
    if( FlushBuffer( io ) < 0 ) return;
    if( close( io->handle ) < 0 ) {
        FSetSysErr( io );
        return;
    }
    MEM_FREE( io );
    IOOk( NULL );
}
Пример #7
0
static  void    SysIOInfo( ftnfile *fcb ) {
//=========================================

// Get system file information.

    struct stat         info;
    char                *sys_name;
    bool                exist = true;

    if( fcb->bufflen == 0 ) {
        fcb->bufflen = SYS_DFLT_RECSIZE;
    }
    if( fcb->blocksize == 0 ) {
        fcb->blocksize = IO_BUFFER;
    }
    fcb->device = 0;
    if( fcb->fileptr != NULL ) { // file is open
#if defined( __NETWARE__ )
        if( ( ((a_file *)(fcb->fileptr))->handle == STDIN_FILENO ) ||
            ( ((a_file *)(fcb->fileptr))->handle == STDOUT_FILENO ) ||
            ( ((a_file *)(fcb->fileptr))->handle == STDERR_FILENO ) ) {
            fcb->device |= INFO_DEV;
        } else {
#endif
        // for stdin, don't use file name "CON" since information will always
        // indicate it's a device even if stdin is redirected
            if( fstat( ((a_file *)(fcb->fileptr))->handle, &info ) == -1 ) {
                FSetSysErr( fcb->fileptr );
                IOErr( IO_FILE_PROBLEM );
                return;
            }
            if( S_ISCHR( info.st_mode ) ) {
                fcb->device |= INFO_DEV;
#if defined( __DOS__ ) || defined( __WINDOWS__ )
            } else {
                fcb->device |= INFO_VALID_DRIVE;
#endif
            }
#if defined( __NETWARE__ )
        }
#endif
    } else {
        if( stat( fcb->filename, &info ) == -1 ) {
            // if we are trying to open a file in a non-existent
            // directory we don't want to issue an error
            if( fcb->flags & FTN_FSEXIST ) {
                FSetSysErr( fcb->fileptr );
                IOErr( IO_FILE_PROBLEM );
                return;
            }
            exist = false;
        } else if( S_ISCHR( info.st_mode ) ) {
            fcb->device |= INFO_DEV;
            // devices always exist
            fcb->flags |= FTN_FSEXIST;
#if !defined( __UNIX__ )
        } else {
            fcb->device |= INFO_VALID_DRIVE;
#endif
        }
    }
    if( ( fcb->flags & FTN_FSEXIST ) && !IsDevice( fcb ) ) {
#if !defined( __UNIX__ )
        // Assume the two most significant bits contain no useful information
        fcb->device = INFO_DRIVE & info.st_dev; // save drive letter
#endif
        if( ( info.st_mode & S_IRUSR ) && ( info.st_mode & S_IWUSR ) ) {
            fcb->action = ACTION_RW;
        } else if( info.st_mode & S_IRUSR ) {
            fcb->action = ACTION_READ;
        } else if( info.st_mode & S_IWUSR ) {
            fcb->action = ACTION_WRITE;
        } else {
            // if none of the above are set,
            // assume read/write
            fcb->action = ACTION_RW;
        }
    }
    sys_name = GetSysName( fcb );
    if( sys_name == NULL ) {
        if( exist ) {
            FSetSysErr( fcb->fileptr );
            IOErr( IO_FILE_PROBLEM );
        }
        return;
    }
    RMemFree( fcb->filename );
    fcb->filename = sys_name;
}
Пример #8
0
int     SysSeek( b_file *io, long int new_offset, int seek_mode )
{
    long int    curr_offset;
    long int    new_page;
    long int    page_offset;
    uint        bytes_read;

    curr_offset = CurrFileOffset( io );
    if( seek_mode == SEEK_CUR ) {
        new_offset += curr_offset;
    }
    if( io->attrs & WRITE_ONLY ) {
        if( curr_offset != new_offset ) {
            if( FlushBuffer( io ) < 0 ) {
                FSetSysErr( io );
                return( -1 );
            }
            if( lseek( io->handle, new_offset, SEEK_SET ) == -1 ) {
                FSetSysErr( io );
                return( -1 );
            }
            io->phys_offset = new_offset;
        }
        return( 0 );
    } else if( io->attrs & READ_AHEAD ) {
        page_offset = io->phys_offset - io->read_len;
        if( page_offset <= new_offset ) {
            if( (new_offset < io->phys_offset) ||
                ( (io->attrs & PAST_EOF) &&
                  (new_offset < page_offset + io->buff_size) ) ) {
                // we have the part of file in memory still, or we know we're
                // at the end of the file and the offset we want is on this
                // page as well
                io->b_curs = new_offset - io->phys_offset + io->read_len;
                return( 0 );
            }
        }
    } else if( io->phys_offset <= new_offset &&
                            new_offset < io->phys_offset + io->buff_size ) {
        io->b_curs = new_offset - io->phys_offset;
        if( ( io->attrs & PAST_EOF ) || io->b_curs < io->high_water ) {
            // We already know that the EOF is on this page so don't bother
            // seeking and reading.  Or we already have the part of the
            // file in the buffer.
            return( 0 );
        }
        // we have part of this page in memory already... so read the
        // rest of the page
        if( lseek( io->handle, io->high_water, SEEK_CUR ) < 0 ) {
            FSetSysErr( io );
            return( -1 );
        }
        io->phys_offset += io->high_water;
        bytes_read = readbytes( io, io->buffer + io->high_water,
                                            io->buff_size - io->high_water );
        if( bytes_read == READ_ERROR ) {
            if( io->stat != IO_EOF ) return( -1 );
            IOOk( io );
            io->phys_offset -= io->high_water;  // restore offset
            if( lseek( io->handle, -(long)io->high_water, SEEK_CUR ) < 0 ) {
                FSetSysErr( io );
                return( -1 );
            }
            io->attrs |= PAST_EOF;              // we now know the EOF is here
        } else {
            io->attrs |= READ_AHEAD;
            io->read_len = io->high_water + bytes_read;
            if( bytes_read < io->buff_size - io->high_water ) {
                io->attrs |= PAST_EOF;          // we now know the EOF is here
            }
        }
        return( 0 );
    }
    if( new_offset != curr_offset ) {
        if( FlushBuffer( io ) < 0 ) return( 0 );
        // round down to the nearest multiple of buff_size
        new_page = new_offset - new_offset % io->buff_size;
        if( lseek( io->handle, new_page, SEEK_SET ) < 0 ) {
            FSetSysErr( io );
            return( -1 );
        }
        io->phys_offset = new_page;
        io->b_curs = new_offset - new_page;
        bytes_read = readbytes( io, io->buffer, io->buff_size );
        if( bytes_read == READ_ERROR ) {
            if( io->stat != IO_EOF ) return( -1 );
            IOOk( io );
            io->attrs |= PAST_EOF;
        } else {
            if( bytes_read < io->buff_size ) {
                io->attrs |= PAST_EOF;
            } else {
                io->attrs &= ~PAST_EOF;
            }
            io->attrs |= READ_AHEAD;
            io->read_len = bytes_read;
        }
    }
    return( 0 );
}