- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试将 cat 命令作为内核模块来实现。我知道文件 i/o 不应该在内核模块中完成。每次我使用 insmod module.ko
时,我都会得到 killed
的输出。我该如何解决?另外我该如何改进代码?
内核版本 - 4.4
代码:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/unistd.h>
#include <linux/syscalls.h>
#include <linux/fcntl.h>
#include <asm/uaccess.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/file.h>
static char* argv[10];
static int argc = 1;
module_param_array(argv, int, &argc , 0);
static void cat(int f, char *s)
{
char buf[8192];
struct file *file;
loff_t pos = 0;
long n;
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
while((n = vfs_read(f, buf, (long)sizeof buf, &pos)) > 0)
{
//write(1, buf, n);
file = fget(f);
if (file) {
vfs_write(file, buf, (long)sizeof buf, &pos);
fput(file);
}
}
set_fs(old_fs);
}
static void __init hello_init(void)
{
int f, i;
if(argc == 1)
cat(0, "<stdin>");
else for(i=1; i<argc; i++)
{
f = filp_open(argv[i], O_RDONLY, 0);
if(f < 0)
printk("error");
else{
cat(f, argv[i]);
filp_close(f);
}
}
}
static void __exit hello_cleanup(void)
{
printk(KERN_INFO "Cleaning up module.\n");
}
module_init(hello_init);
module_exit(hello_cleanup);
这是上面代码的简化版本,它只读取一个文件。在注释掉 vfs_read
部分时,我能够对其进行 insmod,但是对于 vfs_read
它显示已被杀死。
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/syscalls.h>
#include <linux/fcntl.h>
#include <asm/uaccess.h>
static void read_file(char *filename)
{
int fd;
char buf[1];
loff_t f_pos = 0;
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
fd = filp_open(filename, O_RDONLY, 0);
if (fd >= 0) {
printk(KERN_DEBUG);
while (vfs_read(fd, buf, 1, &f_pos) == 1) //if this
printk("%c", buf[0]); //and this is removed I'm able to insmod it
printk("\n");
sys_close(fd);
}
set_fs(old_fs);
}
static int __init init(void)
{
read_file("/etc/shadow");
return 0;
}
static void __exit exit(void)
{ }
module_init(init);
module_exit(exit);
最佳答案
一些事情......
您正在尝试从模块初始化回调中执行所有这些操作。
argc/argv
中没有任何内容,所以这是一个问题(即您可能会遇到段错误)。
您可以使用有效值硬连线argc/argv
,但您必须重新编译并使用您想要 cat 的不同文件重新加载驱动程序。
但是接受一个模块参数并用一个 strtok
等价于填充你的 argv
来拆分它可能会更好。这是与驱动程序的 argv
等价物最接近的东西 [它的存在方式与应用程序中的 main
完全不同]。
您不必重新编译该模块,但是,您仍然每次都必须重新加载它(每次给 insmod
一个不同的参数)
但是,真正/正确的方法是在模块初始化中使用标准机制将您的驱动程序注册为字符设备。同样,在模块清理例程中注销它。
然后,创建一个 /dev
条目(例如 /dev/mycat
)。
从一个应用程序中,打开 /dev/mycat
,然后将您想要 cat 的文件列表写入文件描述符,每行一个。
让驱动程序的 write
回调例程,解析您传递的缓冲区中的数据(即,就像您在用户空间中实现自己的 fgets
一样),以及处理它获得的列表,对每个文件执行 cat 操作。
与其创建 /dev
条目,不如创建 /proc
条目(例如 /proc/mycat
)--YMMV
将文件列表传送给驱动程序的实际机制是任意的。您可以使用 AF_UNIX
套接字、命名管道、连接到 SysV 消息队列等,但 /dev
或 /proc
解决方案可能更容易。
更新:
There seems to be another problem in vfs_read. dmesg gives RIP [] vfs_read+0x5/0x130 and fbcon_switch: detected unhandled fb_set_par error
除其他事项外,您将 int
作为第一个 arg 传递给 vfs_read
。第一个 arg 需要是 struct file *
[就像 vfs_write
]。
注意:如果您使用标准机制构建驱动程序,这将使用 -Wall
进行编译,并且会在编译时进行标记。
此外,您正在尝试将 [cat 输出] 写入您正在读取的同一个文件,即使您使用 O_RDONLY
打开它(即相当于用户空间 cat foobar > foobar
).那是因为,对于 vfs_write
,您执行了 file = fget(f)
。你真正想做的是 file = fget(1)
对于 vfs_read
和 vfs_write
,您需要 fget/fput
配对。而且,它们需要分开:
file_in = fget(f);
file_out = fget(1);
// read/write loop ...
while (1) {
...
}
fput(file_in);
fput(file_out);
您不想要将 buf
放入堆栈。这会产生竞争条件。 [内核] 线程可以迁移到另一个处理器,而 I/O 仍在 vfs_read
[AFAIK] 上挂起。其他执行类似操作的驱动程序使用 kmalloc
获取缓冲区 [并使用 kfree
释放它]。
关于c - 内核模块在使用 insmod 时被杀死,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41972971/
如何在终止父进程时关闭我的子文件描述符? 我创建了一个执行以下操作的程序: 派生 2 个子进程。 进程 1 是一个读取器。它从 STDIN_FILENO 读取并使用 scanf/printf 写入 S
我试着写了一个小的暴力破解程序。密码程序在密码正确时返回 1,错误时返回 0。所以它很简单。 在 bruteforce 程序中,我使用 createprocess() 调用 pw 程序。 我的问题是,
谁能帮我解释一下我从一本书中得到的这个脚本。练习是编写一个名为 killalljobs 的脚本来终止所有后台作业。 为此给出的代码是: kill "$@" $( jobs -p) 我确定我在这里真
我正在开发一个包含许多库的应用程序。后来我注意到有几次应用程序进程在关闭应用程序后仍在耗尽 CPU。 我先终止了进程,但它继续运行。我卸载了该应用程序 - 但它仍然存在! (使用开发人员选项中的“显示
有没有办法在无人机完成或超时之前杀死它? 无人机的默认超时时间为 6 小时 ( https://github.com/drone/drone/blob/master/cmd/drone/drone.g
我有几个自动启动的菜单栏程序/进程/应用程序。我希望能够使用单个命令或脚本将它们全部关闭;有时带宽受到限制或受限,它们会导致(或至少导致)旋转的沙滩球死亡。目前,我手动关闭每一个。 关注 answer
当我阅读 learnyousomeerlang.com 上的一篇文章时,我有一个问题。 http://learnyousomeerlang.com/errors-and-processes 它说: E
有什么方法可以通过 OpenCL API 终止正在运行的 OpenCL 内核吗?我没有在规范中找到任何内容。 我能想出的唯一解决方案是 1) 定期检查内核中的标志,当主机希望内核停止时写入该标志,或
我已经对套接字(使用fsockopen()和stream_socket_client())和cURL进行了一些测试,以强制关闭连接(TCP/HTTP)。但是,没有运气。 无论我使用的是1毫秒的超时时间
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭10 年前。 Improve th
我以不太优雅的方式杀死了 IRB 提示符(从 heroku run irb 开始),现在我有一个僵尸进程,但我似乎无法杀死它: Process State Co
致kill background process inside Codeship我们需要使用以下命令: #!/bin/bash nohup bash -c "YOUR_COMMAND 2>&1 &"
我第一次在这里发帖,因为我在互联网上找不到干净的解决方案。 我的目标很简单,我需要创建 一个 后台操作 (goroutine 或进程或其他...)我可以 正确杀死 (不要留在后台)。 我尝试了很多事情
我有一个进程调用: p=multiprocessing.Process(target=func_a) 然后func_a启动一个子进程: subprocess.Popen(["nc", "-l", "-
我正在运行一个基本上运行一堆服务器以进行本地测试的脚本。 这些 jar 在不同的 screen 中运行,因为它们需要独立地接受键盘输入。为此,我使用了 screen 。 command1="java
我有一个用 java 编写的应用程序,它在 Unix 上运行,并在启动时启动两个子进程(通过 Runtime.getRuntime().exec())。如果应用程序由于某种原因崩溃,子进程不会被终止。
我想要像 Pushbullet、SmartLockScreen 或 WhatsApp 那样独立运行的服务,它正在等待某个事件的发生。我已经尝试过前台服务,在 onStartCommand 中返回 ST
强制停止应用程序后,是否可以在 Android 应用程序中获取位置更新。在 IOS 中,如果我们强制停止应用程序,则有可能获得位置更新,以类似的方式,是否有任何服务可以为在 android 中被杀死的
我正在调查是否有任何方法可以防止 android 服务因未捕获的异常而被杀死。 我们有 10 个 UI 应用程序与 5-6 个服务通信。该平台是Android 2.2。 由于不可预见的情况,服务中的某
我刚刚将我的 javascript 转移到 jQuery 来实现简单的 AJAX 功能。不过,我尝试将灯箱插件与 jQuery 结合使用,因为我想保留相同的功能,但不想包含 10 个不同的库。如果我删
我是一名优秀的程序员,十分优秀!