# Current working directory of a process



## noobster (Sep 22, 2009)

How can I obtain the current working directory for a given PID? Thanks.


----------



## DutchDaemon (Sep 22, 2009)

You could install sysutils/lsof and grep the pid from its output. Or if you know the process name (e.g. named):


```
lsof | grep ^named
```

That's just a crude approach, because lsof has many flags that can approach this question from different angles. Be sure to check out the EXAMPLES in lsof(8).

p.s. ( <- pun ), don't underestimate the command-line information in e.g. [cmd=]ps auxww[/cmd].


----------



## phoenix (Sep 23, 2009)

There's also the procstat(1) tool in FreeBSD 8+.

And fstat(1) may be useful as well.


----------



## noobster (Sep 23, 2009)

Got it, thanks for your replies.


----------



## Beastie (Sep 23, 2009)

phoenix said:
			
		

> There's also the procstat(1) tool in FreeBSD 8+.


The first output line of `% procstat -f PID` is cwd in 7.2.


----------



## frakswe (Jun 27, 2020)

Hey,
I need to set `sysctl security.bsd.unprivileged_proc_debug=1` for a non root user to make any real use of the `procstat` command, but even
then cwd doesn't resolve the full path of the process id.

i get the same results with lsof and fstat, none of them resolve the full path (seems to default to /usr/home/$USER)

What's the proper way to get a full process id path on FreeBSD? surely there must be a way that doesn't involve hacking the planet.


----------



## memreflect (Jun 27, 2020)

frakswe said:


> cwd doesn't resolve the full path of the process id.
> 
> i get the same results with lsof and fstat, none of them resolve the full path (seems to default to /usr/home/$USER)


cwd is the directory where that process is running, as if you typed `pwd` at a shell prompt.  If it's reporting a $HOME directory, then the process was executed in that $HOME directory.

If you seek the full path used to execute some process, you can use `procstat -b PID`:

```
$ procstat -b (pgrep dbus)
  PID COMM                OSREL PATH
11874 dbus-daemon       1201000 /usr/local/bin/dbus-daemon
11711 dbus-launch       1201000 /usr/local/bin/dbus-launch
```

You can add the -h option to suppress the header and pipe the output through `awk '{ print $4 }'` to only print the PATH field.  However, this isn't always reliable.  From procstat(1):

```
PATH    path to process binary (if available)
```

If it's not available, there's nothing that can be done:

```
$ doas procstat -b 9
  PID COMM                OSREL PATH
    9 zfskern           1201000 -
```

Some processes simply don't have filesystem paths.


----------



## frakswe (Jun 27, 2020)

This is suckless terminal st, kinda need that functionality for a few patches but i guess it needs particular code that advertises it's process id cwd for FreeBSD.

Dang.


----------



## memreflect (Jun 27, 2020)

frakswe said:


> This is suckless terminal st, kinda need that functionality for a few patches but i guess it needs particular code that advertises it's process id cwd for FreeBSD.


You might start a new thread in Userland Programming and Scripting.  I suspect sysctl(3) with KERN_PROC_PATHNAME is the way to go, but yes, it's specific to FreeBSD.


----------



## ralphbsz (Jun 27, 2020)

frakswe said:


> I need to set `sysctl security.bsd.unprivileged_proc_debug=1` for a non root user to make any real use of the `procstat` command,


That is correct, and working as intended. If you set this to zero, the non-privileged processes can not debug other processes, and that includes not being able to look at their settings such as open files. In general, this is considered a good thing for security, as in most cases non-privileged users do not need to debug other processes.



> What's the proper way to get a full process id path on FreeBSD? surely there must be a way that doesn't involve hacking the planet.


To begin with, please explain clearly what you mean by "full process id path". I think you mean the current working directory of a process. But some of the discussions above are about the currently running binary (executable), so I'll try to answer both.

Strange. For me, it works perfectly, on 11.3-RELEASE. I can to procstat -b and procstat -f from either a user process or from root, and I do see the full path name for either the executing binary (if it exists, as memreflect points out kernel processes do not have one), and I do see the full current working directory in the -f output for all processes (which is always "/" for kernel processes). Example:

```
# procstat -f 40614 | fgrep cwd
40614 bash               cwd v d r-------   -       - -   /home/ralph
# procstat -b 40614
  PID COMM                OSREL PATH
40614 bash              1103000 /usr/local/bin/bash
```



frakswe said:


> This is suckless terminal st, kinda need that functionality for a few patches but i guess it needs particular code that advertises it's process id cwd for FreeBSD.


I don't understand. What is "suckless terminal st"? And what does it mean for something to advertise its cwd? The current working directory can be examined using procstat, if enabled. If you have control of the source code for a program, why don't you have the program determine its current working directory itself, and then leave it in a well-known place (such as its stdout), for others to inspect?

I think what we have here is actually an XY problem. You are asking how to perform a particular task, namely look up the current working directory or the current running binary of a process. It would probably help us give you more reasoned answers if you explained to us what problem you are actually trying to solve.


----------



## frakswe (Jun 27, 2020)

Sure,It's https://st.suckless.org and i want to apply https://st.suckless.org/patches/newterm/st-newterm-0.8.2.diff that contains 
	
	



```
snprintf(buf, sizeof buf, "/proc/%d/cwd", pid);
```
 which doesn't work. Looked for workarounds,found this thread.


----------



## ralphbsz (Jun 27, 2020)

Ah, now I get it. Suckless is a terminal emulator. Agree that replacing xterm is a good idea, its source code is a mess. The problem is that suckless is clearly designed for Linux, which has an extensive /proc file system, which allows seeing all manner of information about other processes. There are a few reasons why this is a very bad design. The security and privacy problems are already fascinating. The real issue is how the /proc file system is implemented: it first goes through the VFS layer (with its complex caching and directory/inode mechanisms), and then looks at live kernel data structure, which causes lots of consistency and race condition problems. But it's easy and convenient for hackers.

The various BSD operating systems never fully embraced the /proc file system, nor the /sys file system. And I agree with them that a file system paradigm is not appropriate for getting system information (and for many years I have been a file system developer). Matter-of-fact, I vaguely remember that OpenBSD has completely abandoned the /proc file system, while on FreeBSD it is getting more and more obsolescent. But equivalent mechanisms exist.

So, you want to find the equivalent mechanism for FreeBSD. I think what you'll have to do is (a) first make sure that procstat works for you (so do the sysctl configuration to enable it, and make sure it is actually returning things correctly, with the full path name when running it with -f for the CWD), and then (b) read the man pages for libprocstat. Start with "man 3 procstat" and read the description of the APIs. It is probably also instructive to read the source code for the procstat utility as a guide for how to do it. Depending on your experience level, this is probably a project that will take hours or days.

If you are working on improving the source code ot the suckless terminal for everyone, not just for you, then you also have to make a decision what to do if the sysctl is not enabled; if it's only for yourself, then you can just enable it.


----------



## George (Jun 27, 2020)

Since it looks like C, maybe libprocstat() has a function for that.


----------



## frakswe (Jun 27, 2020)

Thanks guys, i'll read up on the libs. Even if it goes nowhere atleast i increased my unix beard.


----------

