Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
4921 Serge 1
/* open.c -- open a file.
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 
16
#include 
17
#include 
18
#include 
19
#include "glue.h"
20
#include "io.h"
21
 
22
#undef erro
23
extern int errno;
24
 
5198 serge 25
static inline int is_slash(char c)
26
{
27
    return c=='/' || c=='\\';
28
}
29
 
30
void fix_slashes(char * in,char * out)
31
{
32
    int slash_count;
33
 
34
    for(slash_count=1;in && out && *in;in++)
35
    {
36
        if(is_slash(*in))
37
        {
38
            slash_count++;
39
            continue;
40
        }
41
        else
42
        {
43
            if(slash_count)
44
            {
45
                slash_count=0;
46
                *out++='/';
47
            }
48
            *out++=*in;
49
        }
50
    }
51
    *out='\0';
52
};
53
 
54
 
55
void buildpath(char *buf, const char* file)
56
{
57
    char *ptr;
58
 
59
    ptr = buf + strlen(buf);
60
 
61
    while (*file)
62
    {
63
        if (file[0] == '.' && file[1] == 0)
64
            break;
65
 
66
        if (file[0] == '.' && file[1] == '/')
67
        {
68
            file+=2;
69
            continue;
70
        };
71
 
72
        if (file[0] == '.' && file[1] == '.' &&
73
            (file[2] == 0 || file[2] == '/'))
74
        {
75
            while (ptr > buf && ptr[-1] != '/')
76
                --ptr;
77
            file+=2;
78
            if (*file == 0)
79
                break;
80
            ++file;
81
            continue;
82
        }
83
        *ptr++ = '/';
84
        if (*file == '/')
85
            ++file;
86
        while (*file && *file!='/')
87
            *ptr++ = *file++;
88
    }
89
    *ptr = 0;
90
};
91
 
92
static char *getccwd(char *buf, size_t size)
93
{
94
    int bsize;
95
    __asm__ __volatile__(
96
    "int $0x40"
97
    :"=a"(bsize)
98
    :"a"(30),"b"(2),"c"(buf), "d"(size)
99
    :"memory");
100
 
101
    return buf;
102
};
103
 
4921 Serge 104
int open (const char * filename, int flags, ...)
105
{
5198 serge 106
    char buf[1024];
107
 
4921 Serge 108
    __io_handle *ioh;
109
    fileinfo_t   info;
110
    int iomode, rwmode, offset;
111
    int hid;
112
    int err;
113
 
114
    hid = __io_alloc();
115
    if(hid < 0)
116
    {
117
        errno = EMFILE;
6744 siemargl 118
        __io_free(hid);
4921 Serge 119
        return (-1);
120
    };
121
 
5198 serge 122
    if (filename[0]=='/')
123
    {
124
        strcpy(buf,filename);
125
    }
126
    else
127
    {
128
        getccwd(buf, 1024);
129
        buildpath(buf, filename);
130
    }
4921 Serge 131
 
5198 serge 132
    err = get_fileinfo(buf, &info);
133
 
4921 Serge 134
    if( flags & O_EXCL &&
135
        flags & O_CREAT )
136
    {
137
        if( !err )
138
        {
139
            errno = EEXIST;
6744 siemargl 140
            __io_free(hid);
4921 Serge 141
            return (-1);
142
        };
143
    }
144
 
145
    if( err )
146
    {
147
        if(flags & O_CREAT)
5198 serge 148
            err=create_file(buf);
4921 Serge 149
        if( err )
150
        {
151
            errno = EACCES;
6744 siemargl 152
            __io_free(hid);
4921 Serge 153
            return -1;
154
        };
155
    };
156
 
157
    if( flags & O_TRUNC )
5198 serge 158
        set_file_size(buf, 0);
4921 Serge 159
 
160
    ioh = &__io_tab[hid];
161
 
162
    rwmode = flags & ( O_RDONLY | O_WRONLY | O_RDWR );
163
 
164
    iomode = 0;
165
    offset = 0;
166
 
167
    if( rwmode == O_RDWR )
168
        iomode |= _READ | _WRITE;
169
    else if( rwmode == O_RDONLY)
170
        iomode |= _READ;
171
    else if( rwmode == O_WRONLY)
172
        iomode |= _WRITE;
173
 
174
    if( flags & O_APPEND )
175
    {
176
        iomode |= _APPEND;
177
        offset = info.size;
178
    };
179
 
180
    if( flags & (O_BINARY|O_TEXT) )
181
    {
182
        if( flags & O_BINARY )
183
            iomode |= _BINARY;
184
    } else
185
        iomode |= _BINARY;
186
 
5198 serge 187
    ioh->name   = strdup(buf);
4921 Serge 188
    ioh->offset = offset;
189
    ioh->mode   = iomode;
190
    ioh->read   = read_file;
191
    ioh->write  = write_file;
192
 
193
    return hid;
194
};
195