1

I want to create a directory in the same path as my program, to ultimately save data to. To do this I need OS specific calls surrounded by preprocessor branches, but I've never wrote any OS specific code before this point. I am unsure what headers I need to include, or what functions to use from them.

If the OS are Windows, Mac, and Linux (whatever method would work for most linux distros anyway), what functions and headers should I use?

The reason I don't want to use boost filesystem for this is, I've had difficulty all day compiling it; it's documentation and build system is, uh, too academic/verbose for my simple soul it seems! Ultimately, I believe maintaining 3 or 4 seperate file loading branches will be faster for me.

Anne Quinn
  • 12,609
  • 8
  • 54
  • 101

2 Answers2

3

On all Unix systems (Linux, Mac OS X, etc.), you should call mkdir with two arguments:

mkdir(filename, 0755);

On Windows, you want to use _mkdir with just one argument:

_mkdir(filename);

So your code should say

#ifdef WIN32
#include <direct.h>
rc = _mkdir(filename);
#else
#include <sys/stat.h>
rc = mkdir(filename, 0755);
#endif
jch
  • 5,382
  • 22
  • 41
  • `_mkdir` requires the header `` to be included. It's also worth noting that there is a Unicode-aware version `_wmkdir`, that allows to reliably create directories with characters outside the ASCII range. – IInspectable Jan 11 '15 at 14:30
2

First, if you want to write cross-platform code (for all of Linux, Windows, MacOSX), you might use some multi-platform framework library like POCO or Qt

Then, if you want POSIX specific function to make a directory, use mkdir function. On Linux, it is the mkdir(2) syscall (listed in syscalls(2)...). The documentation explains which headers should be included, and it is part of the C standard library on Linux.

BTW, on most Linux distributions, you often don't need to compile Boost; on Debian-like distributions (e.g. Ubuntu) you can install the libboost-all-dev meta-package (all boost related libraries, for development) using aptitude install libboost-all-dev or apt-get install libboost-all-dev

To get an overview of Linux programming, read Advanced Linux Programming

Also, gcc (and other C or C++ compilers) predefines a set of preprocessor symbols. See this answer. So in your code, you might simply use #if linux ... #endif to wrap Linux-specific code.

Notice also that POSIX is a standard specification: you should be able to compile the same code on all POSIX compliant operating systems (notably Linux, *BSD, Solaris, MacOSX). Sadly, Windows is not POSIX compliant (even if you can buy a POSIX-compliant kit from MicroSoft)

Perhaps mkdir is available on Windows too....

Read also feature_test_macros(7)


Notice also that "create a directory in the same path as my program" is ambiguous. You can run your program in several processes, each having a different current working directory. And quite often (at least on Linux) an executable program is installed in some directory (e.g. /usr/local/bin/, /usr/bin/ or $HOME/bin/) mentioned in your PATH but unwritable by most programs. Read more about the Filesystem Hierarchy Standard. So I won't persist your software data in the same directory as your program. Also, you could use application checkpointing or persist your data using sqlite or something else (PostGreSQL, MongoDB, JSON, ...)

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547