9

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?

  • `pwd` is going to return the "present working directory" of the executable unless you change directories explicitly. –  Apr 29 '13 at 18:26
  • @0A0D I think it actually means `print working directory` – Nelson Apr 29 '13 at 18:28

5 Answers5

20

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);
}
Sujoy
  • 8,041
  • 3
  • 30
  • 36
7

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
PADYMKO
  • 4,217
  • 2
  • 36
  • 41
3

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).

jbr
  • 6,198
  • 3
  • 30
  • 42
1

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.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
0

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().

ST3
  • 8,826
  • 3
  • 68
  • 92