-- TOC --
前面的几个驱动程序,测试都用python,也该学学用C直接进行系统调用了,这样可以控制的更精确。
下面这段代码,实现了读取一个device file固定长度,并将读取的内容打印在屏幕上:
$ cat mychar_read.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#define ERRBUF_SIZE 64
#define _PERROR \
do { \
char errbuf[ERRBUF_SIZE] = {0}; \
sprintf(errbuf, "%s:%d", __FILE__, __LINE__); \
perror(errbuf); \
} while(0) \
int main(int argc, char **argv) {
int i, fd;
ssize_t cnt;
char *rbuf;
/* disable the unused warning */
assert(argc == 3);
/* open */
if ((fd=open(argv[1],O_RDONLY)) == -1) {
_PERROR;
return errno;
}
/* alloc memory */
i = atoi(argv[2]);
rbuf = malloc(i);
if (rbuf == NULL) {
_PERROR;
return errno;
}
memset(rbuf, 0, i);
/* read */
if ((cnt=read(fd,rbuf,i)) == -1) {
_PERROR;
free(rbuf);
return errno;
}
/* print out */
printf("read out %ld bytes\n", cnt);
for (i=0; i<cnt; ++i) printf("%02X ", (unsigned char)rbuf[i]);
if (cnt != 0) printf("\n");
/* close */
if (close(fd) == -1) {
_PERROR;
free(rbuf);
return errno;
}
free(rbuf);
return 0;
}
用到了open,close,read这3个系统调用,另外将perror封装在一个macro里面,以方便打印出具体的错误字符串,以及错误发生的位置。
查询系统调用:$ man 2 xxxx
调试过程还是肥了一点点周折,但现在写总结时,却发现似乎没啥可写的,一切似乎都是理所当然。
errno
在系统调用返回错误时被设置位具体的错误码,用perror
库函数可以打印出错误字符串,此函数接收一个参数,作为输出的prefix。我也用了最流行的do {...} while(0)这种结构定义macro function。errbuf不是全局的,这样可以支持多线程,而errno本就thread-safe!
这些errno,定义在内核的如下两个文件中:
include/uapi/asm-generic/errno-base.h
和include/uapi/asm-generic/errno.h
中!
注意如何按16进制打印char!要cast到unsigned char类型。
这么一个小小的功能,引用的头文件还不少......
用上一篇的mychar驱动,以及系统自带的伪设备测试,OK的:
$ gcc -Wall -Wextra mychar_read.c -o mychar_read
$ echo '123123' > mychar-4
$ cat mychar-4
123123
$ ./mychar_read mychar-4 4
read out 4 bytes
31 32 33 31
$ ./mychar_read mychar-4 8
read out 7 bytes
31 32 33 31 32 33 0A
$ ./mychar_read /dev/random 8
read out 8 bytes
BA 53 C4 8B 83 83 62 D7
$ ./mychar_read /dev/random 16
read out 16 bytes
56 3D 00 DF 84 19 76 20 2E 5D 7E 83 28 C0 CD 05
$ ./mychar_read mychar-8 8 # non-exist device file
mychar_read.c:29: No such file or directory
本文链接:https://cs.pynote.net/sf/linux/dd/202112262/
-- EOF --
-- MORE --