Revision 10f5bff6

b/include/qemu-common.h
360 360

  
361 361
/* OS specific functions */
362 362
void os_setup_early_signal_handling(void);
363
char *os_find_datadir(const char *argv0);
363
char *os_find_datadir(void);
364 364
void os_parse_cmd_args(int index, const char *optarg);
365 365
void os_pidfile_error(void);
366 366

  
b/include/qemu/osdep.h
215 215
 */
216 216
char *qemu_get_local_state_pathname(const char *relative_pathname);
217 217

  
218
/* Find program directory, and save it for later usage with
219
 * qemu_get_exec_dir().
220
 * Try OS specific API first, if not working, parse from argv0. */
221
void qemu_init_exec_dir(const char *argv0);
222

  
223
/* Get the saved exec dir.
224
 * Caller needs to release the returned string by g_free() */
225
char *qemu_get_exec_dir(void);
226

  
218 227
/**
219 228
 * qemu_getauxval:
220 229
 * @type: the auxiliary vector key to lookup
b/os-posix.c
84 84
   running from the build tree this will be "$bindir/../pc-bios".  */
85 85
#define SHARE_SUFFIX "/share/qemu"
86 86
#define BUILD_SUFFIX "/pc-bios"
87
char *os_find_datadir(const char *argv0)
87
char *os_find_datadir(void)
88 88
{
89
    char *dir;
90
    char *p = NULL;
89
    char *dir, *exec_dir;
91 90
    char *res;
92
    char buf[PATH_MAX];
93 91
    size_t max_len;
94 92

  
95
#if defined(__linux__)
96
    {
97
        int len;
98
        len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
99
        if (len > 0) {
100
            buf[len] = 0;
101
            p = buf;
102
        }
103
    }
104
#elif defined(__FreeBSD__)
105
    {
106
        static int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
107
        size_t len = sizeof(buf) - 1;
108

  
109
        *buf = '\0';
110
        if (!sysctl(mib, ARRAY_SIZE(mib), buf, &len, NULL, 0) &&
111
            *buf) {
112
            buf[sizeof(buf) - 1] = '\0';
113
            p = buf;
114
        }
115
    }
116
#endif
117
    /* If we don't have any way of figuring out the actual executable
118
       location then try argv[0].  */
119
    if (!p) {
120
        p = realpath(argv0, buf);
121
        if (!p) {
122
            return NULL;
123
        }
93
    exec_dir = qemu_get_exec_dir();
94
    if (exec_dir == NULL) {
95
        return NULL;
124 96
    }
125
    dir = dirname(p);
126
    dir = dirname(dir);
97
    dir = dirname(exec_dir);
127 98

  
128 99
    max_len = strlen(dir) +
129 100
        MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1;
......
137 108
        }
138 109
    }
139 110

  
111
    g_free(exec_dir);
140 112
    return res;
141 113
}
142 114
#undef SHARE_SUFFIX
b/os-win32.c
84 84
}
85 85

  
86 86
/* Look for support files in the same directory as the executable.  */
87
char *os_find_datadir(const char *argv0)
87
char *os_find_datadir(void)
88 88
{
89
    char *p;
90
    char buf[MAX_PATH];
91
    DWORD len;
92

  
93
    len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
94
    if (len == 0) {
95
        return NULL;
96
    }
97

  
98
    buf[len] = 0;
99
    p = buf + len - 1;
100
    while (p != buf && *p != '\\')
101
        p--;
102
    *p = 0;
103
    if (access(buf, R_OK) == 0) {
104
        return g_strdup(buf);
105
    }
106
    return NULL;
89
    return qemu_get_exec_dir();
107 90
}
108 91

  
109 92
void os_set_line_buffering(void)
b/qemu-img.c
2719 2719
#endif
2720 2720

  
2721 2721
    error_set_progname(argv[0]);
2722
    qemu_init_exec_dir(argv[0]);
2722 2723

  
2723 2724
    qemu_init_main_loop();
2724 2725
    bdrv_init();
b/qemu-io.c
381 381
#endif
382 382

  
383 383
    progname = basename(argv[0]);
384
    qemu_init_exec_dir(argv[0]);
