0001
0002
0003
0004
0005
0006 #include <string.h>
0007 #include <stdlib.h>
0008 #include <stdio.h>
0009 #include <stdint.h>
0010 #include <dirent.h>
0011 #include <errno.h>
0012 #include <ctype.h>
0013 #include "iio_utils.h"
0014
0015 const char *iio_dir = "/sys/bus/iio/devices/";
0016
0017 static char * const iio_direction[] = {
0018 "in",
0019 "out",
0020 };
0021
0022
0023
0024
0025
0026
0027
0028
0029 int iioutils_break_up_name(const char *full_name, char **generic_name)
0030 {
0031 char *current;
0032 char *w, *r;
0033 char *working, *prefix = "";
0034 int i, ret;
0035
0036 for (i = 0; i < ARRAY_SIZE(iio_direction); i++)
0037 if (!strncmp(full_name, iio_direction[i],
0038 strlen(iio_direction[i]))) {
0039 prefix = iio_direction[i];
0040 break;
0041 }
0042
0043 current = strdup(full_name + strlen(prefix) + 1);
0044 if (!current)
0045 return -ENOMEM;
0046
0047 working = strtok(current, "_\0");
0048 if (!working) {
0049 free(current);
0050 return -EINVAL;
0051 }
0052
0053 w = working;
0054 r = working;
0055
0056 while (*r != '\0') {
0057 if (!isdigit(*r)) {
0058 *w = *r;
0059 w++;
0060 }
0061
0062 r++;
0063 }
0064 *w = '\0';
0065 ret = asprintf(generic_name, "%s_%s", prefix, working);
0066 free(current);
0067
0068 return (ret == -1) ? -ENOMEM : 0;
0069 }
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 static int iioutils_get_type(unsigned int *is_signed, unsigned int *bytes,
0087 unsigned int *bits_used, unsigned int *shift,
0088 uint64_t *mask, unsigned int *be,
0089 const char *device_dir, int buffer_idx,
0090 const char *name, const char *generic_name)
0091 {
0092 FILE *sysfsfp;
0093 int ret;
0094 DIR *dp;
0095 char *scan_el_dir, *builtname, *builtname_generic, *filename = 0;
0096 char signchar, endianchar;
0097 unsigned padint;
0098 const struct dirent *ent;
0099
0100 ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir, buffer_idx);
0101 if (ret < 0)
0102 return -ENOMEM;
0103
0104 ret = asprintf(&builtname, FORMAT_TYPE_FILE, name);
0105 if (ret < 0) {
0106 ret = -ENOMEM;
0107 goto error_free_scan_el_dir;
0108 }
0109 ret = asprintf(&builtname_generic, FORMAT_TYPE_FILE, generic_name);
0110 if (ret < 0) {
0111 ret = -ENOMEM;
0112 goto error_free_builtname;
0113 }
0114
0115 dp = opendir(scan_el_dir);
0116 if (!dp) {
0117 ret = -errno;
0118 goto error_free_builtname_generic;
0119 }
0120
0121 ret = -ENOENT;
0122 while (ent = readdir(dp), ent)
0123 if ((strcmp(builtname, ent->d_name) == 0) ||
0124 (strcmp(builtname_generic, ent->d_name) == 0)) {
0125 ret = asprintf(&filename,
0126 "%s/%s", scan_el_dir, ent->d_name);
0127 if (ret < 0) {
0128 ret = -ENOMEM;
0129 goto error_closedir;
0130 }
0131
0132 sysfsfp = fopen(filename, "r");
0133 if (!sysfsfp) {
0134 ret = -errno;
0135 fprintf(stderr, "failed to open %s\n",
0136 filename);
0137 goto error_free_filename;
0138 }
0139
0140 ret = fscanf(sysfsfp,
0141 "%ce:%c%u/%u>>%u",
0142 &endianchar,
0143 &signchar,
0144 bits_used,
0145 &padint, shift);
0146 if (ret < 0) {
0147 ret = -errno;
0148 fprintf(stderr,
0149 "failed to pass scan type description\n");
0150 goto error_close_sysfsfp;
0151 } else if (ret != 5) {
0152 ret = -EIO;
0153 fprintf(stderr,
0154 "scan type description didn't match\n");
0155 goto error_close_sysfsfp;
0156 }
0157
0158 *be = (endianchar == 'b');
0159 *bytes = padint / 8;
0160 if (*bits_used == 64)
0161 *mask = ~(0ULL);
0162 else
0163 *mask = (1ULL << *bits_used) - 1ULL;
0164
0165 *is_signed = (signchar == 's');
0166 if (fclose(sysfsfp)) {
0167 ret = -errno;
0168 fprintf(stderr, "Failed to close %s\n",
0169 filename);
0170 goto error_free_filename;
0171 }
0172
0173 sysfsfp = 0;
0174 free(filename);
0175 filename = 0;
0176
0177
0178
0179
0180
0181 if (strcmp(builtname, ent->d_name) == 0)
0182 break;
0183 }
0184
0185 error_close_sysfsfp:
0186 if (sysfsfp)
0187 if (fclose(sysfsfp))
0188 perror("iioutils_get_type(): Failed to close file");
0189
0190 error_free_filename:
0191 if (filename)
0192 free(filename);
0193
0194 error_closedir:
0195 if (closedir(dp) == -1)
0196 perror("iioutils_get_type(): Failed to close directory");
0197
0198 error_free_builtname_generic:
0199 free(builtname_generic);
0200 error_free_builtname:
0201 free(builtname);
0202 error_free_scan_el_dir:
0203 free(scan_el_dir);
0204
0205 return ret;
0206 }
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218 int iioutils_get_param_float(float *output, const char *param_name,
0219 const char *device_dir, const char *name,
0220 const char *generic_name)
0221 {
0222 FILE *sysfsfp;
0223 int ret;
0224 DIR *dp;
0225 char *builtname, *builtname_generic;
0226 char *filename = NULL;
0227 const struct dirent *ent;
0228
0229 ret = asprintf(&builtname, "%s_%s", name, param_name);
0230 if (ret < 0)
0231 return -ENOMEM;
0232
0233 ret = asprintf(&builtname_generic,
0234 "%s_%s", generic_name, param_name);
0235 if (ret < 0) {
0236 ret = -ENOMEM;
0237 goto error_free_builtname;
0238 }
0239
0240 dp = opendir(device_dir);
0241 if (!dp) {
0242 ret = -errno;
0243 goto error_free_builtname_generic;
0244 }
0245
0246 ret = -ENOENT;
0247 while (ent = readdir(dp), ent)
0248 if ((strcmp(builtname, ent->d_name) == 0) ||
0249 (strcmp(builtname_generic, ent->d_name) == 0)) {
0250 ret = asprintf(&filename,
0251 "%s/%s", device_dir, ent->d_name);
0252 if (ret < 0) {
0253 ret = -ENOMEM;
0254 goto error_closedir;
0255 }
0256
0257 sysfsfp = fopen(filename, "r");
0258 if (!sysfsfp) {
0259 ret = -errno;
0260 goto error_free_filename;
0261 }
0262
0263 errno = 0;
0264 if (fscanf(sysfsfp, "%f", output) != 1)
0265 ret = errno ? -errno : -ENODATA;
0266
0267 break;
0268 }
0269 error_free_filename:
0270 if (filename)
0271 free(filename);
0272
0273 error_closedir:
0274 if (closedir(dp) == -1)
0275 perror("iioutils_get_param_float(): Failed to close directory");
0276
0277 error_free_builtname_generic:
0278 free(builtname_generic);
0279 error_free_builtname:
0280 free(builtname);
0281
0282 return ret;
0283 }
0284
0285
0286
0287
0288
0289
0290
0291 void bsort_channel_array_by_index(struct iio_channel_info *ci_array, int cnt)
0292 {
0293 struct iio_channel_info temp;
0294 int x, y;
0295
0296 for (x = 0; x < cnt; x++)
0297 for (y = 0; y < (cnt - 1); y++)
0298 if (ci_array[y].index > ci_array[y + 1].index) {
0299 temp = ci_array[y + 1];
0300 ci_array[y + 1] = ci_array[y];
0301 ci_array[y] = temp;
0302 }
0303 }
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314 int build_channel_array(const char *device_dir, int buffer_idx,
0315 struct iio_channel_info **ci_array, int *counter)
0316 {
0317 DIR *dp;
0318 FILE *sysfsfp;
0319 int count = 0, i;
0320 struct iio_channel_info *current;
0321 int ret;
0322 const struct dirent *ent;
0323 char *scan_el_dir;
0324 char *filename;
0325
0326 *counter = 0;
0327 ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir, buffer_idx);
0328 if (ret < 0)
0329 return -ENOMEM;
0330
0331 dp = opendir(scan_el_dir);
0332 if (!dp) {
0333 ret = -errno;
0334 goto error_free_name;
0335 }
0336
0337 while (ent = readdir(dp), ent)
0338 if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"),
0339 "_en") == 0) {
0340 ret = asprintf(&filename,
0341 "%s/%s", scan_el_dir, ent->d_name);
0342 if (ret < 0) {
0343 ret = -ENOMEM;
0344 goto error_close_dir;
0345 }
0346
0347 sysfsfp = fopen(filename, "r");
0348 if (!sysfsfp) {
0349 ret = -errno;
0350 free(filename);
0351 goto error_close_dir;
0352 }
0353
0354 errno = 0;
0355 if (fscanf(sysfsfp, "%i", &ret) != 1) {
0356 ret = errno ? -errno : -ENODATA;
0357 if (fclose(sysfsfp))
0358 perror("build_channel_array(): Failed to close file");
0359
0360 free(filename);
0361 goto error_close_dir;
0362 }
0363 if (ret == 1)
0364 (*counter)++;
0365
0366 if (fclose(sysfsfp)) {
0367 ret = -errno;
0368 free(filename);
0369 goto error_close_dir;
0370 }
0371
0372 free(filename);
0373 }
0374
0375 *ci_array = malloc(sizeof(**ci_array) * (*counter));
0376 if (!*ci_array) {
0377 ret = -ENOMEM;
0378 goto error_close_dir;
0379 }
0380
0381 seekdir(dp, 0);
0382 while (ent = readdir(dp), ent) {
0383 if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"),
0384 "_en") == 0) {
0385 int current_enabled = 0;
0386
0387 current = &(*ci_array)[count++];
0388 ret = asprintf(&filename,
0389 "%s/%s", scan_el_dir, ent->d_name);
0390 if (ret < 0) {
0391 ret = -ENOMEM;
0392
0393 count--;
0394 goto error_cleanup_array;
0395 }
0396
0397 sysfsfp = fopen(filename, "r");
0398 if (!sysfsfp) {
0399 ret = -errno;
0400 free(filename);
0401 count--;
0402 goto error_cleanup_array;
0403 }
0404
0405 errno = 0;
0406 if (fscanf(sysfsfp, "%i", ¤t_enabled) != 1) {
0407 ret = errno ? -errno : -ENODATA;
0408 free(filename);
0409 count--;
0410 goto error_cleanup_array;
0411 }
0412
0413 if (fclose(sysfsfp)) {
0414 ret = -errno;
0415 free(filename);
0416 count--;
0417 goto error_cleanup_array;
0418 }
0419
0420 if (!current_enabled) {
0421 free(filename);
0422 count--;
0423 continue;
0424 }
0425
0426 current->scale = 1.0;
0427 current->offset = 0;
0428 current->name = strndup(ent->d_name,
0429 strlen(ent->d_name) -
0430 strlen("_en"));
0431 if (!current->name) {
0432 free(filename);
0433 ret = -ENOMEM;
0434 count--;
0435 goto error_cleanup_array;
0436 }
0437
0438
0439 ret = iioutils_break_up_name(current->name,
0440 ¤t->generic_name);
0441 if (ret) {
0442 free(filename);
0443 free(current->name);
0444 count--;
0445 goto error_cleanup_array;
0446 }
0447
0448 ret = asprintf(&filename,
0449 "%s/%s_index",
0450 scan_el_dir,
0451 current->name);
0452 if (ret < 0) {
0453 free(filename);
0454 ret = -ENOMEM;
0455 goto error_cleanup_array;
0456 }
0457
0458 sysfsfp = fopen(filename, "r");
0459 if (!sysfsfp) {
0460 ret = -errno;
0461 fprintf(stderr, "failed to open %s\n",
0462 filename);
0463 free(filename);
0464 goto error_cleanup_array;
0465 }
0466
0467 errno = 0;
0468 if (fscanf(sysfsfp, "%u", ¤t->index) != 1) {
0469 ret = errno ? -errno : -ENODATA;
0470 if (fclose(sysfsfp))
0471 perror("build_channel_array(): Failed to close file");
0472
0473 free(filename);
0474 goto error_cleanup_array;
0475 }
0476
0477 if (fclose(sysfsfp)) {
0478 ret = -errno;
0479 free(filename);
0480 goto error_cleanup_array;
0481 }
0482
0483 free(filename);
0484
0485 ret = iioutils_get_param_float(¤t->scale,
0486 "scale",
0487 device_dir,
0488 current->name,
0489 current->generic_name);
0490 if ((ret < 0) && (ret != -ENOENT))
0491 goto error_cleanup_array;
0492
0493 ret = iioutils_get_param_float(¤t->offset,
0494 "offset",
0495 device_dir,
0496 current->name,
0497 current->generic_name);
0498 if ((ret < 0) && (ret != -ENOENT))
0499 goto error_cleanup_array;
0500
0501 ret = iioutils_get_type(¤t->is_signed,
0502 ¤t->bytes,
0503 ¤t->bits_used,
0504 ¤t->shift,
0505 ¤t->mask,
0506 ¤t->be,
0507 device_dir,
0508 buffer_idx,
0509 current->name,
0510 current->generic_name);
0511 if (ret < 0)
0512 goto error_cleanup_array;
0513 }
0514 }
0515
0516 if (closedir(dp) == -1) {
0517 ret = -errno;
0518 goto error_cleanup_array;
0519 }
0520
0521 free(scan_el_dir);
0522
0523 bsort_channel_array_by_index(*ci_array, *counter);
0524
0525 return 0;
0526
0527 error_cleanup_array:
0528 for (i = count - 1; i >= 0; i--) {
0529 free((*ci_array)[i].name);
0530 free((*ci_array)[i].generic_name);
0531 }
0532 free(*ci_array);
0533 *ci_array = NULL;
0534 *counter = 0;
0535 error_close_dir:
0536 if (dp)
0537 if (closedir(dp) == -1)
0538 perror("build_channel_array(): Failed to close dir");
0539
0540 error_free_name:
0541 free(scan_el_dir);
0542
0543 return ret;
0544 }
0545
0546 static int calc_digits(int num)
0547 {
0548 int count = 0;
0549
0550 while (num != 0) {
0551 num /= 10;
0552 count++;
0553 }
0554
0555 return count;
0556 }
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567 int find_type_by_name(const char *name, const char *type)
0568 {
0569 const struct dirent *ent;
0570 int number, numstrlen, ret;
0571
0572 FILE *namefp;
0573 DIR *dp;
0574 char thisname[IIO_MAX_NAME_LENGTH];
0575 char *filename;
0576
0577 dp = opendir(iio_dir);
0578 if (!dp) {
0579 fprintf(stderr, "No industrialio devices available\n");
0580 return -ENODEV;
0581 }
0582
0583 while (ent = readdir(dp), ent) {
0584 if (strcmp(ent->d_name, ".") != 0 &&
0585 strcmp(ent->d_name, "..") != 0 &&
0586 strlen(ent->d_name) > strlen(type) &&
0587 strncmp(ent->d_name, type, strlen(type)) == 0) {
0588 errno = 0;
0589 ret = sscanf(ent->d_name + strlen(type), "%d", &number);
0590 if (ret < 0) {
0591 ret = -errno;
0592 fprintf(stderr,
0593 "failed to read element number\n");
0594 goto error_close_dir;
0595 } else if (ret != 1) {
0596 ret = -EIO;
0597 fprintf(stderr,
0598 "failed to match element number\n");
0599 goto error_close_dir;
0600 }
0601
0602 numstrlen = calc_digits(number);
0603
0604 if (strncmp(ent->d_name + strlen(type) + numstrlen,
0605 ":", 1) != 0) {
0606 filename = malloc(strlen(iio_dir) + strlen(type)
0607 + numstrlen + 6);
0608 if (!filename) {
0609 ret = -ENOMEM;
0610 goto error_close_dir;
0611 }
0612
0613 ret = sprintf(filename, "%s%s%d/name", iio_dir,
0614 type, number);
0615 if (ret < 0) {
0616 free(filename);
0617 goto error_close_dir;
0618 }
0619
0620 namefp = fopen(filename, "r");
0621 if (!namefp) {
0622 free(filename);
0623 continue;
0624 }
0625
0626 free(filename);
0627 errno = 0;
0628 if (fscanf(namefp, "%s", thisname) != 1) {
0629 ret = errno ? -errno : -ENODATA;
0630 goto error_close_dir;
0631 }
0632
0633 if (fclose(namefp)) {
0634 ret = -errno;
0635 goto error_close_dir;
0636 }
0637
0638 if (strcmp(name, thisname) == 0) {
0639 if (closedir(dp) == -1)
0640 return -errno;
0641
0642 return number;
0643 }
0644 }
0645 }
0646 }
0647 if (closedir(dp) == -1)
0648 return -errno;
0649
0650 return -ENODEV;
0651
0652 error_close_dir:
0653 if (closedir(dp) == -1)
0654 perror("find_type_by_name(): Failed to close directory");
0655
0656 return ret;
0657 }
0658
0659 static int _write_sysfs_int(const char *filename, const char *basedir, int val,
0660 int verify)
0661 {
0662 int ret = 0;
0663 FILE *sysfsfp;
0664 int test;
0665 char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
0666
0667 if (!temp)
0668 return -ENOMEM;
0669
0670 ret = sprintf(temp, "%s/%s", basedir, filename);
0671 if (ret < 0)
0672 goto error_free;
0673
0674 sysfsfp = fopen(temp, "w");
0675 if (!sysfsfp) {
0676 ret = -errno;
0677 fprintf(stderr, "failed to open %s\n", temp);
0678 goto error_free;
0679 }
0680
0681 ret = fprintf(sysfsfp, "%d", val);
0682 if (ret < 0) {
0683 if (fclose(sysfsfp))
0684 perror("_write_sysfs_int(): Failed to close dir");
0685
0686 goto error_free;
0687 }
0688
0689 if (fclose(sysfsfp)) {
0690 ret = -errno;
0691 goto error_free;
0692 }
0693
0694 if (verify) {
0695 sysfsfp = fopen(temp, "r");
0696 if (!sysfsfp) {
0697 ret = -errno;
0698 fprintf(stderr, "failed to open %s\n", temp);
0699 goto error_free;
0700 }
0701
0702 if (fscanf(sysfsfp, "%d", &test) != 1) {
0703 ret = errno ? -errno : -ENODATA;
0704 if (fclose(sysfsfp))
0705 perror("_write_sysfs_int(): Failed to close dir");
0706
0707 goto error_free;
0708 }
0709
0710 if (fclose(sysfsfp)) {
0711 ret = -errno;
0712 goto error_free;
0713 }
0714
0715 if (test != val) {
0716 fprintf(stderr,
0717 "Possible failure in int write %d to %s/%s\n",
0718 val, basedir, filename);
0719 ret = -1;
0720 }
0721 }
0722
0723 error_free:
0724 free(temp);
0725 return ret;
0726 }
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736 int write_sysfs_int(const char *filename, const char *basedir, int val)
0737 {
0738 return _write_sysfs_int(filename, basedir, val, 0);
0739 }
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749
0750 int write_sysfs_int_and_verify(const char *filename, const char *basedir,
0751 int val)
0752 {
0753 return _write_sysfs_int(filename, basedir, val, 1);
0754 }
0755
0756 static int _write_sysfs_string(const char *filename, const char *basedir,
0757 const char *val, int verify)
0758 {
0759 int ret = 0;
0760 FILE *sysfsfp;
0761 char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
0762
0763 if (!temp) {
0764 fprintf(stderr, "Memory allocation failed\n");
0765 return -ENOMEM;
0766 }
0767
0768 ret = sprintf(temp, "%s/%s", basedir, filename);
0769 if (ret < 0)
0770 goto error_free;
0771
0772 sysfsfp = fopen(temp, "w");
0773 if (!sysfsfp) {
0774 ret = -errno;
0775 fprintf(stderr, "Could not open %s\n", temp);
0776 goto error_free;
0777 }
0778
0779 ret = fprintf(sysfsfp, "%s", val);
0780 if (ret < 0) {
0781 if (fclose(sysfsfp))
0782 perror("_write_sysfs_string(): Failed to close dir");
0783
0784 goto error_free;
0785 }
0786
0787 if (fclose(sysfsfp)) {
0788 ret = -errno;
0789 goto error_free;
0790 }
0791
0792 if (verify) {
0793 sysfsfp = fopen(temp, "r");
0794 if (!sysfsfp) {
0795 ret = -errno;
0796 fprintf(stderr, "Could not open file to verify\n");
0797 goto error_free;
0798 }
0799
0800 if (fscanf(sysfsfp, "%s", temp) != 1) {
0801 ret = errno ? -errno : -ENODATA;
0802 if (fclose(sysfsfp))
0803 perror("_write_sysfs_string(): Failed to close dir");
0804
0805 goto error_free;
0806 }
0807
0808 if (fclose(sysfsfp)) {
0809 ret = -errno;
0810 goto error_free;
0811 }
0812
0813 if (strcmp(temp, val) != 0) {
0814 fprintf(stderr,
0815 "Possible failure in string write of %s "
0816 "Should be %s written to %s/%s\n", temp, val,
0817 basedir, filename);
0818 ret = -1;
0819 }
0820 }
0821
0822 error_free:
0823 free(temp);
0824
0825 return ret;
0826 }
0827
0828
0829
0830
0831
0832
0833
0834
0835
0836 int write_sysfs_string_and_verify(const char *filename, const char *basedir,
0837 const char *val)
0838 {
0839 return _write_sysfs_string(filename, basedir, val, 1);
0840 }
0841
0842
0843
0844
0845
0846
0847
0848
0849
0850 int write_sysfs_string(const char *filename, const char *basedir,
0851 const char *val)
0852 {
0853 return _write_sysfs_string(filename, basedir, val, 0);
0854 }
0855
0856
0857
0858
0859
0860
0861
0862
0863
0864 int read_sysfs_posint(const char *filename, const char *basedir)
0865 {
0866 int ret;
0867 FILE *sysfsfp;
0868 char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
0869
0870 if (!temp) {
0871 fprintf(stderr, "Memory allocation failed");
0872 return -ENOMEM;
0873 }
0874
0875 ret = sprintf(temp, "%s/%s", basedir, filename);
0876 if (ret < 0)
0877 goto error_free;
0878
0879 sysfsfp = fopen(temp, "r");
0880 if (!sysfsfp) {
0881 ret = -errno;
0882 goto error_free;
0883 }
0884
0885 errno = 0;
0886 if (fscanf(sysfsfp, "%d\n", &ret) != 1) {
0887 ret = errno ? -errno : -ENODATA;
0888 if (fclose(sysfsfp))
0889 perror("read_sysfs_posint(): Failed to close dir");
0890
0891 goto error_free;
0892 }
0893
0894 if (fclose(sysfsfp))
0895 ret = -errno;
0896
0897 error_free:
0898 free(temp);
0899
0900 return ret;
0901 }
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911 int read_sysfs_float(const char *filename, const char *basedir, float *val)
0912 {
0913 int ret = 0;
0914 FILE *sysfsfp;
0915 char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
0916
0917 if (!temp) {
0918 fprintf(stderr, "Memory allocation failed");
0919 return -ENOMEM;
0920 }
0921
0922 ret = sprintf(temp, "%s/%s", basedir, filename);
0923 if (ret < 0)
0924 goto error_free;
0925
0926 sysfsfp = fopen(temp, "r");
0927 if (!sysfsfp) {
0928 ret = -errno;
0929 goto error_free;
0930 }
0931
0932 errno = 0;
0933 if (fscanf(sysfsfp, "%f\n", val) != 1) {
0934 ret = errno ? -errno : -ENODATA;
0935 if (fclose(sysfsfp))
0936 perror("read_sysfs_float(): Failed to close dir");
0937
0938 goto error_free;
0939 }
0940
0941 if (fclose(sysfsfp))
0942 ret = -errno;
0943
0944 error_free:
0945 free(temp);
0946
0947 return ret;
0948 }
0949
0950
0951
0952
0953
0954
0955
0956
0957
0958 int read_sysfs_string(const char *filename, const char *basedir, char *str)
0959 {
0960 int ret = 0;
0961 FILE *sysfsfp;
0962 char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
0963
0964 if (!temp) {
0965 fprintf(stderr, "Memory allocation failed");
0966 return -ENOMEM;
0967 }
0968
0969 ret = sprintf(temp, "%s/%s", basedir, filename);
0970 if (ret < 0)
0971 goto error_free;
0972
0973 sysfsfp = fopen(temp, "r");
0974 if (!sysfsfp) {
0975 ret = -errno;
0976 goto error_free;
0977 }
0978
0979 errno = 0;
0980 if (fscanf(sysfsfp, "%s\n", str) != 1) {
0981 ret = errno ? -errno : -ENODATA;
0982 if (fclose(sysfsfp))
0983 perror("read_sysfs_string(): Failed to close dir");
0984
0985 goto error_free;
0986 }
0987
0988 if (fclose(sysfsfp))
0989 ret = -errno;
0990
0991 error_free:
0992 free(temp);
0993
0994 return ret;
0995 }