lkmpg/examples/other/userspace_ioctl.c

105 lines
2.3 KiB
C
Raw Permalink Normal View History

/* userspace_ioctl.c - the process to use ioctl's to control the kernel module
*
* Until now we could have used cat for input and output. But now
* we need to do ioctl's, which require writing our own process.
*/
/* device specifics, such as ioctl numbers and the
* major device file. */
#include "../chardev.h"
#include <stdio.h> /* standard I/O */
#include <fcntl.h> /* open */
#include <unistd.h> /* close */
#include <stdlib.h> /* exit */
#include <sys/ioctl.h> /* ioctl */
/* Functions for the ioctl calls */
int ioctl_set_msg(int file_desc, char *message)
{
int ret_val;
ret_val = ioctl(file_desc, IOCTL_SET_MSG, message);
if (ret_val < 0) {
printf("ioctl_set_msg failed:%d\n", ret_val);
}
return ret_val;
}
int ioctl_get_msg(int file_desc)
{
int ret_val;
char message[100] = { 0 };
/* Warning - this is dangerous because we don't tell
* the kernel how far it's allowed to write, so it
* might overflow the buffer. In a real production
* program, we would have used two ioctls - one to tell
* the kernel the buffer length and another to give
* it the buffer to fill
*/
ret_val = ioctl(file_desc, IOCTL_GET_MSG, message);
if (ret_val < 0) {
printf("ioctl_get_msg failed:%d\n", ret_val);
}
printf("get_msg message:%s", message);
return ret_val;
}
int ioctl_get_nth_byte(int file_desc)
{
int i, c;
printf("get_nth_byte message:");
i = 0;
do {
c = ioctl(file_desc, IOCTL_GET_NTH_BYTE, i++);
if (c < 0) {
printf("\nioctl_get_nth_byte failed at the %d'th byte:\n", i);
return c;
}
putchar(c);
} while (c != 0);
return 0;
}
/* Main - Call the ioctl functions */
int main(void)
{
int file_desc, ret_val;
char *msg = "Message passed by ioctl\n";
file_desc = open(DEVICE_PATH, O_RDWR);
if (file_desc < 0) {
printf("Can't open device file: %s, error:%d\n", DEVICE_PATH,
file_desc);
exit(EXIT_FAILURE);
}
ret_val = ioctl_set_msg(file_desc, msg);
if (ret_val)
goto error;
ret_val = ioctl_get_nth_byte(file_desc);
if (ret_val)
goto error;
ret_val = ioctl_get_msg(file_desc);
if (ret_val)
goto error;
close(file_desc);
return 0;
error:
close(file_desc);
exit(EXIT_FAILURE);
}