“弹出”如何让进程关闭文件句柄?

“弹出”如何让进程关闭文件句柄?

在我的 Mac 上,当我“弹出”网络安装的共享时,我的 Mac 会向我显示以下消息,并尝试让进程关闭打开的文件句柄并彻底卸载共享。我的问题是,它到底是如何实现这一目标的?我想它会枚举使用我的共享路径打开的文件句柄,然后向拥有这些文件句柄的进程发送某种信号?只是一个猜测,请填写我,我很好奇。 弹出对话框 我想过在 Apple stack Exchange 上询问这个问题,但我猜这实际上是一个更普遍适用的 UNIX 问题。如果我错了,并且 macOS 有一种特殊/新的方法可以做到这一点,并且这个问题需要在那里关闭并重新打开,请告诉我。

编辑:添加屏幕截图。

答案1

我不知道,但是有一个随机的 USB 记忆棒和一个程序

$ df | grep Vol
/dev/disk1s2  12228  20  12208  1%  512  0  100%   /Volumes/Firmware
$ perl -E 'say $$; chdir "/Volumes/Firmware" or die "nope $!"; sleep 9999'
66433

我们确实可以停止弹出,但在此之前我们需要对进程进行一些调试,这里由在其他终端中运行的 DTrace 提供

$ sudo dtruss -p 66433
...

然后通过英文中所谓的强制弹出按钮,点击几下、延迟和警告,测试程序仍在运行,并且 USB 记忆棒已卸载,并且dtruss没有显示任何内容:

...
^C
$ lsof -p 66433 | grep cwd
perl5.26 66433 jhqdoe  cwd        cwd|rtd info error: No such file or directory
$ 

因此,至少对于一个标准的 UNIX 程序来说,除了从其下方移除挂载点之外,没有发生任何事情。接下来我们可以再次使用标准 unix 程序测试向挂载点写入一些内容

$ cat writeslow
#!/usr/bin/env perl
use 5.14.0;
use warnings;

open( my $fh, ">", "/Volumes/Firmware/mlatu" ) or die "nope $!";
while (1) {
    syswrite( $fh, "mlatu\n" ) or warn "hmm $!";
    sleep 3;
}
$ perl writeslow

在其他地方,我们确认猫正在出现(如果您使用一些更高级别的写入函数,缓冲可能会成为问题)

$ cat /Volumes/Firmware/mlatu
mlatu
mlatu
$ 

我们再次强制弹出,程序确实注意到了这一点(但继续运行,因为它是这样写的):

$ perl writeslow
hmm Input/output error at writeslow line 7.
hmm Input/output error at writeslow line 7.

因此,Mac OS X 10.11(因为这个硬件太旧了,无法运行 macOS)没有按照问题中的要求“尝试让进程关闭打开的文件句柄”,并且没有证据表明“某种信号[已发送]”拥有这些文件句柄的进程”发生;相反,该进程继续运行,如果它进行任何类型的错误检查,那么它可能会失败,具体取决于它的编写方式。

至少对于具有标准unixcwd并使用标准I/O调用的标准unix程序来说;也许苹果框架程序有些不同?让我们再次重新安装 USB 记忆棒并mlatu使用以下命令打开文件Hex Fiend.app...

$ open -a Hex\ Fiend /Volumes/Firmware/mlatu
$ lsof | grep mlatu
Hex\x20Fi 66642 jhqdoe  8r  REG  1,5  216  7 /Volumes/Firmware/mlatu
$ 

(或者TextEdit如果您没有Hex Fiend安装,则使用或其他东西)并再次进行强制弹出舞蹈......

$ screencapture -w error.png
$ 

十六进制恶魔使用分区错误

现在我们得到的消息与标准 UNIX 程序不同,并且没有强制卸载的选项。

答案2

事实并非如此。它只是卸载文件系统,因此当程序尝试再次访问文件系统时,它将出现错误(希望它会尝试顺利解决问题)。

与物理分离外部磁盘(或 USB 笔)的情况没有太大区别。文件系统不再可用,但程序将在第一次使用后看到它。

相关内容