user1824918
user1824918

Reputation:

How to get the path to the current file (pwd) in Linux from C?

I'd like to know if it is somehow possible to run system("pwd") on the current DIR. So for example let's have this folder structure:

example
 >test
  >>file
 >test2
  >>file3
  >>file4

And with opendir() and readdir() I'll get to file3, and I want to use system("pwd") to get the path ..../example/test2/file3. Is this somehow possible, or will pwd return the path to main.c all the time?

Upvotes: 9

Views: 76764

Answers (5)

How to not hardcode the path length with pathconf

I believe this is the correct way to do it:

#define _XOPEN_SOURCE 700
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

int main(void) {
    long n;
    char *buf;

    n = pathconf(".", _PC_PATH_MAX);
    assert(n != -1);
    buf = malloc(n * sizeof(*buf));
    assert(buf);
    if (getcwd(buf, n) == NULL) {
        perror("getcwd");
        exit(EXIT_FAILURE);
    } else {
        printf("%s\n", buf);
    }
    free(buf);
    return EXIT_SUCCESS;
}

GitHub upstream.

Compile and run:

gcc -Wall -Wextra -std=c11 -pedantic-errors  -o getcwd.out getcwd.c
./getcwd.out

POSIX describes _PC_PATH_MAX it as:

The value returned for the variable {PATH_MAX} indicates the longest relative pathname that could be given if the specified directory is the process' current working directory. A process may not always be able to generate a name that long and use it if a subdirectory in the pathname crosses into a more restrictive file system.

Tested on Ubuntu 18.10, n == 4096 in this implementation.

Upvotes: 1

ВелоКастръ
ВелоКастръ

Reputation: 4453

For POSIX systems I found three solutions:

Get value from an environment variables "PWD"

#include <stdio.h>
#include <stdlib.h>

#ifdef __unix__
    #define IS_POSIX 1
#else
    #define IS_POSIX 0
#endif


int main (int argv, char **argc)
{
    if (IS_POSIX == 1) {
        puts("Path info by use environment variable PWD:");
        printf("\tWorkdir: %s\n", getenv("PWD"));
        printf("\tFilepath: %s/%s\n", getenv("PWD"), __FILE__);
    }
    return 0;
}

Result:

Path info by use environment variable PWD:
    Workdir: /media/setivolkylany/WorkDisk/Programming/Projects/c-utils
    Filepath: /media/setivolkylany/WorkDisk/Programming/Projects/c-utils/main.c

Use getcwd()

#include <stdio.h>
#include <stdlib.h>

#ifdef __unix__
    #define IS_POSIX 1
    #include <unistd.h>
#else
    #define IS_POSIX 0
#endif


int main (int argv, char **argc)
{
    if (IS_POSIX == 1) {
        char cwd[1024];
        getcwd(cwd, sizeof(cwd));
        puts("Path info by use getcwd():");
        printf("\tWorkdir: %s\n", cwd);
        printf("\tFilepath: %s/%s\n", cwd, __FILE__);
    }
    return 0;
}

Result

Path info by use getcwd():
    Workdir: /media/setivolkylany/WorkDisk/Programming/Projects/c-utils
    Filepath: /media/setivolkylany/WorkDisk/Programming/Projects/c-utils/main.c

Execute system command "pwd" and read output

#ifdef __unix__
    #define IS_POSIX 1
    #define _BSD_SOURCE
#else
    #define IS_POSIX 0
#endif

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


int main (int argv, char **argc)
{
    if (IS_POSIX == 1) {
        char buffer[500];
        FILE *output;

        // read output of a command
        output = popen("/bin/pwd", "r");
        char *pwd = fgets(buffer, sizeof(buffer), output);

        // strip '\n' on ending of a line
        pwd = strtok(pwd, "\n");

        puts("Path info by execute shell command 'pwd':");
        printf("\tWorkdir: %s\n", pwd);
        printf("\tFilepath: %s/%s\n", pwd, __FILE__);
    }
    return 0;
}

Result:

Path info by execute shell command 'pwd':
    Workdir: /media/setivolkylany/WorkDisk/Programming/Projects/c-utils
    Filepath: /media/setivolkylany/WorkDisk/Programming/Projects/c-utils/main.c

Upvotes: 8

Sujoy
Sujoy

Reputation: 8319

Simply opening and reading directories does not change the current working directory. However, changing directory in your program will.

for reference,

#include <unistd.h>
#include <stdio.h>

int main() {
    char cwd[1024];
    chdir("/path/to/change/directory/to");
    getcwd(cwd, sizeof(cwd));
    printf("Current working dir: %s\n", cwd);
}

Upvotes: 20

jbr
jbr

Reputation: 6258

You can use chdir(2) to change dir from C, then system("pwd"); will give you what ever directory you chdir'ed to.

The C-equvivalent of the pwd-command is getcwd(3).

Upvotes: 3

ST3
ST3

Reputation: 8946

When you use system(...) call with Windows and Linux it just executes one command. It is possible to do the same using file with commands (you can create it with C code), but my oppinion is, that you should use nftw() to get dirrectories and after that use opendir()/readdir().

Upvotes: 0

Related Questions