summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2014-02-22 23:17:16 +0100
committerThomas Martitz <kugel@rockbox.org>2014-02-23 20:23:52 +0100
commit46137ebd4d59d7a91d0b8d98d846a3fd2ec70f5c (patch)
treef7e9762b88973d363f17a0758da5aa3beeb8dc27
parent0f928f87850153a38c7e6cfafd283ce4f52a0666 (diff)
downloadrockbox-46137ebd4d59d7a91d0b8d98d846a3fd2ec70f5c.tar.gz
rockbox-46137ebd4d59d7a91d0b8d98d846a3fd2ec70f5c.zip
simulator: Fully simulate external storage.
The external storage will be created during make install, as simext folder in the build directory. Upon pressing the e key the sim will mount (virtually ) this into the root directory. It can be accessed in the same way as an sd/mmc card on real targets. This requires quite some path trickery in io.c. Change-Id: I2fa9070a3146101ec5655b5b4115ca349d1d4bf4
-rw-r--r--firmware/export/disk.h5
-rw-r--r--firmware/export/mv.h6
-rw-r--r--tools/root.make10
-rw-r--r--uisimulator/common/io.c72
4 files changed, 72 insertions, 21 deletions
diff --git a/firmware/export/disk.h b/firmware/export/disk.h
index b97ec11039..8d6b41b5bd 100644
--- a/firmware/export/disk.h
+++ b/firmware/export/disk.h
@@ -50,9 +50,4 @@ int disk_unmount(int drive);
50int disk_get_sector_multiplier(IF_MD_NONVOID(int drive)); 50int disk_get_sector_multiplier(IF_MD_NONVOID(int drive));
51#endif 51#endif
52 52
53#ifdef HAVE_HOTSWAP
54bool volume_removable(int volume);
55bool volume_present(int volume);
56#endif
57
58#endif 53#endif
diff --git a/firmware/export/mv.h b/firmware/export/mv.h
index 0d98ed1211..05c9c6349f 100644
--- a/firmware/export/mv.h
+++ b/firmware/export/mv.h
@@ -56,6 +56,12 @@
56#define VOL_NAMES "<HD%d>" 56#define VOL_NAMES "<HD%d>"
57#define VOL_ENUM_POS 3 57#define VOL_ENUM_POS 3
58#endif /* CONFIG_STORAGE */ 58#endif /* CONFIG_STORAGE */
59
60#ifdef HAVE_HOTSWAP
61bool volume_removable(int volume);
62bool volume_present(int volume);
63#endif
64
59#else /* empty definitions if no multi-volume */ 65#else /* empty definitions if no multi-volume */
60#define IF_MV(x...) 66#define IF_MV(x...)
61#define IF_MV_NONVOID(x...) void 67#define IF_MV_NONVOID(x...) void
diff --git a/tools/root.make b/tools/root.make
index 20e1ce3b53..4d58e26e8e 100644
--- a/tools/root.make
+++ b/tools/root.make
@@ -355,19 +355,23 @@ voice: voicetools $(BUILDDIR)/apps/features
355endif 355endif
356 356
357ifeq (,$(findstring android, $(APP_TYPE))) 357ifeq (,$(findstring android, $(APP_TYPE)))
358
359simext:
360 $(SILENT)mkdir -p $@
361
358bininstall: $(BUILDDIR)/$(BINARY) 362bininstall: $(BUILDDIR)/$(BINARY)
359 @echo "Installing your rockbox binary in your '$(RBPREFIX)' dir" 363 @echo "Installing your rockbox binary in your '$(RBPREFIX)' dir"
360 $(SILENT)cp $(BINARY) "$(RBPREFIX)/.rockbox/" 364 $(SILENT)cp $(BINARY) "$(RBPREFIX)/.rockbox/"
361 365
362install: 366install: simext
363 @echo "Installing your build in your '$(RBPREFIX)' dir" 367 @echo "Installing your build in your '$(RBPREFIX)' dir"
364 $(SILENT)$(TOOLSDIR)/buildzip.pl $(VERBOSEOPT) --app=$(APPLICATION) -m "$(MODELNAME)" -i "$(TARGET_ID)" $(INSTALL) -z "zip -r0" -r "$(ROOTDIR)" --rbdir="$(RBDIR)" -f 0 $(TARGET) $(BINARY) 368 $(SILENT)$(TOOLSDIR)/buildzip.pl $(VERBOSEOPT) --app=$(APPLICATION) -m "$(MODELNAME)" -i "$(TARGET_ID)" $(INSTALL) -z "zip -r0" -r "$(ROOTDIR)" --rbdir="$(RBDIR)" -f 0 $(TARGET) $(BINARY)
365 369
366fullinstall: 370fullinstall: simext
367 @echo "Installing a full setup in your '$(RBPREFIX)' dir" 371 @echo "Installing a full setup in your '$(RBPREFIX)' dir"
368 $(SILENT)$(TOOLSDIR)/buildzip.pl $(VERBOSEOPT) --app=$(APPLICATION) -m "$(MODELNAME)" -i "$(TARGET_ID)" $(INSTALL) -z "zip -r0" -r "$(ROOTDIR)" --rbdir="$(RBDIR)" -f 2 $(TARGET) $(BINARY) 372 $(SILENT)$(TOOLSDIR)/buildzip.pl $(VERBOSEOPT) --app=$(APPLICATION) -m "$(MODELNAME)" -i "$(TARGET_ID)" $(INSTALL) -z "zip -r0" -r "$(ROOTDIR)" --rbdir="$(RBDIR)" -f 2 $(TARGET) $(BINARY)
369 373
370symlinkinstall: 374symlinkinstall: simext
371 @echo "Installing a full setup with links in your '$(RBPREFIX)' dir" 375 @echo "Installing a full setup with links in your '$(RBPREFIX)' dir"
372 $(SILENT)$(TOOLSDIR)/buildzip.pl $(VERBOSEOPT) --app=$(APPLICATION) -m "$(MODELNAME)" -i "$(TARGET_ID)" $(INSTALL) -z "zip -r0" -r "$(ROOTDIR)" --rbdir="$(RBDIR)" -f 2 $(TARGET) $(BINARY) -l 376 $(SILENT)$(TOOLSDIR)/buildzip.pl $(VERBOSEOPT) --app=$(APPLICATION) -m "$(MODELNAME)" -i "$(TARGET_ID)" $(INSTALL) -z "zip -r0" -r "$(ROOTDIR)" --rbdir="$(RBDIR)" -f 2 $(TARGET) $(BINARY) -l
373endif 377endif
diff --git a/uisimulator/common/io.c b/uisimulator/common/io.c
index 9401f7d54a..179a919013 100644
--- a/uisimulator/common/io.c
+++ b/uisimulator/common/io.c
@@ -27,7 +27,9 @@
27#include <time.h> 27#include <time.h>
28#include <errno.h> 28#include <errno.h>
29#include "config.h" 29#include "config.h"
30#include "system.h"
30#include "ata_idle_notify.h" 31#include "ata_idle_notify.h"
32#include "mv.h"
31 33
32#define HAVE_STATVFS (!defined(WIN32)) 34#define HAVE_STATVFS (!defined(WIN32))
33#define HAVE_LSTAT (!defined(WIN32)) 35#define HAVE_LSTAT (!defined(WIN32))
@@ -124,7 +126,8 @@ extern int _wrmdir(const wchar_t*);
124#define CLOSE(a) (close)(a) 126#define CLOSE(a) (close)(a)
125#define REMOVE(a) (_wremove)(UTF8_TO_OS(a)) 127#define REMOVE(a) (_wremove)(UTF8_TO_OS(a))
126#define RENAME(a,b) (_wrename)(UTF8_TO_OS(a),utf8_to_ucs2(b,convbuf2)) 128#define RENAME(a,b) (_wrename)(UTF8_TO_OS(a),utf8_to_ucs2(b,convbuf2))
127 129/* readlink isn't used in the sim yet (FIXME) */
130#define READLINK(a,b,c) ({ fprintf(stderr, "no readlink on windows yet"); abort(); })
128#else /* !__MINGW32__ */ 131#else /* !__MINGW32__ */
129 132
130#define UTF8_TO_OS(a) (a) 133#define UTF8_TO_OS(a) (a)
@@ -144,6 +147,7 @@ extern int _wrmdir(const wchar_t*);
144#define CLOSE(x) (close)(x) 147#define CLOSE(x) (close)(x)
145#define REMOVE(a) (remove)(a) 148#define REMOVE(a) (remove)(a)
146#define RENAME(a,b) (rename)(a,b) 149#define RENAME(a,b) (rename)(a,b)
150#define READLINK(a,b,c) (readlink)(a,b,c)
147 151
148#endif /* !__MINGW32__ */ 152#endif /* !__MINGW32__ */
149 153
@@ -183,6 +187,7 @@ struct dirstruct {
183 187
184struct mydir { 188struct mydir {
185 DIR_T *dir; 189 DIR_T *dir;
190 IF_MV(int volumes_returned);
186 char *name; 191 char *name;
187}; 192};
188 193
@@ -323,6 +328,30 @@ ssize_t sim_write(int fd, const void *buf, size_t count)
323} 328}
324 329
325#if !defined(APPLICATION) 330#if !defined(APPLICATION)
331
332static const char *handle_special_links(const char* link)
333{
334 static char buffer[MAX_PATH]; /* sufficiently big */
335 char vol_string[VOL_ENUM_POS + 8];
336 int len = sprintf(vol_string, VOL_NAMES, 1);
337
338 /* link might be passed with or without HOME_DIR expanded. To handle
339 * both perform substring matching (VOL_NAMES is unique enough) */
340 const char *begin = strstr(link, vol_string);
341 if (begin)
342 {
343 /* begin now points to the start of vol_string within link,
344 * we want to copy the remainder of the paths, prefixed by
345 * the actual mount point (the remainder might be "") */
346 snprintf(buffer, sizeof(buffer), "%s/../simext/%s",
347 sim_root_dir ?: SIMULATOR_DEFAULT_ROOT, begin + len);
348 return buffer;
349 }
350 else
351 return link;
352}
353
354
326static const char *get_sim_pathname(const char *name) 355static const char *get_sim_pathname(const char *name)
327{ 356{
328 static char buffer[MAX_PATH]; /* sufficiently big */ 357 static char buffer[MAX_PATH]; /* sufficiently big */
@@ -330,13 +359,14 @@ static const char *get_sim_pathname(const char *name)
330 if(name[0] == '/') 359 if(name[0] == '/')
331 { 360 {
332 snprintf(buffer, sizeof(buffer), "%s%s", 361 snprintf(buffer, sizeof(buffer), "%s%s",
333 sim_root_dir != NULL ? sim_root_dir : SIMULATOR_DEFAULT_ROOT, name); 362 sim_root_dir ?: SIMULATOR_DEFAULT_ROOT, name);
334 return buffer; 363 return handle_special_links(buffer);
335 } 364 }
336 fprintf(stderr, "WARNING, bad file name lacks slash: %s\n", name); 365 fprintf(stderr, "WARNING, bad file name lacks slash: %s\n", name);
337 return name; 366 return name;
338} 367}
339 368
369
340MYDIR *sim_opendir(const char *name) 370MYDIR *sim_opendir(const char *name)
341{ 371{
342 DIR_T *dir; 372 DIR_T *dir;
@@ -348,6 +378,7 @@ MYDIR *sim_opendir(const char *name)
348 my->dir = dir; 378 my->dir = dir;
349 my->name = (char *)malloc(strlen(name)+1); 379 my->name = (char *)malloc(strlen(name)+1);
350 strcpy(my->name, name); 380 strcpy(my->name, name);
381 IF_MV(my->volumes_returned = 0);
351 382
352 return my; 383 return my;
353 } 384 }
@@ -374,16 +405,34 @@ struct sim_dirent *sim_readdir(MYDIR *dir)
374#ifdef EOVERFLOW 405#ifdef EOVERFLOW
375read_next: 406read_next:
376#endif 407#endif
377 x11 = READDIR(dir->dir);
378 408
379 if(!x11) 409#define ATTR_LINK 0x80 /* see dir.h */
380 return (struct sim_dirent *)0; 410
411 secret.info.attribute = 0;
412#ifdef HAVE_MULTIVOLUME
413 if (dir->name[0] == '/' && dir->name[1] == '\0'
414 && dir->volumes_returned++ < (NUM_VOLUMES-1)
415 && volume_present(dir->volumes_returned))
416 {
417 sprintf((char *)secret.d_name, VOL_NAMES, dir->volumes_returned);
418 secret.info.attribute = ATTR_LINK;
419 /* build file name for stat() which is the actual mount point */
420 snprintf(buffer, sizeof(buffer), "%s/../simext",
421 sim_root_dir ?: SIMULATOR_DEFAULT_ROOT);
422 }
423 else
424#endif
425 {
426 x11 = READDIR(dir->dir);
381 427
382 strcpy((char *)secret.d_name, OS_TO_UTF8(x11->d_name)); 428 if(!x11)
429 return (struct sim_dirent *)0;
383 430
384 /* build file name */ 431 strcpy((char *)secret.d_name, OS_TO_UTF8(x11->d_name));
385 snprintf(buffer, sizeof(buffer), "%s/%s", 432 /* build file name for stat() */
386 get_sim_pathname(dir->name), secret.d_name); 433 snprintf(buffer, sizeof(buffer), "%s/%s",
434 get_sim_pathname(dir->name), secret.d_name);
435 }
387 436
388 if (STAT(buffer, &s)) /* get info */ 437 if (STAT(buffer, &s)) /* get info */
389 { 438 {
@@ -401,8 +450,6 @@ read_next:
401 450
402#define ATTR_DIRECTORY 0x10 451#define ATTR_DIRECTORY 0x10
403 452
404 secret.info.attribute = 0;
405
406 if (S_ISDIR(s.st_mode)) 453 if (S_ISDIR(s.st_mode))
407 secret.info.attribute = ATTR_DIRECTORY; 454 secret.info.attribute = ATTR_DIRECTORY;
408 455
@@ -418,7 +465,6 @@ read_next:
418 (tm.tm_sec >> 1); 465 (tm.tm_sec >> 1);
419 466
420#if HAVE_LSTAT 467#if HAVE_LSTAT
421#define ATTR_LINK 0x80
422 if (!lstat(buffer, &s) && S_ISLNK(s.st_mode)) 468 if (!lstat(buffer, &s) && S_ISLNK(s.st_mode))
423 { 469 {
424 secret.info.attribute |= ATTR_LINK; 470 secret.info.attribute |= ATTR_LINK;