qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

path.c (1809B)


      1 /* Code to mangle pathnames into those matching a given prefix.
      2    eg. open("/lib/foo.so") => open("/usr/gnemul/i386-linux/lib/foo.so");
      3 
      4    The assumption is that this area does not change.
      5 */
      6 #include "qemu/osdep.h"
      7 #include <sys/param.h>
      8 #include <dirent.h>
      9 #include "qemu/cutils.h"
     10 #include "qemu/path.h"
     11 #include "qemu/thread.h"
     12 
     13 static const char *base;
     14 static GHashTable *hash;
     15 static QemuMutex lock;
     16 
     17 void init_paths(const char *prefix)
     18 {
     19     if (prefix[0] == '\0' || !strcmp(prefix, "/")) {
     20         return;
     21     }
     22 
     23     if (prefix[0] == '/') {
     24         base = g_strdup(prefix);
     25     } else {
     26         char *cwd = g_get_current_dir();
     27         base = g_build_filename(cwd, prefix, NULL);
     28         g_free(cwd);
     29     }
     30 
     31     hash = g_hash_table_new(g_str_hash, g_str_equal);
     32     qemu_mutex_init(&lock);
     33 }
     34 
     35 /* Look for path in emulation dir, otherwise return name. */
     36 const char *path(const char *name)
     37 {
     38     gpointer key, value;
     39     const char *ret;
     40 
     41     /* Only do absolute paths: quick and dirty, but should mostly be OK.  */
     42     if (!base || !name || name[0] != '/') {
     43         return name;
     44     }
     45 
     46     qemu_mutex_lock(&lock);
     47 
     48     /* Have we looked up this file before?  */
     49     if (g_hash_table_lookup_extended(hash, name, &key, &value)) {
     50         ret = value ? value : name;
     51     } else {
     52         char *save = g_strdup(name);
     53         char *full = g_build_filename(base, name, NULL);
     54 
     55         /* Look for the path; record the result, pass or fail.  */
     56         if (access(full, F_OK) == 0) {
     57             /* Exists.  */
     58             g_hash_table_insert(hash, save, full);
     59             ret = full;
     60         } else {
     61             /* Does not exist.  */
     62             g_free(full);
     63             g_hash_table_insert(hash, save, NULL);
     64             ret = name;
     65         }
     66     }
     67 
     68     qemu_mutex_unlock(&lock);
     69     return ret;
     70 }