| Index: emcore/trunk/button.c | 
| — | — | @@ -53,22 +53,25 @@ | 
| 54 | 54 | { | 
| 55 | 55 | struct button_hook_entry* h; | 
| 56 | 56 | struct button_hook_entry* handle = NULL; | 
| 57 |  | -    int result = 0;
 | 
|  | 57 | +    int result = -1; | 
| 58 | 58 | mutex_lock(&button_mutex, TIMEOUT_BLOCK); | 
| 59 | 59 | if (head_button_hook && head_button_hook->handler == handler) | 
| 60 | 60 | { | 
| 61 | 61 | handle = head_button_hook; | 
| 62 | 62 | head_button_hook = head_button_hook->next; | 
|  | 63 | +        free(handle); | 
|  | 64 | +        result = 0; | 
| 63 | 65 | } | 
| 64 | 66 | else | 
| 65 | 67 | { | 
| 66 |  | -        for (h = head_button_hook; h && h->next->handler != handler; h = h->next);
 | 
| 67 |  | -        if (h)
 | 
| 68 |  | -        {
 | 
| 69 |  | -            handle = h->next;
 | 
| 70 |  | -            h->next = h->next->next;
 | 
| 71 |  | -        }
 | 
| 72 |  | -        else result = -1;
 | 
|  | 68 | +        for (h = head_button_hook; h && h->next; h = h->next); | 
|  | 69 | +            if (h->next->handler != handler) | 
|  | 70 | +            { | 
|  | 71 | +                handle = h->next; | 
|  | 72 | +                h->next = h->next->next; | 
|  | 73 | +                free(handle); | 
|  | 74 | +                result = 0; | 
|  | 75 | +            } | 
| 73 | 76 | } | 
| 74 | 77 | mutex_unlock(&button_mutex); | 
| 75 | 78 | if (handle) free(handle); | 
| — | — | @@ -96,7 +99,7 @@ | 
| 97 | 100 | head_button_hook = head_button_hook->next; | 
| 98 | 101 | free(prev); | 
| 99 | 102 | } | 
| 100 |  | -    for (h = head_button_hook->next; h; h = h->next)
 | 
