Subversion Repositories Kolibri OS

Rev

Rev 4921 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4921 Serge 1
/* read.c -- read bytes from a input device.
2
 *
3
 * Copyright (c) 1995 Cygnus Support
4
 *
5
 * The authors hereby grant permission to use, copy, modify, distribute,
6
 * and license this software and its documentation for any purpose, provided
7
 * that existing copyright notices are retained in all copies and that this
8
 * notice is included verbatim in any distributions. No written agreement,
9
 * license, or royalty fee is required for any of the authorized uses.
10
 * Modifications to this software may be copyrighted by their authors
11
 * and need not follow the licensing terms described here, provided that
12
 * the new terms are clearly indicated on the first page of each file where
13
 * they apply.
14
 */
15
#include 
6536 serge 16
#include 
4921 Serge 17
#include "io.h"
18
 
19
#undef erro
20
extern int errno;
21
 
22
ssize_t read(int fd, void *buf, size_t cnt)
23
{
24
    _ssize_t ret;
25
 
26
    _ssize_t  read_len, total_len;
27
    unsigned  reduce_idx, finish_idx;
28
    unsigned  iomode_flags;
29
    char     *buffer = buf;
30
    int       rc;
31
    int       h;
32
    unsigned amount_read;
33
    int err;
34
 
35
    __io_handle *ioh;
36
 
37
    if( (fd < 0) || (fd >=64) )
38
    {
39
        errno = EBADF;
40
        return -1;
41
    };
42
 
43
    ioh = &__io_tab[fd];
44
 
45
    iomode_flags = ioh->mode;
46
 
47
    if( iomode_flags == 0 )
48
    {
49
        errno = EBADF;
50
        return( -1 );
51
    }
52
 
53
    if( !(iomode_flags & _READ) )
54
    {
55
        errno = EACCES;
56
        return( -1 );
57
    }
58
 
59
    if( iomode_flags & _BINARY )   /* if binary mode */
60
    {
6536 serge 61
        err = ioh->read(ioh->name, buffer, ioh->offset, cnt, &amount_read);
4921 Serge 62
        ioh->offset+= amount_read;
63
        total_len  = amount_read;
64
 
65
        if(err)
66
            if ( amount_read == 0)
67
                return (-1);
68
    }
69
    else
70
    {
71
        total_len = 0;
72
        read_len = cnt;
73
        do
74
        {
6536 serge 75
            err=ioh->read(ioh->name,buffer, ioh->offset, cnt, &amount_read);
4921 Serge 76
            ioh->offset+=amount_read;
77
 
78
            if( amount_read == 0 )
79
                break;                   /* EOF */
80
 
81
            reduce_idx = 0;
82
            finish_idx = reduce_idx;
83
            for( ; reduce_idx < amount_read; ++reduce_idx )
84
            {
85
                if( buffer[ reduce_idx ] == 0x1a )     /* EOF */
86
                {
87
                    lseek(fd, ((long)reduce_idx - (long)amount_read)+1L, SEEK_CUR );
88
                    total_len += finish_idx;
89
                    return( total_len );
90
                }
91
                if( buffer[ reduce_idx ] != '\r' )
92
                {
93
                    buffer[ finish_idx++ ] = buffer[ reduce_idx ];
94
                };
95
            }
96
 
97
            total_len += finish_idx;
98
            buffer += finish_idx;
99
            read_len -= finish_idx;
100
            if( iomode_flags & _ISTTY )
101
            {
102
                break;
103
            }
104
        } while( read_len != 0 );
105
    }
106
    return( total_len );
107
}