mkdir() возвращает -1 при запуске через Finder

У меня есть простая программа, которая создает каталог при выполнении:

#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main(){
    if(int a = mkdir("abc",0700)){
        std::cout << "Failed to create: " << a << std::endl;
    }
    else{
        std::cout << "Created." << std::endl;
    }
}

Он ведет себя по-разному для двух разных вариантов использования:

  • Running the compiled binary through Terminal
    • Output: Created.
  • Launching this program via Finder with double click.
    • Output: Failed to create: -1

Как мне сделать так, чтобы запуск этой программы через Finder создавал папку abc без использования Cocoa framework (компилируется только с g++)?


person swtdrgn    schedule 05.05.2014    source источник
comment
Почти наверняка проблема с рабочим каталогом.   -  person Wooble    schedule 05.05.2014
comment
Проблема действительно связана с рабочим каталогом.   -  person swtdrgn    schedule 05.05.2014


Ответы (1)


Спасибо Wooble за указание в разделе комментариев, что проблема связана с рабочим каталогом. Когда я запустил его через Finder, текущим рабочим каталогом был мой домашний каталог.

Ниже показано, как я решаю проблему:

#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <libproc.h>

int main(int argc, char** argv){
    // Gets and prints out the current directory
    char cwd[1024];
    getcwd(cwd, sizeof(cwd));
    std::cout << "Current Working Directory: " << cwd << std::endl;
    // Above is not necessary

    // Changes working directory to directory that contains executable
    char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
    if(proc_pidpath (getpid(), pathbuf, sizeof(pathbuf)) > 0){ // Gets the executable path
        std::string s(pathbuf);
        s = s.substr(0,s.find_last_of('/')); // Removes executable name from path
        std::cout << "Executable Path: " << s << std::endl;
        chdir(s.c_str()); // Changes working directory
    }

    if(int a = mkdir("abc",0700)){
        std::cout << "Failed to create: " << a << std::endl;
    }
    else{
        std::cout << "Created." << std::endl;
    }
}
person swtdrgn    schedule 05.05.2014
comment
Я немного запутался... Почему все вызовы функций getpid() и т. д., когда argv[0] уже содержит путь к исполняемому файлу? Просто используйте std::string s(argv[0]);. (IIRC, argv[0] всегда будет содержать путь к запущенному исполняемому файлу, и если argc (количество аргументов) > 1, следующие значения argv[] будут содержать аргументы командной строки). - person NSGod; 06.05.2014
comment
У меня просто было ощущение, что это может быть ненадежным. См. ответ pixelbeat и комментарии к его ответам по адресу stackoverflow.com/questions/799679/. - person swtdrgn; 06.05.2014