Subversion Repositories Kolibri OS

Rev

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;
9346 Coldy 81
            //continue;
82
            goto __do_until_slash;
5198 serge 83
        }
84
        *ptr++ = '/';
9346 Coldy 85
__do_until_slash:
5198 serge 86
        if (*file == '/')
87
            ++file;
88
        while (*file && *file!='/')
89
            *ptr++ = *file++;
90
    }
91
    *ptr = 0;
92
};
93
 
94
static char *getccwd(char *buf, size_t size)
95
{
96
    int bsize;
97
    __asm__ __volatile__(
98
    "int $0x40"
99
    :"=a"(bsize)
100
    :"a"(30),"b"(2),"c"(buf), "d"(size)
101
    :"memory");
102
 
103
    return buf;
104
};
105
 
4921 Serge 106
int open (const char * filename, int flags, ...)
107
{
5198 serge 108
    char buf[1024];
109
 
4921 Serge 110
    __io_handle *ioh;
111
    fileinfo_t   info;
112
    int iomode, rwmode, offset;
113
    int hid;
114
    int err;
115
 
116
    hid = __io_alloc();
117
    if(hid < 0)
118
    {
119
        errno = EMFILE;
6744 siemargl 120
        __io_free(hid);
4921 Serge 121
        return (-1);
122
    };
123
 
5198 serge 124
    if (filename[0]=='/')
125
    {
126
        strcpy(buf,filename);
127
    }
128
    else
129
    {
130
        getccwd(buf, 1024);
131
        buildpath(buf, filename);
132
    }
4921 Serge 133
 
5198 serge 134
    err = get_fileinfo(buf, &info);
135
 
4921 Serge 136
    if( flags & O_EXCL &&
137
        flags & O_CREAT )
138
    {
139
        if( !err )
140
        {
141
            errno = EEXIST;
6744 siemargl 142
            __io_free(hid);
4921 Serge 143
            return (-1);
144
        };
145
    }
146
 
147
    if( err )
148
    {
149
        if(flags & O_CREAT)
5198 serge 150
            err=create_file(buf);
4921 Serge 151
        if( err )
152
        {
153
            errno = EACCES;
6744 siemargl 154
            __io_free(hid);
4921 Serge 155
            return -1;
156
        };
157
    };
158
 
159
    if( flags & O_TRUNC )
5198 serge 160
        set_file_size(buf, 0);
4921 Serge 161
 
162
    ioh = &__io_tab[hid];
163
 
164
    rwmode = flags & ( O_RDONLY | O_WRONLY | O_RDWR );
165
 
166
    iomode = 0;
167
    offset = 0;
168
 
169
    if( rwmode == O_RDWR )
170
        iomode |= _READ | _WRITE;
171
    else if( rwmode == O_RDONLY)
172
        iomode |= _READ;
173
    else if( rwmode == O_WRONLY)
174
        iomode |= _WRITE;
175
 
176
    if( flags & O_APPEND )
177
    {
178
        iomode |= _APPEND;
179
        offset = info.size;
180
    };
181
 
182
    if( flags & (O_BINARY|O_TEXT) )
183
    {
184
        if( flags & O_BINARY )
185
            iomode |= _BINARY;
186
    } else
187
        iomode |= _BINARY;
188
 
5198 serge 189
    ioh->name   = strdup(buf);
4921 Serge 190
    ioh->offset = offset;
191
    ioh->mode   = iomode;
192
    ioh->read   = read_file;
193
    ioh->write  = write_file;
194
 
195
    return hid;
196
};
197