384 385

  
385 386
    while ((c = getopt_long(argc, argv, sopt, lopt, &opt_index)) != -1) {
386 387
        switch (c) {
b/qemu-nbd.c
376 376
    memset(&sa_sigterm, 0, sizeof(sa_sigterm));
377 377
    sa_sigterm.sa_handler = termsig_handler;
378 378
    sigaction(SIGTERM, &sa_sigterm, NULL);
379
    qemu_init_exec_dir(argv[0]);
379 380

  
380 381
    while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
381 382
        switch (ch) {
b/util/oslib-posix.c
57 57
#include "trace.h"
58 58
#include "qemu/sockets.h"
59 59
#include <sys/mman.h>
60
#include <libgen.h>
60 61

  
61 62
#ifdef CONFIG_LINUX
62 63
#include <sys/syscall.h>
......
274 275

  
275 276
    tcsetattr(fd, TCSANOW, &tty);
276 277
}
278

  
279
static char exec_dir[PATH_MAX];
280

  
281
void qemu_init_exec_dir(const char *argv0)
282
{
283
    char *dir;
284
    char *p = NULL;
285
    char buf[PATH_MAX];
286

  
287
    assert(!exec_dir[0]);
288

  
289
#if defined(__linux__)
290
    {
291
        int len;
292
        len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
293
        if (len > 0) {
294
            buf[len] = 0;
295
            p = buf;
296
        }
297
    }
298
#elif defined(__FreeBSD__)
299
    {
300
        static int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
301
        size_t len = sizeof(buf) - 1;
302

  
303
        *buf = '\0';
304
        if (!sysctl(mib, ARRAY_SIZE(mib), buf, &len, NULL, 0) &&
305
            *buf) {
306
            buf[sizeof(buf) - 1] = '\0';
307
            p = buf;
308
        }
309
    }
310
#endif
311
    /* If we don't have any way of figuring out the actual executable
312
       location then try argv[0].  */
313
    if (!p) {
314
        if (!argv0) {
315
            return;
316
        }
317
        p = realpath(argv0, buf);
318
        if (!p) {
319
            return;
320
        }
321
    }
322
    dir = dirname(p);
323

  
324
    pstrcpy(exec_dir, sizeof(exec_dir), dir);
325
}
326

  
327
char *qemu_get_exec_dir(void)
328
{
329
    return g_strdup(exec_dir);
330
}
b/util/oslib-win32.c
208 208
                       dwMode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT));
209 209
    }
210 210
}
211

  
212
static char exec_dir[PATH_MAX];
213

  
214
void qemu_init_exec_dir(const char *argv0)
215
{
216

  
217
    char *p;
218
    char buf[MAX_PATH];
219
    DWORD len;
220

  
221
    len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
222
    if (len == 0) {
223
        return;
224
    }
225

  
226
    buf[len] = 0;
227
    p = buf + len - 1;
228
    while (p != buf && *p != '\\') {
229
        p--;
230
    }
231
    *p = 0;
232
    if (access(buf, R_OK) == 0) {
233
        pstrcpy(exec_dir, sizeof(exec_dir), buf);
234
    }
235
}
236

  
237
char *qemu_get_exec_dir(void)
238
{
239
    return g_strdup(exec_dir);
240
}
b/vl.c
2827 2827

  
2828 2828
    atexit(qemu_run_exit_notifiers);
2829 2829
    error_set_progname(argv[0]);
2830
    qemu_init_exec_dir(argv[0]);
2830 2831

  
2831 2832
    g_mem_set_vtable(&mem_trace);
2832 2833
    if (!g_thread_supported()) {
......
3855 3856
    /* If no data_dir is specified then try to find it relative to the
3856 3857
       executable path.  */
3857 3858
    if (data_dir_idx < ARRAY_SIZE(data_dir)) {
3858
        data_dir[data_dir_idx] = os_find_datadir(argv[0]);
3859
        data_dir[data_dir_idx] = os_find_datadir();
3859 3860
        if (data_dir[data_dir_idx] != NULL) {
3860 3861
            data_dir_idx++;
3861 3862
        }

Also available in: Unified diff