Программно получить абсолютный путь к приложению командной строки OS X

Если вы знаете свою оперативную память при запуске своей Java-программы, просто используйте -xmx и определите, сколько общей памяти использовать. Xmx является параметром команды запуска и не может быть изменен динамически. Итак, если вы хотите изменить его на лету, вам нужно его вычислить и перезапустить свою программу с новыми параметрами. Вот хороший пример.

20
задан Cœur 15 April 2017 в 19:13
поделиться

5 ответов

Функция _NSGetExecutablePath вернет полный путь к исполняемому файлу (GUI или нет). Путь может содержать символические ссылки, « .. » и т. Д., Но при необходимости можно использовать функцию realpath для их очистки. Для получения дополнительной информации см. man 3 dyld .

char path[1024];
uint32_t size = sizeof(path);
if (_NSGetExecutablePath(path, &size) == 0)
    printf("executable path is %s\n", path);
else
    printf("buffer too small; need size %u\n", size);

Секрет этой функции в том, что ядро ​​Дарвина помещает исполняемый путь в стек процесса сразу после envp ] массив при создании процесса. Редактор динамических ссылок dyld захватывает это при инициализации и сохраняет указатель на него. Эта функция использует этот указатель.

52
ответ дан 29 November 2019 в 22:30
поделиться

Думаю, нет гарантированного способа. Если argv [0] является символической ссылкой, вы можете использовать readlink (). Если команда выполняется через $ PATH, можно попробуйте некоторые из: search (getenv ("PATH")), getenv ("_"), dladdr ()

2
ответ дан 29 November 2019 в 22:30
поделиться

Похоже, ответ в том, что вы не можете этого сделать:

Я пытаюсь достичь чего-то вроде функциональность lsof и собрать целая куча статистики и информации о запущенных процессах. Если ИСОФ не было так медленно, я был бы счастлив придерживаться с ним.

Если вы переопределите lsof, вы найдете что это медленно, потому что это делает много работы.

Думаю, это не совсем так, потому что lsof пользовательский режим, это больше, чем нужно сканировать адресное пространство задачи искать вещи, подкрепленные внешний пейджер. Есть ли быстрее способ сделать это, когда я в ядро?

Нет. Исф не глуп; это делает что это должно сделать. Если вы просто хотите подмножество его функциональности, вы можете хочу рассмотреть вопрос о начале с Источник (который доступен) и обрезать его, чтобы удовлетворить ваши требования.

Из любопытства, p_textvp используется в все? Похоже, он установлен на родительский p_textvp в kern_fork (и потом освобождают ??) но это не так прикоснуться к любому из kern_exec подпрограммы.

p_textvp не используется. В Дарвине proc не является корнем адреса пространство; задача есть. Здесь нет понятие "Внедрение" для задачи адресное пространство, так как его нет обязательно изначально заселены отображение 1.

Если exec должен был заполнить p_textvp, он потворствовал бы предположению, что все процессы поддерживаются vnode. Тогда программисты предположили бы, что это можно было проложить путь к вноде, а оттуда короткий перейти к предположению, что текущий путь к вноде это путь from which it was launched, and that text processing on the string might lead to the application bundle name... all of which would be impossible to guarantee without substantial penalty.

Mike Smith, Darwin Drivers mailing list

4
ответ дан 29 November 2019 в 22:30
поделиться

Почему бы просто realpath (argv [0], actualpath); ? Правда, у realpath есть некоторые ограничения (задокументированные на странице руководства), но он прекрасно обрабатывает символические ссылки. Протестировано на FreeBSD и Linux

    % ls -l foobar 
    lrwxr-xr-x  1 bortzmeyer  bortzmeyer  22 Apr 29 07:39 foobar -> /tmp/get-real-name-exe

    % ./foobar 
    My real path: /tmp/get-real-name-exe
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <libgen.h>
#include <string.h>
#include <sys/stat.h>

int
main(argc, argv)
    int             argc;
    char          **argv;
{
    char            actualpath[PATH_MAX + 1];

    if (argc > 1) {
        fprintf(stderr, "Usage: %s\n", argv[0]);
        exit(1);
    }
    realpath(argv[0], actualpath);
    fprintf(stdout, "My real path: %s\n", actualpath);
    exit(0);
}

Если программа запускается через PATH, см. Решение pixelbeat.

0
ответ дан 29 November 2019 в 22:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: