Subversion Repositories Kolibri OS

Rev

Rev 6727 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6725 siemargl 1
/*
2
Kolibri OS port for gcc 5.4
3
 
4
Started by Siemargl @Nov 2016
5
 
6775 siemargl 6
Contains realization of directory handling functions:
6725 siemargl 7
    mkdir()
8
    closedir()
9
    opendir()
10
    readdir()
11
    rewinddir()
12
 
13
    !!non reentrant
14
*/
15
 
16
#include 
17
#include 
18
#include 
19
#include 
20
#include 
21
#include 
22
#include "kos32sys1.h"
6775 siemargl 23
#include "sys/kos_io.h"
6725 siemargl 24
 
25
/* defined in newlib headers
26
int	_EXFUN(mkdir,( const char *_path, mode_t __mode ));
27
 
28
struct dirent {
29
  char d_namlen;
30
  char d_name[256];
31
};
32
 
33
typedef struct
34
{
35
//    struct systree_info2 fileinfo;
36
    struct dirent entry;
37
//    __u8 bdfeheader[0x20];
38
//    struct bdfe_item bdfebase;
39
//    __u8 bdfename[264];
40
} DIR;
41
 
42
int     closedir(DIR *dirp);
43
DIR *       opendir(const char *_dirname);
44
struct dirent * readdir(DIR *_dirp);
45
void      rewinddir(DIR *_dirp);
46
*/
47
 
48
static int32_t lastread_block = -1; // non reentrant, must me -1ed in closedir, or will assert
49
static uint32_t lastread_dir_size;
50
static DIR  lastread_dir;
51
 
52
DIR *opendir(const char *_dirname)
53
{
54
    assert(sizeof(struct fs_dirinfo) == 25);  // check struct aligment
55
    assert(lastread_block == -1);
56
 
57
    struct fs_dirinfo di;
58
    struct fs_dirheader dhead;
59
 
60
    memset(&di, 0, sizeof di);
61
    di.ppath = (char*)_dirname;
62
    di.retval = (uint32_t)&dhead;
63
    int rc = sf_file(1, &di);  // read dir size
64
    if(rc) {
65
        fprintf(stderr, "Error reading dir size %s\n", _dirname);
66
        errno = rc;
67
        return NULL;
68
    }
69
    lastread_dir_size = dhead.totl_blocks;
70
 
71
    lastread_dir.entry.d_namlen = strlen(_dirname);
72
    assert (lastread_dir.entry.d_namlen < sizeof(lastread_dir.entry.d_name));
73
    strcpy(lastread_dir.entry.d_name, _dirname);
74
 
75
    return &lastread_dir;
76
};
77
 
78
 
79
int closedir(DIR *dirp)
80
{
81
    assert (lastread_block != -1);  // was opened
82
 
83
    if (!dirp || lastread_block == -1)
84
    {
85
        errno = EBADF;
86
        return -1;
87
    }
88
    lastread_block = -1;
89
    lastread_dir_size = 0;
90
    lastread_dir.entry.d_namlen = 0;
91
    lastread_dir.entry.d_name[0] = '\0';
92
 
93
    return 0;
94
};
95
 
96
 
97
struct dirent* readdir(DIR *dirp)
98
{
99
    assert (lastread_block != -1);  // was opened
100
 
101
    if (!dirp || lastread_block == -1)
102
    {
103
        errno = EBADF;
104
        return NULL;
105
    }
106
    struct fs_dirinfo di;
107
 
108
    assert (lastread_block != -1);  // was opened
109
 
110
    char retdir[sizeof(struct fs_dirheader) + sizeof(struct fsBDFE)];   // 1 block w/cp866 encoding
111
    struct fsBDFE *bdfe = (struct fsBDFE *)(retdir + sizeof(struct fs_dirheader));
112
    memset(&di, 0, sizeof di);
113
    di.ppath = dirp->entry.d_name;
114
    di.retval = (uint32_t)retdir;
115
    di.start = lastread_block;
116
    di.size = 1;
117
 
118
    int rc = sf_file(1, &di);  // read dir
119
    if(rc) {
6727 siemargl 120
        fprintf(stderr, "Error %d reading dir item %s\n", rc, dirp->entry.d_name);
6725 siemargl 121
        errno = rc;
122
        return NULL;
123
    }
124
 
125
    static struct dirent ent;
126
    ent.d_namlen = strlen(bdfe->fname);
127
    assert (ent.d_namlen < sizeof(ent.d_name));
128
    strcpy(ent.d_name, bdfe->fname);
129
    lastread_block++;
130
 
131
    return &ent;
132
};
133
 