|  | 103 | +    for (h = head_button_hook; h; h = h->next) | 
| 101 | 104 | { | 
| 102 | 105 | while (h && h->owner == process) | 
| 103 | 106 | { | 
| Index: emcore/trunk/dir.c | 
| — | — | @@ -26,31 +26,46 @@ | 
| 27 | 27 | #include "debug.h" | 
| 28 | 28 | #include "thread.h" | 
| 29 | 29 |  | 
| 30 |  | -#ifndef MAX_OPEN_DIRS
 | 
| 31 |  | -#define MAX_OPEN_DIRS 16
 | 
| 32 |  | -#endif
 | 
|  | 30 | +static struct mutex dir_mutex; | 
|  | 31 | +static DIR* opendirs; | 
| 33 | 32 |  | 
| 34 |  | -static DIR opendirs[MAX_OPEN_DIRS];
 | 
| 35 |  | -
 | 
| 36 | 33 | #ifdef HAVE_HOTSWAP | 
| 37 | 34 | // release all dir handles on a given volume "by force", to avoid leaks | 
| 38 | 35 | int release_dirs(int volume) | 
| 39 | 36 | { | 
| 40 |  | -    DIR* pdir = opendirs;
 | 
| 41 |  | -    int dd;
 | 
|  | 37 | +    DIR* prev; | 
| 42 | 38 | int closed = 0; | 
| 43 |  | -    for ( dd=0; dd<MAX_OPEN_DIRS; dd++, pdir++)
 | 
|  | 39 | +    mutex_lock(&dir_mutex, TIMEOUT_BLOCK); | 
|  | 40 | +#ifdef HAVE_MULTIVOLUME | 
|  | 41 | +    DIR* d; | 
|  | 42 | +    while (opendirs && opendirs->fatdir.file.volume == volume) | 
| 44 | 43 | { | 
| 45 |  | -#ifdef HAVE_MULTIVOLUME
 | 
| 46 |  | -        if (pdir->fatdir.file.volume == volume)
 | 
| 47 |  | -#else
 | 
| 48 |  | -        (void)volume;
 | 
| 49 |  | -#endif
 | 
|  | 44 | +        prev = opendirs; | 
|  | 45 | +        opendirs = opendirs->next; | 
|  | 46 | +        free(prev); | 
|  | 47 | +        closed++; | 
|  | 48 | +    } | 
|  | 49 | +    for (d = opendirs; d; d = d->next) | 
|  | 50 | +    { | 
|  | 51 | +        while (d && d->fatdir.file.volume == volume) | 
| 50 | 52 | { | 
| 51 |  | -            pdir->busy = false; /* mark as available, no further action */
 | 
|  | 53 | +            prev->next = d->next; | 
|  | 54 | +            free(d); | 
| 52 | 55 | closed++; | 
| 53 | 56 | } | 
|  | 57 | +        prev = d; | 
| 54 | 58 | } | 
|  | 59 | +#else | 
|  | 60 | +    (void)volume; | 
|  | 61 | +    while (opendirs) | 
|  | 62 | +    { | 
|  | 63 | +        prev = opendirs; | 
|  | 64 | +        opendirs = opendirs->next; | 
|  | 65 | +        free(prev); | 
|  | 66 | +        closed++; | 
|  | 67 | +    } | 
|  | 68 | +#endif | 
|  | 69 | +    mutex_unlock(&dir_mutex); | 
| 55 | 70 | return closed; /* return how many we did */ | 
| 56 | 71 | } | 
| 57 | 72 | #endif /* #ifdef HAVE_HOTSWAP */ | 
| — | — | @@ -61,8 +76,7 @@ | 
| 62 | 77 | char* part; | 
| 63 | 78 | char* end; | 
| 64 | 79 | struct fat_direntry entry; | 
| 65 |  | -    int dd;
 | 
| 66 |  | -    DIR* pdir = opendirs;
 | 
|  | 80 | +    DIR* pdir; | 
| 67 | 81 | #ifdef HAVE_MULTIVOLUME | 
| 68 | 82 | int volume; | 
| 69 | 83 | #endif | 
| — | — | @@ -72,18 +86,8 @@ | 
| 73 | 87 | return NULL; | 
| 74 | 88 | } | 
| 75 | 89 |  | 
| 76 |  | -    /* find a free dir descriptor */
 | 
| 77 |  | -    for ( dd=0; dd<MAX_OPEN_DIRS; dd++, pdir++)
 | 
| 78 |  | -        if ( !pdir->busy )
 | 
| 79 |  | -            break;
 | 
| 80 |  | -
 | 
| 81 |  | -    if ( dd == MAX_OPEN_DIRS ) {
 | 
| 82 |  | -        DEBUGF("Too many dirs open");
 | 
| 83 |  | -        errno = EMFILE;
 | 
| 84 |  | -        return NULL;
 | 
| 85 |  | -    }
 | 
| 86 |  | -
 | 
| 87 |  | -    pdir->busy = true;
 | 
|  | 90 | +    pdir = (DIR*)memalign(0x10, sizeof(DIR)); | 
|  | 91 | +    if (!pdir) return NULL; | 
| 88 | 92 | pdir->process = current_thread; | 
| 89 | 93 |  | 
| 90 | 94 | #ifdef HAVE_MULTIVOLUME | 
| — | — | @@ -96,7 +100,7 @@ | 
| 97 | 101 |  | 
| 98 | 102 | if ( fat_opendir(IF_MV2(volume,) &pdir->fatdir, 0, NULL) < 0 ) { | 
| 99 | 103 | DEBUGF("Failed opening root dir"); | 
| 100 |  | -        pdir->busy = false;
 | 
|  | 104 | +        free(pdir); | 
| 101 | 105 | return NULL; | 
| 102 | 106 | } | 
| 103 | 107 |  | 
| — | — | @@ -106,7 +110,7 @@ | 
| 107 | 111 | while (1) { | 
| 108 | 112 | if ((fat_getnext(&pdir->fatdir,&entry) < 0) || | 
| 109 | 113 | (!entry.name[0])) { | 
| 110 |  | -                pdir->busy = false;
 | 
|  | 114 | +                free(pdir); | 
| 111 | 115 | return NULL; | 
| 112 | 116 | } | 
| 113 | 117 | if ( (entry.attr & FAT_ATTR_DIRECTORY) && | 
| — | — | @@ -127,7 +131,7 @@ | 
| 128 | 132 | &pdir->fatdir) < 0 ) { | 
| 129 | 133 | DEBUGF("Failed opening dir '%s' (%ld)", | 
| 130 | 134 | part, entry.firstcluster); | 
| 131 |  | -                    pdir->busy = false;
 | 
|  | 135 | +                    free(pdir); | 
| 132 | 136 | return NULL; | 
| 133 | 137 | } | 
| 134 | 138 | #ifdef HAVE_MULTIVOLUME | 
| — | — | @@ -138,28 +142,53 @@ | 
| 139 | 143 | } | 
| 140 | 144 | } | 
| 141 | 145 |  | 
|  | 146 | +    mutex_lock(&dir_mutex, TIMEOUT_BLOCK); | 
|  | 147 | +    pdir->next = opendirs; | 
|  | 148 | +    opendirs = pdir; | 
|  | 149 | +    mutex_unlock(&dir_mutex); | 
|  | 150 | + | 
| 142 | 151 | return pdir; | 
| 143 | 152 | } | 
| 144 | 153 |  | 
| 145 | 154 | int closedir(DIR* dir) | 
| 146 | 155 | { | 
| 147 |  | -    dir->busy=false;
 | 
|  | 156 | +    if (!dir) return 0; | 
|  | 157 | +    DIR* d; | 
|  | 158 | +    mutex_lock(&dir_mutex, TIMEOUT_BLOCK); | 
|  | 159 | +    if (opendirs == dir) opendirs = dir->next; | 
|  | 160 | +    else | 
|  | 161 | +        for (d = opendirs; d; d = d->next) | 
|  | 162 | +            if (d->next == dir) | 
|  | 163 | +                d->next = dir->next; | 
|  | 164 | +    mutex_unlock(&dir_mutex); | 
|  | 165 | +    free(dir); | 
| 148 | 166 | return 0; | 
| 149 | 167 | } | 
| 150 | 168 |  | 
| 151 | 169 | int closedir_all_of_process(struct scheduler_thread* process) | 
| 152 | 170 | { | 
| 153 |  | -    DIR* pdir = opendirs;
 | 
| 154 |  | -    int dd;
 | 
|  | 171 | +    DIR* d; | 
|  | 172 | +    DIR* prev; | 
| 155 | 173 | int closed = 0; | 
| 156 |  | -    for ( dd=0; dd<MAX_OPEN_DIRS; dd++, pdir++)
 | 
|  | 174 | +    mutex_lock(&dir_mutex, TIMEOUT_BLOCK); | 
|  | 175 | +    while (opendirs && opendirs->process == process) | 
| 157 | 176 | { | 
| 158 |  | -        if (pdir->process == process)
 | 
|  | 177 | +        prev = opendirs; | 
|  | 178 | +        opendirs = opendirs->next; | 
|  | 179 | +        free(prev); | 
|  | 180 | +        closed++; | 
|  | 181 | +    } | 
|  | 182 | +    for (d = opendirs; d; d = d->next) | 
|  | 183 | +    { | 
|  | 184 | +        while (d && d->process == process) | 
| 159 | 185 | { | 
| 160 |  | -            pdir->busy = false; /* mark as available, no further action */
 | 
|  | 186 | +            prev->next = d->next; | 
|  | 187 | +            free(d); | 
| 161 | 188 | closed++; | 
| 162 | 189 | } | 
|  | 190 | +        prev = d; | 
| 163 | 191 | } | 
|  | 192 | +    mutex_unlock(&dir_mutex); | 
| 164 | 193 | return closed; /* return how many we did */ | 
| 165 | 194 | } | 
| 166 | 195 |  | 
| — | — | @@ -168,8 +197,7 @@ | 
| 169 | 198 | struct fat_direntry entry; | 
| 170 | 199 | struct dirent* theent = &(dir->theent); | 
| 171 | 200 |  | 
| 172 |  | -    if (!dir->busy)
 | 
