userspace_ioctl.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /* userspace_ioctl.c - the process to use ioctl's to control the kernel module
  2. *
  3. * Until now we could have used cat for input and output. But now
  4. * we need to do ioctl's, which require writing our own process.
  5. */
  6. /* device specifics, such as ioctl numbers and the
  7. * major device file. */
  8. #include "../chardev.h"
  9. #include <stdio.h> /* standard I/O */
  10. #include <fcntl.h> /* open */
  11. #include <unistd.h> /* close */
  12. #include <stdlib.h> /* exit */
  13. #include <sys/ioctl.h> /* ioctl */
  14. /* Functions for the ioctl calls */
  15. int ioctl_set_msg(int file_desc, char *message)
  16. {
  17. int ret_val;
  18. ret_val = ioctl(file_desc, IOCTL_SET_MSG, message);
  19. if (ret_val < 0) {
  20. printf("ioctl_set_msg failed:%d\n", ret_val);
  21. }
  22. return ret_val;
  23. }
  24. int ioctl_get_msg(int file_desc)
  25. {
  26. int ret_val;
  27. char message[100] = { 0 };
  28. /* Warning - this is dangerous because we don't tell
  29. * the kernel how far it's allowed to write, so it
  30. * might overflow the buffer. In a real production
  31. * program, we would have used two ioctls - one to tell
  32. * the kernel the buffer length and another to give
  33. * it the buffer to fill
  34. */
  35. ret_val = ioctl(file_desc, IOCTL_GET_MSG, message);
  36. if (ret_val < 0) {
  37. printf("ioctl_get_msg failed:%d\n", ret_val);
  38. }
  39. printf("get_msg message:%s", message);
  40. return ret_val;
  41. }
  42. int ioctl_get_nth_byte(int file_desc)
  43. {
  44. int i, c;
  45. printf("get_nth_byte message:");
  46. i = 0;
  47. do {
  48. c = ioctl(file_desc, IOCTL_GET_NTH_BYTE, i++);
  49. if (c < 0) {
  50. printf("\nioctl_get_nth_byte failed at the %d'th byte:\n", i);
  51. return c;
  52. }
  53. putchar(c);
  54. } while (c != 0);
  55. return 0;
  56. }
  57. /* Main - Call the ioctl functions */
  58. int main(void)
  59. {
  60. int file_desc, ret_val;
  61. char *msg = "Message passed by ioctl\n";
  62. file_desc = open(DEVICE_PATH, O_RDWR);
  63. if (file_desc < 0) {
  64. printf("Can't open device file: %s, error:%d\n", DEVICE_PATH,
  65. file_desc);
  66. exit(EXIT_FAILURE);
  67. }
  68. ret_val = ioctl_set_msg(file_desc, msg);
  69. if (ret_val)
  70. goto error;
  71. ret_val = ioctl_get_nth_byte(file_desc);
  72. if (ret_val)
  73. goto error;
  74. ret_val = ioctl_get_msg(file_desc);
  75. if (ret_val)
  76. goto error;
  77. close(file_desc);
  78. return 0;
  79. error:
  80. close(file_desc);
  81. exit(EXIT_FAILURE);
  82. }