134
 
135
void rewinddir(DIR *dirp)
136
{
137
    if (!dirp || lastread_block == -1)
138
    {
139
        return;
140
    }
141
 
142
    lastread_block = 0;
143
}
144
 
145
 
146
int	mkdir(const char *_path, mode_t m)
147
{
6727 siemargl 148
    char   namebuffer[1050]; // need for save data after di!!!
149
    struct fs_dirinfo *di = (struct fs_dirinfo *)namebuffer;
6725 siemargl 150
 
6775 siemargl 151
//debug_board_printf("mkdir start (%s)\n", _path);
6727 siemargl 152
    memset(di, 0, sizeof(struct fs_dirinfo));
153
    //di.ppath = (char*)_path;  // dont work with 70.9
154
    strcpy(di->path, _path);
155
 
156
    int rc = sf_file(9, di);  // creat dir
6725 siemargl 157
    if(rc) {
6727 siemargl 158
        fprintf(stderr, "Error %d creating dir item %s\n", rc, _path);
6725 siemargl 159
        errno = rc;
160
        return -1;
161
    }
162
 
6775 siemargl 163
//debug_board_printf("mkdir end (%s)\n", _path);
6725 siemargl 164
    return 0;
165
}
166
 
6727 siemargl 167
////////////////////////////////////////////////////////////////////////////////////////
168
void __attribute__ ((noinline)) debug_board_write_str(const char* str){
169
  while(*str)
170
    debug_board_write_byte(*str++);
171
}
6725 siemargl 172
 
6727 siemargl 173
void __attribute__ ((noinline)) debug_board_printf(const char *format,...)
174
{
175
        va_list ap;
176
        char log_board[300];
177
 
178
        va_start (ap, format);
179
        vsnprintf(log_board, sizeof log_board, format, ap);
180
        va_end(ap);
181
        debug_board_write_str(log_board);
182
}
183
 
184
__attribute__ ((noinline)) void trap(int n)
185
{
186
    // nothing todo, just see n in debugger. use "bp trap" command
187
    __asm__ __volatile__(
188
    "nop"
189
    :
190
    :"a"(n));
191
}
192
 
193
 
194
 
6725 siemargl 195
/* tested example
196
void* read_folderdata(char* name)
197
{
198
    struct fs_dirinfo di;
199
    struct fs_dirheader dhead;
200
    assert(sizeof di == 25);
201
 
202
    memset(&di, 0, sizeof di);
203
    di.ppath = name;
204
    di.retval = (uint32_t)&dhead;
205
    int rc = sf_file(1, &di);  // read dir size
206
    if(rc) {
207
        debug_board_printf("Error reading dir size %s", name);
208
        exit(1);
209
    }
210
    di.size = dhead.totl_blocks;
211
 
212
    char *retdir = malloc(sizeof dhead + dhead.totl_blocks * sizeof(struct fsBDFE));
213
    if(!retdir) {
214
        debug_board_printf("No memory for dir %s", name);
215
        exit(1);
216
    }
217
    di.retval = (uint32_t)retdir;
218
    rc = sf_file(1, &di);  // read dir
219
    if(rc) {
220
        debug_board_printf("Error 2 reading dir size %s", name);
221
        exit(1);
222
    }
223
 
224
    // manual clear mark flag (random junk in fname free space)
225
    int i;
226
    for (i = 0; i < dhead.totl_blocks; i++)
227
        ((struct fsBDFE*)(retdir+32))[i].fname[259] = 0;
228
 
229
    debug_board_printf("Loaded dir [%s] etnries %d,\n first file [%s]\n", name, ((struct fs_dirheader*)(retdir))->curn_blocks, ((struct fsBDFE*)(retdir+32))->fname);
230
 
231
    return retdir;
232
}
233
*/
6775 siemargl 234
 
235
// while not in newlib
236
int set_fileinfo(const char *path, fileinfo_t *info)
237
{
238
    int retval;
239
 
240
    __asm__ __volatile__ (
241
    "pushl $0 \n\t"
242
    "pushl $0 \n\t"
243
    "movl %1, 1(%%esp) \n\t"
244
    "pushl %%ebx \n\t"
245
    "pushl $0 \n\t"
246
    "pushl $0 \n\t"
247
    "pushl $0 \n\t"
248
    "pushl $6 \n\t"
249
    "movl %%esp, %%ebx \n\t"
250
    "movl $70, %%eax \n\t"
251
    "int $0x40 \n\t"
252
    "addl $28, %%esp \n\t"
253
    :"=a" (retval)
254
    :"r" (path), "b" (info));
255
   return retval;
256
};
257