0

I have a simple program that makes a directory when it is executed:

#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;
    }
}

It behaves differently for two different use cases:

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

How do I make this so that launching this program via Finder creates the folder abc without using Cocoa framework (compiles with g++ only)?

swtdrgn
  • 1,154
  • 4
  • 17
  • 49

1 Answers1

0

Thanks to Wooble for pointing it out in the comment section that the problem is due to the working directory. When I launched it through Finder, the current working directory was my home directory.

Below is how I address the problem:

#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;
    }
}
swtdrgn
  • 1,154
  • 4
  • 17
  • 49
  • I'm a little confused... Why all the function calls to `getpid()`, etc., when `argv[0]` already contains the path to the running executable? Just use `std::string s(argv[0]);`. (IIRC, `argv[0]` will always contain the path of the running executable, and if `argc` (arg count) > 1, the following `argv[]` values will contain command-line arguments). – NSGod May 05 '14 at 20:56
  • I just had the feeling that it may not be reliable. See `pixelbeat`'s answer and comments to his answers at http://stackoverflow.com/questions/799679/programatically-retrieving-the-absolute-path-of-an-os-x-command-line-app. – swtdrgn May 05 '14 at 22:18