Include appropriate commands for fixing the errors. This makes it easier for new users to understand what is going on when they have a problem listing i2c busses that they do not understand. Inspired-by: https://lists.debian.org/msgid-search/E1poMGW-0002KT-8Q@xxxxxxxxxxxx --- tools/i2cbusses.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) v2: fixed some whitespace styling, updated recipient addresses diff --git a/tools/i2cbusses.c b/tools/i2cbusses.c index d23ee7a..8d16905 100644 --- a/tools/i2cbusses.c +++ b/tools/i2cbusses.c @@ -137,6 +137,24 @@ static int sort_i2c_busses(const void *a, const void *b) return adap1->nr - adap2->nr; } +static int dir_has_entries(const char* path) +{ + struct dirent *de; + DIR *dir; + if ((dir = opendir(path))) { + while ((de = readdir(dir)) != NULL) { + if (!strcmp(de->d_name, ".")) + continue; + if (!strcmp(de->d_name, "..")) + continue; + closedir(dir); + return 1; + } + closedir(dir); + } + return 0; +} + struct i2c_adap *gather_i2c_busses(void) { char s[120]; @@ -144,6 +162,7 @@ struct i2c_adap *gather_i2c_busses(void) DIR *dir, *ddir; FILE *f; char fstype[NAME_MAX], sysfs[NAME_MAX], n[NAME_MAX]; + size_t sysfs_end = 0; int foundsysfs = 0; int len, count = 0; struct i2c_adap *adapters; @@ -199,6 +218,13 @@ struct i2c_adap *gather_i2c_busses(void) /* look in sysfs */ /* First figure out where sysfs was mounted */ if ((f = fopen("/proc/mounts", "r")) == NULL) { + fprintf(stderr, "Error: Could not open /proc/mounts: " + "%s\n", strerror(errno)); + if (errno == ENOENT) { + fprintf(stderr, "Please mount procfs: " + "%smount -t procfs proc /proc\n", + getenv("SUDO_COMMAND") ? "sudo " : ""); + } goto done; } while (fgets(n, NAME_MAX, f)) { @@ -210,15 +236,43 @@ struct i2c_adap *gather_i2c_busses(void) } fclose(f); if (! foundsysfs) { + fprintf(stderr, "Error: Could not find sysfs mount\n"); + fprintf(stderr, "Please mount sysfs: " + "%smount -t sysfs sysfs /sys\n", + getenv("SUDO_COMMAND") ? "sudo " : ""); goto done; } /* Bus numbers in i2c-adapter don't necessarily match those in i2c-dev and what we really care about are the i2c-dev numbers. Unfortunately the names are harder to get in i2c-dev */ + sysfs_end = strlen(sysfs); strcat(sysfs, "/class/i2c-dev"); - if(!(dir = opendir(sysfs))) + if (!(dir = opendir(sysfs))) { + if (errno == ENOENT) { + /* Check if there are i2c bus devices in other dirs + as when there are none the error isn't useful + as loading i2c-dev also won't find devices */ + int devices_present = 0; + strcpy(sysfs + sysfs_end, "/bus/i2c/devices"); + devices_present = dir_has_entries(sysfs); + if (! devices_present) { + strcpy(sysfs + sysfs_end, "/class/i2c-adapter"); + devices_present = dir_has_entries(sysfs); + } + if (devices_present) { + fprintf(stderr, "Error: Could not find dir " + "`%s`\n", sysfs); + fprintf(stderr, "Please load i2c-dev: " + "%smodprobe i2c-dev\n", + getenv("SUDO_COMMAND") ? "sudo " : ""); + } + } else { + fprintf(stderr, "Error: Could not open dir " + "`%s': %s\n", sysfs, strerror(errno)); + } goto done; + } /* go through the busses */ while ((de = readdir(dir)) != NULL) { if (!strcmp(de->d_name, ".")) -- 2.40.1