prosource

프로그래밍 방식으로 OS X 명령줄 앱의 절대 경로 검색

probook 2023. 9. 20. 20:24
반응형

프로그래밍 방식으로 OS X 명령줄 앱의 절대 경로 검색

프로그램은 를 수 ./proc/self/exe을 구축해야 더 이 필요합니다 FreeBSD에서는 sysctl call을 구축해야 하기 때문에 더 많은 작업이 필요합니다.

int mib[4];
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PATHNAME;
mib[3] = -1;
char buf[1024];
size_t cb = sizeof(buf);
sysctl(mib, 4, buf, &cb, NULL, 0);

하지만 아직 완전히 가능합니다 에 대해 을 찾을 수 .그러나 명령 줄 응용 프로그램에 대해 OS X에서 이를 결정할 방법을 찾을 수 없습니다.다를 할 수 [[NSBundle mainBundle] bundlePath]그러나 프로그램이 되지 않기 에 이 되지 않습니다

(: )argv[0] 왜냐하면, 만약 symlink에서 시작된다면,argv[0]호출된 실행 파일로 가는 궁극적인 경로가 아니라 그 심볼링크가 될 것입니다.argv[0]바보같은 애플리케이션이 사용한다면 또한 거짓말을 할 수 있습니다.exec()호출하고 야생에서 본 argv를 제대로 초기화하는 것을 잊어버립니다.)

이 함수는 실행 파일(GUI 여부)에 대한 전체 경로를 반환합니다.경로에 기호 링크가 포함되어 있을 수 있습니다."..", 그 외에도 필요하다면 그것들을 치울 수 있는 기능을 사용할 수 있습니다.자세한 내용은3dyld 을 참조하십시오.

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프로세스를 생성할 때 배열합니다.rdyld초기화 시 이를 잡고 포인터를 유지합니다.이 함수는 그 포인터를 사용합니다.

실제로 어떤 PID에도 적합하고 절대 경로를 직접 반환하는 훨씬 더 우아한 솔루션이 있다고 생각합니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <libproc.h>

int main (int argc, char* argv[])
{
    int ret;
    pid_t pid; 
    char pathbuf[PROC_PIDPATHINFO_MAXSIZE];

    pid = getpid();
    ret = proc_pidpath (pid, pathbuf, sizeof(pathbuf));
    if ( ret <= 0 ) {
        fprintf(stderr, "PID %d: proc_pidpath ();\n", pid);
        fprintf(stderr, "    %s\n", strerror(errno));
    } else {
        printf("proc %d: %s\n", pid, pathbuf);
    }

    return 0;
}

답은 당신이 할 수 없다는 것 같습니다.

저는 여러 가지 기능을 달성하고 실행 중인 프로세스에 대한 통계와 정보를 수집하려고 노력하고 있습니다.만약 제가 그렇게 느리지 않았다면 저는 기꺼이 그것을 고수할 것입니다.

를 다시 구현해 보면 작업이 많이 진행되기 때문에 속도가 느리다는 것을 알게 될 것입니다.

그것은 실제로는 사용자 모드이기 때문이 아니라 외부 호출기에서 지원하는 것을 찾기 위해 작업의 주소 공간을 검색해야 하기 때문인 것 같습니다.제가 커널에 있을 때 더 빠른 방법이 없을까요?

아닙니다. 저는 바보가 아닙니다. 해야 할 일을 하는 것입니다.해당 기능의 하위 집합을 원하는 경우에는 ls of source(사용 가능)부터 시작하여 요구 사항에 맞게 축소하는 것을 고려해 볼 수 있습니다.

호기심 때문에.p_textvp쓰임새가 있습니까?부모의 것으로 설정된 것 같습니다.p_textvp인에kern_fork(그러다가 풀려난 건가요?)?) 하지만 그 어떤 것도 손대지 않고 있습니다.kern_exec의 일상적인 일들.

p_textvp사용되지 않습니다.다윈에서 프로시저는 주소 공간의 루트가 아닙니다. 작업은 입니다.작업의 주소 공간을 매핑하여 처음에 채워야 하는 것은 아니기 때문에 작업의 주소 공간에 대한 "vnode" 개념은 없습니다.

exec이 p_textvp를 채우면 모든 프로세스가 vnode에 의해 지원된다는 가정에 부합합니다.그러면 프로그래머는 vnode로의 경로를 얻을 수 있다고 가정하고, 여기서 vnode로의 현재 경로가 vnode가 시작된 경로이며, 문자열에 대한 텍스트 처리를 통해 애플리케이션 번들 이름이 생성될 수 있다고 가정합니다.이 모든 것들은 상당한 벌금 없이는 보장할 수 없을 것입니다.

Mike Smith, Darwin Drivers 메일링 리스트

늦었지만.[[NSBundle mainBundle] executablePath]는 bundled가 아닌 명령줄 프로그램에서도 잘 작동합니다.

내 생각에는 확실한 방법이 없습니다.argv[0]가 symlink이면 readlink()를 사용할 수 있습니다.$PATH를 통해 명령을 실행하면 검색(getenv("PATH")), getenv(_), dladdr() 중 일부를 시도할 수 있습니다.

단순하지 않은 이유realpath(argv[0], actualpath);? 맞아요, 실제 경로는 (설명서 페이지에 나와 있는) 몇 가지 제한이 있지만 심볼릭 링크를 잘 처리합니다.FreeBSD 및 Linux에서 테스트 완료

% ls - l 푸바lrwxr-xr-x 1 bortzmeyer bortzmeyer 22 4월 2907:39 foobar -> /tmp/get-실명-exe
% ./풋바내 진짜 경로: /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를 통해 프로그램이 시작되는 경우 픽셀비트의 솔루션을 참조하십시오.

http://developer.apple.com/documentation/Carbon/Reference/Process_Manager/Reference/reference.html #//apple_ref/c/func/GetProcess 번들 위치

GetProcessBundleLocation이 작동하는 것 같습니다.

언급URL : https://stackoverflow.com/questions/799679/programmatically-retrieving-the-absolute-path-of-an-os-x-command-line-app

반응형