誰もがより良いアイデアを持っていない場合は...
独自のキャラクタデバイスドライバを実装することができます。第3章のテンプレートをLinux Device Drivers (3rd edition)から始めて、それを微調整してclose()でしばらくの間ブロックします。
実際には、ほかに他の人が何も示唆していない場合は、私が持っている既存のコードを適応させることで、これをかなり速やかに取り上げることができます。あなたはどれくらいそれを必要としますか?
[編集]
OK、これを試してみてください...
のMakefile:
ifneq ($(KERNELRELEASE),)
obj-m := closer.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default: modules
%:
$(MAKE) -C $(KERNELDIR) M=$(PWD) "[email protected]"
.PHONY: default
endif
closer.c:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/fs.h>
MODULE_DESCRIPTION("Block-on-close driver");
MODULE_AUTHOR("Nemo <[email protected]>");
MODULE_LICENSE("GPL");
#define VERSION "20110705"
MODULE_VERSION(VERSION);
#define MY_NAME "closer"
int my_open(struct inode *, struct file *);
int my_release(struct inode *, struct file *);
ssize_t my_read(struct file *, char __user *, size_t, loff_t *);
ssize_t my_write(struct file *, const char __user *, size_t, loff_t *);
static struct file_operations my_fops = {
.owner = THIS_MODULE,
.open = my_open,
.read = my_read,
.write = my_write,
.release = my_release,
};
static struct miscdevice my_dev;
int __init
my_init(void)
{
int err = 0;
printk(KERN_INFO "%s: loading version %s\n", MY_NAME, VERSION);
my_dev.minor = MISC_DYNAMIC_MINOR;
my_dev.name = MY_NAME;
my_dev.fops = &my_fops;
err = misc_register(&my_dev);
if (err)
printk(KERN_ERR "%s: misc_register failed, error %d\n", MY_NAME, err);
return err;
}
int
my_open(struct inode *inode, struct file *filp)
{
return 0;
}
ssize_t
my_read(struct file *file, char __user *p, size_t n, loff_t *off) {
return 0;
}
ssize_t
my_write(struct file *file, const char __user *p, size_t n, loff_t *off) {
return n;
}
int
my_release(struct inode *inode, struct file *filp)
{
int err = 0;
/* 10 second sleep, interruptible. */
if (msleep_interruptible(10 * 1000) > 0)
err = -EINTR;
return err;
}
void __exit
my_exit(void)
{
misc_deregister(&my_dev);
printk(KERN_INFO "%s: unloaded\n", MY_NAME);
}
module_init(my_init);
module_exit(my_exit);
ロードinsmodは近い」を使用してモジュール。 o "。合理的に現代的/完全なLinux環境をお持ちの場合、udevは自動的に起床して/ dev /を生成します。ない場合は、自分でデバイスノードを作成することができます。
mknod /dev/closer c `tr : ' ' </sys/class/misc/closer/dev`
(つまり、/ SYS /クラス/ miscの/近くには/ devには大きなを示します。マイナー使用する)
読み込みと同じように動作書き込みを/ dev/null;すなわち、任意の読み取りに対するEOF、任意の書き込みに対する成功。
私は、close()
に「cat </dev/closer」が10秒間ブロックすることを確認しました。 SIGINT
(または何でも)を捕まえるためのテストを作成せず、実際にEINTR
という結果が得られることを確認しました。
2.6.32カーネルに対して構築されています。それがあなたのためにどのように機能するか教えてください。
質問の回答はhttp://stackoverflow.com/questions/40257564/posix-unix-how-to-reliably-close-a-file-descriptorのコードサンプルリンクにあります。この例では、意図的にTCP接続を中断し、パケットを廃棄する必要があります。 close()は、このように数分間分ブロックしておくことができます。 –