Linux:如何获取已运行进程的umask?

33

我该如何检查当前正在运行的程序的umask?

[更新:另一个进程,而不是当前进程。]


当前的进程?还是外部进程? - C. K. Young
之前有一个补丁,可以在/proc/pid/status/proc/pid/stat中报告进程的umask。但是似乎这个补丁并没有被合并到主线内核中。 - Craig McQueen
在[unix.se]上有同样的问题:获取进程pid的当前umask值 - Stephane Chazelas
6个回答

28

您可以将gdb附加到正在运行的进程上,然后在调试器中调用umask:

(gdb) attach <your pid>
...
(gdb) call umask(0)
[Switching to Thread -1217489200 (LWP 11037)]
$1 = 18 # this is the umask
(gdb) call umask(18) # reset umask
$2 = 0
(gdb) 

(注意:在此示例中,18对应于umask的O22

这表明可能有一种非常丑陋的方法可以使用ptrace获取umask。


1
谢谢!并且感谢提醒我将umask设置回去的额外感激之情! - Mark Harrison
2
如果你像我一样感到困惑,那么这行代码“$1 = 18”的意思是进程umask之前设置为18(八进制中的022)。 - njahnke
1
更好的方式:调用 /o umask(027)。 - MarcH
对于跟随者,以八进制形式输出调用/ o,如“022” - rogerdpack

16

从Linux内核4.7开始,umask可以在/proc/<pid>/status中找到。


2
你的 3.10.0 版本中:可能。在主线 3.10.0 版本中:不行。 - egmont
它在RHEL7.4的内核3.10.0-862.3.2.el7.x86_64中。 - hagello

8

《GNU C Library手册》中写道:

Here is an example showing how to read the mask with umask without changing it permanently:

mode_t
read_umask (void)
{
  mode_t mask = umask (0);
  umask (mask);
  return mask;
}

However, it is better to use getumask if you just want to read the mask value, because it is reentrant (at least if you use the GNU operating system).

getumask是特定于glibc的。因此,如果您重视可移植性,则非可重入解决方案是唯一的解决方案。

编辑:我刚刚在整个Linux源代码中搜索了->umask。没有任何地方可以获取不同进程的umask。此外,没有getumask;这似乎只在Hurd上有。


是的,getumask只存在于Hurd系统上。Linux手册上有一句有用的注释:这个函数在glibc手册中有说明,但是截至glibc 2.24版本,在Linux上尚未实现。 - Pete Forman

2

如果您是当前进程,可以将文件写入/tmp并检查其设置。更好的解决方案是调用umask(3),传递零 - 函数返回调用之前的设置 - 然后通过将该值传回umask来重新设置它。

另一个进程的umask似乎没有暴露出来。


1

我的同事向我展示了这个命令行模式。我通常都在使用emacs,所以下面的例子中会包含它。而perl则是我的贡献:

sudo gdb --pid=$(pgrep emacs) --batch -ex 'call/o umask(0)' -ex 'call umask($1)' 2> /dev/null | perl -ne 'print("$1\n")if(/^\$1 = (\d+)$/)'

1

至少在内核4.18中,有一个选项可以搜索状态proc文件: grep Umask /proc/<PID>/status


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接