7

The long answer to my own question, having Googled it and not found anything useful, is to sift through the source of 'ps'. But before I do that, is there anyone willing to provide the lazy man's solution? :-)

I found this question: Knowing the process status using procf/<pid>/status However, the solution doesn't seem to be available on the 3.2 kernel. Is this pstatus_t type available in newer kernels? If so, does that mean newer kernels provide a binary interface to /proc//status?

Community
  • 1
  • 1
Craig
  • 4,268
  • 4
  • 36
  • 53
  • /proc/self/status would seem a good candidate, but what if /proc is not mounted? – Craig Aug 06 '13 at 11:57
  • do you want it for the current process, or for any other process given a pid ? – Sander De Dycker Aug 06 '13 at 11:59
  • 1
    Not the current process, process based on pid. Ignore the /proc/self, that was just my transferring of command line thoughts into ramblings. I actually meant /proc//status. – Craig Aug 06 '13 at 12:03
  • Well, try unmounting `/proc` and see if `ps` still works. (IIRC, it probably won't as it actually gets its information from `/proc`). – nneonneo Aug 06 '13 at 12:04
  • I also looked for something along the lines and did not find a system call that does this for me. – LostBoy Aug 06 '13 at 12:06
  • 1
    Then `/proc//status` is probably your best bet. – Sander De Dycker Aug 06 '13 at 12:12
  • What's wrong with using the `getuid()` and `getgid()` if it's for the current process? – Anya Shenanigans Aug 06 '13 at 12:23
  • @Petesh: It's not for the current process. This has been clarified a few times now. – Craig Aug 06 '13 at 12:33
  • I found this question: http://stackoverflow.com/questions/13469276/knowing-the-process-status-using-procf-pid-status However, the solution doesn't seem to be available on the 3.2 kernel. Is this pstatus_t type available in newer kernels? If so, does that mean newer kernels provide a binary interface to /proc//status? – Craig Aug 07 '13 at 14:24
  • 2
    Older Unix systems (SunOS 4.x, for example) didn't have `/proc`, and yet the `ps` command worked correctly. There must have been another mechanism to get information about a process given its PID. I don't know how system-specific that mechanism was, or whether it still exists in Linux (or Solaris, or ...). – Keith Thompson Aug 07 '13 at 15:17
  • @KeithThompson on older systems, `ps` was a setuid program which was reading the info directly from the kernel memory (from `/dev/mem`) and using the kernel binary (`/unix`) as a map/reference to it. And yes, that still works now as it did in 2013 for privileged/setuid processes, and is the only way to extract some info not exposed by other means (eg. the network namespace of the tun/tap interface corresponding to an endpoint in Linux). –  Jul 12 '19 at 14:52

3 Answers3

3

At the moment, the only viable solution I can come up with is something along the lines of this. Obviously, not gone to the effort to see if this actually works as I would expect it to yet...:

int len, pid, n, fd = open("/proc/12345/status", O_RDONLY | O_NOATIME);
char buf[4096], whitespace[50];

if (0 < (len = read(fd, buf, 4096)))
{
    n = sscanf(buf, "Uid:%s%d ", whitespace, &pid);
}
Craig
  • 4,268
  • 4
  • 36
  • 53
  • 2
    wouldn't it be easier to just `stat` the `/proc/pid` directory and read the st_uid and st_gid values? – Anya Shenanigans Aug 06 '13 at 12:47
  • That's okay for obtaining the 'real' uid and gid. It won't give you effective or fs and it certainly doesn't give you supplementary groups. – Craig Aug 07 '13 at 14:20
1

If I'm not mistaken there are some system calls you can use for this situation:

#include <unistd.h>
#include <sys/types.h>

geteuid() //returns the effective user ID of the calling process.
getuid() //returns the real user ID of the calling process.
getgid() //returns the real group ID of the calling process.

getegid() //returns the effective group ID of the calling process.

See these links for more information:

Unix manual page for getgid()

unix manual page for getuid()

Rezga
  • 390
  • 1
  • 10
  • 2
    These work only for the calling process. OP wants the uid / gid of *any* process given it’s pid. – dbush Jul 12 '19 at 10:43
0

There is not a system call that I know of but since I needed the same, I wrote this small program. Enjoy.

static int getPuid (int gpid) 
{ // by Zibri http://www.zibri.org
    char fname[256];
    char buf[256];
    int pid=8;
    sprintf(fname,"/proc/%d/status",gpid);
    FILE *proc; 
    proc = fopen(fname,"r");    
    if (proc) { 
        while(pid--) fgets(buf,256,proc); // skip first 8 lines
        sscanf(buf,"Uid:\t%lu\t",&pid); 
    } else return -1;   
    fclose(proc);   
    return pid;
}
Zibri
  • 9,096
  • 3
  • 52
  • 44