pax_global_header00006660000000000000000000000064140137046140014512gustar00rootroot0000000000000052 comment=da2f1f8500c0af6663a56ce2bff07f67e60a92e0 sysfsutils-2.1.1/000077500000000000000000000000001401370461400137435ustar00rootroot00000000000000sysfsutils-2.1.1/.gitignore000066400000000000000000000002651401370461400157360ustar00rootroot00000000000000*.la *.lo *.o *.pc .deps .libs INSTALL Makefile Makefile.in aclocal.m4 autom4te.cache compile config.* configure cscope.* depcomp install-sh libtool ltmain.sh missing stamp-h1 tags sysfsutils-2.1.1/.travis.yml000066400000000000000000000001731401370461400160550ustar00rootroot00000000000000language: c dist: xenial arch: - amd64 - ppc64le script: - ./autogen - ./configure - make - sudo make install sysfsutils-2.1.1/AUTHORS000066400000000000000000000002251401370461400150120ustar00rootroot00000000000000Ananth Mavinakayanahalli Daniel Stekloff Mohan Kumar Nitin Vashisth sysfsutils-2.1.1/COPYING000066400000000000000000000005121401370461400147740ustar00rootroot00000000000000 The commands and utilities are licensed under the GNU General Public License (GPL) Version 2, June 1991. The full text of the GPL is located at: sysfsutils/cmd/GPL The sysfs library is licensed under the GNU Lesser Public License (LGPL) Version 2.1, February 1999. The full text of the LGPL is located at: sysfsutils/lib/LGPL sysfsutils-2.1.1/CREDITS000066400000000000000000000064761401370461400150000ustar00rootroot00000000000000 The authors of sysfsutils would like to thank the following people who have made contributions: o Lev Makhlis : - Supplied libsysfs code cleanup including code simplification, read-only strings, and C++ compatibility. o Eric J Bohm : - Supplied dlist generic linked list implementation. - Added dlist_for_each* functionality. o Guo Min : - Supplied sysfs_write_attribute patch o Martin Mares - Author of pciutils. Reused the pci name decoding from Martin's library. o Martin Pitt - Supplied initial makefiles for lsbus and systool o Martin Hicks - Supplied patch to fix class_device functions o Brian King - Supplied patch to fix a memory leak in sysfs_dir.c o Martin Schlemmer - Supplied patch to prevent checks for installed headers, while building. o Lev Makhlis - Supplied patch to make library C++ compatible. o Dr. Hannes Reinecke - Supplied patch to fix SEGV in dlist.c o Arun Bhanu - Supplied patch to fix docs/libsysfs.txt o Kay Sievers - Supplied patch to fix sysfs_get_classdir_attr when the directory vanishes from under us. - Updates for building with udev and klibc. - Numerous other updates, cleanups and general guidelines o Dominik Brodowski - Fix feature in sysfs_write_attribute(), will now write new value to attribute if attribute is a show method and previously had nothing to be read. o Martin Schlemmer - KLIBC updates o Pavel Roskin - Use buildroot for rpmbuilds o Lee Duncan - Supplied patches to fix compilation bugs/warnings with GCC 7/10. - Improved the build scripts to work latest autotools and work with git repository. - Numerous other patches to fix various bugs. - Updated the README info on how to file issues. - Supplied patch to add SUSE-specific libsysfs.conf o Christopher Engelhard - Supplied patch to fix adjusting COPYING file to reflect set of directories covered under GPLv2. - Supplied patch to fix address in the licensing files cmd/GPL and lib/LGPL. - Numerous other patches to fix various bugs. o Aurelien Jarno - Supplied patch to fix missing m4 macro directory. o Guillem Jover - Modernized the build system to use the latest autotools. - Cleaned up the build scripts to remove obsolete files, hooks and improved the build scripts to work with git. - Supplied patch to convert bash to POSIX portable syntax. - Supplied patch to introduce pkg-confile to replace libtool for library detection and linking. - Supplied patch to add out-of-tree support. - Supplied patch to add make rule to move test program into check_PROGRAMS. o Martin Pitt - Supplied patch to valid mount point in sysfs_get_mnt_path(). o Timm Bäder - Supplied patch to rename dprintf() to debugprintf(), to avoid collision with glibc macros. Please visit pulls/issues page at https://github.com/linux-ras/sysfsutils for more information. sysfsutils-2.1.1/Makefile.am000066400000000000000000000003401401370461400157740ustar00rootroot00000000000000ACLOCAL_AMFLAGS = -I m4 man_MANS = systool.1 EXTRA_DIST = docs include $(man_MANS) CREDITS lib/LGPL cmd/GPL test/GPL SUBDIRS = lib cmd test includedir=@includedir@/sysfs include_HEADERS = include/libsysfs.h include/dlist.h sysfsutils-2.1.1/README000066400000000000000000000042721401370461400146300ustar00rootroot00000000000000 Sysfs Utilities Package - Includes Libsysfs (v. 2.1.1) ====================================================== Contents -------- 1. Introduction 2. How to Install 2.1 Caveats/Known issues 3. Licenses 4. Reporting Bugs 1. Introduction --------------- This package's purpose is to provide a set of utilities for interfacing with sysfs, a virtual filesystem in Linux kernel versions 2.5+ that provides a tree of system devices. While a filesystem is a very useful interface, we've decided to provide a stable programming interface that will hopefully make it easier for applications to query system devices and their attributes. This package currently includes: - libsysfs: a library for accessing system devices. - systool: an application to view system device information by bus, class, and topology. - A number of example usage routines in the "test" directory. - A comprehensive testsuite, also shipped as part of the "test" directory. This testsuite can be used to test _all_ the APIs exported by Libsysfs. Please refer the libsysfs.txt file in the "docs" directory for details as to how to use the testsuite. 2. How to Install ----------------- Run the "configure" script to generate Makefiles. Use "make" to build the library and utilities. For a successful install, run "make install" as super-user. "make uninstall" will clean up all installed files. 3. Licenses ----------- The commands and tests are licensed under the GNU Public License (GPL) Version 2, June 1991. The full text of the GPL is located in this package's "cmd" directory: sysfsutils/cmd/GPL The library is licensed under the GNU Lesser Public License (LGPL) Version 2.1, February 1999. The full text of the LGPL is located in this package's "lib" directory: sysfsutils/lib/LGPL 4. Reporting Bugs ----------------- Feel free to report bugs by opening an issue in the GitHub Issue Tracker. 5. Contributions ---------------- For submitting patches, open a GitHub pull request. Please make sure that they are rebased on top of the current master. Code submission guidelines are the same as the Linux Kernel contribution guidelines. You probably want to read the through Linux kernel Documentation/SubmittingPatches for guidance. sysfsutils-2.1.1/TODO000066400000000000000000000003111401370461400144260ustar00rootroot00000000000000Library: -------- - Rework debugging error messages and look into better logging on error. Commands: --------- - Add topology tree view. Documentation: -------------- - Update/improve documentation. sysfsutils-2.1.1/autogen000077500000000000000000000000441401370461400153310ustar00rootroot00000000000000#!/bin/sh set -e autoreconf -f -i sysfsutils-2.1.1/cmd/000077500000000000000000000000001401370461400145065ustar00rootroot00000000000000sysfsutils-2.1.1/cmd/.gitignore000066400000000000000000000000101401370461400164650ustar00rootroot00000000000000systool sysfsutils-2.1.1/cmd/GPL000066400000000000000000000432541401370461400150630ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. sysfsutils-2.1.1/cmd/Makefile.am000066400000000000000000000003611401370461400165420ustar00rootroot00000000000000bin_PROGRAMS = systool systool_SOURCES = systool.c names.c names.h LDADD = $(top_builddir)/lib/libsysfs.la EXTRA_CFLAGS = @EXTRA_CFLAGS@ AM_CPPFLAGS = -I$(top_srcdir)/include AM_CFLAGS = -Wall -W -Wextra -Wstrict-prototypes $(EXTRA_CFLAGS) sysfsutils-2.1.1/cmd/names.c000066400000000000000000000204411401370461400157560ustar00rootroot00000000000000/* * The PCI Library -- ID to Name Translation * * Copyright (c) 1997--2002 Martin Mares * * Can be freely distributed and used under the terms of the GNU GPL. */ #include "config.h" #include #include #include #include #include #include #include #include "names.h" struct nl_entry { struct nl_entry *next; unsigned short id1, id2, id3, id4; int cat; char *name; }; #define NL_VENDOR 0 #define NL_DEVICE 1 #define NL_SUBSYSTEM 2 #define NL_CLASS 3 #define NL_SUBCLASS 4 #define NL_PROGIF 5 #define HASH_SIZE 1024 static inline unsigned int nl_calc_hash(int cat, int id1, int id2, int id3, int id4) { unsigned int h; h = id1 ^ id2 ^ id3 ^ id4 ^ (cat << 5); h += (h >> 6); return h & (HASH_SIZE-1); } static struct nl_entry *nl_lookup(struct pci_access *a, int num, int cat, int id1, int id2, int id3, int id4) { unsigned int h; struct nl_entry *n; if (num) return NULL; h = nl_calc_hash(cat, id1, id2, id3, id4); n = a->nl_hash[h]; while (n && (n->id1 != id1 || n->id2 != id2 || n->id3 != id3 || n->id4 != id4 || n->cat != cat)) n = n->next; return n; } static int nl_add(struct pci_access *a, int cat, int id1, int id2, int id3, int id4, char *text) { unsigned int h = nl_calc_hash(cat, id1, id2, id3, id4); struct nl_entry *n = a->nl_hash[h]; while (n && (n->id1 != id1 || n->id2 != id2 || n->id3 != id3 || n->id4 != id4 || n->cat != cat)) n = n->next; if (n) return 1; n = malloc(sizeof(struct nl_entry)); bzero(n, sizeof(struct nl_entry)); n->id1 = id1; n->id2 = id2; n->id3 = id3; n->id4 = id4; n->cat = cat; n->name = text; n->next = a->nl_hash[h]; a->nl_hash[h] = n; return 0; } static void err_name_list(struct pci_access *a, char *msg) { fprintf(stderr, "%s: %s: %s\n", a->pci_id_file_name, msg, strerror(errno)); } static void parse_name_list(struct pci_access *a) { char *p = (char *)a->nl_list; char *q, *r; int lino = 0; unsigned int id1=0, id2=0, id3=0, id4=0; int cat = -1; while (*p) { lino++; q = p; while (*p && *p != '\n') p++; if (*p == '\n') *p++ = 0; if (!*q || *q == '#') continue; r = p; while (r > q && r[-1] == ' ') *--r = 0; r = q; while (*q == '\t') q++; if (q == r) { if (q[0] == 'C' && q[1] == ' ') { if (strlen(q+2) < 3 || q[4] != ' ' || sscanf(q+2, "%x", &id1) != 1) goto parserr; cat = NL_CLASS; } else { if (strlen(q) < 5 || q[4] != ' ' || sscanf(q, "%x", &id1) != 1) goto parserr; cat = NL_VENDOR; } id2 = id3 = id4 = 0; q += 4; } else if (q == r+1) switch (cat) { case NL_VENDOR: case NL_DEVICE: case NL_SUBSYSTEM: if (sscanf(q, "%x", &id2) != 1 || q[4] != ' ') goto parserr; q += 5; cat = NL_DEVICE; id3 = id4 = 0; break; case NL_CLASS: case NL_SUBCLASS: case NL_PROGIF: if (sscanf(q, "%x", &id2) != 1 || q[2] != ' ') goto parserr; q += 3; cat = NL_SUBCLASS; id3 = id4 = 0; break; default: goto parserr; } else if (q == r+2) switch (cat) { case NL_DEVICE: case NL_SUBSYSTEM: if (sscanf(q, "%x%x", &id3, &id4) != 2 || q[9] != ' ') goto parserr; q += 10; cat = NL_SUBSYSTEM; break; case NL_CLASS: case NL_SUBCLASS: case NL_PROGIF: if (sscanf(q, "%x", &id3) != 1 || q[2] != ' ') goto parserr; q += 3; cat = NL_PROGIF; id4 = 0; break; default: goto parserr; } else goto parserr; while (*q == ' ') q++; if (!*q) goto parserr; if (nl_add(a, cat, id1, id2, id3, id4, q)) fprintf(stderr, "%s, line %d: duplicate entry", a->pci_id_file_name, lino); } return; parserr: fprintf(stderr, "%s, line %d: parse error", a->pci_id_file_name, lino); } static void load_name_list(struct pci_access *a) { int fd; struct stat st; fd = open(a->pci_id_file_name, O_RDONLY); if (fd < 0) { a->numeric_ids = 1; return; } if (fstat(fd, &st) < 0) err_name_list(a, "stat"); a->nl_list = malloc(st.st_size + 1); if (read(fd, a->nl_list, st.st_size) != st.st_size) err_name_list(a, "read"); a->nl_list[st.st_size] = 0; a->nl_hash = malloc(sizeof(struct nl_entry *) * HASH_SIZE); bzero(a->nl_hash, sizeof(struct nl_entry *) * HASH_SIZE); parse_name_list(a); close(fd); } void pci_free_name_list(struct pci_access *a) { int i = 0; struct nl_entry *n = NULL, *temp = NULL; free(a->nl_list); a->nl_list = NULL; if (a->nl_hash != NULL) { for (i = 0; i < HASH_SIZE; i++) { if (a->nl_hash[i] != NULL) { n = a->nl_hash[i]; do { temp = n->next; free (n); n = temp; } while (temp != NULL); } } } free(a->nl_hash); a->nl_hash = NULL; } char * pci_lookup_name(struct pci_access *a, char *buf, int size, int flags, unsigned int arg1, unsigned int arg2, unsigned int arg3, unsigned int arg4) { int num = a->numeric_ids; int res; struct nl_entry *n; if (flags & PCI_LOOKUP_NUMERIC) { flags &= PCI_LOOKUP_NUMERIC; num = 1; } if (!a->nl_hash && !num) { load_name_list(a); num = a->numeric_ids; } switch (flags) { case PCI_LOOKUP_VENDOR: if ((n = nl_lookup(a, num, NL_VENDOR, arg1, 0, 0, 0))) return n->name; else res = snprintf(buf, size, "%04x", arg1); break; case PCI_LOOKUP_DEVICE: if ((n = nl_lookup(a, num, NL_DEVICE, arg1, arg2, 0, 0))) return n->name; else res = snprintf(buf, size, "%04x", arg2); break; case PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE: if (!num) { struct nl_entry *e, *e2; e = nl_lookup(a, 0, NL_VENDOR, arg1, 0, 0, 0); e2 = nl_lookup(a, 0, NL_DEVICE, arg1, arg2, 0, 0); if (!e) res = snprintf(buf, size, "Unknown device %04x:%04x", arg1, arg2); else if (!e2) res = snprintf(buf, size, "%s: Unknown device %04x", e->name, arg2); else res = snprintf(buf, size, "%s %s", e->name, e2->name); } else res = snprintf(buf, size, "%04x:%04x", arg1, arg2); break; case PCI_LOOKUP_VENDOR | PCI_LOOKUP_SUBSYSTEM: if ((n = nl_lookup(a, num, NL_VENDOR, arg3, 0, 0, 0))) return n->name; else res = snprintf(buf, size, "%04x", arg2); break; case PCI_LOOKUP_DEVICE | PCI_LOOKUP_SUBSYSTEM: if ((n = nl_lookup(a, num, NL_SUBSYSTEM, arg1, arg2, arg3, arg4))) return n->name; else if (arg1 == arg3 && arg2 == arg4 && (n = nl_lookup(a, num, NL_DEVICE, arg1, arg2, 0, 0))) return n->name; else res = snprintf(buf, size, "%04x", arg4); break; case PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE | PCI_LOOKUP_SUBSYSTEM: if (!num) { struct nl_entry *e, *e2; e = nl_lookup(a, 0, NL_VENDOR, arg3, 0, 0, 0); e2 = nl_lookup(a, 0, NL_SUBSYSTEM, arg1, arg2, arg3, arg4); if (!e2 && arg1 == arg3 && arg2 == arg4) /* Cheat for vendors blindly setting subsystem ID same as device ID */ e2 = nl_lookup(a, 0, NL_DEVICE, arg1, arg2, 0, 0); if (!e) res = snprintf(buf, size, "Unknown device %04x:%04x", arg3, arg4); else if (!e2) res = snprintf(buf, size, "%s: Unknown device %04x", e->name, arg4); else res = snprintf(buf, size, "%s %s", e->name, e2->name); } else res = snprintf(buf, size, "%04x:%04x", arg3, arg4); break; case PCI_LOOKUP_CLASS: if ((n = nl_lookup(a, num, NL_SUBCLASS, arg1 >> 8, arg1 & 0xff, 0, 0))) return n->name; else if ((n = nl_lookup(a, num, NL_CLASS, arg1, 0, 0, 0))) res = snprintf(buf, size, "%s [%04x]", n->name, arg1); else res = snprintf(buf, size, "Class %04x", arg1); break; case PCI_LOOKUP_PROGIF: if ((n = nl_lookup(a, num, NL_PROGIF, arg1 >> 8, arg1 & 0xff, arg2, 0))) return n->name; if (arg1 == 0x0101) { /* IDE controllers have complex prog-if semantics */ if (arg2 & 0x70) return NULL; res = snprintf(buf, size, "%s%s%s%s%s", (arg2 & 0x80) ? "Master " : "", (arg2 & 0x08) ? "SecP " : "", (arg2 & 0x04) ? "SecO " : "", (arg2 & 0x02) ? "PriP " : "", (arg2 & 0x01) ? "PriO " : ""); if (res) buf[--res] = 0; break; } return NULL; default: return ""; } if (res == size) return ""; else return buf; } sysfsutils-2.1.1/cmd/names.h000066400000000000000000000015001401370461400157560ustar00rootroot00000000000000/* * The PCI Library * * Copyright (c) 1997--2002 Martin Mares * * Can be freely distributed and used under the terms of the GNU GPL. */ #ifndef _NAMES_H_ #define _NAMES_H_ #define PCI_LOOKUP_VENDOR 1 #define PCI_LOOKUP_DEVICE 2 #define PCI_LOOKUP_CLASS 4 #define PCI_LOOKUP_SUBSYSTEM 8 #define PCI_LOOKUP_PROGIF 16 #define PCI_LOOKUP_NUMERIC 0x10000 #define PCI_VENDOR_ID 0x00 #define PCI_DEVICE_ID 0x02 struct pci_access { unsigned int numeric_ids; char *pci_id_file_name; char *nl_list; struct nl_entry **nl_hash; }; extern char *pci_lookup_name(struct pci_access *a, char *buf, int size, int flags, unsigned int arg1, unsigned int arg2, unsigned int arg3, unsigned int arg4); extern void pci_free_name_list(struct pci_access *a); #endif /* _NAMES_H_ */ sysfsutils-2.1.1/cmd/systool.c000066400000000000000000000460701401370461400163750ustar00rootroot00000000000000/* * systool.c * * Sysfs utility to list buses, classes, and devices * * Copyright (C) IBM Corp. 2003-2005 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include "libsysfs.h" #include "names.h" extern char *my_strncpy(char *to, const char *from, size_t max); #define safestrcpy(to, from) my_strncpy(to, from, sizeof(to)) #define safestrcpymax(to, from, max) my_strncpy(to, from, max) extern char *my_strncat(char *to, const char *from, size_t max); #define safestrcat(to, from) my_strncat(to, from, sizeof(to) - strlen(to) - 1) #define safestrcatmax(to, from, max) \ do { \ to[max-1] = '\0'; \ strncat(to, from, max - strlen(to)-1); \ } while (0) /* Command Options */ static int show_options = 0; /* bitmask of show options */ static char *attribute_to_show = NULL; /* show value for this attribute */ static char *device_to_show = NULL; /* show only this bus device */ static char sysfs_mnt_path[SYSFS_PATH_MAX]; /* sysfs mount point */ struct pci_access *pacc = NULL; char *show_bus = NULL; static void show_device(struct sysfs_device *device, int level); static void show_class_device(struct sysfs_class_device *dev, int level); #define SHOW_ATTRIBUTES 0x01 /* show attributes command option */ #define SHOW_ATTRIBUTE_VALUE 0x02 /* show an attribute value option */ #define SHOW_DEVICES 0x04 /* show only devices option */ #define SHOW_DRIVERS 0x08 /* show only drivers option */ #define SHOW_ALL_ATTRIB_VALUES 0x10 /* show all attributes with values */ #define SHOW_CHILDREN 0x20 /* show device children */ #define SHOW_PARENT 0x40 /* show device parent */ #define SHOW_PATH 0x80 /* show device/driver path */ #define SHOW_ALL 0xff static char cmd_options[] = "aA:b:c:dDhm:pP:v"; /* * binary_files - defines existing sysfs binary files. These files will be * printed in hex. */ static char *binary_files[] = { "config", "data" }; static int binfiles = 2; static unsigned int get_pciconfig_word(int offset, unsigned char *buf) { unsigned short val = (unsigned char)buf[offset] | ((unsigned char)buf[offset+1] << 8); return val; } /** * usage: prints utility usage. */ static void usage(void) { fprintf(stdout, "Usage: systool [ [device]]\n"); fprintf(stdout, "\t-a\t\t\tShow attributes\n"); fprintf(stdout, "\t-b \t\tShow a specific bus\n"); fprintf(stdout, "\t-c \t\tShow a specific class\n"); fprintf(stdout, "\t-d\t\t\tShow only devices\n"); fprintf(stdout, "\t-h\t\t\tShow usage\n"); fprintf(stdout, "\t-m \tShow a specific module\n"); fprintf(stdout, "\t-p\t\t\tShow path to device/driver\n"); fprintf(stdout, "\t-v\t\t\tShow all attributes with values\n"); fprintf(stdout, "\t-A \tShow attribute value\n"); fprintf(stdout, "\t-D\t\t\tShow only drivers\n"); fprintf(stdout, "\t-P\t\t\tShow device's parent\n"); } /** * indent: called before printing a line, it adds indent to the line up to * level passed in. * @level: number of spaces to indent. */ static void indent(int level) { int i; for (i = 0; i < level; i++) fprintf(stdout, " "); } /** * remove_end_newline: removes newline on the end of an attribute value * @value: string to remove newline from */ static void remove_end_newline(char *value) { char *p = value + (strlen(value) - 1); if (p && *p == '\n') *p = '\0'; } /** * isbinaryvalue: checks to see if attribute is binary or not. * @attr: attribute to check. * returns 1 if binary, 0 if not. */ static int isbinaryvalue(struct sysfs_attribute *attr) { int i; if (!attr || !attr->value) return 0; for (i = 0; i < binfiles; i++) if ((strcmp(attr->name, binary_files[i])) == 0) return 1; return 0; } /** * show_attribute_value: prints out single attribute value. * @attr: attricute to print. */ static void show_attribute_value(struct sysfs_attribute *attr, int level) { if (!attr) return; if (attr->method & SYSFS_METHOD_SHOW) { if (isbinaryvalue(attr)) { int i; for (i = 0; i < attr->len; i++) { if (!(i % 16) && (i != 0)) { fprintf(stdout, "\n"); indent(level+22); } else if (!(i % 8) && (i != 0)) fprintf(stdout, " "); fprintf(stdout, " %02x", (unsigned char)attr->value[i]); } fprintf(stdout, "\n"); } else if (attr->value && strlen(attr->value) > 0) { remove_end_newline(attr->value); fprintf(stdout, "\"%s\"\n", attr->value); } else fprintf(stdout, "\n"); } else { fprintf(stdout, "\n"); } } /** * show_attribute: prints out a single attribute * @attr: attribute to print. */ static void show_attribute(struct sysfs_attribute *attr, int level) { if (!attr) return; if (show_options & SHOW_ALL_ATTRIB_VALUES) { indent(level); fprintf(stdout, "%-20s= ", attr->name); show_attribute_value(attr, level); } else if ((show_options & SHOW_ATTRIBUTES) || ((show_options & SHOW_ATTRIBUTE_VALUE) && (strcmp(attr->name, attribute_to_show) == 0))) { indent(level); fprintf (stdout, "%-20s", attr->name); if (show_options & SHOW_ATTRIBUTE_VALUE && attr->value != NULL && (strcmp(attr->name, attribute_to_show)) == 0) { fprintf(stdout, "= "); show_attribute_value(attr, level); } else fprintf(stdout, "\n"); } } /** * show_attributes: prints out a list of attributes. * @attributes: print this dlist of attributes/files. */ static void show_attributes(struct dlist *attributes, int level) { if (attributes) { struct sysfs_attribute *cur; dlist_for_each_data(attributes, cur, struct sysfs_attribute) { show_attribute(cur, level); } } } /** * show_device_parent: prints device's parent (if present) * @device: sysfs_device whose parent information is needed */ static void show_device_parent(struct sysfs_device *device, int level) { struct sysfs_device *parent; parent = sysfs_get_device_parent(device); if (parent) { fprintf(stdout, "\n"); indent(level); fprintf(stdout, "Device \"%s\"'s parent\n", device->name); show_device(parent, (level+2)); } } /** * show_device: prints out device information. * @device: device to print. */ static void show_device(struct sysfs_device *device, int level) { struct dlist *attributes; unsigned int vendor_id, device_id; char buf[128], value[256], path[SYSFS_PATH_MAX]; if (device) { indent(level); if (show_bus && (!(strcmp(show_bus, "pci")))) { fprintf(stdout, "%s ", device->bus_id); memset(path, 0, SYSFS_PATH_MAX); memset(value, 0, SYSFS_PATH_MAX); safestrcpy(path, device->path); safestrcat(path, "/config"); struct sysfs_attribute *attr; attr = sysfs_open_attribute(path); if (attr) { if (!sysfs_read_attribute(attr)) { vendor_id = get_pciconfig_word(PCI_VENDOR_ID, (unsigned char *)attr->value); device_id = get_pciconfig_word(PCI_DEVICE_ID, (unsigned char *)attr->value); fprintf(stdout, "%s\n", pci_lookup_name(pacc, buf, 128, PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE, vendor_id, device_id, 0, 0)); } sysfs_close_attribute(attr); } else fprintf(stdout, "\n"); } else fprintf(stdout, "Device = \"%s\"\n", device->bus_id); if (show_options & (SHOW_PATH | SHOW_ALL_ATTRIB_VALUES)) { indent(level); fprintf(stdout, "Device path = \"%s\"\n", device->path); } if (show_options & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE | SHOW_ALL_ATTRIB_VALUES)) { attributes = sysfs_get_device_attributes(device); if (attributes) show_attributes(attributes, (level+2)); } if ((device_to_show) && (show_options & SHOW_PARENT)) { show_options &= ~SHOW_PARENT; show_device_parent(device, (level+2)); } if (show_options ^ SHOW_DEVICES) if (!(show_options & SHOW_DRIVERS)) fprintf(stdout, "\n"); } } /** * show_driver_attributes: prints out driver attributes . * @driver: print this driver's attributes. */ static void show_driver_attributes(struct sysfs_driver *driver, int level) { if (driver) { struct dlist *attributes; attributes = sysfs_get_driver_attributes(driver); if (attributes) { struct sysfs_attribute *cur; dlist_for_each_data(attributes, cur, struct sysfs_attribute) { show_attribute(cur, (level)); } fprintf(stdout, "\n"); } } } /** * show_driver: prints out driver information. * @driver: driver to print. */ static void show_driver(struct sysfs_driver *driver, int level) { struct dlist *devlist; if (driver) { indent(level); fprintf(stdout, "Driver = \"%s\"\n", driver->name); if (show_options & (SHOW_PATH | SHOW_ALL_ATTRIB_VALUES)) { indent(level); fprintf(stdout, "Driver path = \"%s\"\n", driver->path); } if (show_options & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE | SHOW_ALL_ATTRIB_VALUES)) show_driver_attributes(driver, (level+2)); devlist = sysfs_get_driver_devices(driver); if (devlist) { struct sysfs_device *cur; indent(level+2); fprintf(stdout, "Devices using \"%s\" are:\n", driver->name); dlist_for_each_data(devlist, cur, struct sysfs_device) { if (show_options & SHOW_DRIVERS) { show_device(cur, (level+4)); fprintf(stdout, "\n"); } else { indent(level+4); fprintf(stdout, "\"%s\"\n", cur->name); } } } fprintf(stdout, "\n"); } } /** * show_sysfs_bus: prints out everything on a bus. * @busname: bus to print. * returns 0 with success or 1 with error. */ static int show_sysfs_bus(char *busname) { struct sysfs_bus *bus; struct sysfs_device *curdev; struct sysfs_driver *curdrv; struct dlist *devlist; struct dlist *drvlist; if (!busname) { errno = EINVAL; return 1; } bus = sysfs_open_bus(busname); if (bus == NULL) { fprintf(stderr, "Error opening bus %s\n", busname); return 1; } fprintf(stdout, "Bus = \"%s\"\n", busname); if (show_options ^ (SHOW_DEVICES | SHOW_DRIVERS)) fprintf(stdout, "\n"); if (show_options & SHOW_DEVICES) { devlist = sysfs_get_bus_devices(bus); if (devlist) { dlist_for_each_data(devlist, curdev, struct sysfs_device) { if (!device_to_show || (strcmp(device_to_show, curdev->bus_id) == 0)) show_device(curdev, 2); } } } if (show_options & SHOW_DRIVERS) { drvlist = sysfs_get_bus_drivers(bus); if (drvlist) { dlist_for_each_data(drvlist, curdrv, struct sysfs_driver) { show_driver(curdrv, 2); } } } sysfs_close_bus(bus); return 0; } /** * show_classdev_parent: prints the class device's parent if present * @dev: class device whose parent is needed */ static void show_classdev_parent(struct sysfs_class_device *dev, int level) { struct sysfs_class_device *parent; parent = sysfs_get_classdev_parent(dev); if (parent) { fprintf(stdout, "\n"); indent(level); fprintf(stdout, "Class device \"%s\"'s parent is\n", dev->name); show_class_device(parent, level+2); } } /** * show_class_device: prints out class device. * @dev: class device to print. */ static void show_class_device(struct sysfs_class_device *dev, int level) { struct dlist *attributes; struct sysfs_device *device; if (dev) { indent(level); fprintf(stdout, "Class Device = \"%s\"\n", dev->name); if (show_options & (SHOW_PATH | SHOW_ALL_ATTRIB_VALUES)) { indent(level); fprintf(stdout, "Class Device path = \"%s\"\n", dev->path); } if (show_options & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE | SHOW_ALL_ATTRIB_VALUES)) { attributes = sysfs_get_classdev_attributes(dev); if (attributes) show_attributes(attributes, (level+2)); fprintf(stdout, "\n"); } if (show_options & (SHOW_DEVICES | SHOW_ALL_ATTRIB_VALUES)) { device = sysfs_get_classdev_device(dev); if (device) { show_device(device, (level+2)); } } if ((device_to_show) && (show_options & SHOW_PARENT)) { show_options &= ~SHOW_PARENT; show_classdev_parent(dev, level+2); } if (show_options & ~(SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE | SHOW_ALL_ATTRIB_VALUES)) fprintf(stdout, "\n"); } } /** * show_sysfs_class: prints out sysfs class and all its devices. * @classname: class to print. * returns 0 with success and 1 with error. */ static int show_sysfs_class(char *classname) { struct sysfs_class *cls; struct sysfs_class_device *cur; struct dlist *clsdevlist; if (!classname) { errno = EINVAL; return 1; } cls = sysfs_open_class(classname); if (cls == NULL) { fprintf(stderr, "Error opening class %s\n", classname); return 1; } fprintf(stdout, "Class = \"%s\"\n\n", classname); clsdevlist = sysfs_get_class_devices(cls); if (clsdevlist) { dlist_for_each_data(clsdevlist, cur, struct sysfs_class_device) { if (device_to_show == NULL || (strcmp(device_to_show, cur->name) == 0)) show_class_device(cur, 2); } } sysfs_close_class(cls); return 0; } static int show_sysfs_module(char *module) { struct sysfs_module *mod = NULL; if (!module) { errno = EINVAL; return 1; } mod = sysfs_open_module(module); if (mod == NULL) { fprintf(stderr, "Error opening module %s\n", module); return 1; } fprintf(stdout, "Module = \"%s\"\n\n", module); if (show_options & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE | SHOW_ALL_ATTRIB_VALUES)) { struct dlist *attributes = NULL; struct sysfs_attribute *cur; attributes = sysfs_get_module_attributes(mod); if (attributes) { if (show_options & (SHOW_ATTRIBUTES | SHOW_ALL_ATTRIB_VALUES)) { indent(2); fprintf(stdout, "Attributes:\n"); } dlist_for_each_data(attributes, cur, struct sysfs_attribute) { show_attribute(cur, (4)); } } attributes = sysfs_get_module_parms(mod); if (attributes) { if (show_options & (SHOW_ATTRIBUTES | SHOW_ALL_ATTRIB_VALUES)) { fprintf(stdout, "\n"); indent(2); fprintf(stdout, "Parameters:\n"); } dlist_for_each_data(attributes, cur, struct sysfs_attribute) { show_attribute(cur, (4)); } } attributes = sysfs_get_module_sections(mod); if (attributes) { if (show_options & (SHOW_ATTRIBUTES | SHOW_ALL_ATTRIB_VALUES)) { fprintf(stdout, "\n"); indent(2); fprintf(stdout, "Sections:\n"); } dlist_for_each_data(attributes, cur, struct sysfs_attribute) { show_attribute(cur, (4)); } fprintf(stdout, "\n"); } } sysfs_close_module(mod); return 0; } /** * show_default_info: prints current buses, classes, and root devices * supported by sysfs. * returns 0 with success or 1 with error. */ static int show_default_info(void) { char subsys[SYSFS_NAME_LEN]; struct dlist *list; char *cur; int retval = 0; safestrcpy(subsys, sysfs_mnt_path); safestrcat(subsys, "/"); safestrcat(subsys, SYSFS_BUS_NAME); list = sysfs_open_directory_list(subsys); if (list) { fprintf(stdout, "Supported sysfs buses:\n"); dlist_for_each_data(list, cur, char) fprintf(stdout, "\t%s\n", cur); sysfs_close_list(list); } safestrcpy(subsys, sysfs_mnt_path); safestrcat(subsys, "/"); safestrcat(subsys, SYSFS_CLASS_NAME); list = sysfs_open_directory_list(subsys); if (list) { fprintf(stdout, "Supported sysfs classes:\n"); dlist_for_each_data(list, cur, char) fprintf(stdout, "\t%s\n", cur); sysfs_close_list(list); } safestrcpy(subsys, sysfs_mnt_path); safestrcat(subsys, "/"); safestrcat(subsys, SYSFS_DEVICES_NAME); list = sysfs_open_directory_list(subsys); if (list) { fprintf(stdout, "Supported sysfs devices:\n"); dlist_for_each_data(list, cur, char) fprintf(stdout, "\t%s\n", cur); sysfs_close_list(list); } safestrcpy(subsys, sysfs_mnt_path); safestrcat(subsys, "/"); safestrcat(subsys, SYSFS_MODULE_NAME); list = sysfs_open_directory_list(subsys); if (list) { fprintf(stdout, "Supported sysfs modules:\n"); dlist_for_each_data(list, cur, char) fprintf(stdout, "\t%s\n", cur); sysfs_close_list(list); } return retval; } /** * check_sysfs_mounted: Checks to see if sysfs is mounted. * returns 0 if not and 1 if true. */ static int check_sysfs_is_mounted(void) { if (sysfs_get_mnt_path(sysfs_mnt_path, SYSFS_PATH_MAX) != 0) return 0; return 1; } /* MAIN */ int main(int argc, char *argv[]) { char *show_class = NULL; char *show_module = NULL; char *show_root = NULL; int retval = 0; int opt; char *pci_id_file = PCI_IDS_PATHNAME; while((opt = getopt(argc, argv, cmd_options)) != EOF) { switch(opt) { case 'a': show_options |= SHOW_ATTRIBUTES; break; case 'A': if ((strlen(optarg) + 1) > SYSFS_NAME_LEN) { fprintf(stderr, "Attribute name %s is too long\n", optarg); exit(1); } attribute_to_show = optarg; show_options |= SHOW_ATTRIBUTE_VALUE; break; case 'b': show_bus = optarg; break; case 'c': show_class = optarg; break; case 'd': show_options |= SHOW_DEVICES; break; case 'D': show_options |= SHOW_DRIVERS; break; case 'h': usage(); exit(0); break; case 'm': show_module = optarg; /* FALLTHRU */ case 'p': show_options |= SHOW_PATH; break; case 'P': show_options |= SHOW_PARENT; break; case 'v': show_options |= SHOW_ALL_ATTRIB_VALUES; break; default: usage(); exit(1); } } argc -= optind; argv += optind; switch(argc) { case 0: break; case 1: /* get bus to view */ if ((strlen(*argv)) < SYSFS_NAME_LEN) { device_to_show = *argv; show_options |= SHOW_DEVICES; } else { fprintf(stderr, "Invalid argument - device name too long\n"); exit(1); } break; default: usage(); exit(1); } if (check_sysfs_is_mounted() == 0) { fprintf(stderr, "Unable to find sysfs mount point!\n"); exit(1); } if ((!show_bus && !show_class && !show_module && !show_root) && (show_options & (SHOW_ATTRIBUTES | SHOW_ATTRIBUTE_VALUE | SHOW_DEVICES | SHOW_DRIVERS | SHOW_ALL_ATTRIB_VALUES))) { fprintf(stderr, "Please specify a bus, class, module, or root device\n"); usage(); exit(1); } /* default is to print devices */ if (!(show_options & (SHOW_DEVICES | SHOW_DRIVERS))) show_options |= SHOW_DEVICES; if (show_bus) { if ((!(strcmp(show_bus, "pci")))) { pacc = (struct pci_access *) calloc(1, sizeof(struct pci_access)); pacc->pci_id_file_name = pci_id_file; pacc->numeric_ids = 0; } retval = show_sysfs_bus(show_bus); } if (show_class) retval = show_sysfs_class(show_class); if (show_module) retval = show_sysfs_module(show_module); if (!show_bus && !show_class && !show_module && !show_root) retval = show_default_info(); if (show_bus) { if ((!(strcmp(show_bus, "pci")))) { pci_free_name_list(pacc); free (pacc); pacc = NULL; } } if (!(show_options ^ SHOW_DEVICES)) fprintf(stdout, "\n"); exit(retval); } sysfsutils-2.1.1/configure.ac000066400000000000000000000034271401370461400162370ustar00rootroot00000000000000# Process this file with autoconf to produce a configure script. AC_INIT([sysfsutils], [2.1.1], [https://github.com/linux-ras/sysfsutils/issues]) AC_CONFIG_SRCDIR([cmd/systool.c]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([1.11 foreign]) AM_SILENT_RULES([yes]) # Checks for KLIBC support (should be before LT_INIT and AC_PROG_CC) AC_CHECK_KLIBC if test "X$KLIBC" = Xyes; then # Should disable/enable building of shared libraries ... I am open to better # suggestions though (AC_DISABLE_SHARED and co do not do the right thing in # a situation like this that its runtime dependent) ... enable_shared="no" EXTRA_CFLAGS= else # These ones make KLIBC compiles very loud EXTRA_CFLAGS="-Wshadow -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs" fi AM_CONDITIONAL([KLIBC], [test "X$KLIBC" = Xyes]) AC_SUBST([EXTRA_CFLAGS]) AC_ARG_WITH([pci.ids], [AS_HELP_STRING([--with-pci.ids=PATHNAME], [specify the pci.ids database PATHNAME])], [PCI_IDS_PATHNAME=$with_pci_ids], [PCI_IDS_PATHNAME="/usr/share/misc/pci.ids"]) AC_DEFINE_UNQUOTED([PCI_IDS_PATHNAME], ["$PCI_IDS_PATHNAME"], [pci.ids database pathname]) # Checks for LIBTOOL LT_INIT # Checks for programs. AC_PROG_CC AC_PROG_INSTALL AC_PROG_MAKE_SET # Checks for header files. AC_HEADER_DIRENT AC_HEADER_STDC AC_CHECK_HEADERS([fcntl.h malloc.h stdlib.h string.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE AC_TYPE_SIZE_T # Checks for library functions. AC_FUNC_LSTAT AC_FUNC_MALLOC AC_FUNC_STAT AC_CHECK_FUNCS([bzero isascii memset strchr strerror strrchr strstr strtol]) AC_CONFIG_FILES([Makefile lib/Makefile lib/libsysfs.pc cmd/Makefile test/Makefile]) AC_CONFIG_HEADERS([config.h]) AC_OUTPUT sysfsutils-2.1.1/docs/000077500000000000000000000000001401370461400146735ustar00rootroot00000000000000sysfsutils-2.1.1/docs/libsysfs.txt000066400000000000000000001406461401370461400173050ustar00rootroot00000000000000 System Utilities sysfs Library - libsysfs ========================================= Version: 2.1.1 February 21, 2021 Contents -------- 1. Introduction 2. Requirements 3. Definitions 4. Overview 5. Data Structures 5.1 Attribute Data Structure 5.2 Bus Data Structure 5.3 Class Data Structures 5.4 Device Data Structure 5.5 Driver Data Structure 5.6 Module Data Structure 6. Functions 6.1 Calling Conventions in Libsysfs 6.2 Utility Functions 6.3 Attribute Functions 6.4 Bus Functions 6.5 Class Functions 6.6 Device Functions 6.7 Driver Functions 6.8 Module functions 7. Dlists 7.1 Navigating a dlist 7.2 Custom sorting using dlist_sort_custom() 7.3 Custom filtering and sorting using dlist_filter_sort() 8. Usage 9. Testsuite 10. Conclusion 1. Introduction --------------- Libsysfs' purpose is to provide a consistent and stable interface for querying system device information exposed through the sysfs filesystem. The library implements functions for querying filesystem information, such as reading directories and files. It also contains routines for working with buses, classes, and the device tree. 2. Requirements --------------- The library must satisfy the following requirements: - It must provide a stable programming interfaces that applications can be built upon. - It must provide functions to retrieve device Vital Product Data (VPD) information for Error Log Analysis (ELA) support. ELA will provide device driver and device bus address information. - It must provide access to all system devices and information exposed by sysfs. - It must provide a function to find sysfs' current mount point. - It must provide a function for udev to retrieve a device's major and minor numbers. 3. Definitions -------------- - sysfs: Sysfs is a virtual filesystem in 2.5+ Linux kernels that presents a hierarchical representation of all system physical and virtual devices. It presents system devices by bus, by class, and by topology. Callbacks to device drivers are exposed as files in device directories. Sysfs, for all purposes, is our tree of system devices. For more information, please see: http://www.kernel.org/pub/linux/kernel/people/mochel/doc/ - udev: Udev is Greg Kroah-Hartman's User Space implementation of devfs. Udev creates /dev nodes for devices upon Hotplug events. The Hotplug event provides udev with a sysfs directory location of the device. Udev must use that directory to grab device's major and minor number, which it will use to create the /dev node. For more information, please see: http://www.kernel.org/pub/linux/utils/kernel/hotplug/ Udev provides persistent device naming based on a set of user specified rules. The rules a device name is based on could one or a combination of a number of parameters such as the bus the device is on, the serial number of the device (in case of USB), the vendor name (in case of SCSI) and so on. Udev uses Libsysfs to retrieve relevent information to appropriately name devices. 4. Overview ----------- Libsysfs grew from a common need. There are several applications under development that need access to sysfs and system devices. Udev, on a hotplug event, must take a sysfs device path and create a /dev node. Our diagnostic client needs to list all system devices. Finally, our Error Log Analysis piece is required to retrieve VPD information for a failing device. We divided to create a single library interface rather than having these separate applications create their own accesses to sysfs involving reading directories and files. Libsysfs will also provide stability for applications to be built upon. Sysfs currently doesn't enforce any standards for callback or file names. File names change depending on bus or class. Sysfs is also changing, it is currently being developed. Libsysfs will provide a stable interface to applications while allowing sysfs to change underneath it. Like sysfs, the library will provide devices to applications by bus, by class, and by topology. The library will function similar to directories and files that lie underneath it. To query a device on a PCI bus, one would "open" the bus to scan or read devices and "close" the bus when completed. Besides supplying functions to retrieve devices, the library will also provide some utility functions like getting sysfs mount point. A paper on Libsysfs was presented at Linux.Conf.Au 2004 (Adelaide, January 2004). The paper is available online at: http://oss.software.ibm.com/linux/papers/libsysfs/libsysfs-linuxconfau2004.pdf 5. Data Structures ------------------ Libsysfs will classify system devices following sysfs' example, dividing them by bus, class, and devices. The library presents this information generically. It doesn't, for example, differentiate between PCI and USB buses. Device attributes are presented with values as they are exposed by sysfs, the values are not formatted. The library will provide standard definitions for working with sysfs and devices, here's some examples: #define SYSFS_FSTYPE_NAME "sysfs" #define SYSFS_PROC_MNTS "/proc/mounts" #define SYSFS_BUS_NAME "bus" #define SYSFS_CLASS_NAME "class" #define SYSFS_BLOCK_NAME "block" #define SYSFS_DEVICES_NAME "devices" #define SYSFS_DRIVERS_NAME "drivers" #define SYSFS_NAME_ATTRIBUTE "name" #define SYSFS_MOD_PARM_NAME "parameters" #define SYSFS_MOD_SECT_NAME "sections" #define SYSFS_UNKNOWN "unknown" #define SYSFS_PATH_ENV "SYSFS_PATH" The library uses some definitions to mark maximum size of a sysfs name or path length: #define SYSFS_PATH_MAX 256 #define SYSFS_NAME_LEN 64 #define SYSFS_BUS_ID_SIZE 32 NOTE: a. As of release 0.4.0 of sysfsutils, a number of changes have been made so that the dlists and "directory" references in all libsysfs's structures are not populated until such time that it is absolutely necessary. Hence, these elements may not contain valid data at all times (as was the case before). b. As of release 1.0.0 of sysfsutils, all dlists in the library are sorted in alphabetical order. It is now a requirement that the "name" and "path" be the first two elements of all libsysfs structures. c. There has been a major overhaul with 2.0.0 release of sysfsutils. We now have a much leaner and meaner library without the overhead of the sysfs_directory and related structures. The API list has also been pruned to contain the most frequently used calls and the lists are not populated all at once. This has lead to enormous speed improvements as well as reduction in the number of system calls. 5.1 Attribute Data Structure ------------------------------------------- The library implements structure to represent sysfs files. A file in sysfs represents a device or driver attribute. Attributes can be read only, write only, or read and write. File data can be ASCII and binary. The library has the following structure to represent files: struct sysfs_attribute { char name[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; char *value; unsigned short len; /* value length */ enum sysfs_attribute_method method; /* show and store */ }; Path represents the file/attribute's full path. Value is used when reading from or writing to an attribute. "len" is the length of data in "value". Method is an enum for defining if the attribute supports show(read) and/or store(write). 5.2 Bus Data Structure ---------------------- All buses look similar in sysfs including lists of devices and drivers, therefore we use the following structure to represent all sysfs buses: struct sysfs_bus { char name[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; struct dlist *attrlist; /* Private: for internal use only */ struct dlist *drivers; struct dlist *devices; }; The sysfs_bus structure contains the bus "name", while the "path" to bus directory is also stored. It also contains lists of devices on the bus and drivers that are registered on it. 5.3 Class Data Structures ------------------------- The library uses two data structures to represent classes in sysfs. Sysfs classes contains a class directory like "net" or "scsi_host" and then class devices like "eth0", "lo", or "eth1" for the "net" class. struct sysfs_class { char name[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; struct dlist *attrlist; /* Private: for internal use only */ struct dlist *devices; }; The sysfs_class represents device classes in sysfs like "net". It contains the class "name", "path" to the class and a list of class devices struct sysfs_class_device { char name[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; struct dlist *attrlist; char classname[SYSFS_NAME_LEN]; /* Private: for internal use only */ struct sysfs_class_device *parent; struct sysfs_device *sysdevice; /* NULL if virtual */ }; A class device isn't the same as a sysfs_device, it's specific to the class in which it belongs. The class device structure contains the name of the class the class device belongs to and its sysfs_device reference. It also contains the name of the class device - like "eth0", its parent (if present). 5.4 Device Data Structure ------------------------- The sysfs_device structure represents a system device that's exposed in sysfs under the /sys/devices directory structure. struct sysfs_device { char name[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; struct dlist *attrlist; char bus_id[SYSFS_NAME_LEN]; char bus[SYSFS_NAME_LEN]; char driver_name[SYSFS_NAME_LEN]; char subsystem[SYSFS_NAME_LEN]; /* Private: for internal use only */ struct sysfs_device *parent; struct dlist *children; }; The sysfs_device structure contains a "parent" pointer, a list of child devices, if any, device's directory, its bus id - which is the name of device's directory, the bus name on which this device is registered and its driver name. The device structure also contains the absolute path to the device. 5.5 Driver Data Structure ------------------------- The sysfs_driver structure represents a device driver. struct sysfs_driver { char name[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; struct dlist *attrlist; char bus[SYSFS_NAME_LEN]; /* Private: for internal use only */ struct sysfs_module *module; struct dlist *devices; }; The sysfs_driver structure contains a list of devices that use this driver, the name of the driver, the module it is using and a list of attributes for the driver. 5.6 Module Data Structure ------------------------- The sysfs_module structure represents the module loaded in the system. struct sysfs_module { char name[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; struct dlist *attrlist; struct dlist *parmlist; struct dlist *sections; }; The sysfs_module structure contains a list of attributes, parameters and sections used by the corresponding module. It also contains name of the module, its path. The following functions can be used to retrive the information related to the module. struct dlist *sysfs_get_module_parms(struct sysfs_module *module) struct dlist *sysfs_get_module_sections(struct sysfs_module *module) struct dlist *sysfs_get_module_attributes(struct sysfs_module *module) 6. Functions ------------ Libsysfs will provide functions to access system devices by bus, by class, and by device. Functions will act like accessing directories and files, using "open" and "close". Open returns a structure and close is used to clean that structure up. 6.1 Calling Conventions in Libsysfs ----------------------------------- Libsysfs uses a simple API calling convention. APIs are classified to be one of "open", "get", "close" types. The convention is as follows: a. All "open" APIs have a corresponding "close" API. b. References obtained using "get" calls should not be closed explicitly. c. All "opened" references have to be closed with a call to their corresponding "close" call. This takes care of freeing structure references obtained with "get" calls. 6.2 Utility Functions --------------------- The library will provide a few utility functions for working with sysfs. ------------------------------------------------------------------------------- Name: sysfs_get_mnt_path Description: Function finds the mount path for filesystem type "sysfs". Arguments: char *mnt_path Mount path buffer size_t len Size of mount path buffer Returns: Zero with success. -1 with error. Errno will be set with error: - EINVAL for invalid argument, if buffer is NULL or if len is zero Prototype: sysfs_get_mnt_path(char *mnt_path, size_t len); ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_name_from_path Description: Function returns the last directory or file name from the included path. Arguments: const char *path Path to parse name from char *name Buffer to put parsed name into size_t *len Size of name buffer Returns: 0 with success. -1 on Error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: int sysfs_get_name_from_path(const char *path, char *name, size_t *len) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_link Description: Sysfs readlink function, reads the link at supplied path and returns its target path. Arguments: const char *path Link's path char *target Buffer to place link's target size_t len Size of target buffer Returns: 0 with success -1 with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: int sysfs_get_link(const char *path, char *target, size_t len) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_close_list Description: Closes a given dlist. This can be used as a generic list close routine. Arguments: struct dlist *list List to be closed Prototype: void sysfs_close_list(struct dlist *list) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_path_is_dir Description: Utility function to verify if a given path is to a directory. Arguments: const char *path Path to verify Returns: 0 on success, 1 on error - EINVAL for invalid arguments Prototype: int sysfs_path_is_dir(const char *path) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_path_is_file Description: Utility function to verify if a given path is to a file. Arguments: const char *path Path to verify Returns: 0 on success, 1 on error - EINVAL for invalid arguments Prototype: int sysfs_path_is_file(const char *path) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_path_is_link Description: Utility function to verify if a given path is to a link. Arguments: const char *path Path to verify Returns: 0 on success, 1 on error - EINVAL for invalid arguments Prototype: int sysfs_path_is_link(const char *path) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_open_directory_list Description: Utility function to get list of all directories under path. Arguments: const char *path Path to read Returns: Directory list on success, NULL on error Prototype: struct dlist *sysfs_open_directory_list(const char *path) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_open_link_list Description: Utility function to get list of all links under path. Arguments: const char *path Path to read Returns: Links list on success, NULL on error Prototype: struct dlist *sysfs_open_link_list(const char *path) ------------------------------------------------------------------------------- 6.3 Attribute Functions ------------------------ Libsysfs provides a set of functions to open, read, and close attributes in sysfs. These functions mirror their filesystem function counterparts. Along with the usual open, read, and close functions, libsysfs provides a couple other functions for accessing attribute values. ------------------------------------------------------------------------------- Name: sysfs_open_attribute Description: Opens up a file in sysfs and creates a sysfs_attribute structure. File isn't read with this function. Arguments: const char *path File/Attribute's path Returns: struct sysfs_attribute * with success. NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_attribute *sysfs_open_attribute(const char *path) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_close_attribute Description: Cleans up and closes sysfs_attribute structure. Arguments: struct sysfs_attribute *sysattr Attribute to close Prototype: void sysfs_close_attribute(struct sysfs_attribute *sysattr) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_read_attribute Description: Reads the supplied attribute. Since the maximum transfer from a sysfs attribute is a pagesize, function reads in up to a page from the file and stores it in the "value" field in the attribute. Arguments: struct sysfs_attribute *sysattr Attribute to read Returns: 0 with success. -1 with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: int sysfs_read_attribute(struct sysfs_attribute *sysattr) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_write_attribute Description: Writes to the supplied attribute. Function validates if the given attribute is writable, and writes the new value to the attribute. Value to write as well as its length is user supplied. In case the length written is not equal to the length requested to be written, the original value is restored and an error is returned. Arguments: struct sysfs_attribute *sysattr Attribute to write to const char *new_value sysattr's new value size_t len Length of "new_value" Returns: 0 with success. -1 with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: int sysfs_write_attribute(struct sysfs_attribute *sysattr, const char *new_value, size_t len) ------------------------------------------------------------------------------- 6.4 Bus Functions ----------------- The library provides a functions for viewing buses represented in sysfs. The sysfs_open_bus opens a bus in the /sys/bus directory, such as "pci", "usb", or "scsi". The open command returns a sysfs_bus structure that contains a list of the bus' devices. The sysfs_close_bus function is used to clean up the bus structure. Given a device or a driver, functions are provided to determine what bus they are on. ------------------------------------------------------------------------------- Name: sysfs_open_bus Description: Function opens up one of the buses represented in sysfs in the /sys/bus directory. It returns a sysfs_bus structure that includes a list of bus devices and drivers. Arguments: const char *name Bus name to open, like "pci"... Returns: struct sysfs_bus * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_bus *sysfs_open_bus(const char *name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_close_bus Description: Function closes up the sysfs_bus structure including its devices, and drivers and the list of attributes. Arguments: sysfs_bus *bus Bus structure to close Prototype: void sysfs_close_bus(struct sysfs_bus *bus) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_bus_devices Description: Function returns a list of devices that are registered with this bus. Arguments: struct sysfs_bus *bus Bus whose devices list to return Returns: struct dlist * of sysfs_devices on success NULL with error. Errno will be sent with error, returning - EINVAL for invalid arguments Prototype: struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_bus_drivers Description: Function returns a list of drivers that are registered with this bus. Arguments: struct sysfs_bus *bus Bus whose drivers list to return Returns: struct dlist * of sysfs_drivers on success NULL with error. Errno will be sent with error, returning - EINVAL for invalid arguments Prototype: struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_bus_device Description: Function takes a sysfs_bus structure(obtained on a successful return from a sysfs_open_bus() call) and looks for the given device on this bus. On success, it returns a sysfs_device structure corresponding to the device. Arguments: struct sysfs_bus *bus Bus structure on which to search char *id Device to look for Returns: struct sysfs_device * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_device *sysfs_get_bus_device (struct sysfs_bus *bus, char *id) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_bus_driver Description: Function takes a sysfs_bus structure (obtained on a successful return from a sysfs_open_bus() call) and looks for the given driver on this bus. On success, it returns a sysfs_driver structure corresponding to the driver. Arguments: struct sysfs_bus *bus Bus structure on which to search char *drvname Driver to look for Returns: struct sysfs_driver * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_device *sysfs_get_bus_driver (struct sysfs_bus *bus, char *drvname) ------------------------------------------------------------------------------- 6.5 Class Functions ------------------- Libsysfs provides functions to open sysfs classes and their class devices. These functions too operate with open and close, close must be called to clean up the class structures. Given a class device name, functions are provided to determine what class they belong to. Once a class device name and the class it belongs to is known, a function to open the class device is provided. This method can be used when details of a single class device is required. ------------------------------------------------------------------------------- Name: sysfs_open_class Description: Function opens up one of the classes represented in sysfs in the /sys/class directory. It returns a sysfs_class structure that includes a list of class devices. Arguments: const char *name Class name to open, like "net".. Returns: struct sysfs_class * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_class *sysfs_open_class(const char *name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_close_class Description: Function closes up the sysfs_class structure including its class devices. Arguments: sysfs_class *cls Class structure to close Prototype: void sysfs_close_class(struct sysfs_class *cls); ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_open_class_device_path Description: Function opens up one of the class devices represented in sysfs in sysfs/class/"class"/ directory. It returns a sysfs_class_device structure. Arguments: const char *path Path to class device Returns: struct sysfs_class_device * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_class_device *sysfs_open_class_device_path (const char *path) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_close_class_device Description: Function closes up the sysfs_class_device structure. Arguments: sysfs_class_device *dev Class device structure to close Prototype: void sysfs_close_class_device(struct sysfs_class_device *dev) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_class_device Description: Function takes a sysfs_class structure(obtained on a successful return from a sysfs_open_class() call) and looks for the given device in this class. On success, it returns a sysfs_class_device structure corresponding to the class device. Arguments: struct sysfs_class *cls Class on which to search char *name Class device "name" to look for Returns: struct sysfs_class_device * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_class_device *sysfs_get_class_device (struct sysfs_class *cls, char *name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_class_devices Description: Function returns a list of class devices for the given class. Arguments: struct sysfs_class *cls Class whose class device list is required Returns: struct dlist * of sysfs_class_devices on success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct dlist *sysfs_get_class_devices(struct sysfs_class *cls) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_open_class_device Description: Given the name of the class on which to look for, this function locates a given class device and returns a sysfs_class_device structure corresponding to the requested class device. NOTE: 1. The sysfs_class_device structure obtained upon successful return from this function has to be closed by calling sysfs_close_class_device(). 2. Class this device belongs to must be known prior to calling this function. Arguments: const char *classname Class on which to search char *name Class device "name" to open Returns: struct sysfs_class_device * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_class_device *sysfs_open_class_device (const char *classname, char *name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_classdev_device Description: Function returns the sysfs_device reference (if present) for the given class device. Arguments: struct sysfs_class_device *clsdev Class device whose sysfs_device reference is required Returns: struct sysfs_device * on success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_device *sysfs_get_classdev_device (struct sysfs_class_device *clsdev) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_classdev_parent Description: Function returns the sysfs_class_device reference for the parent (if present) of the given class device. Arguments: struct sysfs_class_device *clsdev Class device whose parent reference is required Returns: struct sysfs_class_device * on success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_class_device *sysfs_get_classdev_parent (struct sysfs_class_device *clsdev) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_classdev_attributes Description: Function takes a sysfs_class_device structure and returns a list of attributes for the class device. Arguments: struct sysfs_class_device *cdev Class device for which attributes are required Returns: struct dlist * of attributes with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct dlist *sysfs_get_classdev_attributes (struct sysfs_class_device *cdev) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_classdev_attr Description: Searches supplied class device's attributes by name and returns the attribute. Arguments: struct sysfs_class_device *clsdev Device to search const char *name Attribute name to find Returns: struct sysfs_attribute * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_attribute *sysfs_get_classdev_attr (struct sysfs_class_device *clsdev, const char *name) ------------------------------------------------------------------------------- 6.6 Device Functions -------------------- Devices represent everything in sysfs under /sys/devices, which is a hierarchical view of system devices. Besides the expected open and close functions, libsysfs provides open and close functions for root devices. These functions recursively open or close a device and all of its children. ------------------------------------------------------------------------------- Name: sysfs_open_device_path Description: Opens up a device at a specific path. It opens the device's directory, reads the directory, and returns a sysfs_device structure. Arguments: const char *path Path to device Returns: struct sysfs_device * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_device *sysfs_open_device_path(const char *path) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_close_device Description: Function closes up the sysfs_device structure. Arguments: sysfs_device *dev Device structure to close Prototype: void sysfs_close_device(struct sysfs_device *dev) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_open_device_tree Description: Function opens up the device tree at the specified path. Arguments: const char *path Path at which to open the device tree Returns: struct sysfs_device * with success NULL with error, Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_device *sysfs_open_device_tree(const char *path) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_close_device_tree Description: Function closes the device tree originating at the given sysfs_device. Arguments: struct sysfs_device *devroot Device from which the device tree has to be closed Prototype: void sysfs_close_device_tree(struct sysfs_device *devroot) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_device_parent Description: Function returns the sysfs_device reference for the parent (if present) of the given sysfs_device. Arguments: struct sysfs_device *dev sysfs_device whose parent reference is required Returns: struct sysfs_device * on success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_device *sysfs_get_device_parent (struct sysfs_device *dev) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_device_attr Description: Searches supplied device's attributes by name and returns the attribute. Arguments: struct sysfs_device *dev Device to search const char *name Attribute name to find Returns: struct sysfs_attribute * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_attribute *sysfs_get_device_attr (struct sysfs_device *dev, const char *name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_device_attributes Description: Function takes a sysfs_device structure and returns a list of attributes for the device. Arguments: struct sysfs_device *device Device for which attributes are required Returns: struct dlist * of attributes with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct dlist *sysfs_get_device_attributes (struct sysfs_device *device) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_open_device Description: Given the name of the bus on which to look for, this function locates a given device and returns a sysfs_device structure corresponding to the requested device. Arguments: const char *bus Bus on which to search const char *bus_id Device to look for Returns: struct sysfs_device * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_device *sysfs_open_device (const char *bus, const char *bus_id) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_device_bus Description: Given a sysfs_device, this function fills in the bus this device is on in the sysfs_device->bus field. Arguments: struct sysfs_device *dev Device whose bus name to find Returns: 0 with success. -1 with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: int sysfs_get_device_bus(struct sysfs_device *dev) ------------------------------------------------------------------------------- 6.7 Driver Functions -------------------- Drivers are represented in sysfs under the /sys/bus/xxx/drivers (xxx being the bus type, such as "pci", "usb, and so on). Functions are provided to open and close drivers. ------------------------------------------------------------------------------- Name: sysfs_open_driver_path Description: Opens driver at specific path. Arguments: const char *path Path to driver Returns: struct sysfs_driver * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_driver *sysfs_open_driver_path(const char *path) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_close_driver Description: Closes and cleans up sysfs_driver structure. Arguments: sysfs_driver *driver Driver structure to close Prototype: void sysfs_close_driver(struct sysfs_driver *driver) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_driver_devices Description: Function returns a list of devices that use this driver. Arguments: struct sysfs_driver *driver Driver whose devices list is required Returns: struct dlist * of sysfs_devices on success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct dlist *sysfs_get_driver_devices (struct sysfs_driver *driver) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_driver_attr Description: Searches supplied driver's attributes by name and returns the attribute. Arguments: struct sysfs_driver *drv Driver to search const char *name Attribute name to find Returns: struct sysfs_attribute * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_attribute *sysfs_get_driver_attr (struct sysfs_driver *drv, const char *name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_driver_attributes Description: Function takes a sysfs_driver structure and returns a list of attributes for the driver. Arguments: struct sysfs_driver *driver Driver for which attributes are required Returns: struct dlist * of attributes with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct dlist *sysfs_get_driver_attributes (struct sysfs_driver *driver) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_open_driver Description: Given the name of the bus on which to look for, this function locates a given driver and returns a sysfs_driver structure corresponding to the requested device. NOTE: 1. The sysfs_driver structure obtained upon successful return from this function has to be closed by calling sysfs_close_driver_by_name(). Arguments: const char *bus_name Bus on which to search const char *drv_name Driver name to look for Returns: struct sysfs_driver * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_driver *sysfs_open_driver(const char *bus_name, const char *drv_name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_driver_module Description: Function takes a sysfs_driver structure and returns the module that the driver is using. Arguments: struct sysfs_driver *drv Driver for which the module details are required Returns: struct sysfs_module * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct dlist *sysfs_get_driver_module (struct sysfs_driver *drv) ------------------------------------------------------------------------------- 6.8 Module Functions -------------------- Modules are represented in sysfs under the /sys/module. Functions are provided to open and close modules. ------------------------------------------------------------------------------- Name: sysfs_close_module Description: Closes and cleans up the sysfs_module structure Arguments: struct sysfs_module *module sysfs_module device to close Prototype: void sysfs_close_module(struct sysfs_module *module); ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_open_module_path Description: Opens and populates the sysfs_module struct Arguments: const char *path path to the module to open Returns: struct sysfs_module * with success and NULL if error Prototype: struct sysfs_module *sysfs_open_module_path(const char *path); ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_open_module Description: Opens specific module on a system Arguments: const char *name Name of the module to open Returns: struct sysfs_module * with success or NULL if error Prototype: struct sysfs_module *sysfs_open_module(const char *name); ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_module_parms Description: Get modules list of parameters Arguments: sysfs_module whose parmameter list is required Returns: dlist of parameters on SUCCESS and NULL on error Prototype: struct dlist *sysfs_get_module_parms(struct sysfs_module *module); ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_module_sections Description: Get the set of sections for this module Arguments: sysfs_module whose list of sections is required Returns: dlist of sections on SUCCESS and NULL on error Prototype: struct dlist *sysfs_get_module_sections(struct sysfs_module *module); ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_module_attributes Description: Get dlist of attributes for the requested sysfs_module Arguments: sysfs_module for which attributes are needed Returns: a dlist of attributes if exists, NULL otherwise Prototype: struct dlist *sysfs_get_module_attributes(struct sysfs_module *module); ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_module_attr Description: searches module's attributes by name Arguments: module: to look through name: name of the attribute Returns: sysfs_attribute reference with success or NULL with error Prototype: struct sysfs_attribute *sysfs_get_module_attr (struct sysfs_module *module, const char *name); ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_module_parm Description: searches module's parameters by name Arguments: sysfs_module: to look through parm: parameter name Returns: sysfs_attribute on SUCCESS and NULL on error Prototype: struct sysfs_attribute *sysfs_get_module_parm (struct sysfs_module *module, const char *parm); ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Name: sysfs_get_module_section Description: searches module's sections by name Arguments: sysfs_module: to look through section: section name Returns: sysfs_attribute * on SUCCESS and NULL on error Prototype: struct sysfs_attribute *sysfs_get_module_section (struct sysfs_module *module, const char *section); ------------------------------------------------------------------------------- 7 Dlists -------- Libsysfs uses (yet another) list implementation thanks to Eric J Bohm. 7.1 Navigating a dlist ---------------------- Some library functions return a dlist of devices/drivers/attributes, etc. To navigate the list returned the macro "dlist_for_each_data" is to be used. ------------------------------------------------------------------------------ Function/Macro name: dlist_for_each_data Description: Walk the given list, returning a known data type/ structure in each iteration. Arguments: struct dlist *list List pointer data_iterator Data type/structure variable contained in the list datatype Data type/structure contained in the list Returns: On each iteration, "data_iterator" will contain a list element of "datatype" Usage example: The function sysfs_get_classdev_attributes() returns a dlist of attributes. To navigate the list: struct sysfs_attribute *attr = NULL; struct dlist *attrlist = NULL; . . . attrlist = sysfs_get_classdev_attributes (struct sysfs_class_device *cdev) if (attrlist != NULL) { dlist_for_each_data(attrlist, attr, struct sysfs_attribute) { . . . } } ------------------------------------------------------------------------------- 7.2 Custom sorting using dlist_sort_custom() -------------------------------------------- As of release 1.2.0, libsysfs provides a new interface for custom sorting of dlists. The API dlist_sort_custom() has been added for this purpose. Applications that would like to define their own sorter function can now make use of this API. The sorter function must conform to the following prototype: int compare(void *a, void*b) dlist_sort_custom() expects that the compare function will: return >0 for a before b return <0 for b before a return 0 for a == b 7.3 Custom filtering and sorting using dlist_filter_sort() ---------------------------------------------------------- From release 2.0.0, libsysfs provides a new interface for custom filtering and sorting of dlists. This API is similar to scandir() system call. Applications can call this API with the following arguments: the list, pointer to the filter function, pointer to the sorter function as in dlist_sort_custom. The filter function must conform to the following prototype: int filter(void *a) dlist_filter_sort expects that the filter function will: return 0 for unwanted nodes return 1 for required nodes 8. Usage -------- Accessing devices through libsysfs is supposed to mirror accessing devices in the filesystem it represents. Here's a typical order of operation: - get sysfs mount point - "open" sysfs category, ie. bus, class, or device - work with category - "close" sysfs category 9. Testsuite ------------ From version 2.0.0 sysfsutils ships with a comprehensive testsuite. The testsuite shipped as part of the "test" directory of the sysfsutils source package, results in an executable "testlibsysfs". Some of the salient features of the testsuite are: a. Tests _every_ API exported by the library. b. Tests are performed for all possible combinations of input parameters. c. Detailed output is provided for the correct case. d. Facility to redirect output of the tests to a normal file. e. Number of iterations of tests can be specified. The testsuite comes with its own configuration file "libsysfs.conf" in the "test" directory. This file is used to generate a header file at the time the tests are built. To use the testsuite: a. Modify the variables libsysfs.conf file to appropriate values for your system. (The libsysfs.conf file contains comments describing what each variable stands for and, in some cases, how to determine an appropriate value for the system under test). b. Build testsuite. c. Run the testsuite: testlibsysfs The default logfile is stdout. NOTE: If the libsysfs.conf file is changed, make sure to run "make clean" in the test directory and then a "make" for the changes to take effect. 10. Conclusion -------------- Libsysfs is meant to provide a stable application programming interface to sysfs. Applications can depend upon the library to access system devices and functions exposed through sysfs. sysfsutils-2.1.1/include/000077500000000000000000000000001401370461400153665ustar00rootroot00000000000000sysfsutils-2.1.1/include/dlist.h000066400000000000000000000164571401370461400166730ustar00rootroot00000000000000/* * dlist.h * * Copyright (C) 2003 Eric J Bohm * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _DLIST_H_ #define _DLIST_H_ /* Double linked list header. * navigate your list with DLIST_PREV and DLIST_NEXT. These are macros * so function call overhead is minimized. * Supports perl style push, pop, shift, unshift list semantics. * You allocate the data and give dlist the pointer. If your data is * complex set the dlist->del_func to a an appropriate delete using * dlist_new_with_delete. Your delete function must match (void * )(del(void *) *Otherwise dlist will just use free. * NOTE: The small amount of pain involved in doing that allows us to * avoid copy in copy out semantics. * Dlist uses an internal mark pointer to keep track of where you are * in the list. * insert and delete take a directional parameter. Where direction * corresponds to the direction in which you want the list to go. * true direction corresponded to progressing forward in the last * false to regressing in the list. * so a dlist_insert(yourlist,item,1) will insert it after the mark * so a dlist_insert(yourlist,item,0) will insert it before the mark * any insert will move the mark to the new node regardless of the direction. * Just use the dlist_(insert|delete)_(before|after) macros if you do not want * to think about it. */ #include typedef struct dl_node { struct dl_node *prev; struct dl_node *next; void *data; } DL_node; typedef struct dlist { DL_node *marker; unsigned long count; size_t data_size; void (*del_func)(void *); DL_node headnode; DL_node *head; } Dlist; #ifdef __cplusplus extern "C" { #endif Dlist *dlist_new(size_t datasize); Dlist *dlist_new_with_delete(size_t datasize,void (*del_func)(void*)); void *_dlist_mark_move(Dlist *list,int direction); void *dlist_mark(Dlist *); void dlist_start(Dlist *); void dlist_end(Dlist *); void dlist_move(struct dlist *source, struct dlist *dest, struct dl_node *target,int direction); void *dlist_insert(Dlist *,void *,int) ; void *dlist_insert_sorted(struct dlist *list, void *new_elem, int (*sorter)(void *, void *)); void dlist_delete(Dlist *,int); void dlist_push(Dlist *,void *); void dlist_unshift(Dlist *,void *); void dlist_unshift_sorted(Dlist *,void *,int (*sorter)(void *, void *)); void *dlist_pop(Dlist *); void *dlist_shift(Dlist *); void dlist_destroy(Dlist *); int _dlist_merge(struct dlist *listsource, struct dlist *listdest, unsigned int passcount, int (*compare)(void *, void *)); void *dlist_find_custom(struct dlist *list, void *target, int (*comp)(void *, void *)); void dlist_sort_custom(struct dlist *list, int (*compare)(void *, void *)); void dlist_filter_sort(struct dlist *list, int (*filter) (void *), int (*compare) (void *, void *)); void _dlist_swap(struct dlist *list, struct dl_node *a, struct dl_node *b); void dlist_transform(struct dlist *list, void (*node_operation)(void *)); /* * _dlist_remove is for internal use only * _dlist_mark_move is for internal use only */ void *_dlist_remove(struct dlist *,struct dl_node *,int ); void *_dlist_insert_dlnode(struct dlist *list,struct dl_node *new_node,int direction); #define dlist_prev(A) _dlist_mark_move((A),0) #define dlist_next(A) _dlist_mark_move((A),1) #define dlist_insert_before(A,B) dlist_insert((A),(B),0) #define dlist_insert_after(A,B) dlist_insert((A),(B),1) #define dlist_delete_before(A) dlist_delete((A),0) #define dlist_delete_after(A) dlist_delete((A),1) /** * provide for loop header which iterates the mark from start to end * list: the dlist pointer, use dlist_mark(list) to get iterator */ #define dlist_for_each(list) \ for(dlist_start(list),dlist_next(list); \ (list)->marker!=(list)->head;dlist_next(list)) /** * provide for loop header which iterates the mark from end to start * list: the dlist pointer, use dlist_mark(list) to get iterator */ #define dlist_for_each_rev(list) \ for(dlist_end(list),dlist_prev(list); \ (list)->marker!=(list)->head;dlist_prev(list)) /** * provide for loop header which iterates through the list without moving mark * list: the dlist_pointer * iterator: dl_node pointer to iterate */ #define dlist_for_each_nomark(list,iterator) \ for((iterator)=(list)->head->next; (iterator)!=(list)->head; \ (iterator)=(iterator)->next) /** * provide for loop header which iterates through the list without moving mark * in reverse * list: the dlist_pointer * iterator: dl_node pointer to iterate */ #define dlist_for_each_nomark_rev(list,iterator) \ for((iterator)=(list)->head->prev; (iterator)!=(list)->head; \ (iterator)=(iterator)->prev) /** * provide for loop header which iterates through the list providing a * data iterator * list: the dlist pointer * data_iterator: the pointer of type datatype to iterate * datatype: actual type of the contents in the dl_node->data */ #define dlist_for_each_data(list,data_iterator,datatype) \ for(dlist_start(list), (data_iterator)=(datatype *) dlist_next(list); \ (list)->marker!=(list)->head;(data_iterator)=(datatype *) dlist_next(list)) /** * provide for loop header which iterates through the list providing a * data iterator in reverse * list: the dlist pointer * data_iterator: the pointer of type datatype to iterate * datatype: actual type of the contents in the dl_node->data */ #define dlist_for_each_data_rev(list,data_iterator,datatype) \ for(dlist_end(list), (data_iterator)=(datatype *) dlist_prev(list); \ (list)->marker!=(list)->head;(data_iterator)=(datatype *) dlist_prev(list)) /** * provide for loop header which iterates through the list providing a * data iterator without moving the mark * list: the dlist pointer * iterator: the dl_node pointer to iterate * data_iterator: the pointer of type datatype to iterate * datatype: actual type of the contents in the dl_node->data */ #define dlist_for_each_data_nomark(list,iterator,data_iterator,datatype) \ for((iterator)=(list)->head->next, (data_iterator)=(datatype *) (iterator)->data; \ (iterator)!=(list)->head;(iterator)=(iterator)->next,(data_iterator)=(datatype *) (iterator)) /** * provide for loop header which iterates through the list providing a * data iterator in reverse without moving the mark * list: the dlist pointer * iterator: the dl_node pointer to iterate * data_iterator: the pointer of type datatype to iterate * datatype: actual type of the contents in the dl_node->data */ #define dlist_for_each_data_nomark_rev(list,iterator, data_iterator,datatype) \ for((iterator)=(list)->head->prev, (data_iterator)=(datatype *) (iterator)->data; \ (iterator)!=(list)->head;(iterator)=(iterator)->prev,(data_iterator)=(datatype *) (iterator)) #ifdef __cplusplus } #endif #endif /* _DLIST_H_ */ sysfsutils-2.1.1/include/libsysfs.h000066400000000000000000000211631401370461400174000ustar00rootroot00000000000000/* * libsysfs.h * * Header Definitions for libsysfs * * Copyright (C) IBM Corp. 2004-2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _LIBSYSFS_H_ #define _LIBSYSFS_H_ #include #include #include "dlist.h" #define SYSFS_FSTYPE_NAME "sysfs" #define SYSFS_PROC_MNTS "/proc/mounts" #define SYSFS_BUS_NAME "bus" #define SYSFS_CLASS_NAME "class" #define SYSFS_BLOCK_NAME "block" #define SYSFS_DEVICES_NAME "devices" #define SYSFS_DRIVERS_NAME "drivers" #define SYSFS_MODULE_NAME "module" #define SYSFS_NAME_ATTRIBUTE "name" #define SYSFS_MOD_PARM_NAME "parameters" #define SYSFS_MOD_SECT_NAME "sections" #define SYSFS_UNKNOWN "unknown" #define SYSFS_PATH_ENV "SYSFS_PATH" #define SYSFS_PATH_MAX 256 #define SYSFS_NAME_LEN 64 #define SYSFS_BUS_ID_SIZE 32 /* mount path for sysfs, can be overridden by exporting SYSFS_PATH */ #define SYSFS_MNT_PATH "/sys" enum sysfs_attribute_method { SYSFS_METHOD_SHOW = 0x01, /* attr can be read by user */ SYSFS_METHOD_STORE = 0x02, /* attr can be changed by user */ }; /* * NOTE: * 1. We have the statically allocated "name" as the first element of all * the structures. This feature is used in the "sorter" function for dlists * 2. As is the case with attrlist * 3. As is the case with path */ struct sysfs_attribute { char name[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; char *value; unsigned short len; /* value length */ enum sysfs_attribute_method method; /* show and store */ }; struct sysfs_driver { char name[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; struct dlist *attrlist; char bus[SYSFS_NAME_LEN]; /* Private: for internal use only */ struct sysfs_module *module; struct dlist *devices; }; struct sysfs_device { char name[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; struct dlist *attrlist; char bus_id[SYSFS_NAME_LEN]; char bus[SYSFS_NAME_LEN]; char driver_name[SYSFS_NAME_LEN]; char subsystem[SYSFS_NAME_LEN]; /* Private: for internal use only */ struct sysfs_device *parent; /* NOTE - we still don't populate this */ struct dlist *children; }; struct sysfs_bus { char name[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; struct dlist *attrlist; /* Private: for internal use only */ struct dlist *drivers; struct dlist *devices; }; struct sysfs_class_device { char name[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; struct dlist *attrlist; char classname[SYSFS_NAME_LEN]; /* Private: for internal use only */ struct sysfs_class_device *parent; struct sysfs_device *sysdevice; /* NULL if virtual */ }; struct sysfs_class { char name[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; struct dlist *attrlist; /* Private: for internal use only */ struct dlist *devices; }; struct sysfs_module { char name[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; struct dlist *attrlist; struct dlist *parmlist; struct dlist *sections; }; #ifdef __cplusplus extern "C" { #endif /* * Function Prototypes */ extern int sysfs_get_mnt_path(char *mnt_path, size_t len); extern int sysfs_remove_trailing_slash(char *path); extern int sysfs_get_name_from_path(const char *path, char *name, size_t len); extern int sysfs_path_is_dir(const char *path); extern int sysfs_path_is_link(const char *path); extern int sysfs_path_is_file(const char *path); extern int sysfs_get_link(const char *path, char *target, size_t len); extern struct dlist *sysfs_open_directory_list(const char *path); extern struct dlist *sysfs_open_link_list(const char *path); extern void sysfs_close_list(struct dlist *list); /* sysfs directory and file access */ extern void sysfs_close_attribute(struct sysfs_attribute *sysattr); extern struct sysfs_attribute *sysfs_open_attribute(const char *path); extern int sysfs_read_attribute(struct sysfs_attribute *sysattr); extern int sysfs_write_attribute(struct sysfs_attribute *sysattr, const char *new_value, size_t len); extern struct sysfs_device *sysfs_read_dir_subdirs(const char *path); /* sysfs driver access */ extern void sysfs_close_driver(struct sysfs_driver *driver); extern struct sysfs_driver *sysfs_open_driver (const char *bus_name, const char *drv_name); extern struct sysfs_driver *sysfs_open_driver_path(const char *path); extern struct sysfs_attribute *sysfs_get_driver_attr (struct sysfs_driver *drv, const char *name); extern struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *drv); extern struct dlist *sysfs_get_driver_devices(struct sysfs_driver *drv); extern struct sysfs_module *sysfs_get_driver_module(struct sysfs_driver *drv); /* generic sysfs device access */ extern void sysfs_close_device_tree(struct sysfs_device *device); extern struct sysfs_device *sysfs_open_device_tree(const char *path); extern void sysfs_close_device(struct sysfs_device *dev); extern struct sysfs_device *sysfs_open_device (const char *bus, const char *bus_id); extern struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev); extern struct sysfs_device *sysfs_open_device_path(const char *path); extern int sysfs_get_device_bus(struct sysfs_device *dev); extern struct sysfs_attribute *sysfs_get_device_attr (struct sysfs_device *dev, const char *name); extern struct dlist *sysfs_get_device_attributes (struct sysfs_device *dev); /* generic sysfs class access */ extern void sysfs_close_class_device(struct sysfs_class_device *dev); extern struct sysfs_class_device *sysfs_open_class_device_path (const char *path); extern struct sysfs_class_device *sysfs_open_class_device (const char *classname, const char *name); extern struct sysfs_class_device *sysfs_get_classdev_parent (struct sysfs_class_device *clsdev); extern struct sysfs_attribute *sysfs_get_classdev_attr (struct sysfs_class_device *clsdev, const char *name); extern struct dlist *sysfs_get_classdev_attributes (struct sysfs_class_device *clsdev); extern struct sysfs_device *sysfs_get_classdev_device (struct sysfs_class_device *clsdev); extern void sysfs_close_class(struct sysfs_class *cls); extern struct sysfs_class *sysfs_open_class(const char *name); extern struct sysfs_class_device *sysfs_get_class_device (struct sysfs_class *cls, const char *name); extern struct dlist *sysfs_get_class_devices(struct sysfs_class *cls); /* generic sysfs bus access */ extern void sysfs_close_bus(struct sysfs_bus *bus); extern struct sysfs_bus *sysfs_open_bus(const char *name); extern struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus); extern struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus); extern struct sysfs_device *sysfs_get_bus_device (struct sysfs_bus *bus, const char *id); extern struct sysfs_driver *sysfs_get_bus_driver (struct sysfs_bus *bus, const char *drvname); /* generic sysfs module access */ extern void sysfs_close_module(struct sysfs_module *module); extern struct sysfs_module *sysfs_open_module_path(const char *path); extern struct sysfs_module *sysfs_open_module(const char *name); extern struct dlist *sysfs_get_module_parms(struct sysfs_module *module); extern struct dlist *sysfs_get_module_sections(struct sysfs_module *module); extern struct dlist *sysfs_get_module_attributes(struct sysfs_module *module); extern struct sysfs_attribute *sysfs_get_module_attr (struct sysfs_module *module, const char *name); extern struct sysfs_attribute *sysfs_get_module_parm (struct sysfs_module *module, const char *parm); extern struct sysfs_attribute *sysfs_get_module_section (struct sysfs_module *module, const char *section); /** * sort_list: sorter function to keep list elements sorted in alphabetical * order. Just does a strncmp as you can see :) * * Returns 1 if less than 0 otherwise * * NOTE: We take care to have a statically allocated "name" as the first * lement of all libsysfs structures. Hence, this function will work * AS IS for _ALL_ the lists that have to be sorted. */ static inline int sort_list(void *new_elem, void *old_elem) { return ((strncmp(((struct sysfs_attribute *)new_elem)->name, ((struct sysfs_attribute *)old_elem)->name, strlen(((struct sysfs_attribute *)new_elem)->name))) < 0 ? 1 : 0); } #ifdef __cplusplus } #endif #endif /* _LIBSYSFS_H_ */ sysfsutils-2.1.1/lib/000077500000000000000000000000001401370461400145115ustar00rootroot00000000000000sysfsutils-2.1.1/lib/LGPL000066400000000000000000000636421401370461400152050ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! sysfsutils-2.1.1/lib/Makefile.am000066400000000000000000000007151401370461400165500ustar00rootroot00000000000000EXTRA_DIST = libsysfs.pc.in pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libsysfs.pc lib_LTLIBRARIES = libsysfs.la libsysfs_la_SOURCES = sysfs_utils.c sysfs_attr.c sysfs_class.c dlist.c \ sysfs_device.c sysfs_driver.c sysfs_bus.c sysfs_module.c sysfs.h libsysfs_la_CPPFLAGS = -I$(top_srcdir)/include libsysfs_la_LDFLAGS = -version-info 2:1:0 EXTRA_CFLAGS = @EXTRA_CLFAGS@ libsysfs_la_CFLAGS = -Wall -W -Wextra -Wstrict-prototypes $(EXTRA_CLFAGS) sysfsutils-2.1.1/lib/dlist.c000066400000000000000000000355141401370461400160040ustar00rootroot00000000000000/* * dlist.c * * Copyright (C) 2003 Eric J Bohm * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 021110307 USA * */ /* Double linked list implementation. * You allocate the data and give dlist the pointer. * If your data is complex set the dlist->del_func to a an appropriate * delete function. Otherwise dlist will just use free. */ #include "config.h" #include #include "dlist.h" /* * Return pointer to node at marker. * else null if no nodes. */ inline void *dlist_mark(Dlist *list) { if(list->marker!=NULL) return(list->marker->data); else return(NULL); } /* * Set marker to start. */ inline void dlist_start(Dlist *list) { list->marker=list->head; } /* * Set marker to end. */ inline void dlist_end(Dlist *list) { list->marker=list->head; } /* internal use function * quickie inline to consolidate the marker movement logic * in one place * * when direction true it moves marker after * when direction false it moves marker before. * return pointer to data at new marker * if nowhere to move the marker in desired direction return null */ inline void *_dlist_mark_move(Dlist *list,int direction) { if(direction) { if( list->marker && list->marker->next!=NULL) list->marker=list->marker->next; else return(NULL); } else { if( list->marker && list->marker->prev!=NULL) list->marker=list->marker->prev; else return(NULL); } if(list->marker!=list->head) return(list->marker->data); else return(NULL); } /* * Create new linked list to store nodes of datasize. * return null if list cannot be created. */ Dlist *dlist_new(size_t datasize) { Dlist *list=NULL; if((list=malloc(sizeof(Dlist)))) { list->marker=NULL; list->count=0L; list->data_size=datasize; list->del_func=free; list->head=&(list->headnode); list->head->prev=NULL; list->head->next=NULL; list->head->data=NULL; } return(list); } /* * Create new linked list to store nodes of datasize set list * data node delete function to the passed in del_func * return null if list cannot be created. */ Dlist *dlist_new_with_delete(size_t datasize,void (*del_func)(void*)) { Dlist *list=NULL; list=dlist_new(datasize); if(list!=NULL) list->del_func=del_func; return(list); } /* * remove marker node from list * call data_delete function on data if registered. * otherwise call free. * when direction true it moves marker after * when direction false it moves marker before. * free marker node * return nothing. */ void dlist_delete(Dlist *list,int direction) { if((list->marker != list->head)&&(list->marker!=NULL)) { DL_node *corpse; corpse=list->marker; _dlist_mark_move(list,direction); if(list->head->next==corpse) list->head->next=corpse->next; if(list->head->prev==corpse) list->head->prev=corpse->prev; if(corpse->prev!=NULL) //should be impossible corpse->prev->next=corpse->next; if(corpse->next!=NULL) //should be impossible corpse->next->prev=corpse->prev; list->del_func(corpse->data); list->count--; free(corpse); } } /* * Insert node containing data at marker. * If direction true it inserts after. * If direction false it inserts before. * move marker to inserted node * return pointer to inserted node */ void *dlist_insert(Dlist *list,void *data,int direction) { DL_node *new_node=NULL; if(list==NULL || data==NULL) return(NULL); if(list->marker==NULL) //in case the marker ends up unset list->marker=list->head; if((new_node=malloc(sizeof(DL_node)))) { new_node->data=data; new_node->prev=NULL; new_node->next=NULL; list->count++; if(list->head->next==NULL) //no l { list->head->next=list->head->prev=new_node; new_node->prev=list->head; new_node->next=list->head; } else if(direction) { new_node->next=list->marker->next; new_node->prev=list->marker; list->marker->next->prev=new_node; list->marker->next=new_node; } else { new_node->prev=list->marker->prev; new_node->next=list->marker; list->marker->prev->next=new_node; list->marker->prev=new_node; } list->marker=new_node; } else { return(NULL); } return(list->marker->data); } /* internal use only * Insert dl_node at marker. * If direction true it inserts after. * If direction false it inserts before. * move marker to inserted node * return pointer to inserted node */ void *_dlist_insert_dlnode(struct dlist *list,struct dl_node *new_node,int direction) { if(list==NULL || new_node==NULL) return(NULL); if(list->marker==NULL) //in case the marker ends up unset list->marker=list->head; list->count++; if(list->head->next==NULL) { list->head->next=list->head->prev=new_node; new_node->prev=list->head; new_node->next=list->head; } else if(direction) { new_node->next=list->marker->next; new_node->prev=list->marker; list->marker->next->prev=new_node; list->marker->next=new_node; } else { new_node->prev=list->marker->prev; new_node->next=list->marker; list->marker->prev->next=new_node; list->marker->prev=new_node; } list->marker=new_node; return(list->marker); } /* * Remove DL_node from list without deallocating data. * if marker == killme . * when direction true it moves marker after * when direction false it moves marker before. * to previous if there is no next. */ void *_dlist_remove(Dlist *list,DL_node *killme,int direction) { if(killme!=NULL) { void *killer_data=killme->data; // take care of head and marker pointers. if(list->marker==killme) _dlist_mark_move(list,direction); if(killme ==list->head->next) list->head->next=killme->next; if(killme==list->head->prev) list->head->prev=killme->prev; // remove from list if(killme->prev !=NULL) killme->prev->next=killme->next; if(killme->next !=NULL) killme->next->prev=killme->prev; list->count--; free(killme); return(killer_data); } else return (NULL); } /* * move dl_node from source to dest * if marker == target . * when direction true it moves marker after * when direction false it moves marker before. * to previous if there is no next. */ void dlist_move(struct dlist *source, struct dlist *dest, struct dl_node *target,int direction) { if(target!=NULL) { if(target==source->head) { //not even going to try } else { // take care of head and marker pointers. if(source->marker==target) _dlist_mark_move(source,direction); if(target ==source->head->next) source->head->next=target->next; if(target==source->head->prev) source->head->prev=target->prev; // remove from list if(source->count==1) { target->prev=NULL; target->next=NULL; source->head->next=NULL; source->head->prev=NULL; } else { if(target->prev !=NULL) target->prev->next=target->next; if(target->next !=NULL) target->next->prev=target->prev; target->prev=NULL; target->next=NULL; } source->count--; _dlist_insert_dlnode(dest,target,direction); } } } /* * Insert node containing data after end. */ void dlist_push(Dlist *list,void *data) { list->marker=list->head->prev; dlist_insert(list,data,1); } /* * Insert node containing data at start. */ void dlist_unshift(Dlist *list,void *data) { list->marker=list->head->next; dlist_insert(list,data,0); } void dlist_unshift_sorted(Dlist *list, void *data, int (*sorter)(void *new_elem, void *old_elem)) { if (list->count == 0) dlist_unshift(list, data); else { list->marker=list->head->next; dlist_insert_sorted(list, data, sorter); } } /* * Remove end node from list. * Return pointer to data in removed node. * Null if no nodes. */ void *dlist_pop(Dlist *list) { return(_dlist_remove(list,list->head->prev,0)); } /* * Remove start node from list. * Return pointer to data in removed node. * Null if no nodes. */ void *dlist_shift(Dlist *list) { return(_dlist_remove(list,list->head->next,1)); } /* * destroy the list freeing all memory */ void dlist_destroy(Dlist *list) { if(list !=NULL) { dlist_start(list); dlist_next(list); while (dlist_mark(list)) { dlist_delete(list,1); } free(list); } } /** * Return void pointer to list_data element matching comp function criteria * else null * Does not move the marker. */ void *dlist_find_custom(struct dlist *list, void *target, int (*comp)(void *, void *)) { /* test the comp function on each node */ struct dl_node *nodepointer; dlist_for_each_nomark(list,nodepointer) if(comp(target,nodepointer->data)) return(nodepointer->data); return(NULL); } /** * Apply the node_operation function to each data node in the list */ void dlist_transform(struct dlist *list, void (*node_operation)(void *)) { struct dl_node *nodepointer; dlist_for_each_nomark(list,nodepointer) node_operation(nodepointer->data); } /** * insert new into list in sorted order * sorter function in form int sorter(new,ith) * must return 1 for when new should go before ith * else 0 * return pointer to inserted node * NOTE: assumes list is already sorted */ void *dlist_insert_sorted(struct dlist *list, void *new, int (*sorter)(void *, void *)) { for(dlist_start(list),dlist_next(list); \ list->marker!=list->head && !sorter(new,list->marker->data);dlist_next(list)); return(dlist_insert_before(list,new)); } /* * NOTE: internal use only */ int _dlist_merge(struct dlist *listsource, struct dlist *listdest, unsigned int passcount, int (*compare)(void *, void *)) { struct dl_node *l1head; struct dl_node *l2head; struct dl_node *target; unsigned int l1count=0; unsigned int l2count=0; unsigned int mergecount=0; while(listsource->count>0) { l1head=listsource->head->next; l2head=l1head; while((l1counthead)) { l2head=l2head->next; l1count++; } // so now we have two lists to merge if(l2head==listsource->head) {// l2count l2count=0; } else { l2count=passcount; } while(l1count>0 || l2count>0) { mergecount++; if((l2count>0)&&(l1count>0)) { // we have things to merge int result=compare(l1head->data,l2head->data); if(result>0) { // move from l2 target=l2head; l2head=l2head->next; dlist_move(listsource,listdest,target,1); l2count--; if(l2head==listsource->head) l2count=0; } else { // move from l1 target=l1head; l1head=l1head->next; dlist_move(listsource,listdest,target,1); l1count--; } } else if(l1count>0) { // only have l1 to work with while(l1count>0) { target=l1head; l1head=l1head->next; dlist_move(listsource,listdest,target,1); l1count--; } } else if(l2count>0) { // only have l2 to work with while(l2count>0) { if(l2head==listsource->head) { l2count=0; } else { target=l2head; l2head=l2head->next; dlist_move(listsource,listdest,target,1); l2count--; } } } else { //nothing left and this should be unreachable } } } return(mergecount); } /** * mergesort the list based on compare * compare function in form int sorter(void * a,void * b) * must return >0 for a after b * must return <0 for a before b * else 0 * NOTE: mergesort changes the mark pointer */ void dlist_sort_custom(struct dlist *list, int (*compare)(void *, void *)) { struct dlist *listsource, *listdest, *swap; struct dlist *templist; unsigned int passcount = 1; unsigned int mergecount = 1; if(list->count<2) return; dlist_start(list); templist = dlist_new(list->data_size); templist->del_func = list->del_func; // do nothing if there isn't anything to sort listsource = list; listdest = templist; while(mergecount>0) { mergecount=_dlist_merge(listsource, listdest, passcount, compare); if(mergecount>1) { passcount=passcount*2; //start new pass swap=listsource; listsource=listdest; listdest=swap; } } // now put the input list pointers right // list pointers = newlist pointers // including the forward and next nodes prev and back pointers if(list->count==0) {//copy list->marker = listdest->marker; list->count = listdest->count; list->data_size = listdest->data_size; list->del_func = listdest->del_func; list->head->prev = listdest->head->prev; list->head->next = listdest->head->next; list->head->data = listdest->head->data; list->head->next->prev=list->head; list->head->prev->next=list->head; templist->head->next=NULL; templist->head->prev=NULL; templist->count=0; } else {// no need to copy } dlist_destroy(templist); } /* * The dlist_filter_sort() function scans the list, calling * filter() on each list entry. Entries for which filter() * returns zero are discarded from the list. Then the list is * sorted using mergesort() with the comparison function compare() * and returned. If filter is NULL, all entries are selected. */ void dlist_filter_sort(struct dlist *list, int (*filter) (void *), int (*compare) (void *, void *)) { struct dl_node *nodepointer,*temp; void *data; if(!list->count) return; /* if there is no filter function, directly sort all the entries */ if (!filter) goto sort; /* filter the unwanted entries in the list */ nodepointer = list->head->next; while(nodepointer!=list->head) { if (!filter(nodepointer->data)) { temp = nodepointer->next; data = _dlist_remove(list, nodepointer, 0); if(data) list->del_func(data); nodepointer = temp; } else nodepointer=nodepointer->next; } sort: /* sort out the entries */ dlist_sort_custom(list, compare); } /* internal use function swaps elements a and b No sense in juggling node pointers when we can just swap the data pointers */ void _dlist_swap(__attribute__((unused))struct dlist *list, struct dl_node *a, struct dl_node *b) { void *swap=a->data; a->data=b->data; b->data=swap; } sysfsutils-2.1.1/lib/libsysfs.pc.in000066400000000000000000000003721401370461400173020ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libsysfs Description: interface to Linux sysfs Version: @VERSION@ URL: https://github.com/linux-ras/sysfsutils Libs: -L${libdir} -lsysfs Cflags: -I${includedir} sysfsutils-2.1.1/lib/sysfs.h000066400000000000000000000037711401370461400160410ustar00rootroot00000000000000/* * sysfs.h * * Internal Header Definitions for libsysfs * * Copyright (C) IBM Corp. 2003-2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _SYSFS_H_ #define _SYSFS_H_ #include #include #include #include #include #include #include #include #include extern char *my_strncpy(char *to, const char *from, size_t max); #define safestrcpy(to, from) my_strncpy(to, from, sizeof(to)) #define safestrcpymax(to, from, max) my_strncpy(to, from, max) extern char *my_strncat(char *to, const char *from, size_t max); #define safestrcat(to, from) my_strncat(to, from, sizeof(to) - strlen(to) - 1) #define safestrcatmax(to, from, max) \ do { \ to[max-1] = '\0'; \ strncat(to, from, max - strlen(to)-1); \ } while (0) extern struct sysfs_attribute *get_attribute(void *dev, const char *name); extern struct dlist *read_dir_subdirs(const char *path); extern struct dlist *read_dir_links(const char *path); extern struct dlist *get_dev_attributes_list(void *dev); extern struct dlist *get_attributes_list(struct dlist *alist, const char *path); /* Debugging */ #ifdef DEBUG #define dbg_printf(format, arg...) fprintf(stderr, format, ## arg) #else #define dbg_printf(format, arg...) do { } while (0) #endif #endif /* _SYSFS_H_ */ sysfsutils-2.1.1/lib/sysfs_attr.c000066400000000000000000000370401401370461400170620ustar00rootroot00000000000000/* * sysfs_dir.c * * Directory utility functions for libsysfs * * Copyright (C) IBM Corp. 2003-2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "config.h" #include "libsysfs.h" #include "sysfs.h" static int sort_char(void *new, void *old) { return ((strncmp((char *)new, (char *)old, strlen((char *)new))) < 0 ? 1 : 0); } /** * sysfs_del_name: free function for sysfs_open_subsystem_list * @name: memory area to be freed */ static void sysfs_del_name(void *name) { free(name); } /** * sysfs_del_attribute: routine for dlist integration */ static void sysfs_del_attribute(void *attr) { sysfs_close_attribute((struct sysfs_attribute *)attr); } /** * attr_name_equal: compares attributes by name * @a: attribute name for comparison * @b: sysfs_attribute to be compared. * returns 1 if a==b->name or 0 if not equal */ static int attr_name_equal(void *a, void *b) { if (!a || !b) return 0; if (strcmp(((char *)a), ((struct sysfs_attribute *)b)->name) == 0) return 1; return 0; } /** * sysfs_close_attribute: closes and cleans up attribute * @sysattr: attribute to close. */ void sysfs_close_attribute(struct sysfs_attribute *sysattr) { if (sysattr) { if (sysattr->value) free(sysattr->value); free(sysattr); } } /** * alloc_attribute: allocates and initializes attribute structure * returns struct sysfs_attribute with success and NULL with error. */ static struct sysfs_attribute *alloc_attribute(void) { return (struct sysfs_attribute *) calloc(1, sizeof(struct sysfs_attribute)); } /** * sysfs_open_attribute: creates sysfs_attribute structure * @path: path to attribute. * returns sysfs_attribute struct with success and NULL with error. */ struct sysfs_attribute *sysfs_open_attribute(const char *path) { struct sysfs_attribute *sysattr = NULL; struct stat fileinfo; if (!path) { errno = EINVAL; return NULL; } sysattr = alloc_attribute(); if (!sysattr) { dbg_printf("Error allocating attribute at %s\n", path); return NULL; } if (sysfs_get_name_from_path(path, sysattr->name, SYSFS_NAME_LEN) != 0) { dbg_printf("Error retrieving attrib name from path: %s\n", path); sysfs_close_attribute(sysattr); return NULL; } safestrcpy(sysattr->path, path); if ((stat(sysattr->path, &fileinfo)) != 0) { dbg_printf("Stat failed: No such attribute?\n"); sysattr->method = 0; free(sysattr); sysattr = NULL; } else { if (fileinfo.st_mode & S_IRUSR) sysattr->method |= SYSFS_METHOD_SHOW; if (fileinfo.st_mode & S_IWUSR) sysattr->method |= SYSFS_METHOD_STORE; } return sysattr; } /** * sysfs_read_attribute: reads value from attribute * @sysattr: attribute to read * returns 0 with success and -1 with error. */ int sysfs_read_attribute(struct sysfs_attribute *sysattr) { char *fbuf = NULL; char *vbuf = NULL; ssize_t length = 0; long pgsize = 0; int fd; if (!sysattr) { errno = EINVAL; return -1; } if (!(sysattr->method & SYSFS_METHOD_SHOW)) { dbg_printf("Show method not supported for attribute %s\n", sysattr->path); errno = EACCES; return -1; } pgsize = getpagesize(); fbuf = (char *)calloc(1, pgsize+1); if (!fbuf) { dbg_printf("calloc failed\n"); return -1; } if ((fd = open(sysattr->path, O_RDONLY)) < 0) { dbg_printf("Error reading attribute %s\n", sysattr->path); free(fbuf); return -1; } length = read(fd, fbuf, pgsize); if (length < 0) { dbg_printf("Error reading from attribute %s\n", sysattr->path); close(fd); free(fbuf); return -1; } if (sysattr->len > 0) { if ((sysattr->len == length) && (!(strncmp(sysattr->value, fbuf, length)))) { close(fd); free(fbuf); return 0; } free(sysattr->value); } sysattr->len = length; close(fd); vbuf = (char *)realloc(fbuf, length+1); if (!vbuf) { dbg_printf("realloc failed\n"); free(fbuf); return -1; } sysattr->value = vbuf; return 0; } /** * sysfs_write_attribute: write value to the attribute * @sysattr: attribute to write * @new_value: value to write * @len: length of "new_value" * returns 0 with success and -1 with error. */ int sysfs_write_attribute(struct sysfs_attribute *sysattr, const char *new_value, size_t len) { int fd; int length; if (!sysattr || !new_value || len == 0) { errno = EINVAL; return -1; } if (!(sysattr->method & SYSFS_METHOD_STORE)) { dbg_printf ("Store method not supported for attribute %s\n", sysattr->path); errno = EACCES; return -1; } if (sysattr->method & SYSFS_METHOD_SHOW) { /* * read attribute again to see if we can get an updated value */ if ((sysfs_read_attribute(sysattr))) { dbg_printf("Error reading attribute\n"); return -1; } if ((strncmp(sysattr->value, new_value, sysattr->len)) == 0 && (len == sysattr->len)) { dbg_printf("Attr %s already has the requested value %s\n", sysattr->name, new_value); return 0; } } /* * open O_WRONLY since some attributes have no "read" but only * "write" permission */ if ((fd = open(sysattr->path, O_WRONLY)) < 0) { dbg_printf("Error reading attribute %s\n", sysattr->path); return -1; } length = write(fd, new_value, len); if (length < 0) { dbg_printf("Error writing to the attribute %s - invalid value?\n", sysattr->name); close(fd); return -1; } else if ((unsigned int)length != len) { dbg_printf("Could not write %zd bytes to attribute %s\n", len, sysattr->name); /* * since we could not write user supplied number of bytes, * restore the old value if one available */ if (sysattr->method & SYSFS_METHOD_SHOW) { length = write(fd, sysattr->value, sysattr->len); close(fd); return -1; } } /* * Validate length that has been copied. Alloc appropriate area * in sysfs_attribute. Verify first if the attribute supports reading * (show method). If it does not, do not bother */ if (sysattr->method & SYSFS_METHOD_SHOW) { if (length != sysattr->len) { sysattr->value = (char *)realloc (sysattr->value, length); sysattr->len = length; safestrcpymax(sysattr->value, new_value, length); } else { /*"length" of the new value is same as old one */ safestrcpymax(sysattr->value, new_value, length); } } close(fd); return 0; } /** * add_attribute_to_list: open and add attribute at path to given dlist * @list: dlist attribute is to be added * @path: path to attribute * returns pointer to attr added with success and NULL with error. */ static struct sysfs_attribute *add_attribute_to_list(struct dlist *alist, const char *path) { struct sysfs_attribute *attr; attr = sysfs_open_attribute(path); if (!attr) { dbg_printf("Error opening attribute %s\n", path); return NULL; } if (attr->method & SYSFS_METHOD_SHOW) { if (sysfs_read_attribute(attr)) { dbg_printf("Error reading attribute %s\n", path); sysfs_close_attribute(attr); return NULL; } } if (!alist) { alist = dlist_new_with_delete (sizeof(struct sysfs_attribute), sysfs_del_attribute); } dlist_unshift_sorted(alist, attr, sort_list); return attr; } /** * add_attribute: open and add attribute at path to given directory * @dev: device whose attribute is to be added * @path: path to attribute * returns pointer to attr added with success and NULL with error. */ static struct sysfs_attribute *add_attribute(void *dev, const char *path) { struct sysfs_attribute *attr; attr = sysfs_open_attribute(path); if (!attr) { dbg_printf("Error opening attribute %s\n", path); return NULL; } if (attr->method & SYSFS_METHOD_SHOW) { if (sysfs_read_attribute(attr)) { dbg_printf("Error reading attribute %s\n", path); sysfs_close_attribute(attr); return NULL; } } if (!((struct sysfs_device *)dev)->attrlist) { ((struct sysfs_device *)dev)->attrlist = dlist_new_with_delete (sizeof(struct sysfs_attribute), sysfs_del_attribute); } dlist_unshift_sorted(((struct sysfs_device *)dev)->attrlist, attr, sort_list); return attr; } /* * get_attribute - given a sysfs_* struct and a name, return the * sysfs_attribute corresponding to "name" * returns sysfs_attribute on success and NULL on error */ struct sysfs_attribute *get_attribute(void *dev, const char *name) { struct sysfs_attribute *cur = NULL; char path[SYSFS_PATH_MAX]; if (!dev || !name) { errno = EINVAL; return NULL; } if (((struct sysfs_device *)dev)->attrlist) { /* check if attr is already in the list */ cur = (struct sysfs_attribute *)dlist_find_custom ((((struct sysfs_device *)dev)->attrlist), (void *)name, attr_name_equal); if (cur) return cur; } safestrcpymax(path, ((struct sysfs_device *)dev)->path, SYSFS_PATH_MAX); safestrcatmax(path, "/", SYSFS_PATH_MAX); safestrcatmax(path, name, SYSFS_PATH_MAX); if (!sysfs_path_is_file(path)) cur = add_attribute((void *)dev, path); return cur; } /** * read_dir_links: grabs links in a specific directory * @sysdir: sysfs directory to read * returns list of link names with success and NULL with error. */ struct dlist *read_dir_links(const char *path) { DIR *dir = NULL; struct dirent *dirent = NULL; char file_path[SYSFS_PATH_MAX], *linkname; struct dlist *linklist = NULL; if (!path) { errno = EINVAL; return NULL; } dir = opendir(path); if (!dir) { dbg_printf("Error opening directory %s\n", path); return NULL; } while ((dirent = readdir(dir)) != NULL) { if (0 == strcmp(dirent->d_name, ".")) continue; if (0 == strcmp(dirent->d_name, "..")) continue; memset(file_path, 0, SYSFS_PATH_MAX); safestrcpy(file_path, path); safestrcat(file_path, "/"); safestrcat(file_path, dirent->d_name); if (!sysfs_path_is_link(file_path)) { if (!linklist) { linklist = dlist_new_with_delete (SYSFS_NAME_LEN, sysfs_del_name); if (!linklist) { dbg_printf("Error creating list\n"); return NULL; } } linkname = (char *)calloc(1, SYSFS_NAME_LEN); safestrcpymax(linkname, dirent->d_name, SYSFS_NAME_LEN); dlist_unshift_sorted(linklist, linkname, sort_char); } } closedir(dir); return linklist; } void sysfs_close_dev_tree(void *dev); int add_subdirectory(struct sysfs_device *dev, char *path) { struct sysfs_device *newdev; if (!path) return -1; newdev = sysfs_open_device_path(path); if (newdev == NULL) return -1; if (dev->children == NULL) dev->children = dlist_new_with_delete( sizeof(struct sysfs_device), sysfs_close_dev_tree); dlist_unshift_sorted(dev->children, newdev, sort_list); return 0; } /** * read_dir_subdirs: grabs subdirs in a specific directory * @sysdir: sysfs directory to read * returns list of directory names with success and NULL with error. */ struct sysfs_device *sysfs_read_dir_subdirs(const char *path) { DIR *dir = NULL; struct dirent *dirent = NULL; char file_path[SYSFS_PATH_MAX]; struct sysfs_device *dev = NULL; if (!path) { errno = EINVAL; return NULL; } dev = sysfs_open_device_path(path); dir = opendir(path); if (!dir) { dbg_printf("Error opening directory %s\n", path); return NULL; } while ((dirent = readdir(dir)) != NULL) { if (0 == strcmp(dirent->d_name, ".")) continue; if (0 == strcmp(dirent->d_name, "..")) continue; memset(file_path, 0, SYSFS_PATH_MAX); safestrcpy(file_path, path); safestrcat(file_path, "/"); safestrcat(file_path, dirent->d_name); if (!sysfs_path_is_dir(file_path)) add_subdirectory(dev, file_path); } closedir(dir); return dev; } /** * read_dir_subdirs: grabs subdirs in a specific directory * @sysdir: sysfs directory to read * returns list of directory names with success and NULL with error. */ struct dlist *read_dir_subdirs(const char *path) { DIR *dir = NULL; struct dirent *dirent = NULL; char file_path[SYSFS_PATH_MAX], *dir_name; struct dlist *dirlist = NULL; if (!path) { errno = EINVAL; return NULL; } dir = opendir(path); if (!dir) { dbg_printf("Error opening directory %s\n", path); return NULL; } while ((dirent = readdir(dir)) != NULL) { if (0 == strcmp(dirent->d_name, ".")) continue; if (0 == strcmp(dirent->d_name, "..")) continue; memset(file_path, 0, SYSFS_PATH_MAX); safestrcpy(file_path, path); safestrcat(file_path, "/"); safestrcat(file_path, dirent->d_name); if (!sysfs_path_is_dir(file_path)) { if (!dirlist) { dirlist = dlist_new_with_delete (SYSFS_NAME_LEN, sysfs_del_name); if (!dirlist) { dbg_printf("Error creating list\n"); return NULL; } } dir_name = (char *)calloc(1, SYSFS_NAME_LEN); safestrcpymax(dir_name, dirent->d_name, SYSFS_NAME_LEN); dlist_unshift_sorted(dirlist, dir_name, sort_char); } } closedir(dir); return dirlist; } /** * get_attributes_list: build a list of attributes for the given path * @path: grab attributes at the given path * returns dlist of attributes on success and NULL on failure */ struct dlist *get_attributes_list(struct dlist *alist, const char *path) { DIR *dir = NULL; struct dirent *dirent = NULL; char file_path[SYSFS_PATH_MAX]; if (!path) { errno = EINVAL; return NULL; } dir = opendir(path); if (!dir) { dbg_printf("Error opening directory %s\n", path); return NULL; } while ((dirent = readdir(dir)) != NULL) { if (0 == strcmp(dirent->d_name, ".")) continue; if (0 == strcmp(dirent->d_name, "..")) continue; memset(file_path, 0, SYSFS_PATH_MAX); safestrcpy(file_path, path); safestrcat(file_path, "/"); safestrcat(file_path, dirent->d_name); if (!sysfs_path_is_file(file_path)) { if (!alist) { alist = dlist_new_with_delete (sizeof(struct sysfs_attribute), sysfs_del_attribute); if (!alist) { dbg_printf("Error creating list\n"); return NULL; } } add_attribute_to_list(alist, file_path); } } closedir(dir); return alist; } /** * get_dev_attributes_list: build a list of attributes for the given device * @dev: devices whose attributes list is required * returns dlist of attributes on success and NULL on failure */ struct dlist *get_dev_attributes_list(void *dev) { DIR *dir = NULL; struct dirent *dirent = NULL; struct sysfs_attribute *attr = NULL; char file_path[SYSFS_PATH_MAX], path[SYSFS_PATH_MAX]; if (!dev) { errno = EINVAL; return NULL; } memset(path, 0, SYSFS_PATH_MAX); safestrcpy(path, ((struct sysfs_device *)dev)->path); dir = opendir(path); if (!dir) { dbg_printf("Error opening directory %s\n", path); return NULL; } while ((dirent = readdir(dir)) != NULL) { if (0 == strcmp(dirent->d_name, ".")) continue; if (0 == strcmp(dirent->d_name, "..")) continue; memset(file_path, 0, SYSFS_PATH_MAX); safestrcpy(file_path, path); safestrcat(file_path, "/"); safestrcat(file_path, dirent->d_name); if (!sysfs_path_is_file(file_path)) { if (((struct sysfs_device *)dev)->attrlist) { /* check if attr is already in the list */ attr = (struct sysfs_attribute *) dlist_find_custom ((((struct sysfs_device *)dev)->attrlist), (void *)dirent->d_name, attr_name_equal); if (attr) continue; else add_attribute(dev, file_path); } else attr = add_attribute(dev, file_path); } } closedir(dir); return ((struct sysfs_device *)dev)->attrlist; } sysfsutils-2.1.1/lib/sysfs_bus.c000066400000000000000000000172121401370461400167000ustar00rootroot00000000000000/* * sysfs_bus.c * * Generic bus utility functions for libsysfs * * Copyright (C) IBM Corp. 2003-2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "config.h" #include "libsysfs.h" #include "sysfs.h" static void sysfs_close_dev(void *dev) { sysfs_close_device((struct sysfs_device *)dev); } static void sysfs_close_drv(void *drv) { sysfs_close_driver((struct sysfs_driver *)drv); } /* * compares names. * @a: name looked for * @b: sysfs_device comparing being compared * returns 1 if a==b->name or 0 not equal */ static int name_equal(void *a, void *b) { if (!a || !b) return 0; if (strcmp(((char *)a), ((struct sysfs_device *)b)->name) == 0) return 1; return 0; } /** * sysfs_close_bus: close single bus * @bus: bus structure */ void sysfs_close_bus(struct sysfs_bus *bus) { if (bus) { if (bus->attrlist) dlist_destroy(bus->attrlist); if (bus->devices) dlist_destroy(bus->devices); if (bus->drivers) dlist_destroy(bus->drivers); free(bus); } } /** * alloc_bus: mallocs new bus structure * returns sysfs_bus_bus struct or NULL */ static struct sysfs_bus *alloc_bus(void) { return (struct sysfs_bus *)calloc(1, sizeof(struct sysfs_bus)); } /** * sysfs_get_bus_devices: gets all devices for bus * @bus: bus to get devices for * returns dlist of devices with success and NULL with failure */ struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus) { struct sysfs_device *dev; struct dlist *linklist; char path[SYSFS_PATH_MAX], devpath[SYSFS_PATH_MAX]; char target[SYSFS_PATH_MAX]; char *curlink; if (!bus) { errno = EINVAL; return NULL; } memset(path, 0, SYSFS_PATH_MAX); safestrcpy(path, bus->path); safestrcat(path, "/"); safestrcat(path, SYSFS_DEVICES_NAME); linklist = read_dir_links(path); if (linklist) { dlist_for_each_data(linklist, curlink, char) { if (bus->devices) { dev = (struct sysfs_device *) dlist_find_custom(bus->devices, (void *)curlink, name_equal); if (dev) continue; } safestrcpy(devpath, path); safestrcat(devpath, "/"); safestrcat(devpath, curlink); if (sysfs_get_link(devpath, target, SYSFS_PATH_MAX)) { dbg_printf("Error getting link - %s\n", devpath); continue; } dev = sysfs_open_device_path(target); if (!dev) { dbg_printf("Error opening device at %s\n", target); continue; } if (!bus->devices) bus->devices = dlist_new_with_delete (sizeof(struct sysfs_device), sysfs_close_dev); dlist_unshift_sorted(bus->devices, dev, sort_list); } sysfs_close_list(linklist); } return (bus->devices); } /** * sysfs_get_bus_drivers: gets all drivers for bus * @bus: bus to get devices for * returns dlist of devices with success and NULL with failure */ struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus) { struct sysfs_driver *drv; struct dlist *dirlist; char path[SYSFS_PATH_MAX], drvpath[SYSFS_PATH_MAX]; char *curdir; if (!bus) { errno = EINVAL; return NULL; } memset(path, 0, SYSFS_PATH_MAX); safestrcpy(path, bus->path); safestrcat(path, "/"); safestrcat(path, SYSFS_DRIVERS_NAME); dirlist = read_dir_subdirs(path); if (dirlist) { dlist_for_each_data(dirlist, curdir, char) { if (bus->drivers) { drv = (struct sysfs_driver *) dlist_find_custom(bus->drivers, (void *)curdir, name_equal); if (drv) continue; } safestrcpy(drvpath, path); safestrcat(drvpath, "/"); safestrcat(drvpath, curdir); drv = sysfs_open_driver_path(drvpath); if (!drv) { dbg_printf("Error opening driver at %s\n", drvpath); continue; } if (!bus->drivers) bus->drivers = dlist_new_with_delete (sizeof(struct sysfs_driver), sysfs_close_drv); dlist_unshift_sorted(bus->drivers, drv, sort_list); } sysfs_close_list(dirlist); } return (bus->drivers); } /** * sysfs_open_bus: opens specific bus and all its devices on system * returns sysfs_bus structure with success or NULL with error. */ struct sysfs_bus *sysfs_open_bus(const char *name) { struct sysfs_bus *bus; char buspath[SYSFS_PATH_MAX]; if (!name) { errno = EINVAL; return NULL; } memset(buspath, 0, SYSFS_PATH_MAX); if (sysfs_get_mnt_path(buspath, SYSFS_PATH_MAX)) { dbg_printf("Sysfs not supported on this system\n"); return NULL; } safestrcat(buspath, "/"); safestrcat(buspath, SYSFS_BUS_NAME); safestrcat(buspath, "/"); safestrcat(buspath, name); if (sysfs_path_is_dir(buspath)) { dbg_printf("Invalid path to bus: %s\n", buspath); return NULL; } bus = alloc_bus(); if (!bus) { dbg_printf("calloc failed\n"); return NULL; } safestrcpy(bus->name, name); safestrcpy(bus->path, buspath); if (sysfs_remove_trailing_slash(bus->path)) { dbg_printf("Incorrect path to bus %s\n", bus->path); sysfs_close_bus(bus); return NULL; } return bus; } /** * sysfs_get_bus_device: Get specific device on bus using device's id * @bus: bus to find device on * @id: bus_id for device * returns struct sysfs_device reference or NULL if not found. */ struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, const char *id) { struct sysfs_device *dev = NULL; char devpath[SYSFS_PATH_MAX], target[SYSFS_PATH_MAX]; if (!bus || !id) { errno = EINVAL; return NULL; } if (bus->devices) { dev = (struct sysfs_device *)dlist_find_custom (bus->devices, (void *)id, name_equal); if (dev) return dev; } safestrcpy(devpath, bus->path); safestrcat(devpath, "/"); safestrcat(devpath, SYSFS_DEVICES_NAME); safestrcat(devpath, "/"); safestrcat(devpath, id); if (sysfs_path_is_link(devpath)) { dbg_printf("No such device %s on bus %s?\n", id, bus->name); return NULL; } if (!sysfs_get_link(devpath, target, SYSFS_PATH_MAX)) { dev = sysfs_open_device_path(target); if (!dev) { dbg_printf("Error opening device at %s\n", target); return NULL; } if (!bus->devices) bus->devices = dlist_new_with_delete (sizeof(struct sysfs_device), sysfs_close_dev); dlist_unshift_sorted(bus->devices, dev, sort_list); } return dev; } /** * sysfs_get_bus_driver: Get specific driver on bus using driver name * @bus: bus to find driver on * @drvname: name of driver * returns struct sysfs_driver reference or NULL if not found. */ struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus, const char *drvname) { struct sysfs_driver *drv; char drvpath[SYSFS_PATH_MAX]; if (!bus || !drvname) { errno = EINVAL; return NULL; } if (bus->drivers) { drv = (struct sysfs_driver *)dlist_find_custom (bus->drivers, (void *)drvname, name_equal); if (drv) return drv; } safestrcpy(drvpath, bus->path); safestrcat(drvpath, "/"); safestrcat(drvpath, SYSFS_DRIVERS_NAME); safestrcat(drvpath, "/"); safestrcat(drvpath, drvname); drv = sysfs_open_driver_path(drvpath); if (!drv) { dbg_printf("Error opening driver at %s\n", drvpath); return NULL; } if (!bus->drivers) bus->drivers = dlist_new_with_delete (sizeof(struct sysfs_driver), sysfs_close_drv); dlist_unshift_sorted(bus->drivers, drv, sort_list); return drv; } sysfsutils-2.1.1/lib/sysfs_class.c000066400000000000000000000327761401370461400172300ustar00rootroot00000000000000/* * sysfs_class.c * * Generic class utility functions for libsysfs * * Copyright (C) IBM Corp. 2003-2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "config.h" #include "libsysfs.h" #include "sysfs.h" /** * sysfs_close_class_device: closes a single class device. * @dev: class device to close. */ void sysfs_close_class_device(struct sysfs_class_device *dev) { if (dev) { if (dev->parent) sysfs_close_class_device(dev->parent); if (dev->sysdevice) sysfs_close_device(dev->sysdevice); if (dev->attrlist) dlist_destroy(dev->attrlist); free(dev); } } static void sysfs_close_cls_dev(void *dev) { sysfs_close_class_device((struct sysfs_class_device *)dev); } /** * sysfs_close_class: close the given class * @cls: sysfs_class to close */ void sysfs_close_class(struct sysfs_class *cls) { if (cls) { if (cls->devices) dlist_destroy(cls->devices); if (cls->attrlist) dlist_destroy(cls->attrlist); free(cls); } } /* * pass this function to dlist_find_custom() * so it can compare device names * * return 1 if pathnames are equal, else 0 */ static int cdev_name_equal(void *a, void *b) { char *str_a, *str_b; if (!a || !b) return 0; str_a = (char *)a; str_b = ((struct sysfs_class_device *)b)->name; if (strncmp(str_a, str_b, SYSFS_NAME_LEN) == 0) return 1; return 0; } static struct sysfs_class *alloc_class(void) { return (struct sysfs_class *) calloc(1, sizeof(struct sysfs_class)); } /** * alloc_class_device: mallocs and initializes new class device struct. * returns sysfs_class_device or NULL. */ static struct sysfs_class_device *alloc_class_device(void) { struct sysfs_class_device *dev; dev = calloc(1, sizeof(struct sysfs_class_device)); return dev; } /** * set_classdev_classname: Grabs classname from path * @cdev: class device to set * Returns nothing */ static void set_classdev_classname(struct sysfs_class_device *cdev) { char *c, *e, name[SYSFS_PATH_MAX], link[SYSFS_PATH_MAX]; struct stat stats; int count = 0; /* * Newer driver core changes have a class:class_device representation. * Check if this cdev belongs to the newer style subsystem and * set the classname appropriately. */ memset(name, 0, SYSFS_PATH_MAX); safestrcpy(name, cdev->name); c = strchr(name, ':'); if (c) { safestrcpy(cdev->name, c+1); *c = '\0'; safestrcpy(cdev->classname, name); return; } c = strstr(cdev->path, SYSFS_CLASS_NAME); if (c == NULL) c = strstr(cdev->path, SYSFS_BLOCK_NAME); else c = strstr(c, "/"); if (c) { if (*c == '/') c++; e = c; while (e != NULL && *e != '/' && *e != '\0') { e++; count++; } strncpy(cdev->classname, c, count); } else { strcpy(link, cdev->path); strcat(link, "/subsystem"); sysfs_get_link(link, name, SYSFS_PATH_MAX); if (lstat(name, &stats)) safestrcpy(cdev->classname, SYSFS_UNKNOWN); else { c = strrchr(name, '/'); if (c) safestrcpy(cdev->classname, c+1); else safestrcpy(cdev->classname, SYSFS_UNKNOWN); } } } /** * sysfs_open_class_device_path: Opens and populates class device * @path: path to class device. * returns struct sysfs_class_device with success and NULL with error. */ struct sysfs_class_device *sysfs_open_class_device_path(const char *path) { struct sysfs_class_device *cdev; char temp_path[SYSFS_PATH_MAX]; if (!path) { errno = EINVAL; return NULL; } /* * Post linux-2.6.14 driver model supports nested classes with * links to the nested hierarchy at /sys/class/xxx/. Check for * a link to the actual class device if a directory isn't found */ if (sysfs_path_is_dir(path)) { dbg_printf("%s: Directory not found, checking for a link\n", path); if (!sysfs_path_is_link(path)) { if (sysfs_get_link(path, temp_path, SYSFS_PATH_MAX)) { dbg_printf("Error retrieving link at %s\n", path); return NULL; } } else { dbg_printf("%s is not a valid class device path\n", path); return NULL; } } else safestrcpy(temp_path, path); cdev = alloc_class_device(); if (!cdev) { dbg_printf("calloc failed\n"); return NULL; } if (sysfs_get_name_from_path(temp_path, cdev->name, SYSFS_NAME_LEN)) { errno = EINVAL; dbg_printf("Error getting class device name\n"); sysfs_close_class_device(cdev); return NULL; } safestrcpy(cdev->path, temp_path); if (sysfs_remove_trailing_slash(cdev->path)) { dbg_printf("Invalid path to class device %s\n", cdev->path); sysfs_close_class_device(cdev); return NULL; } set_classdev_classname(cdev); return cdev; } /** * sysfs_get_classdev_parent: Retrieves the parent of a class device. * eg., when working with hda1, this function can be used to retrieve the * sysfs_class_device for hda * * @clsdev: class device whose parent details are required. * Returns sysfs_class_device of the parent on success, NULL on failure */ struct sysfs_class_device *sysfs_get_classdev_parent (struct sysfs_class_device *clsdev) { char abs_path[SYSFS_PATH_MAX], tmp_path[SYSFS_PATH_MAX]; char *c; if (!clsdev) { errno = EINVAL; return NULL; } if (clsdev->parent) return (clsdev->parent); memset(abs_path, 0, SYSFS_PATH_MAX); memset(tmp_path, 0, SYSFS_PATH_MAX); safestrcpy(tmp_path, clsdev->path); c = strstr(tmp_path, clsdev->classname); c = strchr(c, '/'); *c = '\0'; safestrcpy(abs_path, clsdev->path); c = strrchr(abs_path, '/'); *c = '\0'; if ((strncmp(tmp_path, abs_path, strlen(abs_path))) == 0) { dbg_printf("Class device %s doesn't have a parent\n", clsdev->name); return NULL; } clsdev->parent = sysfs_open_class_device_path(abs_path); return clsdev->parent; } /** * get_classdev_path: given the class and a device in the class, return the * absolute path to the device * @classname: name of the class * @clsdev: the class device * @path: buffer to return path * @psize: size of "path" * Returns 0 on SUCCESS or -1 on error */ static int get_classdev_path(const char *classname, const char *clsdev, char *path, size_t len) { char *c; if (!classname || !clsdev || !path) { errno = EINVAL; return -1; } if (sysfs_get_mnt_path(path, len) != 0) { dbg_printf("Error getting sysfs mount path\n"); return -1; } safestrcatmax(path, "/", len); if (strncmp(classname, SYSFS_BLOCK_NAME, sizeof(SYSFS_BLOCK_NAME)) == 0) { safestrcatmax(path, SYSFS_BLOCK_NAME, len); if (!sysfs_path_is_dir(path)) goto done; c = strrchr(path, '/'); *(c+1) = '\0'; } safestrcatmax(path, SYSFS_CLASS_NAME, len); safestrcatmax(path, "/", len); safestrcatmax(path, classname, len); done: safestrcatmax(path, "/", len); safestrcatmax(path, clsdev, len); return 0; } /** * sysfs_open_class_device: Locates a specific class_device and returns it. * Class_device must be closed using sysfs_close_class_device * @classname: Class to search * @name: name of the class_device * * NOTE: * Call sysfs_close_class_device() to close the class device */ struct sysfs_class_device *sysfs_open_class_device (const char *classname, const char *name) { char devpath[SYSFS_PATH_MAX]; struct sysfs_class_device *cdev; if (!classname || !name) { errno = EINVAL; return NULL; } memset(devpath, 0, SYSFS_PATH_MAX); if ((get_classdev_path(classname, name, devpath, SYSFS_PATH_MAX)) != 0) { dbg_printf("Error getting to device %s on class %s\n", name, classname); return NULL; } cdev = sysfs_open_class_device_path(devpath); if (!cdev) { dbg_printf("Error getting class device %s from class %s\n", name, classname); return NULL; } return cdev; } /** * sysfs_get_classdev_attr: searches class device's attributes by name * @clsdev: class device to look through * @name: attribute name to get * returns sysfs_attribute reference with success or NULL with error */ struct sysfs_attribute *sysfs_get_classdev_attr (struct sysfs_class_device *clsdev, const char *name) { if (!clsdev || !name) { errno = EINVAL; return NULL; } return get_attribute(clsdev, (char *)name); } /** * sysfs_get_classdev_attributes: gets list of classdev attributes * @clsdev: class device whose attributes list is needed * returns dlist of attributes on success or NULL on error */ struct dlist *sysfs_get_classdev_attributes(struct sysfs_class_device *clsdev) { if (!clsdev) { errno = EINVAL; return NULL; } return get_dev_attributes_list(clsdev); } /** * sysfs_get_classdev_device: gets the sysfs_device associated with the * given sysfs_class_device * @clsdev: class device whose associated sysfs_device is needed * returns struct sysfs_device * on success or NULL on error */ struct sysfs_device *sysfs_get_classdev_device (struct sysfs_class_device *clsdev) { char linkpath[SYSFS_PATH_MAX], devpath[SYSFS_PATH_MAX]; if (!clsdev) { errno = EINVAL; return NULL; } if (clsdev->sysdevice) return clsdev->sysdevice; memset(linkpath, 0, SYSFS_PATH_MAX); safestrcpy(linkpath, clsdev->path); safestrcat(linkpath, "/device"); if (!sysfs_path_is_link(linkpath)) { memset(devpath, 0, SYSFS_PATH_MAX); if (!sysfs_get_link(linkpath, devpath, SYSFS_PATH_MAX)) clsdev->sysdevice = sysfs_open_device_path(devpath); } return clsdev->sysdevice; } /** * sysfs_open_class: opens specific class and all its devices on system * returns sysfs_class structure with success or NULL with error. */ struct sysfs_class *sysfs_open_class(const char *name) { struct sysfs_class *cls = NULL; char *c, classpath[SYSFS_PATH_MAX]; if (!name) { errno = EINVAL; return NULL; } memset(classpath, 0, SYSFS_PATH_MAX); if ((sysfs_get_mnt_path(classpath, SYSFS_PATH_MAX)) != 0) { dbg_printf("Sysfs not supported on this system\n"); return NULL; } safestrcat(classpath, "/"); if (strcmp(name, SYSFS_BLOCK_NAME) == 0) { safestrcat(classpath, SYSFS_BLOCK_NAME); if (!sysfs_path_is_dir(classpath)) goto done; c = strrchr(classpath, '/'); *(c+1) = '\0'; } safestrcat(classpath, SYSFS_CLASS_NAME); safestrcat(classpath, "/"); safestrcat(classpath, name); done: if (sysfs_path_is_dir(classpath)) { dbg_printf("Class %s not found on the system\n", name); return NULL; } cls = alloc_class(); if (cls == NULL) { dbg_printf("calloc failed\n"); return NULL; } safestrcpy(cls->name, name); safestrcpy(cls->path, classpath); if ((sysfs_remove_trailing_slash(cls->path)) != 0) { dbg_printf("Invalid path to class device %s\n", cls->path); sysfs_close_class(cls); return NULL; } return cls; } /** * sysfs_get_class_device: get specific class device using the device's id * @cls: sysfs_class to find the device on * @name: name of the class device to look for * * Returns sysfs_class_device * on success and NULL on failure */ struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *cls, const char *name) { char path[SYSFS_PATH_MAX]; struct sysfs_class_device *cdev = NULL; if (!cls || !name) { errno = EINVAL; return NULL; } if (cls->devices) { cdev = (struct sysfs_class_device *)dlist_find_custom (cls->devices, (void *)name, cdev_name_equal); if (cdev) return cdev; } safestrcpy(path, cls->path); safestrcat(path, "/"); safestrcat(path, name); cdev = sysfs_open_class_device_path(path); if (!cdev) { dbg_printf("Error opening class device at %s\n", path); return NULL; } if (!cls->devices) cls->devices = dlist_new_with_delete (sizeof(struct sysfs_class_device), sysfs_close_cls_dev); dlist_unshift_sorted(cls->devices, cdev, sort_list); return cdev; } /** * Add class devices to list */ static void add_cdevs_to_classlist(struct sysfs_class *cls, struct dlist *list) { char path[SYSFS_PATH_MAX], *cdev_name; struct sysfs_class_device *cdev = NULL; if (cls == NULL || list == NULL) return; dlist_for_each_data(list, cdev_name, char) { if (cls->devices) { cdev = (struct sysfs_class_device *) dlist_find_custom(cls->devices, (void *)cdev_name, cdev_name_equal); if (cdev) continue; } safestrcpy(path, cls->path); safestrcat(path, "/"); safestrcat(path, cdev_name); cdev = sysfs_open_class_device_path(path); if (cdev) { if (!cls->devices) cls->devices = dlist_new_with_delete (sizeof(struct sysfs_class_device), sysfs_close_cls_dev); dlist_unshift_sorted(cls->devices, cdev, sort_list); } } } /** * sysfs_get_class_devices: get all class devices in the given class * @cls: sysfs_class whose devices list is needed * * Returns a dlist of sysfs_class_device * on success and NULL on failure */ struct dlist *sysfs_get_class_devices(struct sysfs_class *cls) { char path[SYSFS_PATH_MAX]; struct dlist *dirlist, *linklist; if (!cls) { errno = EINVAL; return NULL; } /* * Post linux-2.6.14, we have nested classes and links under * /sys/class/xxx/. are also valid class devices */ safestrcpy(path, cls->path); dirlist = read_dir_subdirs(path); if (dirlist) { add_cdevs_to_classlist(cls, dirlist); sysfs_close_list(dirlist); } linklist = read_dir_links(path); if (linklist) { add_cdevs_to_classlist(cls, linklist); sysfs_close_list(linklist); } return cls->devices; } sysfsutils-2.1.1/lib/sysfs_device.c000066400000000000000000000255531401370461400173550ustar00rootroot00000000000000/* * sysfs_device.c * * Generic device utility functions for libsysfs * * Copyright (C) IBM Corp. 2003-2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "config.h" #include "libsysfs.h" #include "sysfs.h" /** * get_dev_driver: fills in the dev->driver_name field * Returns 0 on SUCCESS and -1 on error */ static int get_dev_driver(struct sysfs_device *dev) { char path[SYSFS_PATH_MAX], devpath[SYSFS_PATH_MAX]; if (!dev) { errno = EINVAL; return -1; } memset(path, 0, SYSFS_PATH_MAX); memset(devpath, 0, SYSFS_PATH_MAX); safestrcpymax(path, dev->path, SYSFS_PATH_MAX); safestrcatmax(path, "/driver", SYSFS_PATH_MAX); if (!sysfs_path_is_link(path)) { if (!sysfs_get_link(path, devpath, SYSFS_PATH_MAX)) { if (!sysfs_get_name_from_path(devpath, dev->driver_name, SYSFS_NAME_LEN)) return 0; } } return -1; } /** * sysfs_get_device_bus: retrieves the bus name the device is on, checks path * to bus' link to make sure it has correct device. * @dev: device to get busname. * returns 0 with success and -1 with error. */ int sysfs_get_device_bus(struct sysfs_device *dev) { char devpath[SYSFS_PATH_MAX], path[SYSFS_PATH_MAX]; if (!dev) { errno = EINVAL; return -1; } memset(path, 0, SYSFS_PATH_MAX); memset(devpath, 0, SYSFS_PATH_MAX); safestrcpymax(path, dev->path, SYSFS_PATH_MAX); safestrcatmax(path, "/bus", SYSFS_PATH_MAX); if (!sysfs_path_is_link(path)) { if (!sysfs_get_link(path, devpath, SYSFS_PATH_MAX)) { if (!sysfs_get_name_from_path(devpath, dev->bus, SYSFS_NAME_LEN)) return 0; } } return -1; } /** * get_dev_subsystem: fills in the dev->subsystem field * Returns 0 on SUCCESS and -1 on error */ static int get_dev_subsystem(struct sysfs_device *dev) { char path[SYSFS_PATH_MAX], devpath[SYSFS_PATH_MAX]; if (!dev) { errno = EINVAL; return -1; } memset(path, 0, SYSFS_PATH_MAX); memset(devpath, 0, SYSFS_PATH_MAX); safestrcpymax(path, dev->path, SYSFS_PATH_MAX); safestrcatmax(path, "/subsystem", SYSFS_PATH_MAX); if (!sysfs_path_is_link(path)) { if (!sysfs_get_link(path, devpath, SYSFS_PATH_MAX)) { if (!sysfs_get_name_from_path(devpath, dev->subsystem, SYSFS_NAME_LEN)) return 0; } } return -1; } /** * sysfs_close_dev_tree: routine for dlist integration */ void sysfs_close_dev_tree(void *dev) { sysfs_close_device_tree((struct sysfs_device *)dev); } /** * sysfs_close_device_tree: closes every device in the supplied tree, * closing children only. * @devroot: device root of tree. */ void sysfs_close_device_tree(struct sysfs_device *devroot) { if (devroot) { if (devroot->children) { struct sysfs_device *child = NULL; dlist_for_each_data(devroot->children, child, struct sysfs_device) sysfs_close_device_tree(child); } devroot->children = NULL; sysfs_close_device(devroot); } } /** * sysfs_close_device: closes and cleans up a device * @dev = device to clean up */ void sysfs_close_device(struct sysfs_device *dev) { if (dev) { if (dev->parent) sysfs_close_device(dev->parent); if (dev->children && dev->children->count) dlist_destroy(dev->children); if (dev->attrlist) dlist_destroy(dev->attrlist); free(dev); } } /** * alloc_device: allocates and initializes device structure * returns struct sysfs_device */ static struct sysfs_device *alloc_device(void) { return (struct sysfs_device *) calloc(1, sizeof(struct sysfs_device)); } /** * sysfs_open_device_path: opens and populates device structure * @path: path to device, this is the /sys/devices/ path * returns sysfs_device structure with success or NULL with error */ struct sysfs_device *sysfs_open_device_path(const char *path) { struct sysfs_device *dev; if (!path) { errno = EINVAL; return NULL; } if (sysfs_path_is_dir(path)) { dbg_printf("Incorrect path to device: %s\n", path); return NULL; } dev = alloc_device(); if (!dev) { dbg_printf("Error allocating device at %s\n", path); return NULL; } if (sysfs_get_name_from_path(path, dev->bus_id, SYSFS_NAME_LEN)) { errno = EINVAL; dbg_printf("Error getting device bus_id\n"); sysfs_close_device(dev); return NULL; } safestrcpy(dev->path, path); if (sysfs_remove_trailing_slash(dev->path)) { dbg_printf("Invalid path to device %s\n", dev->path); sysfs_close_device(dev); return NULL; } /* * The "name" attribute no longer exists... return the device's * sysfs representation instead, in the "dev->name" field, which * implies that the dev->name and dev->bus_id contain same data. */ safestrcpy(dev->name, dev->bus_id); if (sysfs_get_device_bus(dev)) dbg_printf("Could not get device bus\n"); if (get_dev_driver(dev)) { dbg_printf("Could not get device %s's driver\n", dev->bus_id); safestrcpy(dev->driver_name, SYSFS_UNKNOWN); } if (get_dev_subsystem(dev)) { dbg_printf("Could not get device %s's subsystem\n", dev->bus_id); safestrcpy(dev->subsystem, SYSFS_UNKNOWN); } return dev; } /** * sysfs_open_device_tree: opens root device and all of its children, * creating a tree of devices. Only opens children. * @path: sysfs path to devices * returns struct sysfs_device and its children with success or NULL with * error. */ struct sysfs_device *sysfs_open_device_tree(const char *path) { struct sysfs_device *rootdev = NULL, *new = NULL; struct sysfs_device *cur = NULL; struct sysfs_device *devlist; if (path == NULL) { errno = EINVAL; return NULL; } rootdev = sysfs_open_device_path(path); if (rootdev == NULL) { dbg_printf("Error opening root device at %s\n", path); return NULL; } devlist = sysfs_read_dir_subdirs(path); if (devlist->children) { dlist_for_each_data(devlist->children, cur, struct sysfs_device) { new = sysfs_open_device_tree(cur->path); if (new == NULL) { dbg_printf("Error opening device tree at %s\n", cur->path); sysfs_close_device_tree(rootdev); return NULL; } if (rootdev->children == NULL) rootdev->children = dlist_new_with_delete (sizeof(struct sysfs_device), sysfs_close_dev_tree); dlist_unshift_sorted(rootdev->children, new, sort_list); } } return rootdev; } /** * sysfs_get_device_attr: searches dev's attributes by name * @dev: device to look through * @name: attribute name to get * returns sysfs_attribute reference with success or NULL with error. */ struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev, const char *name) { if (!dev || !name) { errno = EINVAL; return NULL; } return get_attribute(dev, (char *)name); } /** * sysfs_get_device_attributes: gets list of device attributes * @dev: device whose attributes list is needed * returns dlist of attributes on success or NULL on error */ struct dlist *sysfs_get_device_attributes(struct sysfs_device *dev) { if (!dev) { errno = EINVAL; return NULL; } return get_dev_attributes_list(dev); } /** * get_device_absolute_path: looks up the bus the device is on, gets * absolute path to the device * @device: device for which path is needed * @path: buffer to store absolute path * @psize: size of "path" * Returns 0 on success -1 on failure */ static int get_device_absolute_path(const char *device, const char *bus, char *path, size_t psize) { char bus_path[SYSFS_PATH_MAX]; if (!device || !path) { errno = EINVAL; return -1; } memset(bus_path, 0, SYSFS_PATH_MAX); if (sysfs_get_mnt_path(bus_path, SYSFS_PATH_MAX)) { dbg_printf ("Sysfs not supported on this system\n"); return -1; } safestrcat(bus_path, "/"); safestrcat(bus_path, SYSFS_BUS_NAME); safestrcat(bus_path, "/"); safestrcat(bus_path, bus); safestrcat(bus_path, "/"); safestrcat(bus_path, SYSFS_DEVICES_NAME); safestrcat(bus_path, "/"); safestrcat(bus_path, device); /* * We now are at /sys/bus/"bus_name"/devices/"device" which is a link. * Now read this link to reach to the device. */ if (sysfs_get_link(bus_path, path, psize)) { dbg_printf("Error getting to device %s\n", device); return -1; } return 0; } /** * sysfs_open_device: open a device by id (use the "bus" subsystem) * @bus: bus the device belongs to * @bus_id: bus_id of the device to open - has to be the "bus_id" in * /sys/bus/xxx/devices * returns struct sysfs_device if found, NULL otherwise * NOTE: * 1. Use sysfs_close_device to close the device * 2. Bus the device is on must be supplied * Use sysfs_find_device_bus to get the bus name */ struct sysfs_device *sysfs_open_device(const char *bus, const char *bus_id) { char sysfs_path[SYSFS_PATH_MAX]; struct sysfs_device *device; if (!bus_id || !bus) { errno = EINVAL; return NULL; } memset(sysfs_path, 0, SYSFS_PATH_MAX); if (get_device_absolute_path(bus_id, bus, sysfs_path, SYSFS_PATH_MAX)) { dbg_printf("Error getting to device %s\n", bus_id); return NULL; } device = sysfs_open_device_path(sysfs_path); if (!device) { dbg_printf("Error opening device %s\n", bus_id); return NULL; } return device; } /** * sysfs_get_device_parent: opens up given device's parent and returns a * reference to its sysfs_device * @dev: sysfs_device whose parent is requested * Returns sysfs_device of the parent on success and NULL on failure */ struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev) { char ppath[SYSFS_PATH_MAX], dpath[SYSFS_PATH_MAX], *tmp; if (!dev) { errno = EINVAL; return NULL; } if (dev->parent) return (dev->parent); memset(ppath, 0, SYSFS_PATH_MAX); memset(dpath, 0, SYSFS_PATH_MAX); safestrcpy(ppath, dev->path); tmp = strrchr(ppath, '/'); if (!tmp) { dbg_printf("Invalid path to device %s\n", ppath); return NULL; } if (*(tmp + 1) == '\0') { *tmp = '\0'; tmp = strrchr(tmp, '/'); if (tmp == NULL) { dbg_printf("Invalid path to device %s\n", ppath); return NULL; } } *tmp = '\0'; /* Make sure we're at the top of the device tree */ if (sysfs_get_mnt_path(dpath, SYSFS_PATH_MAX) != 0) { dbg_printf("Sysfs not supported on this system\n"); return NULL; } safestrcat(dpath, "/"); safestrcat(dpath, SYSFS_DEVICES_NAME); if (strcmp(dpath, ppath) == 0) { dbg_printf("Device at %s does not have a parent\n", dev->path); return NULL; } dev->parent = sysfs_open_device_path(ppath); if (!dev->parent) { dbg_printf("Error opening device %s's parent at %s\n", dev->bus_id, ppath); return NULL; } return (dev->parent); } sysfsutils-2.1.1/lib/sysfs_driver.c000066400000000000000000000162641401370461400174100ustar00rootroot00000000000000/* * sysfs_driver.c * * Driver utility functions for libsysfs * * Copyright (C) IBM Corp. 2003-2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "config.h" #include "libsysfs.h" #include "sysfs.h" static void sysfs_close_driver_device(void *device) { sysfs_close_device((struct sysfs_device *)device); } /** * sysfs_close_driver: closes driver and deletes device lists too * @driver: driver to close */ void sysfs_close_driver(struct sysfs_driver *driver) { if (driver) { if (driver->devices) dlist_destroy(driver->devices); if (driver->attrlist) dlist_destroy(driver->attrlist); if (driver->module) sysfs_close_module(driver->module); free(driver); } } /** * alloc_driver: allocates and initializes driver * returns struct sysfs_driver with success and NULL with error. */ static struct sysfs_driver *alloc_driver(void) { return (struct sysfs_driver *)calloc(1, sizeof(struct sysfs_driver)); } /** * get_driver_bus: gets bus the driver is on * Returns 0 on success and 1 on error */ static int get_driver_bus(struct sysfs_driver *drv) { char drvpath[SYSFS_PATH_MAX], *c = NULL; if (!drv) { errno = EINVAL; return 1; } safestrcpy(drvpath, drv->path); c = strstr(drvpath, SYSFS_DRIVERS_NAME); if (c == NULL) return 1; *--c = '\0'; c = strstr(drvpath, SYSFS_BUS_NAME); if (c == NULL) return 1; c = strstr(c, "/"); if (c == NULL) return 1; c++; safestrcpy(drv->bus, c); return 0; } /** * sysfs_get_driver_attr: searches drv's attributes by name * @drv: driver to look through * @name: attribute name to get * returns sysfs_attribute reference with success or NULL with error. */ struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv, const char *name) { if (!drv || !name) { errno = EINVAL; return NULL; } return get_attribute(drv, (char *)name); } /** * sysfs_get_driver_attributes: gets list of driver attributes * @dev: driver whose attributes list is needed * returns dlist of attributes on success or NULL on error */ struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *drv) { if (!drv) { errno = EINVAL; return NULL; } return get_dev_attributes_list(drv); } /** * sysfs_open_driver_path: opens and initializes driver structure * @path: path to driver directory * returns struct sysfs_driver with success and NULL with error */ struct sysfs_driver *sysfs_open_driver_path(const char *path) { struct sysfs_driver *driver = NULL; if (!path) { errno = EINVAL; return NULL; } if (sysfs_path_is_dir(path)) { dbg_printf("Invalid path to driver: %s\n", path); return NULL; } driver = alloc_driver(); if (!driver) { dbg_printf("Error allocating driver at %s\n", path); return NULL; } if (sysfs_get_name_from_path(path, driver->name, SYSFS_NAME_LEN)) { dbg_printf("Error getting driver name from path\n"); free(driver); return NULL; } safestrcpy(driver->path, path); if (sysfs_remove_trailing_slash(driver->path)) { dbg_printf("Invalid path to driver %s\n", driver->path); sysfs_close_driver(driver); return NULL; } if (get_driver_bus(driver)) { dbg_printf("Could not get the bus driver is on\n"); sysfs_close_driver(driver); return NULL; } return driver; } /** * get_driver_path: looks up the bus the driver is on and builds path to * the driver. * @bus: bus on which to search * @drv: driver to look for * @path: buffer to return path to driver * @psize: size of "path" * Returns 0 on success and -1 on error */ static int get_driver_path(const char *bus, const char *drv, char *path, size_t psize) { if (!bus || !drv || !path || psize == 0) { errno = EINVAL; return -1; } if (sysfs_get_mnt_path(path, psize)) { dbg_printf("Error getting sysfs mount path\n"); return -1; } safestrcatmax(path, "/", psize); safestrcatmax(path, SYSFS_BUS_NAME, psize); safestrcatmax(path, "/", psize); safestrcatmax(path, bus, psize); safestrcatmax(path, "/", psize); safestrcatmax(path, SYSFS_DRIVERS_NAME, psize); safestrcatmax(path, "/", psize); safestrcatmax(path, drv, psize); return 0; } /** * sysfs_open_driver: open driver by name, given its bus * @bus_name: Name of the bus * @drv_name: Name of the driver * Returns the sysfs_driver reference on success and NULL on failure */ struct sysfs_driver *sysfs_open_driver(const char *bus_name, const char *drv_name) { char path[SYSFS_PATH_MAX]; struct sysfs_driver *driver = NULL; if (!drv_name || !bus_name) { errno = EINVAL; return NULL; } memset(path, 0, SYSFS_PATH_MAX); if (get_driver_path(bus_name, drv_name, path, SYSFS_PATH_MAX)) { dbg_printf("Error getting to driver %s\n", drv_name); return NULL; } driver = sysfs_open_driver_path(path); if (!driver) { dbg_printf("Error opening driver at %s\n", path); return NULL; } return driver; } /** * sysfs_get_driver_devices: gets list of devices that use the driver * @drv: sysfs_driver whose device list is needed * Returns dlist of struct sysfs_device on success and NULL on failure */ struct dlist *sysfs_get_driver_devices(struct sysfs_driver *drv) { char *ln = NULL; struct dlist *linklist = NULL; struct sysfs_device *dev = NULL; if (!drv) { errno = EINVAL; return NULL; } linklist = read_dir_links(drv->path); if (linklist) { dlist_for_each_data(linklist, ln, char) { if (!strncmp(ln, SYSFS_MODULE_NAME, strlen(ln))) continue; dev = sysfs_open_device(drv->bus, ln); if (!dev) { dbg_printf("Error opening driver's device\n"); sysfs_close_list(linklist); return NULL; } if (!drv->devices) { drv->devices = dlist_new_with_delete (sizeof(struct sysfs_device), sysfs_close_driver_device); if (!drv->devices) { dbg_printf("Error creating device list\n"); sysfs_close_list(linklist); return NULL; } } dlist_unshift_sorted(drv->devices, dev, sort_list); } sysfs_close_list(linklist); } return drv->devices; } /** * sysfs_get_driver_module: gets the module being used by this driver * @drv: sysfs_driver whose "module" is needed * Returns sysfs_module on success and NULL on failure */ struct sysfs_module *sysfs_get_driver_module(struct sysfs_driver *drv) { char path[SYSFS_PATH_MAX], mod_path[SYSFS_PATH_MAX]; if (!drv) { errno = EINVAL; return NULL; } memset(path, 0, SYSFS_PATH_MAX); safestrcpy(path, drv->path); safestrcat(path, "/"); safestrcat(path, SYSFS_MODULE_NAME); if (!sysfs_path_is_link(path)) { memset(mod_path, 0, SYSFS_PATH_MAX); if (!sysfs_get_link(path, mod_path, SYSFS_PATH_MAX)) drv->module = sysfs_open_module_path(mod_path); } return drv->module; } sysfsutils-2.1.1/lib/sysfs_module.c000066400000000000000000000155661401370461400174060ustar00rootroot00000000000000/* * sysfs_module.c * * Generic module utility functions for libsysfs * * Copyright (C) IBM Corp. 2003-2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "config.h" #include "libsysfs.h" #include "sysfs.h" /** * mod_name_equal: compares modules' name * @a: module_name looking for * @b: sysfs_module being compared */ static int mod_name_equal(void *a, void *b) { if (a == NULL || b == NULL) return 0; if (strcmp(((char *)a), ((struct sysfs_module *)b)->name) == 0) return 1; return 0; } /** * sysfs_close_module: closes a module. * @module: sysfs_module device to close. */ void sysfs_close_module(struct sysfs_module *module) { /* * since both parms and sections are attribs _under_ the * subdir of module->directory, they will get closed by * this single call */ if (module != NULL) { if (module->attrlist != NULL) dlist_destroy(module->attrlist); if (module->parmlist != NULL) dlist_destroy(module->parmlist); if (module->sections != NULL) dlist_destroy(module->sections); free(module); } } /** * alloc_module: callocs and initializes new module struct. * returns sysfs_module or NULL. */ static struct sysfs_module *alloc_module(void) { return (struct sysfs_module *)calloc(1, sizeof(struct sysfs_module)); } /** * sysfs_open_module_path: Opens and populates the module struct * @path: path to module. * returns struct sysfs_module with success and NULL with error. */ struct sysfs_module *sysfs_open_module_path(const char *path) { struct sysfs_module *mod = NULL; if (path == NULL) { errno = EINVAL; return NULL; } if ((sysfs_path_is_dir(path)) != 0) { dbg_printf("%s is not a valid path to a module\n", path); return NULL; } mod = alloc_module(); if (mod == NULL) { dbg_printf("calloc failed\n"); return NULL; } if ((sysfs_get_name_from_path(path, mod->name, SYSFS_NAME_LEN)) != 0) { errno = EINVAL; dbg_printf("Error getting module name\n"); sysfs_close_module(mod); return NULL; } safestrcpy(mod->path, path); if ((sysfs_remove_trailing_slash(mod->path)) != 0) { dbg_printf("Invalid path to module %s\n", mod->path); sysfs_close_module(mod); return NULL; } return mod; } /** * sysfs_open_module: opens specific module on a system * returns sysfs_module structure with success or NULL with error. */ struct sysfs_module *sysfs_open_module(const char *name) { struct sysfs_module *mod = NULL; char modpath[SYSFS_PATH_MAX]; if (name == NULL) { errno = EINVAL; return NULL; } memset(modpath, 0, SYSFS_PATH_MAX); if ((sysfs_get_mnt_path(modpath, SYSFS_PATH_MAX)) != 0) { dbg_printf("Sysfs not supported on this system\n"); return NULL; } safestrcat(modpath, "/"); safestrcat(modpath, SYSFS_MODULE_NAME); safestrcat(modpath, "/"); safestrcat(modpath, name); if ((sysfs_path_is_dir(modpath)) != 0) { dbg_printf("Module %s not found on the system\n", name); return NULL; } mod = alloc_module(); if (mod == NULL) { dbg_printf("calloc failed\n"); return NULL; } safestrcpy(mod->name, name); safestrcpy(mod->path, modpath); if ((sysfs_remove_trailing_slash(mod->path)) != 0) { dbg_printf("Invalid path to module %s\n", mod->path); sysfs_close_module(mod); return NULL; } return mod; } /** * sysfs_get_module_attributes: returns a dlist of attributes for * the requested sysfs_module * @cdev: sysfs_module for which attributes are needed * returns a dlist of attributes if exists, NULL otherwise */ struct dlist *sysfs_get_module_attributes(struct sysfs_module *module) { if (module == NULL) { errno = EINVAL; return NULL; } return get_dev_attributes_list(module); } /** * sysfs_get_module_attr: searches module's attributes by name * @module: module to look through * @name: attribute name to get * returns sysfs_attribute reference with success or NULL with error */ struct sysfs_attribute *sysfs_get_module_attr (struct sysfs_module *module, const char *name) { if (module == NULL || name == NULL) { errno = EINVAL; return NULL; } return get_attribute(module, (char *)name); } /** * sysfs_get_module_parms: Get modules list of parameters * @module: sysfs_module whose parmameter list is required * Returns dlist of parameters on SUCCESS and NULL on error */ struct dlist *sysfs_get_module_parms(struct sysfs_module *module) { char ppath[SYSFS_PATH_MAX]; if (module == NULL) { errno = EINVAL; return NULL; } memset(ppath, 0, SYSFS_PATH_MAX); safestrcpy(ppath, module->path); safestrcat(ppath,"/"); safestrcat(ppath, SYSFS_MOD_PARM_NAME); return (get_attributes_list(module->parmlist, ppath)); } /** * sysfs_get_module_sections: Get the set of sections for this module * @module: sysfs_module whose list of sections is required * Returns dlist of sections on SUCCESS and NULL on error */ struct dlist *sysfs_get_module_sections(struct sysfs_module *module) { char ppath[SYSFS_PATH_MAX]; if (module == NULL) { errno = EINVAL; return NULL; } memset(ppath, 0, SYSFS_PATH_MAX); safestrcpy(ppath, module->path); safestrcat(ppath,"/"); safestrcat(ppath, SYSFS_MOD_SECT_NAME); return (get_attributes_list(module->sections, ppath)); } /** * sysfs_get_module_parm: * @module: sysfs_module to look through * @parm: name of the parameter to look for * Returns sysfs_attribute * on SUCCESS and NULL on error */ struct sysfs_attribute *sysfs_get_module_parm (struct sysfs_module *module, const char *parm) { struct dlist *parm_list = NULL; if (module == NULL || parm == NULL) { errno = EINVAL; return NULL; } parm_list = sysfs_get_module_parms(module); if (parm_list == NULL) return NULL; return (struct sysfs_attribute *)dlist_find_custom(parm_list, (void *)parm, mod_name_equal); } /** * sysfs_get_module_section * @module: sysfs_module to look through * @section: name of the section to look for * Returns sysfs_attribute * on SUCCESS and NULL on error */ struct sysfs_attribute *sysfs_get_module_section (struct sysfs_module *module, const char *section) { struct dlist *sect_list = NULL; if (module == NULL || section == NULL) { errno = EINVAL; return NULL; } sect_list = sysfs_get_module_sections(module); if (sect_list == NULL) return NULL; return (struct sysfs_attribute *)dlist_find_custom(sect_list, (void *)section, mod_name_equal); } sysfsutils-2.1.1/lib/sysfs_utils.c000066400000000000000000000174341401370461400172550ustar00rootroot00000000000000/* * sysfs_utils.c * * System utility functions for libsysfs * * Copyright (C) IBM Corp. 2003-2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "config.h" #include "libsysfs.h" #include "sysfs.h" #include /** * sysfs_remove_trailing_slash: Removes any trailing '/' in the given path * @path: Path to look for the trailing '/' * Returns 0 on success 1 on error */ int sysfs_remove_trailing_slash(char *path) { size_t len; if (!path) { errno = EINVAL; return 1; } len = strlen(path); while (len > 0 && path[len-1] == '/') path[--len] = '\0'; return 0; } /* * sysfs_get_mnt_path: Gets the sysfs mount point. * @mnt_path: place to put "sysfs" mount point * @len: size of mnt_path * returns 0 with success and -1 with error. */ int sysfs_get_mnt_path(char *mnt_path, size_t len) { static char sysfs_path[SYSFS_PATH_MAX] = ""; const char *sysfs_path_env; FILE *mnt; struct mntent *mntent; int ret; if (len == 0 || mnt_path == NULL) return -1; /* evaluate only at the first call */ if (sysfs_path[0] == '\0') { /* possible overrride of real mount path */ sysfs_path_env = getenv(SYSFS_PATH_ENV); if (sysfs_path_env != NULL) { safestrcpymax(mnt_path, sysfs_path_env, len); sysfs_remove_trailing_slash(mnt_path); } else { safestrcpymax(mnt_path, SYSFS_MNT_PATH, len); } } /* check that mount point is indeed mounted */ ret = -1; mnt = setmntent(SYSFS_PROC_MNTS, "r"); if (mnt == NULL) { dbg_printf("Error getting mount information\n"); return -1; } while ((mntent = getmntent(mnt)) != NULL) { if (strcmp(mntent->mnt_type, SYSFS_FSTYPE_NAME) == 0 && strcmp(mntent->mnt_dir, mnt_path) == 0) { ret = 0; break; } } endmntent(mnt); if (ret < 0) errno = ENOENT; return ret; } /** * sysfs_get_name_from_path: returns last name from a "/" delimited path * @path: path to get name from * @name: where to put name * @len: size of name */ int sysfs_get_name_from_path(const char *path, char *name, size_t len) { char tmp[SYSFS_PATH_MAX]; char *n = NULL; if (!path || !name || len == 0) { errno = EINVAL; return -1; } memset(tmp, 0, SYSFS_PATH_MAX); safestrcpy(tmp, path); n = strrchr(tmp, '/'); if (n == NULL) { errno = EINVAL; return -1; } if (*(n+1) == '\0') { *n = '\0'; n = strrchr(tmp, '/'); if (n == NULL) { errno = EINVAL; return -1; } } n++; safestrcpymax(name, n, len); return 0; } /** * sysfs_get_link: returns link source * @path: symbolic link's path * @target: where to put name * @len: size of name */ int sysfs_get_link(const char *path, char *target, size_t len) { char devdir[SYSFS_PATH_MAX]; char linkpath[SYSFS_PATH_MAX]; char *d, *s; int count; if (!path || !target || len == 0) { errno = EINVAL; return -1; } count = readlink(path, linkpath, SYSFS_PATH_MAX); if (count < 0) return -1; else linkpath[count] = '\0'; /* * Three cases here: * 1. relative path => format ../.. * 2. absolute path => format /abcd/efgh * 3. relative path _from_ this dir => format abcd/efgh */ if (*linkpath == '/') { /* absolute path - copy as is */ safestrcpymax(target, linkpath, len); return 0; } safestrcpy(devdir, path); s = strrchr(devdir, '/'); if (s == NULL) s = devdir - 1; d = linkpath; while (*d == '.') { if (*(d+1) == '/') { /* * handle the case where link is of type ./abcd/xxx */ d += 2; while (*d == '/') d++; continue; } else if (*(d+1) != '.' || *(d+2) != '/') /* * relative path from this directory, starting * with a hidden directory */ break; /* * relative path, getting rid of leading "../.."; must * be careful here since any path component of devdir * could be a symlink again */ for (;;) { while (s > devdir && *s == '/') { s--; if (*s == '.' && (s == devdir || *(s-1) == '/')) s--; } *(s+1) = '\0'; if (*devdir == '\0' || sysfs_path_is_link(devdir)) /* * condition will be true eventually * because we already know that all * but the last component of path * resolve to a directory */ break; if (sysfs_get_link(devdir, devdir, SYSFS_PATH_MAX)) return -1; s = devdir + strlen(devdir) - 1; } while (s >= devdir) { if (*s == '/') { if (*(s+1) != '.' || *(s+2) != '.' || *(s+3) != '\0') { d += 3; while (*d == '/') d++; } else s += 2; break; } s--; } if (s < devdir || *(s+1) == '\0') break; } /* * appending to devdir a slash and the (possibly shortened) * relative path to the link source */ s++; if (s > devdir && *s == '\0') *s++ = '/'; *s = '\0'; safestrcpymax(s, d, SYSFS_PATH_MAX-(s-devdir)); safestrcpymax(target, devdir, len); return 0; } /** * sysfs_close_list: generic list free routine * @list: dlist to free * Returns nothing */ void sysfs_close_list(struct dlist *list) { if (list) dlist_destroy(list); } /** * sysfs_open_directory_list: gets a list of all directories under "path" * @path: path to read * Returns a dlist of supported names or NULL no directories (errno is set * in case of error */ struct dlist *sysfs_open_directory_list(const char *path) { if (!path) return NULL; return (read_dir_subdirs(path)); } /** * sysfs_open_link_list: gets a list of all links under "path" * @path: path to read * Returns a dlist of supported links or NULL no directories (errno is set * in case of error */ struct dlist *sysfs_open_link_list(const char *path) { if (!path) return NULL; return (read_dir_links(path)); } /** * sysfs_path_is_dir: Check if the path supplied points to a directory * @path: path to validate * Returns 0 if path points to dir, 1 otherwise */ int sysfs_path_is_dir(const char *path) { struct stat astats; if (!path) { errno = EINVAL; return 1; } if ((lstat(path, &astats)) != 0) { dbg_printf("stat() failed\n"); return 1; } if (S_ISDIR(astats.st_mode)) return 0; return 1; } /** * sysfs_path_is_link: Check if the path supplied points to a link * @path: path to validate * Returns 0 if path points to link, 1 otherwise */ int sysfs_path_is_link(const char *path) { struct stat astats; if (!path) { errno = EINVAL; return 1; } if ((lstat(path, &astats)) != 0) { dbg_printf("stat() failed\n"); return 1; } if (S_ISLNK(astats.st_mode)) return 0; return 1; } /** * sysfs_path_is_file: Check if the path supplied points to a file * @path: path to validate * Returns 0 if path points to file, 1 otherwise */ int sysfs_path_is_file(const char *path) { struct stat astats; if (!path) { errno = EINVAL; return 1; } if ((stat(path, &astats)) != 0) { dbg_printf("stat() failed\n"); return 1; } if (S_ISREG(astats.st_mode)) return 0; return 1; } /** * my_strncpy -- a safe strncpy */ char *my_strncpy(char *to, const char *from, size_t max) { size_t i; for (i = 0; i < max && from[i] != '\0'; i++) to[i] = from[i]; if (i < max) to[i] = '\0'; else to[max-1] = '\0'; return to; } /** * my_strncpy -- a safe strncpy */ char *my_strncat(char *to, const char *from, size_t max) { size_t i = 0; while (i < max && to[i] != '\0') i++; my_strncpy(to+i, from, max-i); return to; } sysfsutils-2.1.1/m4/000077500000000000000000000000001401370461400142635ustar00rootroot00000000000000sysfsutils-2.1.1/m4/.gitignore000066400000000000000000000000171401370461400162510ustar00rootroot00000000000000*.m4 !klibc.m4 sysfsutils-2.1.1/m4/klibc.m4000066400000000000000000000070421401370461400156140ustar00rootroot00000000000000# klibc.m4 serial 99 ## Copyright (C) 1995-2003 Free Software Foundation, Inc. ## This file is free software, distributed under the terms of the GNU ## General Public License. As a special exception to the GNU General ## Public License, this file may be distributed as part of a program ## that contains a configuration script generated by Autoconf, under ## the same distribution terms as the rest of that program. ## ## This file can can be used in projects which are not available under ## the GNU General Public License or the GNU Library General Public ## License but which still want to provide support for the GNU gettext ## functionality. ## Please note that the actual code of the KLIBC Library is partly covered ## by the GNU Library General Public License, and party copyrighted by the ## Regents of The University of California, and the rest is covered by a ## MIT style license. # Authors: # Martin Schlemmer , 2005. # AC_CHECK_KLIBC # -------------- # Check if the user wants KLIBC support enabled. If so, set KLIBC=yes and # fill in KLIBC_PREFIX, KLIBC_BINDIR, KLIBC_SBINDIR, KLIBC_LIBDIR and # KLIBC_INCLUDEDIR. CC is also set to the proper klcc executable. # NOTE: This should be called before AC_PROG_CC, and before header, function # or type checks. AC_DEFUN([AC_CHECK_KLIBC], [AC_BEFORE([$0], [AC_PROG_CC]) AC_REQUIRE([AC_CANONICAL_HOST]) AC_ARG_ENABLE([klibc], [AS_HELP_STRING([--enable-klibc], [Enable linking to klibc [no]. You need at least klibc-1.0 or later for this. Set KLCC to the absolute file name of klcc if not in the PATH])], [KLIBC=$enableval], [KLIBC=no]) AC_ARG_ENABLE([klibc-layout], [AS_HELP_STRING([--enable-klibc-layout], [Enable installing binaries, libraries and headers into the klibc prefix [yes] ])], [if test "X$KLIBC" != Xno; then KLIBC_LAYOUT=$enableval else KLIBC_LAYOUT=no fi], [if test "X$KLIBC" != Xno; then KLIBC_LAYOUT=yes else KLIBC_LAYOUT=no fi]) if test "X$KLIBC" != Xno; then # Basic cross compiling support. I do not think it is wise to use # AC_CHECK_TOOL, because if we are cross compiling, we do not want # just 'klcc' to be returned ... if test "${host_alias}" != "${build_alias}"; then AC_CHECK_PROGS([KLCC], [${host_alias}-klcc], [no]) else AC_CHECK_PROGS([KLCC], [klcc], [no]) fi if test "X$KLCC" = Xno; then AC_MSG_ERROR([cannot find klibc frontend 'klcc'!]) fi CC="$KLCC" CFLAGS="-Os" KLIBC_KCROSS="$($KLCC -print-klibc-kcross 2>/dev/null)" KLIBC_PREFIX="$($KLCC -print-klibc-prefix 2>/dev/null)" KLIBC_BIN_DIR="$($KLCC -print-klibc-bindir 2>/dev/null)" KLIBC_SBIN_DIR="${KLIBC_PREFIX}/${KLIBC_KCROSS}sbin" KLIBC_LIB_DIR="$($KLCC -print-klibc-libdir 2>/dev/null)" KLIBC_INCLUDE_DIR="$($KLCC -print-klibc-includedir 2>/dev/null)" if test "X$KLIBC_LAYOUT" != Xno; then prefix="$KLIBC_PREFIX" bindir="$KLIBC_BIN_DIR" sbindir="$KLIBC_SBIN_DIR" libdir="$KLIBC_LIB_DIR" includedir="$KLIBC_INCLUDE_DIR" fi # At least KLIBC_LIB_DIR should be valid, else klibc is too old or # something went wrong if test ! -d "$KLIBC_LIB_DIR"; then AC_MSG_ERROR([your klibc installation is too old or not functional!]) fi fi AC_SUBST(KLIBC) ])# AC_CHECK_KLIBC sysfsutils-2.1.1/systool.1000066400000000000000000000027631401370461400155510ustar00rootroot00000000000000.TH SYSTOOL 1 "2019-11-16" "sysfsutils" .SH NAME systool \- view system device information by bus, class, and topology .SH SYNOPSIS .B systool [\fIoptions\fP [\fIdevice\fP]] .SH DESCRIPTION Calling .B systool without parameters will present all available bus types, device classes, and root devices. .P When .I device is supplied, the information requested by .I options is shown only for the specified device, otherwise all present devices are displayed. .P .B systool uses APIs provided by .B libsysfs to gather information. .B systool runs only on Linux systems running kernels 2.5 or later, with the sysfs filesystem mounted. .SH OPTIONS .TP .B \-a Show attributes of the requested resource. .TP .B \-b \fIbus\fP Show information for a specific bus. .TP .B \-c \fIclass\fP Show information for a specific class. .TP .B \-d Show only devices. .TP .B \-h Show usage. .TP .B \-m \fImodule_name\fP Show information for a specific module. .TP .B \-p Show absolute sysfs path to the resource. .TP .B \-v Show all attributes with values. .TP .B \-A \fIattribute\fP Show attribute value for the requested resource. .TP .B \-D Show only drivers. .TP .B \-P Show device's parent. .SH SEE ALSO .P The web page of .B libsysfs at . .SH AUTHOR .B systool was written by Ananth Mavinakayanahalli and Daniel Stekloff . .P This man page was contributed by Martin Pitt for the Debian system (but may be used by others). sysfsutils-2.1.1/test/000077500000000000000000000000001401370461400147225ustar00rootroot00000000000000sysfsutils-2.1.1/test/.gitignore000066400000000000000000000001001401370461400167010ustar00rootroot00000000000000dlist_test get_device get_driver get_module testlibsysfs test.h sysfsutils-2.1.1/test/GPL000066400000000000000000000400761401370461400152760ustar00rootroot00000000000000 The GNU General Public License (GPL) Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS sysfsutils-2.1.1/test/Makefile.am000066400000000000000000000012451401370461400167600ustar00rootroot00000000000000check_PROGRAMS = dlist_test get_device get_driver get_module testlibsysfs BUILT_SOURCES = test.h CLEANFILES = test.h test.h: libsysfs.conf create-test $(AM_V_GEN) $(srcdir)/create-test $(srcdir)/libsysfs.conf get_device_SOURCES = get_device.c get_driver_SOURCES = get_driver.c get_module_SOURCES = get_module.c testlibsysfs_SOURCES = test.c test_attr.c test_bus.c test_class.c \ test_device.c test_driver.c test_module.c test_utils.c \ testout.c test-defs.h libsysfs.conf create-test AM_CPPFLAGS = -I$(top_srcdir)/include LDADD = $(top_builddir)/lib/libsysfs.la EXTRA_CFLAGS = @EXTRA_CLFAGS@ AM_CFLAGS = -Wall -W -Wextra -Wstrict-prototypes $(EXTRA_CLFAGS) sysfsutils-2.1.1/test/create-test000077500000000000000000000041171401370461400170730ustar00rootroot00000000000000#! /bin/sh rm -f test.h conf_file=${1:-libsysfs.conf} . $conf_file echo "#define val_dir_path \"$VALID_DIRECTORY_PATH\"" > test.h echo "#define val_link_path \"$VALID_LINK_PATH\"" >> test.h echo "#define val_file_path \"$VALID_FILE_PATH\"" >> test.h echo "#define val_subdir_link_name \"$VALID_SUBDIR_LINK_NAME\"" >> test.h echo "#define val_subdir_name \"$VALID_SUBDIR_NAME\"" >> test.h echo "#define val_subsys \"$VALID_SUBSYSTEM\"" >> test.h echo "#define val_bus_name \"$VALID_BUS_NAME\"" >> test.h echo "#define val_bus_attr \"$VALID_BUS_ATTR\"" >> test.h echo "#define val_root_name \"$VALID_ROOT_NAME\"" >> test.h echo "#define val_root_dev_path \"$VALID_ROOT_PATH\"" >> test.h echo "#define val_bus_id \"$VALID_BUS_ID\"" >> test.h echo "#define val_dev_path \"$VALID_DEVICE_PATH\"" >> test.h echo "#define val_dev_attr \"$VALID_DEVICE_ATTR\"" >> test.h echo "#define val_class \"$VALID_CLASS\"" >> test.h echo "#define val_class_dev \"$VALID_CLASS_DEVICE\"" >> test.h echo "#define val_class_dev_path \"$VALID_CLASS_DEVICE_PATH\"" >> test.h echo "#define val_class_dev_attr \"$VALID_CLASS_DEV_ATTR\"" >> test.h echo "#define val_block_class_dev_path \"$VALID_BLOCK_DEV_PATH\"" >> test.h echo "#define val_drv_name \"$VALID_DRIVER\"" >> test.h echo "#define val_drv_path \"$VALID_DRIVER_PATH\"" >> test.h echo "#define val_drv_bus_name \"$VALID_DRIVER_BUS\"" >> test.h echo "#define val_drv_dev_name \"$VALID_DRIVER_DEVICE\"" >> test.h echo "#define val_drv_attr_name \"$VALID_DRIVER_ATTR\"" >> test.h echo "#define val_drv1_name \"$VALID_DRIVER1\"" >> test.h echo "#define val_drv1_path \"$VALID_DRIVER1_PATH\"" >> test.h echo "#define val_drv1_bus_name \"$VALID_DRIVER1_BUS\"" >> test.h echo "#define val_write_attr_path \"$VALID_WRITE_ATTR_PATH\"" >> test.h echo "#define val_mod_path \"$VALID_MODULE_PATH\"" >> test.h echo "#define val_mod_name \"$VALID_MODULE\"" >> test.h echo "#define val_mod_attr_name \"$VALID_MODULE_ATTRIBUTE\"" >> test.h echo "#define val_mod_param \"$VALID_MODULE_PARAM\"" >> test.h echo "#define val_mod_section \"$VALID_MODULE_SECTION\"" >> test.h sysfsutils-2.1.1/test/dlist_test.c000066400000000000000000000201241401370461400172430ustar00rootroot00000000000000/* * dlist_test.c * * Copyright (C) 2003 Eric J Bohm * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ /* Double linked list implementation tester. */ #include "config.h" #include "dlist.h" #include #include #include // create some dlists put nodes in and out // use dump // try list with del_func and without // use insert, unshift, push // use pop push mark // use prev next typedef struct simple { char label[80]; int number; } Simple; typedef struct complex { int cnumber; Simple *sthing; } Complex; void complex_silly_multiply_by_two( void *a); int complex_equal(void *a, void *b); int complex_less(void *a, void *b); int complex_greater(void *a, void *b); int complex_comp(void *a, void *b); void simple_dump(Dlist *); void simple_dump_rev(Dlist *); void complex_dump(Dlist *); void complex_dump_rev(Dlist *); void complex_out(void *); void complex_del(void *); Complex *complex_maker(int,int,char *); int complex_filter(void *a); Simple *simple_maker(int ,char *); int main (void) { Dlist *list; Simple *s1,*s2,*s3,*stemp; Complex *c1,*c2,*c3, *c4, *ctemp, *cfound; while(1) { s1=simple_maker(1,"one"); s2=simple_maker(2,"two"); s3=simple_maker(3,"three"); if((list=dlist_new(sizeof(Simple)))==NULL) { fprintf(stderr,"ERR dlist_new fail\n"); return(2); } dlist_push(list,s1); dlist_push(list,s2); dlist_push(list,s3); printf("count is %ld\n",list->count); simple_dump(list); simple_dump_rev(list); stemp=dlist_pop(list); printf("popped %s\n",stemp->label); simple_dump(list); printf("pushed\n"); dlist_push(list,s3); simple_dump(list); stemp=dlist_shift(list); printf("shifted %s\n",stemp->label); simple_dump(list); printf("unshifted\n"); dlist_unshift(list,stemp); simple_dump(list); dlist_destroy(list); c1=complex_maker(1,1,"one"); c2=complex_maker(2,2,"two"); c3=complex_maker(3,3,"three"); if((list=dlist_new_with_delete(sizeof(Complex),complex_del))==NULL) { fprintf(stderr,"ERR dlist_new fail\n"); return(2); } if(dlist_insert_sorted(list,c1,complex_less)==NULL) { fprintf(stderr,"ERR dlist_insert fail\n"); return(2); } printf("sorted insert 1\n"); if(dlist_insert_sorted(list,c3,complex_less)==NULL) { fprintf(stderr,"ERR dlist_insert fail\n"); return(2); } if(dlist_insert_sorted(list,c2,complex_less)==NULL) { fprintf(stderr,"ERR dlist_insert fail\n"); return(2); } printf("sorted insert 2\n"); printf("ascending sorted output\n"); complex_dump(list); dlist_transform(list,complex_silly_multiply_by_two); printf("transform multi by 2 output\n"); complex_dump(list); ctemp=complex_maker(6,6,"three"); if((cfound=(Complex *) dlist_find_custom(list,ctemp,complex_equal))!=NULL) { printf("found %d as %d in list\n",ctemp->cnumber,cfound->cnumber); } else { printf("ERROR find failed on %d \n",ctemp->cnumber); return(3); } complex_del(ctemp); dlist_destroy(list); c1=complex_maker(1,1,"one"); c2=complex_maker(2,2,"two"); c3=complex_maker(3,3,"three"); if((list=dlist_new_with_delete(sizeof(Complex),complex_del))==NULL) { fprintf(stderr,"ERR dlist_new fail\n"); return(2); } if(dlist_insert_sorted(list,c1,complex_greater)==NULL) { fprintf(stderr,"ERR dlist_insert fail\n"); return(2); } printf("greater sorted insert 1\n"); if(dlist_insert_sorted(list,c3,complex_greater)==NULL) { fprintf(stderr,"ERR dlist_insert fail\n"); return(2); } printf("greater sorted insert 3\n"); if(dlist_insert_sorted(list,c2,complex_greater)==NULL) { fprintf(stderr,"ERR dlist_insert fail\n"); return(2); } printf("greater sorted insert 2\n"); printf("descending sorted output using transform\n"); dlist_transform(list,complex_out); dlist_destroy(list); c1=complex_maker(1,1,"one"); c2=complex_maker(2,2,"two"); c3=complex_maker(3,3,"three"); c4=complex_maker(4,4,"four"); if((list=dlist_new_with_delete(sizeof(Complex),complex_del))==NULL) { fprintf(stderr,"ERR dlist_new fail\n"); return(2); } dlist_push(list,c2); dlist_push(list,c1); dlist_push(list,c4); dlist_push(list,c3); printf("unsorted custom\n"); complex_dump(list); printf("unsorted custom reversed\n"); complex_dump_rev(list); dlist_sort_custom(list,complex_comp); printf("custom sorted output\n"); complex_dump(list); dlist_filter_sort(list, complex_filter, complex_comp); printf("custom filtered and sorted output\n"); complex_dump(list); dlist_destroy(list); } return(0); } void simple_dump (Dlist *list) { Simple *thisone; printf("count %ld \n",list->count); dlist_for_each_data(list,thisone,Simple) { printf("label %s number %d \n",thisone->label,thisone->number); } } void simple_dump_rev (Dlist *list) { Simple *thisone; printf("rev count %ld \n",list->count); dlist_for_each_data_rev(list,thisone,Simple) { printf("label %s number %d \n",thisone->label,thisone->number); } } Simple * simple_maker(int snumber,char *label) { Simple *stemp; if((stemp=malloc(sizeof(Simple)))==NULL) { fprintf(stderr,"ERR malloc fail\n"); return(NULL); } stemp->number=snumber; strcpy(stemp->label,label); return(stemp); } Complex * complex_maker(int cnumber, int snumber, char* label) { Complex *ctemp; if((ctemp=malloc(sizeof(Complex)))==NULL) { fprintf(stderr,"ERR malloc fail\n"); return(NULL); } ctemp->cnumber=cnumber; ctemp->sthing=simple_maker(snumber,label); return(ctemp); } void complex_out(void *data) { Complex *thisone=(Complex *)data; printf("cnumber %d label %s number %d \n",thisone->cnumber,thisone->sthing->label,thisone->sthing->number); } /** * return 1 if a==b, else 0 */ int complex_equal(void *a, void *b) { if((((Complex *)a)->cnumber==((Complex *)b)->cnumber) && (((Complex *)a)->sthing->number== ((Complex *)b)->sthing->number) && strcmp(((Complex *)a)->sthing->label, ((Complex *)b)->sthing->label)==0) return(1); return(0); } /** for sorting * return 1 if acnumber < ((Complex *)b)->cnumber ); } /** for sorting * return 1 if a>b, else 0 */ int complex_greater(void *a, void *b) { return( ((Complex *)a)->cnumber > ((Complex *)b)->cnumber ); } int complex_comp(void *a, void *b) { return( ((Complex *)a)->cnumber - ((Complex *)b)->cnumber ); } void complex_silly_multiply_by_two( void *a) { ((Complex *)a)->cnumber=((Complex *)a)->cnumber*2; ((Complex *)a)->sthing->number=((Complex *)a)->sthing->number*2; } void complex_dump (Dlist *list) { Complex *thisone; dlist_start(list); printf("count %ld \n",list->count); dlist_for_each_data(list,thisone,Complex) { printf("cnumber %d label %s number %d \n",thisone->cnumber,thisone->sthing->label,thisone->sthing->number); } } void complex_dump_rev (Dlist *list) { Complex *thisone; dlist_start(list); printf("count %ld \n",list->count); dlist_for_each_data_rev(list,thisone,Complex) { printf("cnumber %d label %s number %d \n",thisone->cnumber,thisone->sthing->label,thisone->sthing->number); } } void complex_del (void *item) { Complex *corpse=item; printf("freeing complex\n"); free(corpse->sthing); free(corpse); } int complex_filter(void *a) { Complex *c = (Complex *)a; if (c->cnumber >= 2 && c->cnumber <= 3) return 1; else return 0; } sysfsutils-2.1.1/test/get_device.c000066400000000000000000000030431401370461400171640ustar00rootroot00000000000000/* * get_device.c * * Utility to get details of a given device * * Copyright (C) IBM Corp. 2003-2005 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "config.h" #include #include #include "libsysfs.h" static void print_usage(void) { fprintf(stdout, "Usage: get_device [bus] [device]\n"); } int main(int argc, char *argv[]) { struct sysfs_device *device = NULL; if (argc != 3) { print_usage(); return 1; } device = sysfs_open_device(argv[1], argv[2]); if (device == NULL) { fprintf(stdout, "Device \"%s\" not found on bus \"%s\"\n", argv[2], argv[1]); return 1; } fprintf(stdout, "device is on bus %s, using driver %s\n", device->bus, device->driver_name); struct sysfs_device *parent = sysfs_get_device_parent(device); if (parent) fprintf(stdout, "parent is %s\n", parent->name); else fprintf(stdout, "no parent\n"); return 0; } sysfsutils-2.1.1/test/get_driver.c000066400000000000000000000044401401370461400172220ustar00rootroot00000000000000/* * get_driver.c * * Utility to get details of the given driver * * Copyright (C) IBM Corp. 2003-2005 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "config.h" #include #include #include #include "libsysfs.h" static void print_usage(void) { fprintf(stdout, "Usage: get_driver [bus] [driver]\n"); } int main(int argc, char *argv[]) { char *bus = NULL, path[SYSFS_PATH_MAX]; struct sysfs_driver *driver = NULL; struct sysfs_device *device = NULL; struct dlist *devlist = NULL; if (argc != 3) { print_usage(); return 1; } memset(path, 0, SYSFS_PATH_MAX); if ((sysfs_get_mnt_path(path, SYSFS_PATH_MAX)) != 0) { fprintf(stdout, "Sysfs not mounted?\n"); return 1; } strcat(path, "/"); strcat(path, SYSFS_BUS_NAME); strcat(path, "/"); strcat(path, argv[1]); strcat(path, "/"); strcat(path, SYSFS_DRIVERS_NAME); strcat(path, "/"); strcat(path, argv[2]); driver = sysfs_open_driver_path(path); if (driver == NULL) { fprintf(stdout, "Driver %s not found\n", argv[1]); free(bus); return 1; } devlist = sysfs_get_driver_devices(driver); if (devlist != NULL) { fprintf(stdout, "%s is used by:\n", argv[2]); dlist_for_each_data(devlist, device, struct sysfs_device) fprintf(stdout, "\t\t%s\n", device->bus_id); } else fprintf(stdout, "%s is presently not used by any device\n", argv[2]); fprintf(stdout, "driver %s is on bus %s\n", driver->name, driver->bus); struct sysfs_module *module = sysfs_get_driver_module(driver); if (module) fprintf(stdout, "%s is using the module %s\n", driver->name, module->name); sysfs_close_driver(driver); free(bus); return 0; } sysfsutils-2.1.1/test/get_module.c000066400000000000000000000040031401370461400172070ustar00rootroot00000000000000/* * get_module.c * * Utility to get details of a given module * * Copyright (C) IBM Corp. 2003-2005 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "config.h" #include #include #include "libsysfs.h" static void print_usage(void) { fprintf(stdout, "Usage: get_module [name]\n"); } int main(int argc, char *argv[]) { struct sysfs_module *module = NULL; struct sysfs_attribute *attr = NULL; struct dlist *attrlist = NULL; if (argc != 2) { print_usage(); return 1; } module = sysfs_open_module(argv[1]); if (module == NULL) { fprintf(stdout, "Module \"%s\" not found\n", argv[1]); return 1; } attrlist = sysfs_get_module_attributes(module); if (attrlist != NULL) { dlist_for_each_data(attrlist, attr, struct sysfs_attribute) fprintf(stdout, "\t%-20s : %s", attr->name, attr->value); } fprintf(stdout, "\n"); attrlist = sysfs_get_module_parms(module); if (attrlist != NULL) { fprintf(stdout, "Parameters:\n"); dlist_for_each_data(attrlist, attr, struct sysfs_attribute) fprintf(stdout, "\t%-20s : %s", attr->name, attr->value); } attrlist = sysfs_get_module_sections(module); if (attrlist != NULL) { fprintf(stdout, "Sections:\n"); dlist_for_each_data(attrlist, attr, struct sysfs_attribute) fprintf(stdout, "\t%-20s : %s", attr->name, attr->value); } sysfs_close_module(module); return 0; } sysfsutils-2.1.1/test/libsysfs.conf000066400000000000000000000056461401370461400174420ustar00rootroot00000000000000# The config file for libsysfs testsuite # All values in this file are in relation to the sysfs filesystem only # # Values defined here will be used to dynamically build a header file that # gets used while compiling the testsuite. # NOTE: If you change values in this file, please make sure that you run # "make" (in the "test" directory) for the changes to take effect. # A valid directory path under sysfs # A valid link name under a subidirectory of VALID_DIRECTORY_PATH... eg., if # the VALID_DIRECTORY_PATH is /sys/bus/pci, then enter a pci device name for # VALID SUBDIR_LINK_NAME VALID_DIRECTORY_PATH=/sys/bus/pci VALID_SUBDIR_LINK_NAME=0000:00:00.0 # A valid link path under sysfs - enter the absolute path to a soft-link here VALID_LINK_PATH=/sys/block/sda/device # Absolute path to a regular (readable) attribute (a normal file) under sysfs VALID_FILE_PATH=/sys/block/sda/dev # A valid subsystem name - an entry under /sys VALID_SUBSYSTEM=bus # A valid bus name supported on this system # A device belonging to the bus # Absolute path to the device # A valid attribute defined for this device VALID_BUS_NAME=pci VALID_BUS_ID=0000:00:00.0 VALID_DEVICE_PATH=/sys/devices/pci0000:00/0000:00:00.0 VALID_DEVICE_ATTR=vendor # A valid attribute exported under VALID_BUS_NAME # NOTE: As of now, no buses export attributes, change this to a valid value # when one becomes avaliable VALID_BUS_ATTR=online # A valid directory under /sys/devices # Its absolute path # A valid subdirectory under VALID_ROOT_PATH VALID_ROOT_NAME=pci0000:00 VALID_ROOT_PATH=/sys/devices/pci0000:00 VALID_SUBDIR_NAME=0000:00:00.0 # A valid class - directory under /sys/class # A valid class_device belonging to the class - a dir under VALID_CLASS # Abslolute path to the VALID_CLASS_DEVICE # A valid attribute defined for the VALID_CLASS_DEVICE VALID_CLASS=net VALID_CLASS_DEVICE=eth0 VALID_CLASS_DEVICE_PATH=/sys/class/net/eth0 VALID_CLASS_DEV_ATTR=type # A valid directory path under /sys/block/xxx - preferably a partition VALID_BLOCK_DEV_PATH=/sys/block/hda/hda1 # A valid driver (preferably a driver that exports readable attributes) # The absolute path to the driver # The bus the driver is registered on # A device that is using it and # A valid attribute corresponding to the driver VALID_DRIVER=e100 VALID_DRIVER_PATH=/sys/bus/pci/drivers/e100 VALID_DRIVER_BUS=pci VALID_DRIVER_DEVICE=0000:02:08.0 VALID_DRIVER_ATTR=new_id # Another valid driver - but one that is not being used by any device # Absolute path to the driver # The bus the driver is registered VALID_DRIVER1=usbfs VALID_DRIVER1_PATH=/sys/bus/usb/drivers/usbfs VALID_DRIVER1_BUS=usb # Path to a writable attribute - make sure that the tester has permission to # "write" to the file at VALID_WRITE_ATTR_PATH VALID_WRITE_ATTR_PATH=/sys/class/net/eth0/tx_queue_len VALID_MODULE_PATH=/sys/module/usbcore VALID_MODULE=usbcore VALID_MODULE_ATTRIBUTE=refcnt VALID_MODULE_PARAM=blinkenlights VALID_MODULE_SECTION=__versions sysfsutils-2.1.1/test/libsysfs.conf-suse000066400000000000000000000056521401370461400204140ustar00rootroot00000000000000# The config file for libsysfs testsuite # All values in this file are in relation to the sysfs filesystem only # # Values defined here will be used to dynamically build a header file that # gets used while compiling the testsuite. # NOTE: If you change values in this file, please make sure that you run # "make" (in the "test" directory) for the changes to take effect. # A valid directory path under sysfs # A valid link name under a subidirectory of VALID_DIRECTORY_PATH... eg., if # the VALID_DIRECTORY_PATH is /sys/bus/pci, then enter a pci device name for # VALID SUBDIR_LINK_NAME VALID_DIRECTORY_PATH=/sys/bus/pci VALID_SUBDIR_LINK_NAME=0000:00:00.0 # A valid link path under sysfs - enter the absolute path to a soft-link here VALID_LINK_PATH=/sys/block/sda/device # Absolute path to a regular (readable) attribute (a normal file) under sysfs VALID_FILE_PATH=/sys/block/sda/dev # A valid subsystem name - an entry under /sys VALID_SUBSYSTEM=bus # A valid bus name supported on this system # A device belonging to the bus # Absolute path to the device # A valid attribute defined for this device VALID_BUS_NAME=pci VALID_BUS_ID=0000:00:00.0 VALID_DEVICE_PATH=/sys/devices/pci0000:00/0000:00:00.0 VALID_DEVICE_ATTR=vendor # A valid attribute exported under VALID_BUS_NAME # NOTE: As of now, no buses export attributes, change this to a valid value # when one becomes avaliable VALID_BUS_ATTR=online # A valid directory under /sys/devices # Its absolute path # A valid subdirectory under VALID_ROOT_PATH VALID_ROOT_NAME=pci0000:00 VALID_ROOT_PATH=/sys/devices/pci0000:00 VALID_SUBDIR_NAME=0000:00:00.0 # A valid class - directory under /sys/class # A valid class_device belonging to the class - a dir under VALID_CLASS # Abslolute path to the VALID_CLASS_DEVICE # A valid attribute defined for the VALID_CLASS_DEVICE VALID_CLASS=net VALID_CLASS_DEVICE=ens33 VALID_CLASS_DEVICE_PATH=/sys/class/net/ens33 VALID_CLASS_DEV_ATTR=type # A valid directory path under /sys/block/xxx - preferably a partition VALID_BLOCK_DEV_PATH=/sys/block/sda/sda1 # A valid driver (preferably a driver that exports readable attributes) # The absolute path to the driver # The bus the driver is registered on # A device that is using it and # A valid attribute corresponding to the driver VALID_DRIVER=e1000 VALID_DRIVER_PATH=/sys/bus/pci/drivers/e1000 VALID_DRIVER_BUS=pci VALID_DRIVER_DEVICE=0000:02:01.0 VALID_DRIVER_ATTR=new_id # Another valid driver - but one that is not being used by any device # Absolute path to the driver # The bus the driver is registered VALID_DRIVER1=usbfs VALID_DRIVER1_PATH=/sys/bus/usb/drivers/usbfs VALID_DRIVER1_BUS=usb # Path to a writable attribute - make sure that the tester has permission to # "write" to the file at VALID_WRITE_ATTR_PATH VALID_WRITE_ATTR_PATH=/sys/class/net/ens33/tx_queue_len VALID_MODULE_PATH=/sys/module/usbcore VALID_MODULE=usbcore VALID_MODULE_ATTRIBUTE=refcnt VALID_MODULE_PARAM=blinkenlights VALID_MODULE_SECTION=__verbose sysfsutils-2.1.1/test/test-defs.h000066400000000000000000000114441401370461400167750ustar00rootroot00000000000000/* * test.h * * Generic defines/declarations for the libsysfs testsuite * * Copyright (C) IBM Corp. 2004-2005 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef _TESTER_H_ #define _TESTER_H_ #include #include #include #include #include #include #include #include #include "libsysfs.h" #include "dlist.h" #include "test.h" #define val_drv1_dev_name "dummy1" #define val_drv1_attr_name "dummy2" #define inval_name "invalid_name" #define inval_path "/sys/invalid/path" #define FUNC_TABLE_SIZE (sizeof(func_table) / sizeof(void *)) extern FILE *my_stdout; #define dbg_print(format, arg...) fprintf(my_stdout, format, ## arg) /** * list of display functions */ extern void show_device(struct sysfs_device *device); extern void show_driver(struct sysfs_driver *driver); extern void show_device_list(struct dlist *devlist); extern void show_driver_list(struct dlist *drvlist); extern void show_attribute(struct sysfs_attribute *attr); extern void show_attribute_list(struct dlist *list); extern void show_links_list(struct dlist *linklist); extern void show_dir_list(struct dlist *dirlist); extern void show_class_device(struct sysfs_class_device *dev); extern void show_class_device_list(struct dlist *devlist); extern void show_list(struct dlist *list); extern void show_parm_list(struct dlist *list); extern void show_section_list(struct dlist *list); extern void show_module(struct sysfs_module *module); /** * list of test functions..... */ extern int test_sysfs_get_mnt_path(int flag); extern int test_sysfs_remove_trailing_slash(int flag); extern int test_sysfs_get_name_from_path(int flag); extern int test_sysfs_path_is_dir(int flag); extern int test_sysfs_path_is_link(int flag); extern int test_sysfs_path_is_file(int flag); extern int test_sysfs_get_link(int flag); extern int test_sysfs_open_directory_list(int flag); extern int test_sysfs_open_link_list(int flag); extern int test_sysfs_close_list(int flag); extern int test_sysfs_close_attribute(int flag); extern int test_sysfs_open_attribute(int flag); extern int test_sysfs_read_attribute(int flag); extern int test_sysfs_write_attribute(int flag); extern int test_sysfs_close_driver(int flag); extern int test_sysfs_open_driver(int flag); extern int test_sysfs_open_driver_path(int flag); extern int test_sysfs_get_driver_attr(int flag); extern int test_sysfs_get_driver_attributes(int flag); extern int test_sysfs_get_driver_devices(int flag); extern int test_sysfs_get_driver_module(int flag); extern int test_sysfs_close_device(int flag); extern int test_sysfs_open_device(int flag); extern int test_sysfs_get_device_parent(int flag); extern int test_sysfs_open_device_path(int flag); extern int test_sysfs_get_device_attr(int flag); extern int test_sysfs_get_device_attributes(int flag); extern int test_sysfs_close_bus(int flag); extern int test_sysfs_open_bus(int flag); extern int test_sysfs_get_bus_device(int flag); extern int test_sysfs_get_bus_driver(int flag); extern int test_sysfs_get_bus_drivers(int flag); extern int test_sysfs_get_bus_devices(int flag); extern int test_sysfs_close_class_device(int flag); extern int test_sysfs_open_class_device_path(int flag); extern int test_sysfs_open_class_device(int flag); extern int test_sysfs_get_classdev_device(int flag); extern int test_sysfs_get_classdev_parent(int flag); extern int test_sysfs_close_class(int flag); extern int test_sysfs_open_class(int flag); extern int test_sysfs_get_class_devices(int flag); extern int test_sysfs_get_class_device(int flag); extern int test_sysfs_get_classdev_attributes(int flag); extern int test_sysfs_get_classdev_attr(int flag); extern int test_sysfs_open_classdev_attr(int flag); extern int test_sysfs_close_module(int flag); extern int test_sysfs_open_module_path(int flag); extern int test_sysfs_open_module(int flag); extern int test_sysfs_get_module_attr(int flag); extern int test_sysfs_get_module_attributes(int flag); extern int test_sysfs_get_module_parms(int flag); extern int test_sysfs_get_module_sections(int flag); extern int test_sysfs_get_module_parm(int flag); extern int test_sysfs_get_module_section(int flag); #endif /* _TESTER_H_ */ sysfsutils-2.1.1/test/test.c000066400000000000000000000166071401370461400160570ustar00rootroot00000000000000/* * test.c * * Main program for the libsysfs testsuite * * Copyright (C) IBM Corp. 2004-2005 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * */ /** * this doesn't do much, just loops throug to call each function. */ #include "config.h" #include "test-defs.h" #include FILE *my_stdout; /*************************************************/ char *function_name[] = { "sysfs_get_mnt_path", "sysfs_remove_trailing_slash", "sysfs_get_name_from_path", "sysfs_path_is_dir", "sysfs_path_is_link", "sysfs_path_is_file", "sysfs_get_link", "sysfs_close_list", "sysfs_open_directory_list", "sysfs_open_link_list", "sysfs_close_attribute", "sysfs_open_attribute", "sysfs_read_attribute", "sysfs_write_attribute", "sysfs_close_driver", "sysfs_open_driver", "sysfs_open_driver_path", "sysfs_get_driver_attr", "sysfs_get_driver_attributes", "sysfs_get_driver_devices", "sysfs_close_device", "sysfs_open_device", "sysfs_get_device_parent", "sysfs_open_device_path", "sysfs_get_device_attr", "sysfs_get_device_attributes", "sysfs_close_bus", "sysfs_open_bus", "sysfs_get_bus_device", "sysfs_get_bus_driver", "sysfs_get_bus_drivers", "sysfs_get_bus_devices", "sysfs_close_class_device", "sysfs_open_class_device_path", "sysfs_open_class_device", "sysfs_get_classdev_device", "sysfs_get_classdev_parent", "sysfs_close_class", "sysfs_open_class", "sysfs_get_class_devices", "sysfs_get_class_device", "sysfs_get_classdev_attributes", "sysfs_get_classdev_attr", "sysfs_close_module", "sysfs_open_module_path", "sysfs_open_module", "sysfs_get_module_attr", "sysfs_get_module_attributes", "sysfs_get_module_parms", "sysfs_get_module_sections", "sysfs_get_module_parm", "sysfs_get_module_section", }; int (*func_table[])(int) = { test_sysfs_get_mnt_path, test_sysfs_remove_trailing_slash, test_sysfs_get_name_from_path, test_sysfs_path_is_dir, test_sysfs_path_is_link, test_sysfs_path_is_file, test_sysfs_get_link, test_sysfs_close_list, test_sysfs_open_directory_list, test_sysfs_open_link_list, test_sysfs_close_attribute, test_sysfs_open_attribute, test_sysfs_read_attribute, test_sysfs_write_attribute, test_sysfs_close_driver, test_sysfs_open_driver, test_sysfs_open_driver_path, test_sysfs_get_driver_attr, test_sysfs_get_driver_attributes, test_sysfs_get_driver_devices, test_sysfs_close_device, test_sysfs_open_device, test_sysfs_get_device_parent, test_sysfs_open_device_path, test_sysfs_get_device_attr, test_sysfs_get_device_attributes, test_sysfs_close_bus, test_sysfs_open_bus, test_sysfs_get_bus_device, test_sysfs_get_bus_driver, test_sysfs_get_bus_drivers, test_sysfs_get_bus_devices, test_sysfs_close_class_device, test_sysfs_open_class_device_path, test_sysfs_open_class_device, test_sysfs_get_classdev_device, test_sysfs_get_classdev_parent, test_sysfs_close_class, test_sysfs_open_class, test_sysfs_get_class_devices, test_sysfs_get_class_device, test_sysfs_get_classdev_attributes, test_sysfs_get_classdev_attr, test_sysfs_close_module, test_sysfs_open_module_path, test_sysfs_open_module, test_sysfs_get_module_attr, test_sysfs_get_module_attributes, test_sysfs_get_module_parms, test_sysfs_get_module_sections, test_sysfs_get_module_parm, test_sysfs_get_module_section, }; char *dir_paths[] = { val_dir_path, val_root_dev_path, val_class_dev_path, val_block_class_dev_path, val_drv_path, val_drv1_path, NULL }; char *file_paths[] = { val_file_path, val_write_attr_path, NULL }; char *link_paths[] = { val_link_path, NULL }; static int path_is_dir(const char *path) { struct stat astats; if ((stat(path, &astats)) != 0) goto direrr; if (S_ISDIR(astats.st_mode)) return 0; direrr: fprintf(stdout, "Config error: %s not a directory\n", path); return 1; } static int path_is_file(const char *path) { struct stat astats; if ((lstat(path, &astats)) != 0) goto fileerr; if (S_ISREG(astats.st_mode)) return 0; fileerr: fprintf(stdout, "Config error: %s not a file\n", path); return 1; } static int path_is_link(const char *path) { struct stat astats; if ((lstat(path, &astats)) != 0) goto linkerr; if (S_ISLNK(astats.st_mode)) return 0; linkerr: fprintf(stdout, "Config error: %s not a link\n", path); return 1; } /* * Check validity of the test.h file entries */ static int check_header(void) { char *var_path = NULL; char path1[SYSFS_PATH_MAX]; int i = 0; for (i = 0; dir_paths[i] != NULL; i++) { var_path = dir_paths[i]; if (path_is_dir(var_path) != 0) return 1; } for (i = 0; file_paths[i] != NULL; i++) { var_path = file_paths[i]; if (path_is_file(var_path) != 0) return 1; } for (i = 0; link_paths[i] != NULL; i++) { var_path = link_paths[i]; if (path_is_link(var_path) != 0) return 1; } memset(path1, 0, SYSFS_PATH_MAX); strcpy(path1, val_root_dev_path); strcat(path1, "/"); strcat(path1, val_subdir_name); if (path_is_dir(path1) != 0) return 1; memset(path1, 0, SYSFS_PATH_MAX); strcpy(path1, val_drv_path); strcat(path1, "/"); strcat(path1, val_drv_dev_name); if (path_is_link(path1) != 0) return 1; memset(path1, 0, SYSFS_PATH_MAX); strcpy(path1, val_dir_path); strcat(path1, "/devices"); strcat(path1, "/"); strcat(path1, val_subdir_link_name); if (path_is_link(path1) != 0) return 1; memset(path1, 0, SYSFS_PATH_MAX); strcpy(path1, val_class_dev_path); strcat(path1, "/"); strcat(path1, val_class_dev_attr); if (path_is_file(path1) != 0) return 1; memset(path1, 0, SYSFS_PATH_MAX); strcpy(path1, val_dev_path); strcat(path1, "/"); strcat(path1, val_dev_attr); if (path_is_file(path1) != 0) return 1; memset(path1, 0, SYSFS_PATH_MAX); strcpy(path1, val_drv_path); strcat(path1, "/"); strcat(path1, val_drv_attr_name); if (path_is_file(path1) != 0) return 1; return 0; } static void usage(void) { fprintf(stdout, "testlibsysfs [log-file]\n"); fprintf(stdout, "\t eg: testlibsysfs 3 /home/user/test.log\n"); } int main(int argc, char *argv[]) { char std_out[] = "/dev/stdout"; char *file_name = NULL; int i = 0, j = 0, k = 0, num = 1; if (argc == 3) { file_name = argv[2]; } else { file_name = std_out; } my_stdout = fopen(file_name,"w"); if (argc < 2) { usage(); return 0; } else num = strtol(argv[1], NULL, 0); if (check_header() != 0) return 1; dbg_print("\nTest running %d times\n", num); for (k = 0; k < num ; k++) { dbg_print("\nThis is the %d test run\n", k+1); for (i = 0; i < (int)FUNC_TABLE_SIZE; i++) { dbg_print("\n**************************************************************\n"); dbg_print("TESTING: %s, function no: %d\n\n", function_name[i], i); for (j = 0; ; j++) { fflush(my_stdout); if (func_table[i](j) == -1) break; } dbg_print("**************************************************************\n"); } } fclose(my_stdout); return 0; } sysfsutils-2.1.1/test/test_attr.c000066400000000000000000000165671401370461400171160ustar00rootroot00000000000000/* * test_dir.c * * Tests for directory related functions for the libsysfs testsuite * * Copyright (C) IBM Corp. 2004-2005 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * */ /** *************************************************************************** * this will test the directory related functions provided by libsysfs. * * extern void sysfs_close_attribute(struct sysfs_attribute *sysattr); * extern struct sysfs_attribute *sysfs_open_attribute * (const char *path); * extern int sysfs_read_attribute(struct sysfs_attribute *sysattr); * extern int sysfs_write_attribute(struct sysfs_attribute *sysattr, * const char *new_value, size_t len); **************************************************************************** */ #include "config.h" #include "test-defs.h" #include /** * extern void sysfs_close_attribute(struct sysfs_attribute *sysattr); * * flag: * 0: sysattr -> valid * 1: sysattr -> NULL */ int test_sysfs_close_attribute(int flag) { struct sysfs_attribute *sysattr = NULL; char *path = NULL; switch (flag) { case 0: path = val_file_path; sysattr = sysfs_open_attribute(path); if (sysattr == NULL) { dbg_print("%s: Error opening attribute at %s\n", __FUNCTION__, val_file_path); return 0; } break; case 1: sysattr = NULL; break; default: return -1; } sysfs_close_attribute(sysattr); dbg_print("%s: returns void\n", __FUNCTION__); return 0; } /** * extern struct sysfs_attribute *sysfs_open_attribute * (const char *path); * * flag: * 0: path -> valid * 1: path -> invalid * 2: path -> NULL */ int test_sysfs_open_attribute(int flag) { char *path = NULL; struct sysfs_attribute *sysattr = NULL; switch (flag) { case 0: path = val_file_path; break; case 1: path = inval_path; break; case 2: path = NULL; break; default: return -1; } sysattr = sysfs_open_attribute(path); switch (flag) { case 0: if (sysattr == NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); dbg_print("Attrib name = %s, at %s\n\n", sysattr->name, sysattr->path); } break; case 1: case 2: if (sysattr != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (sysattr != NULL) { sysfs_close_attribute(sysattr); sysattr = NULL; } return 0; } /** * extern int sysfs_read_attribute(struct sysfs_attribute *sysattr); * * flag: * 0: sysattr -> valid * 1: sysattr -> NULL */ int test_sysfs_read_attribute(int flag) { struct sysfs_attribute *sysattr = NULL; int ret = 0; switch (flag) { case 0: sysattr = sysfs_open_attribute(val_file_path); if (sysattr == NULL) { dbg_print("%s: failed opening attribute at %s\n", __FUNCTION__, val_file_path); return 0; } break; case 1: sysattr = NULL; break; default: return -1; } ret = sysfs_read_attribute(sysattr); switch (flag) { case 0: if (ret != 0) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_attribute(sysattr); dbg_print("\n"); } break; case 1: if (ret == 0) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (sysattr != NULL) sysfs_close_attribute(sysattr); return 0; } /** * extern int sysfs_write_attribute(struct sysfs_attribute *sysattr, * const char *new_value, size_t len); * * flag: * 0: sysattr -> valid, new_value -> valid, len -> valid; * 1: sysattr -> valid, new_value -> invalid, len -> invalid; * 2: sysattr -> valid, new_value -> NULL, len -> invalid; * 3: sysattr -> NULL, new_value -> valid, len -> valid; * 4: sysattr -> NULL, new_value -> invalid, len -> invalid; * 5: sysattr -> NULL, new_value -> NULL, len -> invalid; */ int test_sysfs_write_attribute(int flag) { struct sysfs_attribute *sysattr = NULL; char *new_value = NULL; size_t len = 0; int ret = 0; switch (flag) { case 0: sysattr = sysfs_open_attribute(val_write_attr_path); if (sysattr == NULL) { dbg_print("%s: failed opening attribute at %s\n", __FUNCTION__, val_write_attr_path); return 0; } if (sysfs_read_attribute(sysattr) != 0) { dbg_print("%s: failed reading attribute at %s\n", __FUNCTION__, val_write_attr_path); return 0; } new_value = calloc(1, sysattr->len + 1); strncpy(new_value, sysattr->value, sysattr->len); len = sysattr->len; break; case 1: sysattr = sysfs_open_attribute(val_write_attr_path); if (sysattr == NULL) { dbg_print("%s: failed opening attribute at %s\n", __FUNCTION__, val_write_attr_path); return 0; } new_value = calloc(1, SYSFS_PATH_MAX); strncpy(new_value, "this should not get copied in the attrib", SYSFS_PATH_MAX); len = SYSFS_PATH_MAX; break; case 2: sysattr = sysfs_open_attribute(val_write_attr_path); if (sysattr == NULL) { dbg_print("%s: failed opening attribute at %s\n", __FUNCTION__, val_write_attr_path); return 0; } new_value = NULL; len = SYSFS_PATH_MAX; break; case 3: sysattr = sysfs_open_attribute(val_write_attr_path); if (sysattr == NULL) { dbg_print("%s: failed opening attribute at %s\n", __FUNCTION__, val_write_attr_path); return 0; } new_value = calloc(1, sysattr->len + 1); strncpy(new_value, sysattr->value, sysattr->len); len = sysattr->len; sysfs_close_attribute(sysattr); sysattr = NULL; break; case 4: sysattr = NULL; new_value = calloc(1, SYSFS_PATH_MAX); strncpy(new_value, "this should not get copied in the attrib", SYSFS_PATH_MAX); len = SYSFS_PATH_MAX; break; case 5: sysattr = NULL; new_value = NULL; len = SYSFS_PATH_MAX; break; default: return -1; } ret = sysfs_write_attribute(sysattr, new_value, len); switch (flag) { case 0: if (ret != 0) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); dbg_print("Attribute at %s now has value %s\n\n", sysattr->path, sysattr->value); } break; case 1: case 2: case 3: case 4: case 5: if (ret == 0) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (sysattr != NULL) { sysfs_close_attribute(sysattr); sysattr = NULL; } if (new_value != NULL) free(new_value); return 0; } sysfsutils-2.1.1/test/test_bus.c000066400000000000000000000227571401370461400167330ustar00rootroot00000000000000/* * test_bus.c * * Tests for bus related functions for the libsysfs testsuite * * Copyright (C) IBM Corp. 2004-2005 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * */ /** ****************************************************************************** * this will test the bus related functions provided by libsysfs. * * extern void sysfs_close_bus(struct sysfs_bus *bus); * extern struct sysfs_bus *sysfs_open_bus(const char *name); * extern struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, * char *id); * extern struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus, * char *drvname); * extern struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus); * extern struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus); ****************************************************************************** */ #include "config.h" #include "test-defs.h" #include /** * extern void sysfs_close_bus(struct sysfs_bus *bus); * * flags: * 0 -> bus -> valid * 1 -> bus -> null. */ int test_sysfs_close_bus(int flag) { struct sysfs_bus *bus = NULL; char *bus_name = NULL; switch (flag) { case 0: bus_name = val_bus_name; bus = sysfs_open_bus(bus_name); if (bus == NULL) { dbg_print("%s: sysfs_open_bus() failed\n",__FUNCTION__); return 0; } break; case 1: bus = NULL; break; default: return -1; } sysfs_close_bus(bus); dbg_print("%s: returns void\n", __FUNCTION__); return 0; } /** * extern struct sysfs_bus *sysfs_open_bus(const char *name); * * flag: * 0 - name -> valid * 1 - name -> invalid * 2 - name -> null */ int test_sysfs_open_bus(int flag) { struct sysfs_bus *bus = NULL; char *name = NULL; switch (flag) { case 0: name = val_bus_name; break; case 1: name = inval_name; break; case 2: name = NULL; break; default: return -1; } bus = sysfs_open_bus(name); switch (flag) { case 0: if (bus == NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); dbg_print("Bus = %s, path = %s\n\n", bus->name, bus->path); } break; case 1: case 2: if (bus != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: return 0; } if (bus != NULL) sysfs_close_bus(bus); return 0; } /** * extern struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, * char *id); * * flag: * 0 : bus -> valid, id -> valid * 1 : bus -> valid, id -> invalid * 2 : bus -> valid, id -> NULL * 3 : bus -> NULL, id -> valid * 4 : bus -> NULL, id -> invalid * 5 : bus -> NULL, id -> NULL */ int test_sysfs_get_bus_device(int flag) { struct sysfs_bus *bus = NULL; struct sysfs_device *dev = NULL; char *bus_name = NULL; char *id = NULL; switch(flag) { case 0: bus_name = val_bus_name; bus = sysfs_open_bus(bus_name); if (bus == NULL) { dbg_print("%s: sysfs_open_bus() failed\n",__FUNCTION__); return 0; } id = val_bus_id; break; case 1: bus_name = val_bus_name; bus = sysfs_open_bus(bus_name); if (bus == NULL) { dbg_print("%s: sysfs_open_bus() failed\n",__FUNCTION__); return 0; } id = inval_name; break; case 2: bus_name = val_bus_name; bus = sysfs_open_bus(bus_name); if (bus == NULL) { dbg_print("%s: sysfs_open_bus() failed\n",__FUNCTION__); return 0; } id = NULL; break; case 3: bus = NULL; id = val_bus_id; break; case 4: bus = NULL; id = inval_name; break; case 5: bus = NULL; id = NULL; break; default: return -1; } dev = sysfs_get_bus_device(bus, id); switch (flag) { case 0: if (dev == NULL) { if (errno == 0) dbg_print("%s: Device %s not on bus %s\n", __FUNCTION__, id, bus_name); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_device(dev); dbg_print("\n"); } break; case 1: case 2: case 3: case 4: case 5: if (dev != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (bus != NULL) sysfs_close_bus(bus); return 0; } /** * extern struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus, * char *drvname); * * flag: * 0 : bus -> valid, drvname -> valid * 1 : bus -> valid, drvname -> invalid * 2 : bus -> valid, drvname -> NULL * 3 : bus -> NULL, drvname -> valid * 4 : bus -> NULL, drvname -> invalid * 5 : bus -> NULL, drvname -> NULL */ int test_sysfs_get_bus_driver(int flag) { struct sysfs_bus *bus = NULL; struct sysfs_driver *drv = NULL; char *drvname = NULL; char *bus_name = NULL; switch(flag) { case 0: bus_name = val_drv_bus_name; bus = sysfs_open_bus(bus_name); if (bus == NULL) { dbg_print("%s: sysfs_open_bus() failed\n",__FUNCTION__); return 0; } drvname = val_drv_name; break; case 1: bus_name = val_drv_bus_name; bus = sysfs_open_bus(bus_name); if (bus == NULL) { dbg_print("%s: sysfs_open_bus() failed\n",__FUNCTION__); return 0; } drvname = inval_name; break; case 2: bus_name = val_drv_bus_name; bus = sysfs_open_bus(bus_name); if (bus == NULL) { dbg_print("%s: sysfs_open_bus() failed\n",__FUNCTION__); return 0; } drvname = NULL; break; case 3: bus = NULL; drvname = val_drv_name; break; case 4: bus = NULL; drvname = inval_name; break; case 5: bus = NULL; drvname = NULL; break; default: return -1; } drv = sysfs_get_bus_driver(bus, drvname); switch (flag) { case 0: if (drv == NULL) { if (errno == 0) dbg_print("%s: Driver %s not on bus %s\n", __FUNCTION__, drvname, bus_name); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_driver(drv); dbg_print("\n"); } break; case 1: case 2: case 3: case 4: case 5: if (drv != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (bus != NULL) sysfs_close_bus(bus); return 0; } /** * extern struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus); * * flag: * 0 : bus -> valid * 1 : bus -> NULL */ int test_sysfs_get_bus_drivers(int flag) { struct sysfs_bus *bus = NULL; struct dlist *list = NULL; char *bus_name = NULL; switch (flag) { case 0: bus_name = val_bus_name; bus = sysfs_open_bus(bus_name); if (bus == NULL) { dbg_print("%s: sysfs_open_bus() failed\n",__FUNCTION__); return 0; } break; case 1: bus = NULL; break; default: return -1; } list = sysfs_get_bus_drivers(bus); switch (flag) { case 0: if (list == NULL) { if (errno == 0) dbg_print("%s: No drivers registered with bus %s\n", __FUNCTION__, bus_name); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_driver_list(list); dbg_print("\n"); } break; case 1: if (list != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: return 0; } if (bus != NULL) sysfs_close_bus(bus); return 0; } /** * extern struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus); * * flag: * 0 : bus -> valid * 1 : bus -> NULL */ int test_sysfs_get_bus_devices(int flag) { struct sysfs_bus *bus = NULL; struct dlist *list = NULL; char *bus_name = NULL; switch (flag) { case 0: bus_name = val_bus_name; bus = sysfs_open_bus(bus_name); if (bus == NULL) { dbg_print("%s: sysfs_open_bus() failed\n",__FUNCTION__); return 0; } break; case 1: bus = NULL; break; default: return -1; } list = sysfs_get_bus_devices(bus); switch (flag) { case 0: if (list == NULL) { if (errno == 0) dbg_print("%s: No devices registered with bus %s\n", __FUNCTION__, bus_name); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_device_list(list); dbg_print("\n"); } break; case 1: if (list != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: return 0; } if (bus != NULL) sysfs_close_bus(bus); return 0; } sysfsutils-2.1.1/test/test_class.c000066400000000000000000000415041401370461400172360ustar00rootroot00000000000000/* * test_class.c * * Tests for class related functions for the libsysfs testsuite * * Copyright (C) IBM Corp. 2004-2005 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * */ /** *************************************************************************** * this will test the class related functions provided by libsysfs. * * extern void sysfs_close_class_device(struct sysfs_class_device *dev); * extern struct sysfs_class_device *sysfs_open_class_device_path * (const char *path); * extern struct sysfs_class_device *sysfs_open_class_device * (const char *classname, const char *name); * extern struct sysfs_device *sysfs_get_classdev_device * (struct sysfs_class_device *clsdev); * extern struct sysfs_class_device *sysfs_get_classdev_parent * (struct sysfs_class_device *clsdev); * extern void sysfs_close_class(struct sysfs_class *cls); * extern struct sysfs_class *sysfs_open_class(const char *name); * extern struct dlist *sysfs_get_class_devices(struct sysfs_class *cls); * extern struct sysfs_class_device *sysfs_get_class_device * (struct sysfs_class *cls, char *name); * extern struct dlist *sysfs_get_classdev_attributes * (struct sysfs_class_device *cdev); * extern struct sysfs_attribute *sysfs_get_classdev_attr * (struct sysfs_class_device *clsdev, const char *name); ***************************************************************************** */ #include "config.h" #include "test-defs.h" #include /** * this test the function: * extern void sysfs_close_class_device(struct sysfs_class_device *dev); * this has no return, * * flag: * 0: dev -> valid * 1: dev -> NULL */ int test_sysfs_close_class_device(int flag) { struct sysfs_class_device *dev = NULL; char *path = NULL; switch (flag) { case 0: path = val_class_dev_path; dev = sysfs_open_class_device_path(path); if (dev == NULL) { dbg_print("%s: failed opening class device at %s\n", __FUNCTION__, path); return 0; } break; case 1: dev = NULL; break; default: return -1; } sysfs_close_class_device(dev); dbg_print("%s: returns void\n", __FUNCTION__); return 0; } /** * extern struct sysfs_class_device *sysfs_open_class_device_path * (const char *path); * flag: * 0: path -> valid * 1: path -> invalid * 2: path -> NULL */ int test_sysfs_open_class_device_path(int flag) { struct sysfs_class_device *dev = NULL; char *path = NULL; switch (flag) { case 0: path = val_class_dev_path; break; case 1: path = inval_path; break; case 2: path = NULL; break; default: return -1; } dev = sysfs_open_class_device_path(path); switch (flag) { case 0: if (dev == NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_class_device(dev); dbg_print("\n"); } break; case 1: case 2: if (dev != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); default: break; } if (dev != NULL) sysfs_close_class_device(dev); return 0; } /** * extern struct sysfs_class_device *sysfs_open_class_device * (const char *class, const char *name); * * flag: * 0: class -> valid , name -> valid * 1: class -> valid , name -> invalid * 2: class -> valid , name -> NULL * 3: class -> invalid , name -> valid * 4: class -> invalid , name -> invalid * 5: class -> invalid , name -> NULL * 6: class -> NULL valid , name -> valid * 7: class -> NULL , name -> invalid * 8: class -> NULL , name -> NULL */ int test_sysfs_open_class_device(int flag) { struct sysfs_class_device *clsdev = NULL; char *name = NULL; char *class = NULL; switch(flag) { case 0: class = val_class; name = val_class_dev; break; case 1: class = val_class; name = inval_name; break; case 2: class = val_class; name = NULL; break; case 3: class = inval_name; name = val_class_dev; break; case 4: class = inval_name; name = inval_name; break; case 5: class = inval_name; name = NULL; break; case 6: class = NULL; name = val_class_dev; break; case 7: class = NULL; name = inval_name; break; case 8: class = NULL; name = NULL; break; default: return -1; } clsdev = sysfs_open_class_device(class, name); switch(flag) { case 0: if (clsdev == NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_class_device(clsdev); dbg_print("\n"); } break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: if (clsdev != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (clsdev != NULL) sysfs_close_class_device(clsdev); return 0; } /** * extern struct sysfs_device *sysfs_get_classdev_device * (struct sysfs_class_device *clsdev); * * flag: * 0: clsdev -> valid * 1: clsdev -> NULL */ int test_sysfs_get_classdev_device(int flag) { struct sysfs_class_device *clsdev = NULL; struct sysfs_device *dev = NULL; char *path = NULL; switch(flag) { case 0: path = val_class_dev_path; clsdev = sysfs_open_class_device_path(path); if (clsdev == NULL) { dbg_print("%s: failed opening class device at %s\n", __FUNCTION__, path); return 0; } break; case 1: clsdev = NULL; break; default: return -1; } dev = sysfs_get_classdev_device(clsdev); switch (flag) { case 0: if (dev == NULL) { if (errno == 0) dbg_print("%s: Class device at %s does not have a device symlink\n", __FUNCTION__, path); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_device(dev); dbg_print("\n"); } break; case 1: if (dev != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (clsdev != NULL) sysfs_close_class_device(clsdev); return 0; } /** * extern struct sysfs_class_device *sysfs_get_classdev_parent * (struct sysfs_class_device *clsdev); * flag: * 0: clsdev -> valid * 1: clsdev -> NULL */ int test_sysfs_get_classdev_parent(int flag) { struct sysfs_class_device *clsdev = NULL; struct sysfs_class_device *parent = NULL; char *path = NULL; switch(flag) { case 0: path = val_block_class_dev_path; clsdev = sysfs_open_class_device_path(path); if (clsdev == NULL) { dbg_print("%s: failed opening class device at %s\n", __FUNCTION__, path); return 0; } break; case 1: clsdev = NULL; break; default: return -1; } parent = sysfs_get_classdev_parent(clsdev); switch (flag) { case 0: if (parent == NULL) { if (errno == 0) dbg_print("%s: Class device at %s does not have a parent\n", __FUNCTION__, path); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_class_device(parent); dbg_print("\n"); } break; case 1: if (parent != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (clsdev != NULL) sysfs_close_class_device(clsdev); return 0; } /** * extern void sysfs_close_class(struct sysfs_class *cls); * * flag: * 0: cls -> valid * 1: cls -> NULL */ int test_sysfs_close_class(int flag) { struct sysfs_class *cls = NULL; char *class = NULL; switch(flag) { case 0: class = val_class; cls = sysfs_open_class(class); if (cls == NULL) { dbg_print("%s: failed opening class device at %s\n", __FUNCTION__, class); return 0; } break; case 1: cls = NULL; break; default: return -1; } sysfs_close_class(cls); dbg_print("%s: returns void\n", __FUNCTION__); return 0; } /** * extern struct sysfs_class *sysfs_open_class(const char *name); * * flag: * 0: name -> valid * 1: name -> invalid * 2: name -> NULL */ int test_sysfs_open_class(int flag) { struct sysfs_class *cls = NULL; char *name = NULL; switch(flag) { case 0: name = val_class; break; case 1: name = inval_name; break; case 2: name = NULL; break; default: return -1; } cls = sysfs_open_class(name); switch(flag) { case 0: if (cls == NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); dbg_print("Class %s is at %s\n\n", cls->name, cls->path); } break; case 1: case 2: if (cls != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (cls != NULL) sysfs_close_class(cls); return 0; } /** * extern struct dlist *sysfs_get_class_devices(struct sysfs_class *cls); * * flag: * 0: cls -> valid * 1: cls -> NULL */ int test_sysfs_get_class_devices(int flag) { struct sysfs_class *cls = NULL; struct dlist *list = NULL; char *class = NULL; switch(flag) { case 0: class = val_class; cls = sysfs_open_class(class); if (cls == NULL) { dbg_print("%s: failed opening class device at %s\n", __FUNCTION__, class); return 0; } break; case 1: cls = NULL; break; default: return -1; } list = sysfs_get_class_devices(cls); switch(flag) { case 0: if (list == NULL) { if (errno == 0) dbg_print("%s: Class %s does not have devices\n", __FUNCTION__, val_class); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_class_device_list(list); dbg_print("\n"); } break; case 1: if (list != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (cls != NULL) sysfs_close_class(cls); return 0; } /** * extern struct sysfs_class_device *sysfs_get_class_device * (struct sysfs_class *class, char *name); * * flag: * 0: class -> valid, name -> valid * 1: class -> valid, name -> invalid * 2: class -> valid, name -> NULL * 3: class -> NULL, name -> valid * 4: class -> NULL, name -> invalid * 5: class -> NULL, name -> NULL */ int test_sysfs_get_class_device(int flag) { struct sysfs_class_device *clsdev = NULL; struct sysfs_class *class = NULL; char *name = NULL; switch(flag) { case 0: class = sysfs_open_class(val_class); if (class == NULL) { dbg_print("%s: failed opening class %s\n", __FUNCTION__, val_class); return 0; } name = val_class_dev; break; case 1: class = sysfs_open_class(val_class); if (class == NULL) { dbg_print("%s: failed opening class %s\n", __FUNCTION__, val_class); return 0; } name = inval_name; break; case 2: class = sysfs_open_class(val_class); if (class == NULL) { dbg_print("%s: failed opening class %s\n", __FUNCTION__, val_class); return 0; } name = NULL; break; case 3: class = NULL; name = val_class_dev; break; case 4: class = NULL; name = inval_name; break; case 5: class = NULL; name = NULL; break; default: return -1; } clsdev = sysfs_get_class_device(class, name); switch(flag) { case 0: if (clsdev == NULL) { if (errno == 0) dbg_print("%s: Class device %s does not belong to the %s class\n", __FUNCTION__, val_class_dev, val_class); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_class_device(clsdev); dbg_print("\n"); } break; case 1: case 2: case 3: case 4: case 5: if (clsdev != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); default: break; } if (class) sysfs_close_class(class); return 0; } /** * extern struct dlist *sysfs_get_classdev_attributes * (struct sysfs_class_device *cdev); * flag: * 0: cdev -> valid * 1: cdev -> NULL */ int test_sysfs_get_classdev_attributes(int flag) { struct dlist *list = NULL; struct sysfs_class_device *cdev = NULL; char *path = NULL; switch (flag) { case 0: path = val_class_dev_path; cdev = sysfs_open_class_device_path(path); if (cdev == NULL) { dbg_print("%s: failed opening class device at %s\n", __FUNCTION__, path); return 0; } break; case 1: cdev = NULL; break; default: return -1; } list = sysfs_get_classdev_attributes(cdev); switch (flag) { case 0: if (list == NULL) { if (errno == 0) dbg_print("%s: Class device at %s does not export attributes\n", __FUNCTION__, path); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_attribute_list(list); dbg_print("\n"); } break; case 1: if (list != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); default: break; } if (cdev != NULL) sysfs_close_class_device(cdev); return 0; } /** * extern struct sysfs_attribute *sysfs_get_classdev_attr * (struct sysfs_class_device *clsdev, const char *name); * * flag: * 0: clsdev -> valid, name -> valid * 1: clsdev -> valid, name -> invalid * 2: clsdev -> valid, name -> NULL * 3: clsdev -> NULL, name -> valid * 4: clsdev -> NULL, name -> invalid * 5: clsdev -> NULL, name -> NULL */ int test_sysfs_get_classdev_attr(int flag) { struct sysfs_attribute *attr = NULL; struct sysfs_class_device *clsdev = NULL; char *name = NULL; char *path = NULL; switch (flag) { case 0: path = val_class_dev_path; clsdev = sysfs_open_class_device_path(path); if (clsdev == NULL) { dbg_print("%s: failed opening class device at %s\n", __FUNCTION__, path); return 0; } name = val_class_dev_attr; break; case 1: path = val_class_dev_path; clsdev = sysfs_open_class_device_path(path); if (clsdev == NULL) { dbg_print("%s: failed opening class device at %s\n", __FUNCTION__, path); return 0; } name = inval_name; break; case 2: path = val_class_dev_path; clsdev = sysfs_open_class_device_path(path); if (clsdev == NULL) { dbg_print("%s: failed opening class device at %s\n", __FUNCTION__, path); return 0; } name = NULL; break; case 3: clsdev = NULL; name = val_class_dev_attr; break; case 4: clsdev = NULL; name = inval_name; break; case 5: clsdev = NULL; name = NULL; break; default: return -1; } attr = sysfs_get_classdev_attr(clsdev, name); switch (flag) { case 0: if (attr == NULL) { if (errno == EACCES) dbg_print("%s: attribute %s does not support READ\n", __FUNCTION__, name); else if (errno == ENOENT) dbg_print("%s: attribute %s not defined for class device at %s\n", __FUNCTION__, name, path); else if (errno == 0) dbg_print("%s: class device at %s does not export attributes\n", __FUNCTION__, path); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_attribute(attr); dbg_print("\n"); } break; case 1: case 2: case 3: case 4: case 5: if (attr != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); default: break; } if (clsdev != NULL) sysfs_close_class_device(clsdev); return 0; } sysfsutils-2.1.1/test/test_device.c000066400000000000000000000231631401370461400173710ustar00rootroot00000000000000/* * test_root.c * * Tests for device/root device related functions for the libsysfs testsuite * * Copyright (C) IBM Corp. 2004-2005 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * */ /** ****************************************************************************** * this will test the device/root device related functions provided by libsysfs * * extern void sysfs_close_device(struct sysfs_device *dev); * extern struct sysfs_device *sysfs_open_device * (const char *bus, const char *bus_id); * extern struct sysfs_device *sysfs_get_device_parent * (struct sysfs_device *dev); * extern struct sysfs_device *sysfs_open_device_path * (const char *path); * extern struct sysfs_attribute *sysfs_get_device_attr * (struct sysfs_device *dev, const char *name); * extern struct dlist *sysfs_get_device_attributes * (struct sysfs_device *device); ****************************************************************************** */ #include "config.h" #include "test-defs.h" #include /** * extern void sysfs_close_device(struct sysfs_device *dev); * * flag: * 0: dev -> valid * 1: dev -> NULL */ int test_sysfs_close_device(int flag) { struct sysfs_device *dev = NULL; char *path = NULL; switch (flag) { case 0: path = val_dev_path; dev = sysfs_open_device_path(path); if (dev == NULL) { dbg_print("%s: failed to open device at %s\n", __FUNCTION__, path); return 0; } break; case 1: dev = NULL; break; default: return -1; } sysfs_close_device(dev); dbg_print("%s: returns void\n", __FUNCTION__); return 0; } /** * extern struct sysfs_device *sysfs_open_device * (const char *bus, const char *bus_id); * * flag: * 0: bus -> valid, bus_id -> valid * 1: bus -> valid, bus_id -> invalid * 2: bus -> valid, bus_id -> invalid * 3: bus -> invalid, bus_id -> valid * 4: bus -> invalid, bus_id -> invalid * 5: bus -> invalid, bus_id -> invalid * 6: bus -> NULL, bus_id -> valid * 7: bus -> NULL, bus_id -> invalid * 8: bus -> NULL, bus_id -> invalid */ int test_sysfs_open_device(int flag) { struct sysfs_device *dev = NULL; char *bus = NULL; char *bus_id = NULL; switch (flag) { case 0: bus = val_bus_name; bus_id = val_bus_id; break; case 1: bus = val_bus_name; bus_id = inval_name; break; case 2: bus = val_bus_name; bus_id = NULL; break; case 3: bus = inval_name; bus_id = val_bus_id; break; case 4: bus = inval_name; bus_id = inval_name; break; case 5: bus = inval_name; bus_id = NULL; break; case 6: bus = NULL; bus_id = val_bus_id; break; case 7: bus = NULL; bus_id = inval_name; break; case 8: bus = NULL; bus_id = NULL; break; default: return -1; } dev = sysfs_open_device(bus, bus_id); switch (flag) { case 0: if (dev == NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_device(dev); dbg_print("\n"); break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: if (dev == NULL) dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); break; } if (dev != NULL) sysfs_close_device(dev); return 0; } /** * extern struct sysfs_device *sysfs_get_device_parent * (struct sysfs_device *dev); * * flag: * 0: dev -> valid * 1: dev -> NULL */ int test_sysfs_get_device_parent(int flag) { struct sysfs_device *pdev = NULL; struct sysfs_device *dev = NULL; char *dev_path = NULL; switch (flag) { case 0: dev_path = val_dev_path; dev = sysfs_open_device_path(dev_path); if (dev == NULL) { dbg_print("%s: failed to open device at %s\n", __FUNCTION__, dev_path); return 0; } break; case 1: dev = NULL; break; default: return -1; } pdev = sysfs_get_device_parent(dev); switch (flag) { case 0: if (pdev == NULL) { if (errno == 0) dbg_print("%s: Device at %s does not have a parent\n", __FUNCTION__, dev_path); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_device(pdev); dbg_print("\n"); } break; case 1: if (pdev == NULL) dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); default: break; } if (dev != NULL) { sysfs_close_device(dev); } return 0; } /** * extern struct sysfs_device *sysfs_open_device_path * (const char *path); * * flag: * 0: path -> valid * 1: path -> invalid * 2: path -> NULL * */ int test_sysfs_open_device_path(int flag) { struct sysfs_device *dev = NULL; char *path = NULL; switch (flag) { case 0: path = val_dev_path; break; case 1: path = inval_path; break; case 2: path = NULL; break; default: return -1; } dev = sysfs_open_device_path(path); switch (flag) { case 0: if (dev == NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_device(dev); dbg_print("\n"); } break; case 1: case 2: if (dev == NULL) dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); default: break; } if (dev != NULL) sysfs_close_device(dev); return 0; } /** * extern struct sysfs_attribute *sysfs_get_device_attr * (struct sysfs_device *dev, const char *name); * * flag: * 0: dev -> valid, name -> valid * 1: dev -> valid, name -> invalid * 2: dev -> valid, name -> NULL * 3: dev -> NULL, name -> valid * 4: dev -> NULL, name -> invalid * 5: dev -> NULL, name -> NULL */ int test_sysfs_get_device_attr(int flag) { struct sysfs_device *dev = NULL; char *name = NULL; char *path = NULL; struct sysfs_attribute *attr = NULL; switch (flag) { case 0: path = val_dev_path; dev = sysfs_open_device_path(path); if (dev == NULL) { dbg_print("%s: failed to open device at %s\n", __FUNCTION__, path); return 0; } name = val_dev_attr; break; case 1: dev = sysfs_open_device_path(path); name = inval_name; break; case 2: dev = sysfs_open_device_path(path); name = NULL; break; case 3: dev = NULL; name = val_dev_attr; break; case 4: dev = NULL; name = inval_name; break; case 5: dev = NULL; name = NULL; break; default: return -1; } attr = sysfs_get_device_attr(dev, name); switch (flag) { case 0: if (attr == NULL) { if (errno == EACCES) dbg_print("%s: attribute %s does not support READ\n", __FUNCTION__, name); else if (errno == ENOENT) dbg_print("%s: attribute %s not defined for device at %s\n", __FUNCTION__, name, path); else if (errno == 0) dbg_print("%s: device at %s does not export attributes\n", __FUNCTION__, path); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_attribute(attr); dbg_print("\n"); } break; case 1: case 2: case 3: case 4: case 5: if (attr != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { if (errno == EINVAL) dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); } default: break; } if (dev != NULL) sysfs_close_device(dev); return 0; } /** * extern struct dlist *sysfs_get_device_attributes * (struct sysfs_device *device); * * flag: * 0: device -> valid * 1: device -> NULL */ int test_sysfs_get_device_attributes(int flag) { struct sysfs_device *device = NULL; struct dlist *list = NULL; char *path = NULL; switch (flag) { case 0: path = val_dev_path; device = sysfs_open_device_path(path); if (device == NULL) { dbg_print("%s: failed to open device at %s\n", __FUNCTION__, path); return 0; } break; case 1: device = NULL; break; default: return -1; } list = sysfs_get_device_attributes(device); switch (flag) { case 0: if (list == NULL) { if (errno == 0) dbg_print("%s: device at %s does not export attributes\n", __FUNCTION__, path); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_attribute_list(list); dbg_print("\n"); } break; case 1: if (errno != EINVAL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); default: break; } if (device != NULL) sysfs_close_device(device); return 0; } sysfsutils-2.1.1/test/test_driver.c000066400000000000000000000244471401370461400174330ustar00rootroot00000000000000/* * test_driver.c * * Tests for driver related functions for the libsysfs testsuite * * Copyright (C) IBM Corp. 2004-2005 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * */ /** ****************************************************************************** * this will test the driver related functions provided by libsysfs. * * extern void sysfs_close_driver(struct sysfs_driver *driver); * extern struct sysfs_driver *sysfs_open_driver * (const char *bus_name, const char *drv_name); * extern struct sysfs_driver *sysfs_open_driver_path * (const char *path); * extern struct sysfs_attribute *sysfs_get_driver_attr * (struct sysfs_driver *drv, const char *name); * extern struct dlist *sysfs_get_driver_attributes * (struct sysfs_driver *driver); * extern struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver); ****************************************************************************** */ #include "config.h" #include "test-defs.h" #include /** * extern void sysfs_close_driver(struct sysfs_driver *driver); * * flag: * 0: driver -> valid * 1: driver -> NULL */ int test_sysfs_close_driver(int flag) { struct sysfs_driver *driver = NULL; switch (flag) { case 0: driver = sysfs_open_driver_path(val_drv_path); if (driver == NULL) return 0; break; case 1: driver = NULL; break; default: return -1; } sysfs_close_driver(driver); dbg_print("%s: returns void\n", __FUNCTION__); return 0; } /** * extern struct sysfs_driver *sysfs_open_driver_path * (const char *path); * * flag: * 0: path -> valid * 1: path -> invalid * 2: path -> NULL */ int test_sysfs_open_driver_path(int flag) { struct sysfs_driver *driver = NULL; char *path = NULL; switch (flag) { case 0: path = val_drv_path; break; case 1: path = inval_path; break; case 2: path = NULL; break; default: return -1; } driver = sysfs_open_driver_path(path); switch (flag) { case 0: if (driver == NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_driver(driver); dbg_print("\n"); } break; case 1: case 2: if (driver != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); default: break; } if (driver != NULL) sysfs_close_driver(driver); return 0; } /** * extern struct sysfs_driver *sysfs_open_driver * (const char *bus_name, const char *drv_name); * * flag: * 0: path -> valid, name -> valid * 1: path -> valid, name -> invalid * 2: path -> valid, name -> NULL * 3: path -> invalid, name -> valid * 4: path -> invalid, name -> invalid * 5: path -> invalid, name -> NULL * 6: path -> NULL, name -> valid * 7: path -> NULL, name -> invalid * 8: path -> NULL, name -> NULL */ int test_sysfs_open_driver(int flag) { struct sysfs_driver *driver = NULL; char *bus_name = NULL; char *drv_name = NULL; switch (flag) { case 0: bus_name = val_drv_bus_name; drv_name = val_drv_name; dbg_print("bus_name = %s, drv_name = %s\n", bus_name, drv_name); break; case 1: bus_name = val_drv_bus_name; drv_name = inval_name; break; case 2: bus_name = val_drv_bus_name; drv_name = NULL; break; case 3: bus_name = inval_name; drv_name = val_drv_name; break; case 4: bus_name = inval_name; drv_name = inval_name; break; case 5: bus_name = inval_name; drv_name = NULL; break; case 6: bus_name = NULL; drv_name = val_drv_name; break; case 7: bus_name = NULL; drv_name = inval_name; break; case 8: bus_name = NULL; drv_name = NULL; break; default: return -1; } driver = sysfs_open_driver(bus_name, drv_name); switch (flag) { case 0: if (driver == NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_driver(driver); dbg_print("\n"); } break; case 1: case 2: if (driver != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); default: break; } if (driver != NULL) sysfs_close_driver(driver); return 0; } /** * extern struct sysfs_attribute *sysfs_get_driver_attr * (struct sysfs_driver *drv, const char *name); * * flag: * 0: drv -> valid, name -> valid * 1: drv -> valid, name -> invalid * 2: drv -> valid, name -> NULL * 3: drv -> NULL, name -> valid * 4: drv -> NULL, name -> invalid * 5: drv -> NULL, name -> NULL */ int test_sysfs_get_driver_attr(int flag) { char *name = NULL; char *attrname = NULL; struct sysfs_driver *drv = NULL; struct sysfs_attribute *attr = NULL; switch (flag) { case 0: name = val_drv_path; drv = sysfs_open_driver_path(name); if (drv == NULL) { dbg_print("%s: failed opening driver at %s\n", __FUNCTION__, name); return 0; } attrname = val_drv_attr_name; break; case 1: name = val_drv_path; drv = sysfs_open_driver_path(name); if (drv == NULL) { dbg_print("%s: failed opening driver at %s\n", __FUNCTION__, name); return 0; } attrname = inval_name; break; case 2: name = val_drv_path; drv = sysfs_open_driver_path(name); if (drv == NULL) { dbg_print("%s: failed opening driver at %s\n", __FUNCTION__, name); return 0; } attrname = NULL; break; case 3: drv = NULL; attrname = val_drv_attr_name; break; case 4: drv = NULL; attrname = inval_name; break; case 5: drv = NULL; attrname = NULL; break; default: return -1; } attr = sysfs_get_driver_attr(drv, attrname); switch (flag) { case 0: if (attr == NULL) { if (errno == EACCES) dbg_print("%s: attribute %s does not support READ\n", __FUNCTION__, attrname); else if (errno == ENOENT) dbg_print("%s: attribute %s not defined for driver at %s\n", __FUNCTION__, attrname, name); else if (errno == 0) dbg_print("%s: driver at %s does not export attributes\n", __FUNCTION__, val_drv_path); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_attribute(attr); dbg_print("\n"); } break; case 1: case 2: case 3: case 4: case 5: if (attr != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); default: break; } if (drv != NULL) sysfs_close_driver(drv); return 0; } /** * extern struct dlist *sysfs_get_driver_attributes * (struct sysfs_driver *driver); * * flag: * 0: driver -> valid * 1: driver -> NULL */ int test_sysfs_get_driver_attributes(int flag) { struct sysfs_driver *driver = NULL; struct dlist *list = NULL; char *drv = NULL; switch (flag) { case 0: drv = val_drv_path; driver = sysfs_open_driver_path(drv); if (driver == NULL) { dbg_print("%s: failed opening driver at %s\n", __FUNCTION__, val_drv_path); return 0; } break; case 1: driver = NULL; break; case 2: drv = val_drv1_path; driver = sysfs_open_driver_path(drv); if (driver == NULL) { dbg_print("%s: failed opening driver at %s\n", __FUNCTION__, val_drv1_path); return 0; } break; default: return -1; } list = sysfs_get_driver_attributes(driver); switch (flag) { case 0: case 2: if (list == NULL) { if (errno == 0) dbg_print("%s: No attributes are defined for the driver at %s\n", __FUNCTION__, drv); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_attribute_list(list); dbg_print("\n"); } break; case 1: if (list != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); default: break; } if (driver != NULL) sysfs_close_driver(driver); return 0; } /** * extern struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver); * * flag: * 0: driver -> valid * 1: driver -> NULL */ int test_sysfs_get_driver_devices(int flag) { struct sysfs_driver *driver = NULL; struct dlist *list = NULL; char *drv = NULL; switch (flag) { case 0: drv = val_drv_path; driver = sysfs_open_driver_path(drv); if (driver == NULL) { dbg_print("%s: failed opening driver at %s\n", __FUNCTION__, val_drv_path); return 0; } break; case 1: driver = NULL; break; case 2: drv = val_drv1_path; driver = sysfs_open_driver_path(drv); if (driver == NULL) { dbg_print("%s: failed opening driver at %s\n", __FUNCTION__, val_drv1_path); return 0; } break; default: return -1; } errno = 0; list = sysfs_get_driver_devices(driver); switch (flag) { case 0: case 2: if (list == NULL) { if (errno == 0) dbg_print("%s: No devices are using the driver at %s\n", __FUNCTION__, drv); else dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_device_list(list); dbg_print("\n"); } break; case 1: if (list != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); default: break; } if (driver != NULL) sysfs_close_driver(driver); return 0; } sysfsutils-2.1.1/test/test_module.c000066400000000000000000000366321401370461400174240ustar00rootroot00000000000000/* * sysfs_module.c * * Generic module utility functions for libsysfs * * Copyright (C) IBM Corp. 2003-2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ /** *************************************************************************** * this will test the module related functions provided by libsysfs. * * extern void sysfs_close_module(struct sysfs_module *module); * extern struct sysfs_module *sysfs_open_module_path(const char *path); * extern struct sysfs_module *sysfs_open_module(const char *name); * extern struct dlist *sysfs_get_module_attributes * (struct sysfs_module *module); * extern struct sysfs_attribute *sysfs_get_module_attr * (struct sysfs_module *module, const char *name); * extern struct dlist *sysfs_get_module_parms(struct sysfs_module *module); * extern struct dlist *sysfs_get_module_sections(struct sysfs_module *module); * extern struct sysfs_attribute *sysfs_get_module_parm * (struct sysfs_module *module, const char *parm); * extern struct sysfs_attribute *sysfs_get_module_section * (struct sysfs_module *module, const char *section); */ #include "config.h" #include "test-defs.h" #include /** * sysfs_close_module: closes a module. * @module: sysfs_module device to close. * flag: * 0: path -> valid * 1: path -> NULL */ int test_sysfs_close_module(int flag) { struct sysfs_module *module; switch (flag) { case 0: module = sysfs_open_module_path(val_mod_path); if (module == NULL) return 0; break; case 1: module = NULL; break; default: return -1; } sysfs_close_module(module); dbg_print("%s: returns void\n",__FUNCTION__); return 0; } /** * sysfs_open_module_path: Opens and populates the module struct * @path: path to module. * returns struct sysfs_module with success and NULL with error. * * flag: * 0: path -> valid * 1: path -> invalid * 2: path -> NULL */ int test_sysfs_open_module_path(int flag) { struct sysfs_module *module = NULL; char *path = NULL; switch (flag) { case 0: path = val_mod_path; break; case 1: path = inval_path; break; case 2: path = NULL; break; default: return -1; } module = sysfs_open_module_path(path); switch (flag) { case 0: if (module == NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_module(module); dbg_print("\n"); } break; case 1: case 2: if (module != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); default: break; } if (module!= NULL) sysfs_close_module(module); return 0; } /** * sysfs_open_module: opens specific module on a system * returns sysfs_module structure with success or NULL with error. * flag: * 0: name -> valid * 1: name -> invalid * 2: name -> NULL */ int test_sysfs_open_module(int flag) { struct sysfs_module *module = NULL; char *modname = NULL; switch (flag) { case 0: modname = val_mod_name; break; case 1: modname = inval_name; break; case 2: modname = NULL; break; default: return -1; } module = sysfs_open_module(modname); switch (flag) { case 0: if (module == NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_module(module); dbg_print("\n"); } break; case 1: case 2: if (module) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (module) sysfs_close_module(module); return 0; } /** * sysfs_get_module_attr: searches module's attributes by name * @module: module to look through * @name: attribute name to get * returns sysfs_attribute reference with success or NULL with error * flag: * 0: name -> valid, attrname -> valid * 1: name -> valid, attrname -> invalid * 2: name -> valid, attrname -> NULL */ int test_sysfs_get_module_attr(int flag) { char *name, *attrname; struct sysfs_attribute *attr; struct sysfs_module *module; switch (flag) { case 0: name = val_mod_path; module = sysfs_open_module_path(name); if (!module) { dbg_print("%s: failed opening module at %s\n", __FUNCTION__, name); return 0; } attrname = val_mod_attr_name; break; case 1: name = val_mod_path; module = sysfs_open_module_path(name); if (!module) { dbg_print("%s: failed opening module at %s\n", __FUNCTION__, name); return 0; } attrname = inval_name; break; case 2: name = val_mod_path; module = sysfs_open_module_path(name); if (!module) { dbg_print("%s: failed opening module at %s\n", __FUNCTION__, name); return 0; } attrname = NULL; break; default: return -1; } attr = sysfs_get_module_attr(module,attrname); switch (flag) { case 0: if(!attr) { if (errno == EACCES) dbg_print("%s: attribute %s does not support " "READ\n", __FUNCTION__, attrname); else if (errno == ENOENT) dbg_print("%s: attribute %s not defined for " "module at %s\n", __FUNCTION__, attrname, name); else if (errno == 0) dbg_print("%s: module at %s does not export " "attributes\n", __FUNCTION__, val_drv_path); else dbg_print("%s: FAILED with flag = %d errno = " "%d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_attribute(attr); dbg_print("\n"); } break; case 1: case 2: if (attr) dbg_print("%s: FAILED with flag = %d errno = " "%d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); dbg_print("******************\n"); default: break; } if (module) sysfs_close_module(module); return 0; } /** * sysfs_get_module_attributes: returns a dlist of attributes for * the requested sysfs_module * @cdev: sysfs_module for which attributes are needed * returns a dlist of attributes if exists, NULL otherwise * flag: * 0: name -> valid * 1: name -> invalid * 2: name -> NULL */ int test_sysfs_get_module_attributes(int flag) { struct dlist *list; struct sysfs_module *module; char *name; switch (flag) { case 0: name = val_mod_path; module = sysfs_open_module_path(name); if (!module) { dbg_print("%s: failed opening module at %s\n", __FUNCTION__, name); return 0; } break; case 1: name = inval_name; module = sysfs_open_module_path(name); if (!module) { return 0; } break; case 2: name = NULL; module = sysfs_open_module_path(name); if (!module) { return 0; } break; default: return -1; } list = sysfs_get_module_attributes(module); switch (flag) { case 0: if (!list) { if (errno == 0) dbg_print("%s: No attributes are defined for " "the module at %s\n", __FUNCTION__, name); else dbg_print("%s: FAILED with flag = %d errno = " "%d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_attribute_list(list); dbg_print("\n"); } break; case 1: case 2: if (list != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (module) sysfs_close_module(module); return 0; } /** * sysfs_get_module_parms: Get modules list of parameters * @module: sysfs_module whose parmameter list is required * Returns dlist of parameters on SUCCESS and NULL on error * flag: * 0: name -> valid * 1: name -> invalid * 2: name -> NULL */ int test_sysfs_get_module_parms(int flag) { struct dlist *params; char *name; struct sysfs_module *module; switch (flag) { case 0: name = val_mod_path; module = sysfs_open_module_path(name); if (!module) { dbg_print("%s: failed opening module at %s\n", __FUNCTION__, name); return 0; } break; case 1: name = inval_name; module = sysfs_open_module_path(name); if (!module) { return 0; } break; case 2: name = NULL; module = sysfs_open_module_path(name); if (!module) { return 0; } break; default: return -1; } params = sysfs_get_module_parms(module); switch (flag) { case 0: if (!params) { if (errno == 0) dbg_print("%s: No parameters are passed for " "the module at %s\n", __FUNCTION__, name); else dbg_print("%s: FAILED with flag = %d errno = " "%d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_parm_list(params); dbg_print("\n"); } break; case 1: case 2: if (params) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (module) sysfs_close_module(module); return 0; } /** * sysfs_get_module_sections: Get the set of sections for this module * @module: sysfs_module whose list of sections is required * Returns dlist of sections on SUCCESS and NULL on error * 0: name -> valid * 1: name -> invalid * 2: name -> NULL */ int test_sysfs_get_module_sections(int flag) { struct dlist *sections; char *name; struct sysfs_module *module; switch (flag) { case 0: name = val_mod_path; module = sysfs_open_module_path(name); if (!module) { dbg_print("%s: failed opening module at %s\n", __FUNCTION__, name); return 0; } break; case 1: name = inval_name; module = sysfs_open_module_path(name); if (!module) { return 0; } break; case 2: name = NULL; module = sysfs_open_module_path(name); if (!module) { return 0; } break; default: return -1; } sections = sysfs_get_module_sections(module); switch (flag) { case 0: if (!sections) { if (errno == 0) dbg_print("%s: No sections for the module at " "%s\n", __FUNCTION__, name); else dbg_print("%s: FAILED with flag = %d errno = " "%d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_section_list(sections); dbg_print("\n"); } break; case 1: case 2: if (sections) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (module) sysfs_close_module(module); return 0; } /** * sysfs_get_module_parm: * @module: sysfs_module to look through * @parm: name of the parameter to look for * Returns sysfs_attribute * on SUCCESS and NULL on error * flag: * 0: name -> valid, paramname -> valid * 1: name -> valid, paramname -> invalid * 2: name -> valid, paramname -> NULL */ int test_sysfs_get_module_parm(int flag) { char *name, *paramname; struct sysfs_attribute *attr; struct sysfs_module *module; switch (flag) { case 0: name = val_mod_path; module = sysfs_open_module_path(name); if (!module) { dbg_print("%s: failed opening module at %s\n", __FUNCTION__, name); return 0; } paramname = val_mod_param; break; case 1: name = val_mod_path; module = sysfs_open_module_path(name); if (!module) { dbg_print("%s: failed opening module at %s\n", __FUNCTION__, name); return 0; } paramname = inval_name; break; case 2: name = val_mod_path; module = sysfs_open_module_path(name); if (!module) { dbg_print("%s: failed opening module at %s\n", __FUNCTION__, name); return 0; } paramname = NULL; break; default: return -1; } attr = sysfs_get_module_parm(module,paramname); switch (flag) { case 0: if(!attr) { if (errno == EACCES) dbg_print("%s: parameter %s not used by module" , __FUNCTION__, paramname); else if (errno == ENOENT) dbg_print("%s: attribute %s not defined for " "module at %s\n", __FUNCTION__, paramname, name); else if (errno == 0) dbg_print("%s: module at %s does not use " "parameter\n", __FUNCTION__, val_mod_path); else dbg_print("%s: FAILED with flag = %d errno = " "%d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_attribute(attr); dbg_print("\n"); } break; case 1: case 2: if (attr) dbg_print("%s: FAILED with flag = %d errno = " "%d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); default: break; } if (module) sysfs_close_module(module); return 0; } /** * sysfs_get_module_section * @module: sysfs_module to look through * @section: name of the section to look for * Returns sysfs_attribute * on SUCCESS and NULL on error * flag: * 0: name -> valid, sectname -> valid * 1: name -> valid, sectname -> invalid * 2: name -> valid, sectname -> NULL */ int test_sysfs_get_module_section(int flag) { char *name, *sectname; struct sysfs_attribute *attr; struct sysfs_module *module; switch (flag) { case 0: name = val_mod_path; module = sysfs_open_module_path(name); if (!module) { dbg_print("%s: failed opening module at %s\n", __FUNCTION__, name); return 0; } sectname = val_mod_section; break; case 1: name = val_mod_path; module = sysfs_open_module_path(name); if (!module) { dbg_print("%s: failed opening module at %s\n", __FUNCTION__, name); return 0; } sectname = inval_name; break; case 2: name = val_mod_path; module = sysfs_open_module_path(name); if (!module) { dbg_print("%s: failed opening module at %s\n", __FUNCTION__, name); return 0; } sectname = NULL; break; default: return -1; } attr = sysfs_get_module_section(module,sectname); switch (flag) { case 0: if(!attr) { if (errno == EACCES) dbg_print("%s: section %s not used by module" , __FUNCTION__, sectname); else if (errno == ENOENT) dbg_print("%s: section %s not defined for " "module at %s\n", __FUNCTION__, sectname, name); else if (errno == 0) dbg_print("%s: module at %s does not use " "section\n", __FUNCTION__, val_mod_path); else dbg_print("%s: FAILED with flag = %d errno = " "%d\n", __FUNCTION__, flag, errno); } else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_attribute(attr); dbg_print("\n"); } break; case 1: case 2: if (attr) dbg_print("%s: FAILED with flag = %d errno = " "%d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); default: break; } if (module) sysfs_close_module(module); return 0; } sysfsutils-2.1.1/test/test_utils.c000066400000000000000000000273551401370461400173010ustar00rootroot00000000000000/* * test_utils.c * * Tests for utility functions for the libsysfs testsuite * * Copyright (C) IBM Corp. 2004-2005 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * */ /** *************************************************************************** * this will test the utility functions provided by libsysfs. * * extern int sysfs_get_mnt_path(char *mnt_path, size_t len); * extern int sysfs_remove_trailing_slash(char *path); * extern int sysfs_get_name_from_path(const char *path, * char *name, size_t len); * extern int sysfs_path_is_dir(const char *path); * extern int sysfs_path_is_link(const char *path); * extern int sysfs_path_is_file(const char *path); * extern int sysfs_get_link(const char *path, char *target, size_t len); * extern struct dlist *sysfs_open_directory_list(char *name); * extern struct dlist *sysfs_open_link_list(char *name); * extern void sysfs_close_list(struct dlist *list); ***************************************************************************** */ #include "config.h" #include "test-defs.h" #include /** * extern int sysfs_get_mnt_path(char *mnt_path, size_t len); * * flag: * 0: mnt_path -> valid, len -> valid * 1: mnt_path -> valid, len -> 0 * 2: mnt_path -> NULL, len -> valid * 3: mnt_path -> NULL, len -> NULL */ int test_sysfs_get_mnt_path(int flag) { char *mnt_path = NULL; size_t len = 0; int ret = 0; switch (flag) { case 0: mnt_path = calloc(1, SYSFS_PATH_MAX); len = SYSFS_PATH_MAX; break; case 1: mnt_path = calloc(1, SYSFS_PATH_MAX); len = 0; break; case 2: mnt_path = NULL; len = SYSFS_PATH_MAX; break; case 3: mnt_path = NULL; len = 0; break; default: return -1; } ret = sysfs_get_mnt_path(mnt_path, len); switch (flag) { case 0: if (ret) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); dbg_print("sysfs is mounted at \"%s\"\n\n", mnt_path); } break; case 1: case 2: case 3: if (!ret) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (mnt_path != NULL) { free(mnt_path); mnt_path = NULL; } return 0; } /** * extern int sysfs_remove_trailing_slash(char *path); * * flag: * 0: path -> valid * 1: path -> NULL */ int test_sysfs_remove_trailing_slash(int flag) { char *path = NULL; int ret = 0; switch (flag) { case 0: path = calloc(1, SYSFS_PATH_MAX); strcpy(path, "/some/path/is/this/"); break; case 1: path = NULL; break; default: return -1; } ret = sysfs_remove_trailing_slash(path); switch (flag) { case 0: if (ret != 0) dbg_print("%s: FAILED with flag = %d errno = %d\n\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); dbg_print("Path now is \"%s\"\n\n", path); } break; case 1: if (ret == 0) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (path != NULL) { free(path); path = NULL; } return 0; } /** * extern int sysfs_get_name_from_path(const char *path, * char *name, size_t len); * * flag: * 0: path -> valid, name -> valid, len -> valid * 1: path -> valid, name -> NULL, len -> invalid * 2: path -> NULL, name -> valid, len -> valid * 3: path -> NULL, name -> NULL, len -> invalid */ int test_sysfs_get_name_from_path(int flag) { char *path = NULL; char *name = NULL; size_t len = SYSFS_NAME_LEN; int ret = 0; switch (flag) { case 0: path = val_dir_path; name = calloc(1, SYSFS_NAME_LEN); break; case 1: path = val_dir_path; name = NULL; break; case 2: path = NULL; name = calloc(1, SYSFS_NAME_LEN); break; case 3: path = NULL; name = NULL; break; default: return -1; } ret = sysfs_get_name_from_path(path, name, len); switch (flag) { case 0: if (ret != 0) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); dbg_print("Name extracted from \"%s\" is \"%s\"\n\n", path, name); } break; case 1: case 2: case 3: if (ret == 0) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (name != NULL) { free(name); name = NULL; } return 0; } /** * extern int sysfs_path_is_dir(const char *path); * * flag: * 0: path -> valid * 1: path -> invalid * 2: path -> NULL */ int test_sysfs_path_is_dir(int flag) { char *path = NULL; int ret = 0; switch (flag) { case 0: path = val_dir_path; break; case 1: path = inval_path; break; case 2: path = NULL; break; default: return -1; } ret = sysfs_path_is_dir(path); switch (flag) { case 0: if (ret != 0) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); dbg_print("Path \"%s\" points to a directory\n\n", path); } break; case 1: case 2: if (ret == 0) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: return 0; break; } return 0; } /** * extern int sysfs_path_is_link(const char *path); * * flag: * 0: path -> valid * 1: path -> invalid * 2: path -> NULL */ int test_sysfs_path_is_link(int flag) { char *path = NULL; int ret = 0; switch (flag) { case 0: path = val_link_path; break; case 1: path = inval_path; break; case 2: path = NULL; break; default: return -1; } ret = sysfs_path_is_link(path); switch (flag) { case 0: if (ret != 0) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); dbg_print("Path \"%s\" points to a link\n\n", path); } break; case 1: case 2: if (ret == 0) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: return 0; break; } return 0; } /** * extern int sysfs_path_is_file(const char *path); * * flag: * 0: path -> valid * 1: path -> invalid * 2: path -> NULL */ int test_sysfs_path_is_file(int flag) { char *path = NULL; int ret = 0; switch (flag) { case 0: path = val_file_path; break; case 1: path = inval_path; break; case 2: path = NULL; break; default: return -1; } ret = sysfs_path_is_file(path); switch (flag) { case 0: if (ret != 0) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); dbg_print("Path \"%s\" points to a file\n\n", path); } break; case 1: case 2: if (ret == 0) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: return 0; break; } return 0; } /** * extern int sysfs_get_link(const char *path, * char *target, size_t len); * * flag: * 0: path -> valid, target -> valid * 1: path -> valid, target -> NULL * 2: path -> NULL, target -> valid * 3: path -> NULL, target -> NULL */ int test_sysfs_get_link(int flag) { char *path = NULL; char *target = NULL; size_t len = SYSFS_PATH_MAX; int ret = 0; switch (flag) { case 0: path = val_link_path; target = calloc(1, SYSFS_PATH_MAX); break; case 1: path = val_link_path; target = NULL; break; case 2: path = NULL; target = calloc(1, SYSFS_PATH_MAX); break; case 3: path = NULL; target = NULL; break; default: return -1; } ret = sysfs_get_link(path, target, len); switch (flag) { case 0: if (ret != 0) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); dbg_print("Link at \"%s\" points to \"%s\"\n\n", path, target); } break; case 1: case 2: case 3: if (ret == 0) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: return 0; break; } if (target != NULL) { free(target); target = NULL; } return 0; } /** * extern struct dlist *sysfs_open_directory_list(char *name); * * flag: * 0: name -> valid * 1: name -> invalid * 2: name -> NULL * */ int test_sysfs_open_directory_list(int flag) { char *path = NULL; struct dlist *list = NULL; switch (flag) { case 0: path = val_dir_path; break; case 1: path = inval_path; break; case 2: path = NULL; break; default: return -1; } list = sysfs_open_directory_list(path); switch (flag) { case 0: if (list == NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_list(list); dbg_print("\n"); } break; case 1: case 2: if (list != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (list != NULL) { sysfs_close_list(list); list = NULL; } return 0; } /** * extern struct dlist *sysfs_open_link_list(char *name); * * flag: * 0: name -> valid * 1: name -> invalid * 2: name -> NULL * */ int test_sysfs_open_link_list(int flag) { char *path = NULL; struct dlist *list = NULL; switch (flag) { case 0: path = val_link_path; break; case 1: path = inval_path; break; case 2: path = NULL; break; default: return -1; } list = sysfs_open_link_list(path); switch (flag) { case 0: if (list == NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else { dbg_print("%s: SUCCEEDED with flag = %d\n\n", __FUNCTION__, flag); show_list(list); dbg_print("\n"); } break; case 1: case 2: if (list != NULL) dbg_print("%s: FAILED with flag = %d errno = %d\n", __FUNCTION__, flag, errno); else dbg_print("%s: SUCCEEDED with flag = %d\n", __FUNCTION__, flag); break; default: break; } if (list != NULL) { sysfs_close_list(list); list = NULL; } return 0; } /** * extern void sysfs_close_list(struct dlist *list); * * flag: * 0: list -> valid * 1: list -> NULL */ int test_sysfs_close_list(int flag) { struct dlist *list = NULL; switch (flag) { case 0: list = NULL; break; default: return -1; } sysfs_close_list(list); dbg_print("%s: returns void\n", __FUNCTION__); return 0; } sysfsutils-2.1.1/test/testout.c000066400000000000000000000064421401370461400166030ustar00rootroot00000000000000/* * testout.c * * Display routines for the libsysfs testsuite * * Copyright (C) IBM Corp. 2004-2005 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * */ /** * Display routines for test functions */ #include "config.h" #include static void remove_end_newline(char *value) { char *p = value + (strlen(value) - 1); if (p != NULL && *p == '\n') *p = '\0'; } void show_device(struct sysfs_device *device) { if (device != NULL) dbg_print("Device is \"%s\" at \"%s\"\n", device->name, device->path); } void show_driver(struct sysfs_driver *driver) { if (driver != NULL) dbg_print("Driver is \"%s\" at \"%s\"\n", driver->name, driver->path); } void show_device_list(struct dlist *devlist) { if (devlist != NULL) { struct sysfs_device *dev = NULL; dlist_for_each_data(devlist, dev, struct sysfs_device) show_device(dev); } } void show_driver_list(struct dlist *drvlist) { if (drvlist != NULL) { struct sysfs_driver *drv = NULL; dlist_for_each_data(drvlist, drv, struct sysfs_driver) show_driver(drv); } } void show_attribute(struct sysfs_attribute *attr) { if (attr != NULL) { if (attr->value) remove_end_newline(attr->value); dbg_print("Attr \"%s\" at \"%s\" has a value \"%s\" \n", attr->name, attr->path, attr->value); } } void show_attribute_list(struct dlist *attrlist) { if (attrlist != NULL) { struct sysfs_attribute *attr = NULL; dlist_for_each_data(attrlist, attr, struct sysfs_attribute) show_attribute(attr); } } void show_class_device(struct sysfs_class_device *dev) { if (dev != NULL) dbg_print("Class device \"%s\" belongs to the \"%s\" class\n", dev->name, dev->classname); } void show_class_device_list(struct dlist *devlist) { if (devlist != NULL) { struct sysfs_class_device *dev = NULL; dlist_for_each_data(devlist, dev, struct sysfs_class_device) show_class_device(dev); } } void show_list(struct dlist *list) { if (list != NULL) { char *name = NULL; dlist_for_each_data(list, name, char) dbg_print("%s\n", name); } } void show_parm_list(struct dlist *list) { if (list != NULL) { char *name = NULL; dlist_for_each_data(list, name, char) dbg_print("%s\n", name); } } void show_section_list(struct dlist *list) { if (list != NULL) { char *name = NULL; dlist_for_each_data(list, name, char) dbg_print("%s\n", name); } } void show_module(struct sysfs_module *module) { if (module) { dbg_print("Module name is %s, path is %s\n", module->name, module->path); show_attribute_list(module->attrlist); show_parm_list(module->parmlist); show_section_list(module->sections); } }