在驱动中执行shell脚本的一种方法

本文介绍了一种在Linux驱动程序中执行Shell脚本的方法,通过用户层与内核层的交互实现。具体实现了uevent_shell函数用于发送命令,并通过文件操作接口进行读取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有时需要在驱动中,执行shell脚本,这时可通过用户层来实现。具体的实现为

uevent.c

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kfifo.h>
#include <linux/wait.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/miscdevice.h>

#define DEVICE_NAME "uevent"
#define FIFO_SIZE 1024
static DEFINE_MUTEX(read_lock);
static struct miscdevice uevent_dev;
static wait_queue_head_t uevent_wait;
typedef STRUCT_KFIFO_REC_1(FIFO_SIZE) uevent_fifo;
static uevent_fifo uevent;

void uevent_shell(char *cmd)
{	
	char buf[100];
	printk("the uevent shell is %s\n",cmd);
	kfifo_in(&uevent,cmd,strlen(cmd)+1);
	//kfifo_out(&uevent,buf,sizeof(buf));
	//printk("the kfifio out is %s",buf);
	wake_up_interruptible(&uevent_wait);
}
EXPORT_SYMBOL(uevent_shell);

int uevent_open(struct inode *node, struct file *filp)
{
	return 0;
}

static unsigned int uevent_poll(struct file *file,struct poll_table_struct *poll)
{
	unsigned int mask=0;
	poll_wait(file,&uevent_wait,poll);
	if(!kfifo_is_empty(&uevent))
		mask |= POLLIN | POLLRDNORM;  
	return mask;
}

static ssize_t uevent_read(struct file *file, char __user *buf,size_t count, loff_t *ppos)
{
	int ret;
	unsigned int copied;

	if (mutex_lock_interruptible(&read_lock))
		return -ERESTARTSYS;
	ret = kfifo_to_user(&uevent, buf, count, &copied);
	mutex_unlock(&read_lock);
	return ret ? ret : copied;
}

int uevent_release(struct inode *node, struct file *filp)
{
	return 0;
}

static struct file_operations uevent_dev_fops={
	.owner          = THIS_MODULE,
	.open           = uevent_open,
	.poll  	        = uevent_poll,
 	.read           = uevent_read,
	.release        = uevent_release,
};

static struct miscdevice uevent_dev = {
    .minor          = MISC_DYNAMIC_MINOR,
    .name           = DEVICE_NAME,
    .fops           = &uevent_dev_fops,
};

static int __init uevent_init(void) 
{
	int ret;
	char *cmd="ls -al";
	char *cmd2="du";
	char *cmd3="mount";
	printk("%s\n",__func__);
	ret = misc_register(&uevent_dev);
	init_waitqueue_head(&uevent_wait);
	INIT_KFIFO(uevent);
	msleep(1000);
	msleep(1000);
	msleep(1000);
	uevent_shell(cmd);
	msleep(1000);
	msleep(1000);
	uevent_shell(cmd2);
	msleep(1000);
	msleep(1000);
	msleep(1000);
	uevent_shell(cmd3);
	return ret;
}

static void __exit uevent_exit(void)
{
	misc_deregister(&uevent_dev);
	printk("%s\n",__func__);
}

module_init(uevent_init);
module_exit(uevent_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("www");

用户层的app如下

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>
#include <unistd.h>
#include <signal.h>
#include <poll.h>

#define dev_name "uevent"

void systemstatus(int status)
{
	if (-1 == status)
	{
		printf("system error!");  
	}
	else
        {
		printf("exit status value = [0x%x]\n", status);  
		if (WIFEXITED(status))
		{
			if (WEXITSTATUS(status) == 0)
			{
				printf("run shell script successfully.\n");  
			}
                	else
			{
                		printf("run shell script fail, script exit code: %d\n", WEXITSTATUS(status));  
            }
       }
        else
        {
            printf("exit status = [%d]\n", WEXITSTATUS(status));  
        }
    }   
} 

int main(void)
{
	struct pollfd fds;
	int fd,ret,status;;
	char dev_point[20];
	unsigned char buf[100];
	snprintf(dev_point,sizeof(buf),"/dev/%s",dev_name);
	fd = open(dev_point, O_RDWR);
	if(fd < 0)
	{
		perror("open");
		return -1;
	}
	fds.fd=fd;
	fds.events=POLLIN;
	while(1)  
	{   
		poll(&fds,1,-1);  
		ret=read(fd,&buf,sizeof(buf));
		status=system(buf);
		systemstatus(status);              
    }   
	close(fd);
	return 0;
}

相应的Makefile如下

ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /usr/src/linux-headers-4.4.0-31-generic/  
PWD :=$(shell pwd)
EXTRA_LIBS += -lpthread -static
CC=gcc
EXEC =  app
OBJS =  app.o
all: $(EXEC)  modules
$(EXEC): $(OBJS)
	$(CC) $(LDFLAGS) -o $@ $(OBJS)  $(EXTRA_LIBS)
modules:  
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules  
modules_install:  
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install  
clean:  
	rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions modules.order  Module.symvers  
.PHONY: modules modules_install clean  
else  
	obj-m:= uevent.o  
endif



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值