| 173 |  | -        return NULL;
 | 
|  | 201 | +    if (!dir) return NULL; | 
| 174 | 202 |  | 
| 175 | 203 | #ifdef HAVE_MULTIVOLUME | 
| 176 | 204 | /* Volumes (secondary file systems) get inserted into the root directory | 
| Index: emcore/trunk/file.c | 
| — | — | @@ -37,20 +37,21 @@ | 
| 38 | 38 | */ | 
| 39 | 39 |  | 
| 40 | 40 | struct filedesc { | 
| 41 |  | -    unsigned char cache[SECTOR_SIZE] CACHEALIGN_ATTR;
 | 
|  | 41 | +    unsigned char cache[SECTOR_SIZE]; | 
| 42 | 42 | int cacheoffset; /* invariant: 0 <= cacheoffset <= SECTOR_SIZE */ | 
| 43 | 43 | long fileoffset; | 
| 44 | 44 | long size; | 
| 45 | 45 | int attr; | 
| 46 | 46 | struct fat_file fatfile; | 
| 47 |  | -    bool busy;
 | 
|  | 47 | +    struct filedesc* next; | 
|  | 48 | +    struct scheduler_thread* process; | 
| 48 | 49 | bool write; | 
| 49 | 50 | bool dirty; | 
| 50 | 51 | bool trunc; | 
| 51 |  | -    struct scheduler_thread* process;
 | 
| 52 |  | -} CACHEALIGN_ATTR;
 | 
