lsiio.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Industrial I/O utilities - lsiio.c
  4. *
  5. * Copyright (c) 2010 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
  6. */
  7. #include <string.h>
  8. #include <dirent.h>
  9. #include <stdio.h>
  10. #include <errno.h>
  11. #include <stdint.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <sys/types.h>
  15. #include <sys/stat.h>
  16. #include <sys/dir.h>
  17. #include "iio_utils.h"
  18. static enum verbosity {
  19. VERBLEVEL_DEFAULT, /* 0 gives lspci behaviour */
  20. VERBLEVEL_SENSORS, /* 1 lists sensors */
  21. } verblevel = VERBLEVEL_DEFAULT;
  22. const char *type_device = "iio:device";
  23. const char *type_trigger = "trigger";
  24. static inline int check_prefix(const char *str, const char *prefix)
  25. {
  26. return strlen(str) > strlen(prefix) &&
  27. strncmp(str, prefix, strlen(prefix)) == 0;
  28. }
  29. static inline int check_postfix(const char *str, const char *postfix)
  30. {
  31. return strlen(str) > strlen(postfix) &&
  32. strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
  33. }
  34. static int dump_channels(const char *dev_dir_name)
  35. {
  36. DIR *dp;
  37. const struct dirent *ent;
  38. dp = opendir(dev_dir_name);
  39. if (!dp)
  40. return -errno;
  41. while (ent = readdir(dp), ent)
  42. if (check_prefix(ent->d_name, "in_") &&
  43. (check_postfix(ent->d_name, "_raw") ||
  44. check_postfix(ent->d_name, "_input")))
  45. printf(" %-10s\n", ent->d_name);
  46. return (closedir(dp) == -1) ? -errno : 0;
  47. }
  48. static int dump_one_device(const char *dev_dir_name)
  49. {
  50. char name[IIO_MAX_NAME_LENGTH];
  51. int dev_idx;
  52. int ret;
  53. ret = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_device), "%i",
  54. &dev_idx);
  55. if (ret != 1)
  56. return -EINVAL;
  57. ret = read_sysfs_string("name", dev_dir_name, name);
  58. if (ret < 0)
  59. return ret;
  60. printf("Device %03d: %s\n", dev_idx, name);
  61. if (verblevel >= VERBLEVEL_SENSORS)
  62. return dump_channels(dev_dir_name);
  63. return 0;
  64. }
  65. static int dump_one_trigger(const char *dev_dir_name)
  66. {
  67. char name[IIO_MAX_NAME_LENGTH];
  68. int dev_idx;
  69. int ret;
  70. ret = sscanf(dev_dir_name + strlen(iio_dir) + strlen(type_trigger),
  71. "%i", &dev_idx);
  72. if (ret != 1)
  73. return -EINVAL;
  74. ret = read_sysfs_string("name", dev_dir_name, name);
  75. if (ret < 0)
  76. return ret;
  77. printf("Trigger %03d: %s\n", dev_idx, name);
  78. return 0;
  79. }
  80. static int dump_devices(void)
  81. {
  82. const struct dirent *ent;
  83. int ret;
  84. DIR *dp;
  85. dp = opendir(iio_dir);
  86. if (!dp) {
  87. fprintf(stderr, "No industrial I/O devices available\n");
  88. return -ENODEV;
  89. }
  90. while (ent = readdir(dp), ent) {
  91. if (check_prefix(ent->d_name, type_device)) {
  92. char *dev_dir_name;
  93. if (asprintf(&dev_dir_name, "%s%s", iio_dir,
  94. ent->d_name) < 0) {
  95. ret = -ENOMEM;
  96. goto error_close_dir;
  97. }
  98. ret = dump_one_device(dev_dir_name);
  99. if (ret) {
  100. free(dev_dir_name);
  101. goto error_close_dir;
  102. }
  103. free(dev_dir_name);
  104. if (verblevel >= VERBLEVEL_SENSORS)
  105. printf("\n");
  106. }
  107. }
  108. rewinddir(dp);
  109. while (ent = readdir(dp), ent) {
  110. if (check_prefix(ent->d_name, type_trigger)) {
  111. char *dev_dir_name;
  112. if (asprintf(&dev_dir_name, "%s%s", iio_dir,
  113. ent->d_name) < 0) {
  114. ret = -ENOMEM;
  115. goto error_close_dir;
  116. }
  117. ret = dump_one_trigger(dev_dir_name);
  118. if (ret) {
  119. free(dev_dir_name);
  120. goto error_close_dir;
  121. }
  122. free(dev_dir_name);
  123. }
  124. }
  125. return (closedir(dp) == -1) ? -errno : 0;
  126. error_close_dir:
  127. if (closedir(dp) == -1)
  128. perror("dump_devices(): Failed to close directory");
  129. return ret;
  130. }
  131. int main(int argc, char **argv)
  132. {
  133. int c, err = 0;
  134. while ((c = getopt(argc, argv, "v")) != EOF) {
  135. switch (c) {
  136. case 'v':
  137. verblevel++;
  138. break;
  139. case '?':
  140. default:
  141. err++;
  142. break;
  143. }
  144. }
  145. if (err || argc > optind) {
  146. fprintf(stderr, "Usage: lsiio [options]...\n"
  147. "List industrial I/O devices\n"
  148. " -v Increase verbosity (may be given multiple times)\n");
  149. exit(1);
  150. }
  151. return dump_devices();
  152. }