5

I am working on a project in which I need to know the current working directory of the executable which called the system call. I think it would be possible as some system calls like open would make use of that information.

Could you please tell how I can get the current working directory path in a string?

gaurav
  • 872
  • 2
  • 10
  • 25

3 Answers3

12

You can look at how the getcwd syscall is implemented to see how to do that.

That syscall is in fs/dcache.c and calls:

get_fs_root_and_pwd(current->fs, &root, &pwd);

root and pwd are struct path variables,

That function is defined as an inline function in include/linux/fs_struct.h, which also contains:

static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd)

and that seems to be what you are after.

Mat
  • 202,337
  • 40
  • 393
  • 406
  • OK isn't there anything that could be simpler than this like a simple function call which could written the current working directory in a string ? – gaurav Dec 03 '11 at 10:47
  • It is a simple function call to get the `struct path`. Did I misunderstand your question, and you are not actually writing kernel code? – Mat Dec 03 '11 at 10:49
  • No I am writing kernel code actually I am making some changes in fs/namei.c so I need to know the current working directory there ? I thought I could call some sys_getcwd type call like I can use sys_getpid to get the pid. Could you tell me where I can see what exports are done so that I could use that function ? Or I will use your answer. :) – gaurav Dec 03 '11 at 10:54
  • sys_getcwd expects a pointer to user memory to store the path (uses copy_to_user). If you're in kernel space, that's not appropriate. Read that function in dcache.c to see how it works, or look for other usages of `get_fs_pwd` in the code. – Mat Dec 03 '11 at 11:13
  • ok I understand. Thank you very much for your help indeed. Also I need to know the complete name of the executable which called this system call can I get that ? – gaurav Dec 03 '11 at 11:32
  • It's possible, the `/proc/pid/exe` link displays it for instance. Look in `fs/proc/base.c`, `proc_exe_link` function. – Mat Dec 03 '11 at 11:35
  • Yes I know about that sorry couldn't explain it better but how would I read a file in kernel code? Also could I find some documentation of these functions somewhere, it becomes difficult to see what is argument and what is returned ? – gaurav Dec 03 '11 at 11:40
  • http://stackoverflow.com/questions/1184274/kernelhow-to-read-write-files-within-kernel-module. Please do a bit of research, it's a pretty common question. Also this is not a forum, if you have other questions, ask them as questions. – Mat Dec 03 '11 at 11:44
  • Thanks a lot for your help , sorry for my mistake will remember that. – gaurav Dec 03 '11 at 11:55
  • I have got the struct path but how to get the path in string form from it ? – gaurav Dec 03 '11 at 12:34
  • Please read the getcwd syscall code. It calls a helper that does that. – Mat Dec 03 '11 at 12:42
  • Ok Thanks again , I think prepend_path is that helper function, one last question, how can I allocate memory for cwd string, I don't think using static array would be a good idea, the getcwd takes page from user space how should I do that in kernel space? – gaurav Dec 03 '11 at 12:51
  • Please do some research, allocating memory in kernel is not trivial but you'll find plenty of reference very fast, and I repeat: this is not a forum. If you want to code in kernel space, you'll need to invest significant time in searching and reading code. – Mat Dec 03 '11 at 12:53
  • Thanks for your help. I will surely follow your advice. – gaurav Dec 03 '11 at 12:56
  • @gaurav: It is worth adding that kernel code should in general *not* be using the text representation of paths - it should be working with the `struct path` (and likewise it should not be working with a PID, it should be using the `struct task`). – caf Dec 05 '11 at 03:25
  • @caf : Thanks a lot for your advice, I understand why its like that. I will try my best to keep it systematic – gaurav Dec 05 '11 at 15:00
  • Is there any explanation for how the parent directory and the current directory can be deleted and yet still traversable and readdirable when you have used `chdir` into the current subdirectory? What is the mechanism in the kernel that does this? It's definitely not nlink, since that goes down to 0. What about dcache? – CMCDragonkai Sep 15 '17 at 17:31
0

In newer kernels things changed a little bit. You can use this to get the current working directory:

#include <linux/init.h>         // module_{init,exit}()
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/dcache.h>       // dentry_path_raw
#include <linux/fs_struct.h>    // get_fs_pwd

static int __init get_cwd_module_init(void)
{
    struct path abs_path;
    char *buf, *full_path;

    buf = __getname();
    if (!buf)
        return -ENOMEM;

    get_fs_pwd(current->fs, &abs_path);

    full_path = dentry_path_raw(abs_path.dentry, buf, PATH_MAX);
    if (IS_ERR(full_path)) {
        pr_err("dentry_path_raw failed: %li", PTR_ERR(full_path));
    } else {
        pr_info("Full path: '%s'", full_path);
    }
    __putname(buf);
    path_put(&abs_path);
}

static void __exit get_cwd_module_exit(void)
{
    pr_info("exiting...");
}

module_init(get_cwd_module_init)
module_exit(get_cwd_module_exit)

MODULE_AUTHOR("garlix");
MODULE_LICENSE("GPL");

garlix
  • 576
  • 9
  • 26
-1

How do you do that in a terminal ? You use pwd which looks at the environment variable named PWD.

#include <stdlib.h>

int main(int ac, char **av) {
    printf("%s\n", getenv("PWD");

    return 0;
}

If you want to know in which directory the executable is located you can combine the information from getenv and from argv[0].

Daimrod
  • 4,902
  • 23
  • 25