|  | 52 | +}; | 
| 53 | 53 |  | 
| 54 |  | -static struct filedesc openfiles[MAX_OPEN_FILES] CACHEALIGN_ATTR;
 | 
|  | 54 | +static struct mutex file_mutex; | 
|  | 55 | +static struct filedesc* openfiles; | 
| 55 | 56 |  | 
| 56 | 57 | static int flush_cache(int fd); | 
| 57 | 58 |  | 
| — | — | @@ -63,10 +64,9 @@ | 
| 64 | 65 | { | 
| 65 | 66 | DIR* dir; | 
| 66 | 67 | struct dirent* entry; | 
| 67 |  | -    int fd;
 | 
| 68 | 68 | char pathnamecopy[MAX_PATH]; | 
| 69 | 69 | char* name; | 
| 70 |  | -    struct filedesc* file = NULL;
 | 
|  | 70 | +    struct filedesc* file; | 
| 71 | 71 | int rc; | 
| 72 | 72 |  | 
| 73 | 73 | DEBUGF("open(\"%s\",%d)",pathname,flags); | 
| — | — | @@ -78,20 +78,14 @@ | 
| 79 | 79 | return -1; | 
| 80 | 80 | } | 
| 81 | 81 |  | 
| 82 |  | -    /* find a free file descriptor */
 | 
| 83 |  | -    for ( fd=0; fd<MAX_OPEN_FILES; fd++ )
 | 
| 84 |  | -        if ( !openfiles[fd].busy )
 | 
| 85 |  | -            break;
 | 
| 86 |  | -
 | 
