Subversion Repositories Kolibri OS

Rev

Rev 5198 | Rev 6744 | 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;
118
        return (-1);
119
    };
120
 
5198 serge 121
    if (filename[0]=='/')
122
    {
123
        strcpy(buf,filename);
124
    }
125
    else
126
    {
127
        getccwd(buf, 1024);
128
        buildpath(buf, filename);
129
    }
4921 Serge 130
 
5198 serge 131
    err = get_fileinfo(buf, &info);
132
 
4921 Serge 133
    if( flags & O_EXCL &&
134
        flags & O_CREAT )
135
    {
136
        if( !err )
137
        {
138
            errno = EEXIST;
139
            return (-1);
140
        };
141
    }
142
 
143
    if( err )
144
    {
145
        if(flags & O_CREAT)
5198 serge 146
            err=create_file(buf);
4921 Serge 147
        if( err )
148
        {
149
            errno = EACCES;
150
            return -1;
151
        };
152
    };
153
 
154
    if( flags & O_TRUNC )
5198 serge 155
        set_file_size(buf, 0);
4921 Serge 156
 
157
    ioh = &__io_tab[hid];
158
 
159
    rwmode = flags & ( O_RDONLY | O_WRONLY | O_RDWR );
160
 
161
    iomode = 0;
162
    offset = 0;
163
 
164
    if( rwmode == O_RDWR )
165
        iomode |= _READ | _WRITE;
166
    else if( rwmode == O_RDONLY)
167
        iomode |= _READ;
168
    else if( rwmode == O_WRONLY)
169
        iomode |= _WRITE;
170
 
171
    if( flags & O_APPEND )
172
    {
173
        iomode |= _APPEND;
174
        offset = info.size;
175
    };
176
 
177
    if( flags & (O_BINARY|O_TEXT) )
178
    {
179
        if( flags & O_BINARY )
180
            iomode |= _BINARY;
181
    } else
182
        iomode |= _BINARY;
183
 
5198 serge 184
    ioh->name   = strdup(buf);
4921 Serge 185
    ioh->offset = offset;
186
    ioh->mode   = iomode;
187
    ioh->read   = read_file;
188
    ioh->write  = write_file;
189
 
190
    return hid;
191
};
192