wok-next diff syslinux/stuff/extra/fs.u @ rev 15481
Add memtester
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Sun Nov 10 15:03:57 2013 +0000 (2013-11-10) |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/syslinux/stuff/extra/fs.u Sun Nov 10 15:03:57 2013 +0000 1.3 @@ -0,0 +1,347 @@ 1.4 +--- core/fs/fs.c 1.5 ++++ core/fs/fs.c 1.6 +@@ -1,10 +1,16 @@ 1.7 ++#include <sys/file.h> 1.8 + #include <stdio.h> 1.9 + #include <stdbool.h> 1.10 + #include <string.h> 1.11 ++#include <unistd.h> 1.12 + #include <dprintf.h> 1.13 ++#include "core.h" 1.14 ++#include "dev.h" 1.15 + #include "fs.h" 1.16 + #include "cache.h" 1.17 + 1.18 ++char *PATH; 1.19 ++ 1.20 + /* The currently mounted filesystem */ 1.21 + struct fs_info *this_fs = NULL; /* Root filesystem */ 1.22 + 1.23 +@@ -76,19 +82,30 @@ 1.24 + } 1.25 + 1.26 + /* 1.27 +- * Convert between a 16-bit file handle and a file structure 1.28 ++ * Find and open the configuration file 1.29 + */ 1.30 +- 1.31 +-void pm_load_config(com32sys_t *regs) 1.32 ++int open_config(void) 1.33 + { 1.34 +- int err; 1.35 ++ int fd, handle; 1.36 ++ struct file_info *fp; 1.37 + 1.38 +- err = this_fs->fs_ops->load_config(); 1.39 ++ fd = opendev(&__file_dev, NULL, O_RDONLY); 1.40 ++ if (fd < 0) 1.41 ++ return -1; 1.42 + 1.43 +- if (err) 1.44 +- printf("ERROR: No configuration file found\n"); 1.45 ++ fp = &__file_info[fd]; 1.46 + 1.47 +- set_flags(regs, err ? EFLAGS_ZF : 0); 1.48 ++ handle = this_fs->fs_ops->open_config(&fp->i.fd); 1.49 ++ if (handle < 0) { 1.50 ++ close(fd); 1.51 ++ errno = ENOENT; 1.52 ++ return -1; 1.53 ++ } 1.54 ++ 1.55 ++ fp->i.offset = 0; 1.56 ++ fp->i.nbytes = 0; 1.57 ++ 1.58 ++ return fd; 1.59 + } 1.60 + 1.61 + void pm_mangle_name(com32sys_t *regs) 1.62 +@@ -202,11 +219,10 @@ 1.63 + 1.64 + int searchdir(const char *name) 1.65 + { 1.66 +- struct inode *inode = NULL; 1.67 +- struct inode *parent = NULL; 1.68 ++ static char root_name[] = "/"; 1.69 + struct file *file; 1.70 +- char *pathbuf = NULL; 1.71 +- char *part, *p, echar; 1.72 ++ char *path, *inode_name, *next_inode_name; 1.73 ++ struct inode *tmp, *inode = NULL; 1.74 + int symlink_count = MAX_SYMLINK_CNT; 1.75 + 1.76 + dprintf("searchdir: %s root: %p cwd: %p\n", 1.77 +@@ -228,113 +244,165 @@ 1.78 + 1.79 + /* else, try the generic-path-lookup method */ 1.80 + 1.81 +- parent = get_inode(this_fs->cwd); 1.82 +- p = pathbuf = strdup(name); 1.83 +- if (!pathbuf) 1.84 +- goto err; 1.85 ++ /* Copy the path */ 1.86 ++ path = strdup(name); 1.87 ++ if (!path) { 1.88 ++ dprintf("searchdir: Couldn't copy path\n"); 1.89 ++ goto err_path; 1.90 ++ } 1.91 + 1.92 +- do { 1.93 +- got_link: 1.94 +- if (*p == '/') { 1.95 +- put_inode(parent); 1.96 +- parent = get_inode(this_fs->root); 1.97 ++ /* Work with the current directory, by default */ 1.98 ++ inode = get_inode(this_fs->cwd); 1.99 ++ if (!inode) { 1.100 ++ dprintf("searchdir: Couldn't use current directory\n"); 1.101 ++ goto err_curdir; 1.102 ++ } 1.103 ++ 1.104 ++ for (inode_name = path; inode_name; inode_name = next_inode_name) { 1.105 ++ /* Root directory? */ 1.106 ++ if (inode_name[0] == '/') { 1.107 ++ next_inode_name = inode_name + 1; 1.108 ++ inode_name = root_name; 1.109 ++ } else { 1.110 ++ /* Find the next inode name */ 1.111 ++ next_inode_name = strchr(inode_name + 1, '/'); 1.112 ++ if (next_inode_name) { 1.113 ++ /* Terminate the current inode name and point to next */ 1.114 ++ *next_inode_name++ = '\0'; 1.115 ++ } 1.116 + } 1.117 ++ if (next_inode_name) { 1.118 ++ /* Advance beyond redundant slashes */ 1.119 ++ while (*next_inode_name == '/') 1.120 ++ next_inode_name++; 1.121 + 1.122 +- do { 1.123 +- inode = get_inode(parent); 1.124 ++ /* Check if we're at the end */ 1.125 ++ if (*next_inode_name == '\0') 1.126 ++ next_inode_name = NULL; 1.127 ++ } 1.128 ++ dprintf("searchdir: inode_name: %s\n", inode_name); 1.129 ++ if (next_inode_name) 1.130 ++ dprintf("searchdir: Remaining: %s\n", next_inode_name); 1.131 + 1.132 +- while (*p == '/') 1.133 +- p++; 1.134 ++ /* Root directory? */ 1.135 ++ if (inode_name[0] == '/') { 1.136 ++ /* Release any chain that's already been established */ 1.137 ++ put_inode(inode); 1.138 ++ inode = get_inode(this_fs->root); 1.139 ++ continue; 1.140 ++ } 1.141 + 1.142 +- if (!*p) 1.143 +- break; 1.144 ++ /* Current directory? */ 1.145 ++ if (!strncmp(inode_name, ".", sizeof ".")) 1.146 ++ continue; 1.147 + 1.148 +- part = p; 1.149 +- while ((echar = *p) && echar != '/') 1.150 +- p++; 1.151 +- *p++ = '\0'; 1.152 ++ /* Parent directory? */ 1.153 ++ if (!strncmp(inode_name, "..", sizeof "..")) { 1.154 ++ /* If there is no parent, just ignore it */ 1.155 ++ if (!inode->parent) 1.156 ++ continue; 1.157 + 1.158 +- if (part[0] == '.' && part[1] == '.' && part[2] == '\0') { 1.159 +- if (inode->parent) { 1.160 +- put_inode(parent); 1.161 +- parent = get_inode(inode->parent); 1.162 +- put_inode(inode); 1.163 +- inode = NULL; 1.164 +- if (!echar) { 1.165 +- /* Terminal double dots */ 1.166 +- inode = parent; 1.167 +- parent = inode->parent ? 1.168 +- get_inode(inode->parent) : NULL; 1.169 +- } 1.170 +- } 1.171 +- } else if (part[0] != '.' || part[1] != '\0') { 1.172 +- inode = this_fs->fs_ops->iget(part, parent); 1.173 +- if (!inode) 1.174 +- goto err; 1.175 +- if (inode->mode == DT_LNK) { 1.176 +- char *linkbuf, *q; 1.177 +- int name_len = echar ? strlen(p) : 0; 1.178 +- int total_len = inode->size + name_len + 2; 1.179 +- int link_len; 1.180 ++ /* Add a reference to the parent so we can release the child */ 1.181 ++ tmp = get_inode(inode->parent); 1.182 + 1.183 +- if (!this_fs->fs_ops->readlink || 1.184 +- --symlink_count == 0 || /* limit check */ 1.185 +- total_len > MAX_SYMLINK_BUF) 1.186 +- goto err; 1.187 ++ /* Releasing the child will drop the parent back down to 1 */ 1.188 ++ put_inode(inode); 1.189 + 1.190 +- linkbuf = malloc(total_len); 1.191 +- if (!linkbuf) 1.192 +- goto err; 1.193 ++ inode = tmp; 1.194 ++ continue; 1.195 ++ } 1.196 + 1.197 +- link_len = this_fs->fs_ops->readlink(inode, linkbuf); 1.198 +- if (link_len <= 0) { 1.199 +- free(linkbuf); 1.200 +- goto err; 1.201 +- } 1.202 ++ /* Anything else */ 1.203 ++ tmp = inode; 1.204 ++ inode = this_fs->fs_ops->iget(inode_name, inode); 1.205 ++ if (!inode) { 1.206 ++ /* Failure. Release the chain */ 1.207 ++ put_inode(tmp); 1.208 ++ break; 1.209 ++ } 1.210 + 1.211 +- q = linkbuf + link_len; 1.212 ++ /* Sanity-check */ 1.213 ++ if (inode->parent && inode->parent != tmp) { 1.214 ++ dprintf("searchdir: iget returned a different parent\n"); 1.215 ++ put_inode(inode); 1.216 ++ inode = NULL; 1.217 ++ put_inode(tmp); 1.218 ++ break; 1.219 ++ } 1.220 ++ inode->parent = tmp; 1.221 ++ inode->name = strdup(inode_name); 1.222 ++ dprintf("searchdir: path component: %s\n", inode->name); 1.223 + 1.224 +- if (echar) { 1.225 +- if (link_len > 0 && q[-1] != '/') 1.226 +- *q++ = '/'; 1.227 ++ /* Symlink handling */ 1.228 ++ if (inode->mode == DT_LNK) { 1.229 ++ char *new_path; 1.230 ++ int new_len, copied; 1.231 + 1.232 +- memcpy(q, p, name_len+1); 1.233 +- } else { 1.234 +- *q = '\0'; 1.235 +- } 1.236 ++ /* target path + NUL */ 1.237 ++ new_len = inode->size + 1; 1.238 + 1.239 +- free(pathbuf); 1.240 +- p = pathbuf = linkbuf; 1.241 +- put_inode(inode); 1.242 +- inode = NULL; 1.243 +- goto got_link; 1.244 +- } 1.245 ++ if (next_inode_name) { 1.246 ++ /* target path + slash + remaining + NUL */ 1.247 ++ new_len += strlen(next_inode_name) + 1; 1.248 ++ } 1.249 + 1.250 +- inode->name = strdup(part); 1.251 +- dprintf("path component: %s\n", inode->name); 1.252 ++ if (!this_fs->fs_ops->readlink || 1.253 ++ /* limit checks */ 1.254 ++ --symlink_count == 0 || 1.255 ++ new_len > MAX_SYMLINK_BUF) 1.256 ++ goto err_new_len; 1.257 + 1.258 +- inode->parent = parent; 1.259 +- parent = NULL; 1.260 ++ new_path = malloc(new_len); 1.261 ++ if (!new_path) 1.262 ++ goto err_new_path; 1.263 + 1.264 +- if (!echar) 1.265 +- break; 1.266 ++ copied = this_fs->fs_ops->readlink(inode, new_path); 1.267 ++ if (copied <= 0) 1.268 ++ goto err_copied; 1.269 ++ new_path[copied] = '\0'; 1.270 ++ dprintf("searchdir: Symlink: %s\n", new_path); 1.271 + 1.272 +- if (inode->mode != DT_DIR) 1.273 +- goto err; 1.274 +- 1.275 +- parent = inode; 1.276 +- inode = NULL; 1.277 ++ if (next_inode_name) { 1.278 ++ new_path[copied] = '/'; 1.279 ++ strcpy(new_path + copied + 1, next_inode_name); 1.280 ++ dprintf("searchdir: New path: %s\n", new_path); 1.281 + } 1.282 +- } while (echar); 1.283 +- } while (0); 1.284 + 1.285 +- free(pathbuf); 1.286 +- pathbuf = NULL; 1.287 +- put_inode(parent); 1.288 +- parent = NULL; 1.289 ++ free(path); 1.290 ++ path = next_inode_name = new_path; 1.291 + 1.292 +- if (!inode) 1.293 ++ /* Add a reference to the parent so we can release the child */ 1.294 ++ tmp = get_inode(inode->parent); 1.295 ++ 1.296 ++ /* Releasing the child will drop the parent back down to 1 */ 1.297 ++ put_inode(inode); 1.298 ++ 1.299 ++ inode = tmp; 1.300 ++ continue; 1.301 ++err_copied: 1.302 ++ free(new_path); 1.303 ++err_new_path: 1.304 ++err_new_len: 1.305 ++ put_inode(inode); 1.306 ++ inode = NULL; 1.307 ++ break; 1.308 ++ } 1.309 ++ 1.310 ++ /* If there's more to process, this should be a directory */ 1.311 ++ if (next_inode_name && inode->mode != DT_DIR) { 1.312 ++ dprintf("searchdir: Expected a directory\n"); 1.313 ++ put_inode(inode); 1.314 ++ inode = NULL; 1.315 ++ break; 1.316 ++ } 1.317 ++ } 1.318 ++err_curdir: 1.319 ++ free(path); 1.320 ++err_path: 1.321 ++ if (!inode) { 1.322 ++ dprintf("searchdir: Not found\n"); 1.323 + goto err; 1.324 ++ } 1.325 + 1.326 + file->inode = inode; 1.327 + file->offset = 0; 1.328 +@@ -342,10 +410,6 @@ 1.329 + return file_to_handle(file); 1.330 + 1.331 + err: 1.332 +- put_inode(inode); 1.333 +- put_inode(parent); 1.334 +- if (pathbuf) 1.335 +- free(pathbuf); 1.336 + _close_file(file); 1.337 + err_no_close: 1.338 + return -1; 1.339 +@@ -483,6 +547,11 @@ 1.340 + fs.root = fs.fs_ops->iget_root(&fs); 1.341 + fs.cwd = get_inode(fs.root); 1.342 + dprintf("init: root inode %p, cwd inode %p\n", fs.root, fs.cwd); 1.343 ++ } 1.344 ++ 1.345 ++ if (fs.fs_ops->chdir_start) { 1.346 ++ if (fs.fs_ops->chdir_start() < 0) 1.347 ++ printf("Failed to chdir to start directory\n"); 1.348 + } 1.349 + 1.350 + SectorShift = fs.sector_shift;