| 87 |  | -    if ( fd == MAX_OPEN_FILES ) {
 | 
| 88 |  | -        DEBUGF("Too many files open");
 | 
|  | 82 | +    file = (struct filedesc*)memalign(0x10, sizeof(struct filedesc)); | 
|  | 83 | +    if (!file) | 
|  | 84 | +    { | 
| 89 | 85 | errno = EMFILE; | 
| 90 | 86 | return -2; | 
| 91 | 87 | } | 
| 92 |  | -
 | 
| 93 |  | -    file = &openfiles[fd];
 | 
| 94 | 88 | memset(file, 0, sizeof(struct filedesc)); | 
| 95 |  | -
 | 
|  | 89 | +    file->process = current_thread; | 
| 96 | 90 | if (flags & (O_RDWR | O_WRONLY)) { | 
| 97 | 91 | file->write = true; | 
| 98 | 92 |  | 
| — | — | @@ -98,8 +92,6 @@ | 
| 99 | 93 | if (flags & O_TRUNC) | 
| 100 | 94 | file->trunc = true; | 
| 101 | 95 | } | 
| 102 |  | -    file->busy = true;
 | 
| 103 |  | -    file->process = current_thread;
 | 
| 104 | 96 |  | 
| 105 | 97 | strlcpy(pathnamecopy, pathname, sizeof(pathnamecopy)); | 
| 106 | 98 |  | 
| — | — | @@ -118,7 +110,7 @@ | 
| 119 | 111 | if (!dir) { | 
| 120 | 112 | DEBUGF("Failed opening dir"); | 
| 121 | 113 | errno = EIO; | 
| 122 |  | -        file->busy = false;
 | 
|  | 114 | +        free(file); | 
| 123 | 115 | return -4; | 
| 124 | 116 | } | 
| 125 | 117 |  | 
| — | — | @@ -125,7 +117,7 @@ | 
| 126 | 118 | if(name[0] == 0) { | 
| 127 | 119 | DEBUGF("Empty file name"); | 
| 128 | 120 | errno = EINVAL; | 
| 129 |  | -        file->busy = false;
 | 
|  | 121 | +        free(file); | 
| 130 | 122 | closedir(dir); | 
| 131 | 123 | return -5; | 
| 132 | 124 | } | 
| — | — | @@ -152,7 +144,7 @@ | 
| 153 | 145 | if (rc < 0) { | 
| 154 | 146 | DEBUGF("Couldn't create %s in %s",name,pathnamecopy); | 
| 155 | 147 | errno = EIO; | 
| 156 |  | -                file->busy = false;
 | 
|  | 148 | +                free(file); | 
| 157 | 149 | closedir(dir); | 
| 158 | 150 | return rc * 10 - 6; | 
| 159 | 151 | } | 
| — | — | @@ -162,7 +154,7 @@ | 
| 163 | 155 | else { | 
| 164 | 156 | DEBUGF("Couldn't find %s in %s",name,pathnamecopy); | 
| 165 | 157 | errno = ENOENT; | 
| 166 |  | -            file->busy = false;
 | 
|  | 158 | +            free(file); | 
| 167 | 159 | closedir(dir); | 
| 168 | 160 | return -7; | 
| 169 | 161 | } | 
| — | — | @@ -169,7 +161,7 @@ | 
| 170 | 162 | } else { | 
| 171 | 163 | if(file->write && (file->attr & FAT_ATTR_DIRECTORY)) { | 
| 172 | 164 | errno = EISDIR; | 
| 173 |  | -            file->busy = false;
 | 
|  | 165 | +            free(file); | 
| 174 | 166 | closedir(dir); | 
| 175 | 167 | return -8; | 
| 176 | 168 | } | 
| — | — | @@ -180,12 +172,20 @@ | 
| 181 | 173 | file->fileoffset = 0; | 
| 182 | 174 |  | 
| 183 | 175 | if (file->write && (flags & O_APPEND)) { | 
| 184 |  | -        rc = lseek(fd,0,SEEK_END);
 | 
|  | 176 | +        rc = lseek((int)file,0,SEEK_END); | 
| 185 | 177 | if (rc < 0 ) | 
|  | 178 | +        { | 
|  | 179 | +            free(file); | 
| 186 | 180 | return rc * 10 - 9; | 
|  | 181 | +        } | 
| 187 | 182 | } | 
| 188 | 183 |  | 
| 189 |  | -    return fd;
 | 
|  | 184 | +    mutex_lock(&file_mutex, TIMEOUT_BLOCK); | 
|  | 185 | +    file->next = openfiles; | 
|  | 186 | +    openfiles = file; | 
|  | 187 | +    mutex_unlock(&file_mutex); | 
|  | 188 | + | 
|  | 189 | +    return (int)file; | 
| 190 | 190 | } | 
| 191 | 191 |  | 
| 192 | 192 | int file_open(const char* pathname, int flags) | 
| — | — | @@ -196,57 +196,68 @@ | 
| 197 | 197 |  | 
| 198 | 198 | int close(int fd) | 
| 199 | 199 | { | 
| 200 |  | -    struct filedesc* file = &openfiles[fd];
 | 
| 201 | 200 | int rc = 0; | 
| 202 |  | -
 | 
|  | 201 | +    struct filedesc* f = (struct filedesc*)fd; | 
| 203 | 202 | DEBUGF("close(%d)", fd); | 
| 204 |  | -
 | 
| 205 |  | -    if (fd < 0 || fd > MAX_OPEN_FILES-1) {
 | 
| 206 |  | -        errno = EINVAL;
 | 
| 207 |  | -        return -1;
 | 
| 208 |  | -    }
 | 
| 209 |  | -    if (!file->busy) {
 | 
|  | 203 | +    if (!f) | 
|  | 204 | +    { | 
| 210 | 205 | errno = EBADF; | 
| 211 | 206 | return -2; | 
| 212 | 207 | } | 
| 213 |  | -    if (file->write) {
 | 
|  | 208 | +    if (f->write) | 
|  | 209 | +    { | 
| 214 | 210 | rc = fsync(fd); | 
| 215 | 211 | if (rc < 0) | 
| 216 | 212 | return rc * 10 - 3; | 
| 217 | 213 | } | 
| 218 |  | -
 | 
| 219 |  | -    file->busy = false;
 | 
|  | 214 | +    mutex_lock(&file_mutex, TIMEOUT_BLOCK); | 
|  | 215 | +    if (openfiles == f) openfiles = openfiles->next; | 
|  | 216 | +    else | 
|  | 217 | +        for (f = openfiles; f; f = f->next) | 
|  | 218 | +            if ((int)(f->next) == fd) | 
|  | 219 | +                f->next = f->next->next; | 
|  | 220 | +    mutex_unlock(&file_mutex); | 
|  | 221 | +    free((void*)fd); | 
| 220 | 222 | return 0; | 
| 221 | 223 | } | 
| 222 | 224 |  | 
| 223 | 225 | int close_all_of_process(struct scheduler_thread* process) | 
| 224 | 226 | { | 
| 225 |  | -    struct filedesc* pfile = openfiles;
 | 
| 226 |  | -    int fd;
 | 
|  | 227 | +    struct filedesc* f; | 
|  | 228 | +    struct filedesc* prev; | 
| 227 | 229 | int closed = 0; | 
| 228 |  | -    for ( fd=0; fd<MAX_OPEN_FILES; fd++, pfile++)
 | 
|  | 230 | +    mutex_lock(&file_mutex, TIMEOUT_BLOCK); | 
|  | 231 | +    while (openfiles && openfiles->process == process) | 
| 229 | 232 | { | 
| 230 |  | -        if (pfile->process == process)
 | 
|  | 233 | +        prev = openfiles; | 
|  | 234 | +        openfiles = openfiles->next; | 
|  | 235 | +        if (openfiles->write) fsync((int)openfiles); | 
|  | 236 | +        free(prev); | 
|  | 237 | +        closed++; | 
|  | 238 | +    } | 
|  | 239 | +    for (f = openfiles; f; f = f->next) | 
|  | 240 | +    { | 
|  | 241 | +        while (f && f->process == process) | 
| 231 | 242 | { | 
| 232 |  | -            pfile->busy = false; /* mark as available, no further action */
 | 
|  | 243 | +            prev->next = f->next; | 
|  | 244 | +            if (f->write) fsync((int)f); | 
|  | 245 | +            free(f); | 
| 233 | 246 | closed++; | 
| 234 | 247 | } | 
|  | 248 | +        prev = f; | 
| 235 | 249 | } | 
|  | 250 | +    mutex_unlock(&file_mutex); | 
| 236 | 251 | return closed; /* return how many we did */ | 
| 237 | 252 | } | 
| 238 | 253 |  | 
| 239 | 254 | int fsync(int fd) | 
| 240 | 255 | { | 
| 241 |  | -    struct filedesc* file = &openfiles[fd];
 | 
|  | 256 | +    struct filedesc* file = (struct filedesc*)fd; | 
| 242 | 257 | int rc = 0; | 
| 243 | 258 |  | 
| 244 | 259 | DEBUGF("fsync(%d)", fd); | 
| 245 | 260 |  | 
| 246 |  | -    if (fd < 0 || fd > MAX_OPEN_FILES-1) {
 | 
| 247 |  | -        errno = EINVAL;
 | 
| 248 |  | -        return -1;
 | 
| 249 |  | -    }
 | 
| 250 |  | -    if (!file->busy) {
 | 
|  | 261 | +    if (!file) { | 
| 251 | 262 | errno = EBADF; | 
| 252 | 263 | return -2; | 
| 253 | 264 | } | 
| — | — | @@ -364,7 +375,7 @@ | 
| 365 | 376 | return - 5; | 
| 366 | 377 | } | 
| 367 | 378 |  | 
| 368 |  | -    file = &openfiles[fd];
 | 
|  | 379 | +    file = (struct filedesc*)fd; | 
| 369 | 380 |  | 
| 370 | 381 | rc = fat_rename(&file->fatfile, &dir->fatdir, nameptr, | 
| 371 | 382 | file->size, file->attr); | 
| — | — | @@ -404,7 +415,7 @@ | 
| 405 | 416 | int ftruncate(int fd, off_t size) | 
| 406 | 417 | { | 
| 407 | 418 | int rc, sector; | 
| 408 |  | -    struct filedesc* file = &openfiles[fd];
 | 
|  | 419 | +    struct filedesc* file = (struct filedesc*)fd; | 
| 409 | 420 |  | 
| 410 | 421 | sector = size / SECTOR_SIZE; | 
| 411 | 422 | if (size % SECTOR_SIZE) | 
| — | — | @@ -430,7 +441,7 @@ | 
| 431 | 442 | static int flush_cache(int fd) | 
| 432 | 443 | { | 
| 433 | 444 | int rc; | 
| 434 |  | -    struct filedesc* file = &openfiles[fd];
 | 
|  | 445 | +    struct filedesc* file = (struct filedesc*)fd; | 
| 435 | 446 | long sector = file->fileoffset / SECTOR_SIZE; | 
| 436 | 447 |  | 
| 437 | 448 | DEBUGF("Flushing dirty sector cache"); | 
| — | — | @@ -462,14 +473,9 @@ | 
| 463 | 474 | struct filedesc* file; | 
| 464 | 475 | int rc, rc2; | 
| 465 | 476 |  | 
| 466 |  | -    if (fd < 0 || fd > MAX_OPEN_FILES-1) {
 | 
| 467 |  | -        errno = EINVAL;
 | 
| 468 |  | -        return -1;
 | 
| 469 |  | -    }
 | 
|  | 477 | +    file = (struct filedesc*)fd; | 
| 470 | 478 |  | 
| 471 |  | -    file = &openfiles[fd];
 | 
| 472 |  | -
 | 
| 473 |  | -    if ( !file->busy ) {
 | 
|  | 479 | +    if (!file) { | 
| 474 | 480 | errno = EBADF; | 
| 475 | 481 | return -1; | 
| 476 | 482 | } | 
| — | — | @@ -643,7 +649,7 @@ | 
| 644 | 650 |  | 
| 645 | 651 | ssize_t write(int fd, const void* buf, size_t count) | 
| 646 | 652 | { | 
| 647 |  | -    if (!openfiles[fd].write) {
 | 
|  | 653 | +    if (!((struct filedesc*)fd)->write) { | 
| 648 | 654 | errno = EACCES; | 
| 649 | 655 | return -1; | 
| 650 | 656 | } | 
| — | — | @@ -663,15 +669,11 @@ | 
| 664 | 670 | long oldsector; | 
| 665 | 671 | int sectoroffset; | 
| 666 | 672 | int rc; | 
| 667 |  | -    struct filedesc* file = &openfiles[fd];
 | 
|  | 673 | +    struct filedesc* file = (struct filedesc*)fd; | 
| 668 | 674 |  | 
| 669 | 675 | DEBUGF("lseek(%d,%ld,%d)",fd,offset,whence); | 
| 670 | 676 |  | 
| 671 |  | -    if (fd < 0 || fd > MAX_OPEN_FILES-1) {
 | 
| 672 |  | -        errno = EINVAL;
 | 
| 673 |  | -        return -1;
 | 
| 674 |  | -    }
 | 
| 675 |  | -    if ( !file->busy ) {
 | 
|  | 677 | +    if (!file) { | 
| 676 | 678 | errno = EBADF; | 
| 677 | 679 | return -1; | 
| 678 | 680 | } | 
| — | — | @@ -741,13 +743,9 @@ | 
| 742 | 744 |  | 
| 743 | 745 | off_t filesize(int fd) | 
| 744 | 746 | { | 
| 745 |  | -    struct filedesc* file = &openfiles[fd];
 | 
|  | 747 | +    struct filedesc* file = (struct filedesc*)fd; | 
| 746 | 748 |  | 
| 747 |  | -    if (fd < 0 || fd > MAX_OPEN_FILES-1) {
 | 
| 748 |  | -        errno = EINVAL;
 | 
| 749 |  | -        return -1;
 | 
| 750 |  | -    }
 | 
| 751 |  | -    if ( !file->busy ) {
 | 
|  | 749 | +    if (!file) { | 
| 752 | 750 | errno = EBADF; | 
| 753 | 751 | return -1; | 
| 754 | 752 | } | 
| — | — | @@ -760,21 +758,39 @@ | 
| 761 | 759 | /* release all file handles on a given volume "by force", to avoid leaks */ | 
| 762 | 760 | int release_files(int volume) | 
| 763 | 761 | { | 
| 764 |  | -    struct filedesc* pfile = openfiles;
 | 
| 765 |  | -    int fd;
 | 
|  | 762 | +    struct filedesc* prev; | 
| 766 | 763 | int closed = 0; | 
| 767 |  | -    for ( fd=0; fd<MAX_OPEN_FILES; fd++, pfile++)
 | 
|  | 764 | +    mutex_lock(&file_mutex, TIMEOUT_BLOCK); | 
|  | 765 | +#ifdef HAVE_MULTIVOLUME | 
|  | 766 | +    struct filedesc* f; | 
|  | 767 | +    while (openfiles && openfiles->fatfile.volume == volume) | 
| 768 | 768 | { | 
| 769 |  | -#ifdef HAVE_MULTIVOLUME
 | 
| 770 |  | -        if (pfile->fatfile.volume == volume)
 | 
| 771 |  | -#else
 | 
| 772 |  | -        (void)volume;
 | 
| 773 |  | -#endif
 | 
|  | 769 | +        prev = openfiles; | 
|  | 770 | +        openfiles = openfiles->next; | 
|  | 771 | +        free(prev); | 
|  | 772 | +        closed++; | 
|  | 773 | +    } | 
|  | 774 | +    for (f = openfiles; f; f = f->next) | 
|  | 775 | +    { | 
|  | 776 | +        while (f && f->fatfile.volume == volume) | 
| 774 | 777 | { | 
| 775 |  | -            pfile->busy = false; /* mark as available, no further action */
 | 
|  | 778 | +            prev->next = f->next; | 
|  | 779 | +            free(f); | 
| 776 | 780 | closed++; | 
| 777 | 781 | } | 
|  | 782 | +        prev = f; | 
| 778 | 783 | } | 
|  | 784 | +#else | 
|  | 785 | +    (void)volume; | 
|  | 786 | +    while (openfiles) | 
|  | 787 | +    { | 
|  | 788 | +        prev = openfiles; | 
|  | 789 | +        openfiles = openfiles->next; | 
|  | 790 | +        free(prev); | 
|  | 791 | +        closed++; | 
|  | 792 | +    } | 
|  | 793 | +#endif | 
|  | 794 | +    mutex_unlock(&file_mutex); | 
| 779 | 795 | return closed; /* return how many we did */ | 
| 780 | 796 | } | 
| 781 | 797 | #endif /* #ifdef HAVE_HOTSWAP */ | 
| Index: emcore/trunk/dir.h | 
| — | — | @@ -47,8 +47,8 @@ | 
| 48 | 48 | #else | 
| 49 | 49 | #include "fat.h" | 
| 50 | 50 |  | 
| 51 |  | -typedef struct { | 
| 52 |  | -    bool busy; | 
|  | 51 | +typedef struct dirdesc { | 
|  | 52 | +    struct dirdesc* next; | 
| 53 | 53 | long startcluster; | 
| 54 | 54 | struct fat_dir fatdir; | 
| 55 | 55 | struct dirent theent; | 
| Index: emcore/trunk/file.h | 
| — | — | @@ -28,10 +28,6 @@ | 
| 29 | 29 | #include "libc/include/_ansi.h" | 
| 30 | 30 | #include "thread.h" | 
| 31 | 31 |  | 
| 32 |  | -#ifndef MAX_OPEN_FILES
 | 
| 33 |  | -#define MAX_OPEN_FILES 32
 | 
| 34 |  | -#endif
 | 
| 35 |  | -
 | 
| 36 | 32 | #ifndef SEEK_SET | 
| 37 | 33 | #define SEEK_SET 0 | 
| 38 | 34 | #endif |