Is it better to use getcwd(NULL, 0) or get_current_dir_name() ? What is common practice ?
My uninformed guess is that a call to getcwd(NULL, 0) may be a better idea since it is possible that the PWD variable is not set…
Advertisement
Answer
Is it better to use
getcwd(NULL, 0)orget_current_dir_name()? What is common practice ?
This is operating system specific. I guess you use Linux.
Then, read syscalls(2) and getcwd(3). Study the source code of its implementation in GNU libc or in musl libc
Notice that
getcwdtakes a buffer of a given known size. In practice, 256 bytes might be often enough, but in principle the buffer should be much bigger. See sysconf(3) and pathconf(3). Acceptinggetcwd(NULL,0)is an extension equivalent toget_current_dir_name()so usesmallocand could fail. My Debian computer has in/usr/include/linux/limits.ha macro definition#define PATH_MAX 4096(but 4096, when used as the size of some automatic variable, is a lot for a call frame of any recursive function; look also into nftw(3)).getwdis obsolete since prone to buffer overflow. Don’t use it in 2021.get_current_dir_nameuses malloc(3) which could fail.
AFAIK, getcwd(3) should not use the PWD environment variable. It should work if you code your own /sbin/init using it
And sometimes, you can boot a Linux kernel running /bin/bash instead of /sbin/init. In such case, the PWD environment variable is not set. See environ(7) and credentials(7).
Of course, in most other programs, PWD is correctly set (e.g. by GNU bash, whose source code you can study since it is free software)
My personal recommendation
assume and document that your program won’t run for file paths larger than e.g. 256 bytes (but be aware that UTF 8 is everywhere in 2021). This assumption could be false for file names which are generated with UUID strings or several IPV6 addresses, and you might want to use C dynamic memory allocation for
pathbelow…. so a near equivalent ofget_current_dir_name. Don’t forget tofreeit!code something like:
char path[256]; memset (path, 0, sizeof(path)); if (getcwd(path, sizeof(path)) == NULL) { perror("getcwd"); exit(EXIT_FAILURE); // or abort() }
Of course, if you code an init-like program for some robot, this is not good enough. Robots on Mars might generate long path names!