├── .gitignore ├── libsysdev.pc.in ├── LICENSE ├── util ├── devinfo.1 └── devinfo.c ├── getprodids.c ├── getsyspath.c ├── convenience.c ├── libsysdev └── sysdev.h ├── README ├── Makefile └── libsysdev.3 /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.lo 3 | *.s 4 | *.i 5 | *.a 6 | *.so* 7 | ~* 8 | *.swp 9 | core 10 | devinfo 11 | *.pc 12 | -------------------------------------------------------------------------------- /libsysdev.pc.in: -------------------------------------------------------------------------------- 1 | libdir=@LIBDIR@ 2 | incdir=@INCDIR@ 3 | 4 | Name: libsysdev 5 | Version: @VERSION@ 6 | Description: Library to get information from sysfs about devices 7 | Cflags: -I${incdir} 8 | Libs: -L${libdir} -lsysdev 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Permission to use, copy, modify, and/or distribute this software for any 2 | purpose, with or without fee, is hereby granted. 3 | 4 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 5 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 6 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 7 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 8 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 9 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 10 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 11 | 12 | -------------------------------------------------------------------------------- /util/devinfo.1: -------------------------------------------------------------------------------- 1 | .\" Copyright (c) 2015 A.D. Isaac Dunham, no rights reserved 2 | .\" Released under the libsysdev license 3 | .TH "DEVINFO" 1 2015 "libsysdev" 4 | .SH NAME 5 | devinfo \- print information about a device 6 | .SH SYNOPSIS 7 | .BI "devinfo " /dev/node " ..." 8 | .SH DESCRIPTION 9 | .BR devinfo 10 | prints the corresponding sysfs path and (if applicable) 11 | the PCI IDs for the hardware. 12 | .SH EXAMPLE 13 | .SS Example 1 shows the PCI IDs of the primary graphics card: 14 | .nf 15 | $ devinfo /dev/dri/card0 16 | /sys//devices/pci0000:00/0000:00:02.0/drm/card0/device 8086 27AE 17 | .fi 18 | 19 | .SS Example 2 shows the "name" assigned by the kernel to each input device: 20 | .nf 21 | $ for i in `devinfo /dev/input/* |cut -f1`; do cat "$i"/name; done 22 | AT Translated Set 2 keyboard 23 | HDA Digital PCBeep 24 | HDA VIA VT82xx Front Headphone 25 | HDA VIA VT82xx Line Out CLFE 26 | .fi 27 | -------------------------------------------------------------------------------- /getprodids.c: -------------------------------------------------------------------------------- 1 | /* Copyright Isaac Dunham, in the year of our Lord 2015 2 | * No rights reserved, see LICENSE for details. 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | /* Read up to bufsiz bytes of name into buf, return result of read */ 14 | static int sdp_readfileat(char *buf, ssize_t bufsiz, int dfd, char *name) 15 | { 16 | int result, fd; 17 | fd = openat(dfd, name, O_RDONLY); 18 | if (fd < 0) 19 | return -1; 20 | 21 | memset(buf, 0, bufsiz); 22 | result = read(fd, buf, bufsiz - 1); 23 | close(fd); 24 | return result; 25 | } 26 | 27 | /* given fd of syspath, set vendor_id and device_id; return 0 for success */ 28 | int sysdev_getproductids(int *vendor_id, int *device_id, int sysfd) 29 | { 30 | char id[8]; 31 | 32 | if (sdp_readfileat(id, 8, sysfd, "vendor") < 6) 33 | return -1; 34 | *vendor_id = (int)strtol(id, (char **)0, 16); 35 | 36 | if (sdp_readfileat(id, 8, sysfd, "device") < 6) 37 | return -1; 38 | *device_id = (int)strtol(id, (char **)0, 16); 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /getsyspath.c: -------------------------------------------------------------------------------- 1 | /* Copyright Isaac Dunham, in the year of our Lord 2015 2 | * No rights reserved, see LICENSE for details. 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | /* Given major/minor/type, return the directory in /sys 17 | * Returns NULL on failure. 18 | */ 19 | char *sysdev_getsyspath(unsigned int major, unsigned int minor, int ischar) 20 | { 21 | char tpath[256], *syspath = NULL; 22 | ssize_t len; 23 | 24 | errno = 0; 25 | len = snprintf(tpath, sizeof(tpath), "/sys/dev/%s/%u:%u", 26 | ischar ? "char" : "block", major, minor); 27 | if (len < sizeof(tpath)) { 28 | syspath = calloc(PATH_MAX, 1); 29 | if (syspath) { 30 | len = readlink(tpath, syspath, PATH_MAX); 31 | if ((len < 6) || (len > PATH_MAX - 8)) { 32 | free(syspath); 33 | syspath = NULL; 34 | } 35 | } 36 | /* Overwrite the start of syspath (../..) with "/sys/" */ 37 | if (syspath) { 38 | memcpy(syspath, "/sys/", 5); 39 | strncat(syspath, "/device", PATH_MAX - 1); 40 | } 41 | } 42 | return syspath; 43 | } 44 | -------------------------------------------------------------------------------- /util/devinfo.c: -------------------------------------------------------------------------------- 1 | #ifndef _XOPEN_SOURCE 2 | #define _XOPEN_SOURCE 700 3 | #endif 4 | 5 | #define _BSD_SOURCE 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | void usage(char *progname) 16 | { 17 | fprintf(stderr, "usage: %s /dev/node", progname); 18 | exit(1); 19 | } 20 | 21 | int shownode(char *arg) 22 | { 23 | char *syspath; 24 | int sysfd = -1, vend = 0, dev = 0, ret = 0; 25 | struct stat st; 26 | 27 | if (stat(arg, &st) || (!(st.st_mode & (S_IFCHR | S_IFBLK)))) 28 | return 1; 29 | syspath = sysdev_getsyspath(major(st.st_rdev), minor(st.st_rdev), 30 | S_ISCHR(st.st_mode)); 31 | if (syspath) 32 | sysfd = open(syspath, O_RDONLY); 33 | if (sysfd > -1) { 34 | printf("%s", syspath); 35 | if (!sysdev_getproductids(&vend, &dev, sysfd)) 36 | printf("\t%X\t%X", vend, dev); 37 | printf("\n"); 38 | close(sysfd); 39 | } else 40 | ret = 1; 41 | if (syspath) 42 | free(syspath); 43 | return ret; 44 | } 45 | 46 | int main(int argc, char **argv) 47 | { 48 | int i, ret = 0; 49 | 50 | if (argc < 2) 51 | usage(argv[0]); 52 | 53 | for (i=1; i < argc;) { 54 | ret |= shownode(argv[i++]); 55 | } 56 | return ret; 57 | } 58 | -------------------------------------------------------------------------------- /convenience.c: -------------------------------------------------------------------------------- 1 | /* Copyright Isaac Dunham, in the year of our Lord 2015 2 | * No rights reserved, see LICENSE for details. 3 | */ 4 | #define _BSD_SOURCE /* for major()/minor() */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | /* given fd of device, return the directory in /sys 18 | * returns a calloc'd string (or NULL on failure) 19 | * sets errno = EINVAL if devfd is not a device 20 | */ 21 | char *sysdev_devfd_to_syspath(int devfd) 22 | { 23 | struct stat st; 24 | 25 | if (fstat(devfd, &st) || !(st.st_mode & (S_IFCHR | S_IFBLK))) { 26 | if (!errno) 27 | errno = EINVAL; 28 | return NULL; 29 | } 30 | return sysdev_getsyspath(major(st.st_rdev), minor(st.st_rdev), 31 | S_ISCHR(st.st_mode)); 32 | } 33 | 34 | /* given fd of device, return fd of corresponding syspath 35 | * returns -1 on failure, sets errno = EINVAL if devfd is not a device 36 | */ 37 | int sysdev_devfd_to_sysfd(int devfd) 38 | { 39 | char *syspath; 40 | int sysfd; 41 | 42 | syspath = sysdev_devfd_to_syspath(devfd); 43 | if (!syspath) 44 | return -1; 45 | sysfd = open(syspath, O_RDONLY); 46 | free(syspath); 47 | return sysfd; 48 | } 49 | 50 | /* given fd of device, read vendor_id and device_id 51 | * returns 0 for success, nonzero for failure 52 | */ 53 | int sysdev_devfd_to_pciid(int *vendor_id, int *device_id, int devfd) 54 | { 55 | int ret, sysfd = sysdev_devfd_to_sysfd(devfd); 56 | 57 | if (sysfd > -1) { 58 | ret = sysdev_getproductids(vendor_id, device_id, sysfd); 59 | close(sysfd); 60 | return ret; 61 | } 62 | return -1; 63 | } 64 | -------------------------------------------------------------------------------- /libsysdev/sysdev.h: -------------------------------------------------------------------------------- 1 | /* libsysdev public defines. 2 | * This contains only a description of the API provided by libsysdev, 3 | * and as such the author does not consider it copyrightable and 4 | * waives any and all claims to copyright. 5 | * In jurisdictions where this is not recognized by law, 6 | * it is subject to the following copyright, license, 7 | * and disclaimer of warranty: 8 | 9 | Copyright Isaac Dunham, in the year of our Lord 2015. 10 | 11 | Permission to use, copy, modify, and/or distribute this software for any 12 | purpose, with or without fee, is hereby granted. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 15 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 16 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 17 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 19 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 20 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 | 22 | * 23 | * libsysdev uses the sysdev_ namespace for public APIs 24 | * The sdp_ namespace is used internally; if it's visible, it's broken. 25 | */ 26 | 27 | #ifndef _LIBSYSDEV_SYSDEV_H 28 | #define _LIBSYSDEV_SYSDEV_H 1 29 | 30 | /* given fd of syspath, set vendor_id and device_id 31 | * returns 0 for success, nonzero for failure 32 | */ 33 | int sysdev_getproductids(int *vendor_id, int *device_id, int sysfd); 34 | 35 | /* given major/minor/type, return the directory in /sys 36 | * returns a calloc'd string (or NULL on failure) 37 | */ 38 | char * sysdev_getsyspath(unsigned int major, unsigned int minor, int ischar); 39 | 40 | /* given fd of device, return the directory in /sys 41 | * returns a calloc'd string (or NULL on failure) 42 | * sets errno = EINVAL if devfd is not a device 43 | */ 44 | char *sysdev_devfd_to_syspath(int devfd); 45 | 46 | /* given fd of device, return fd of corresponding syspath 47 | * returns -1 on failure, sets errno = EINVAL if devfd is not a device 48 | */ 49 | int sysdev_devfd_to_sysfd(int devfd); 50 | 51 | /* given fd of device, read vendor_id and device_id 52 | * returns 0 for success, nonzero for failure 53 | */ 54 | int sysdev_devfd_to_pciid(int *vendor_id, int *device_id, int devfd); 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | libsysdev introduction 2 | 3 | The general purpose is to provide a sysfs-based library that can replace 4 | libudev. This does not mean API/ABI-compatible; rather, it should provide 5 | similar functionality without a daemon, and a program should be able to 6 | link with both libsysdev and libudev at the same time (so libsysdev can 7 | be used as a fallback when udevd is not running). 8 | The --enable-sysfs code in mesa provided inspiration. 9 | If someone wants to write a partial udev-compat shim, I'm open to including it. 10 | 11 | The API is based on a quick glance through xf86-input-evdev 12 | and mesa to see where they need udev/what they do instead. 13 | By my reading, sysdev_getsyspath() or sysdev_devfd_to_syspath() should be 14 | enough for evdev, while mesa would need sysdev_getproductids() as well. 15 | 16 | Thanks to Karl Hammar for inspiration to do this. 17 | 18 | Copyright/license: 19 | See LICENSE and the individual files for license information. 20 | The bulk of the library is copyright 21 | Copyright Isaac Dunham, in the year of our Lord 2015. 22 | No rights reserved, see LICENSE for details. 23 | 24 | TODO: 25 | * Handle multiarch and multilib configurations better than 26 | expecting the builder to set LIBDIR. 27 | * (WIP) Get evdev to use this. 28 | A first try, which has *not* been tested beyond compile, is available at 29 | https://github.com/idunham/xf86-input-evdev 30 | (in branch sysdev). 31 | 32 | API: 33 | libsysdev uses the sysdev_ namespace for public APIs. 34 | Internal functions are prefixed with sdp_ instead. 35 | 36 | See util/devinfo.c for an example of how you could use sysdev_getsyspath() 37 | and sysdev_getproductids(). 38 | 39 | If you have a device fd (devfd) and want to get the PCI IDs, just use this: 40 | int vendor, device; 41 | ... 42 | if (sysdev_devfd_to_pciid(&vendor, &device, devfd)) { 43 | // handle error condition (PCI ids not read) 44 | } 45 | 46 | Here are the currently available functions: 47 | /* given fd of syspath, set vendor_id and device_id 48 | * returns 0 for success, nonzero for failure 49 | */ 50 | int sysdev_getproductids(int *vendor_id, int *device_id, int sysfd); 51 | 52 | /* given major/minor/type, return the directory in /sys 53 | * returns a calloc'd string (or NULL on failure) 54 | */ 55 | char * sysdev_getsyspath(unsigned int major, unsigned int minor, int ischar); 56 | 57 | /* given fd of device, return the directory in /sys 58 | * returns a calloc'd string (or NULL on failure) 59 | * sets errno = EINVAL if devfd is not a device 60 | */ 61 | char *sysdev_devfd_to_syspath(int devfd); 62 | 63 | /* given fd of device, return fd of corresponding syspath 64 | * returns -1 on failure, sets errno = EINVAL if devfd is not a device 65 | */ 66 | int sysdev_devfd_to_sysfd(int devfd); 67 | 68 | /* given fd of device, read vendor_id and device_id 69 | * returns 0 for success, nonzero for failure 70 | */ 71 | int sysdev_devfd_to_pciid(int *vendor_id, int *device_id, int devfd); 72 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for libsysdev 2 | # Written by and copyright Isaac Dunham, in the year of our Lord 2015 3 | # No rights reserved - see LICENSE for details. 4 | 5 | 6 | # set DESTDIR if you're packaging, PREFIX to install somewhere 7 | DESTDIR ?= 8 | PREFIX ?= /usr 9 | LIBDIR ?= ${PREFIX}/lib 10 | BINDIR ?= ${PREFIX}/bin 11 | INCDIR ?= ${PREFIX}/include 12 | DATAROOTDIR ?= ${PREFIX}/share 13 | DOCDIR ?= ${DATAROOTDIR}/doc/libsysdev 14 | MANDIR ?= ${DATAROOTDIR}/man 15 | 16 | # set AR and CC if you're cross-compiling 17 | AR ?= ar 18 | # We assume SUSv4, but set _ATFILE_SOURCE for old glibc versions 19 | XFLAGS += -D_XOPEN_SOURCE=700 -D_ATFILE_SOURCE -I. 20 | CFLAGS ?= -Os -g 21 | # so the user/packager can select -fpic if they want 22 | PIC = -fPIC 23 | # so the user/packager can select whether to build shared/static/both 24 | LIBS ?= libsysdev.a libsysdev.so.${SOVER} 25 | 26 | # This should not be modified unless you are adding code or 27 | # releasing a new version. 28 | # SOVER is the soversion; only modify it when libsysdev no longer provides 29 | # the same ABI. 30 | # SOMIN is the minor version; update for a release with a new symbol export 31 | # AROBJS/SOOBJS should be updated to add new source files. 32 | PKGVER = 0.1.0 33 | SOVER = 0 34 | SOMIN = 0 35 | AROBJS = getprodids.o \ 36 | getsyspath.o \ 37 | convenience.o 38 | SOOBJS = getprodids.lo \ 39 | getsyspath.lo \ 40 | convenience.lo 41 | 42 | 43 | all: ${LIBS} devinfo 44 | 45 | install: ${LIBS} devinfo libsysdev.pc 46 | echo "Making directories..." 47 | install -d -m 0755 ${DESTDIR}${LIBDIR}/pkgconfig 48 | install -d -m 0755 ${DESTDIR}${BINDIR} 49 | install -d -m 0755 ${DESTDIR}${INCDIR}/libsysdev 50 | install -d -m 0755 ${DESTDIR}${DOCDIR} 51 | install -d -m 0755 ${DESTDIR}${MANDIR}/man1 52 | install -d -m 0755 ${DESTDIR}${MANDIR}/man3 53 | echo "Installing libs..." 54 | # installing the shared lib? 55 | echo ${LIBS} | grep libsysdev.so && \ 56 | install -m 0644 libsysdev.so.${SOVER}.${SOMIN} ${DESTDIR}${LIBDIR}/ 57 | ln -sf libsysdev.so.${SOVER}.${SOMIN} ${DESTDIR}${LIBDIR}/libsysdev.so.${SOVER} 58 | ln -sf libsysdev.so.${SOVER}.${SOMIN} ${DESTDIR}${LIBDIR}/libsysdev.so 59 | echo ${LIBS} | grep libsysdev.a && \ 60 | install -m 0644 libsysdev.a ${DESTDIR}${LIBDIR} 61 | install -m 0644 libsysdev.pc ${DESTDIR}${LIBDIR}/pkgconfig/ 62 | install -m 0644 libsysdev/sysdev.h \ 63 | ${DESTDIR}${INCDIR}/libsysdev/sysdev.h 64 | echo "Installing utilities..." 65 | install -m 0755 devinfo ${DESTDIR}${BINDIR} 66 | echo "Installing documentation..." 67 | install -m 0644 libsysdev.3 ${DESTDIR}${MANDIR}/man3/ 68 | install -m 0644 util/devinfo.1 ${DESTDIR}${MANDIR}/man1/ 69 | install -m 0644 README LICENSE ${DESTDIR}${DOCDIR}/ 70 | 71 | 72 | clean: 73 | rm -f ${SOOBJS} ${AROBJS} libsysdev.so* libsysdev.a devinfo \ 74 | libsysdev.pc 75 | 76 | %.lo: %.c 77 | ${CC} ${CFLAGS} ${CPPFLAGS} ${XFLAGS} ${PIC} -c -o $@ $< 78 | 79 | %.o: %.c 80 | ${CC} ${CFLAGS} ${CPPFLAGS} ${XFLAGS} -c -o $@ $< 81 | 82 | %.pc: %.pc.in 83 | sed -e "s:@LIBDIR@:${LIBDIR}:" \ 84 | -e "s:@INCDIR@:${INCDIR}:" \ 85 | -e "s:@VERSION@:${PKGVER}:" \ 86 | $< | { test "${LIBDIR}" = "/usr/lib" && \ 87 | sed -e 's/-L.*}//' -e '/^libdir.*/d' || cat; } | \ 88 | { test "${INCDIR}" = "/usr/include" && \ 89 | sed -e '/^Cflags.*/d' -e '/^incdir.*/d' || cat; } > $@ 90 | 91 | libsysdev.so.${SOVER}: ${SOOBJS} 92 | ${CC} ${LDFLAGS} -shared -o $@.${SOMIN} -Wl,-soname,$@ ${SOOBJS} 93 | ln -sf $@.${SOMIN} $@ 94 | ln -sf $@.${SOMIN} libsysdev.so 95 | 96 | libsysdev.a: ${AROBJS} 97 | ${AR} -rcs $@ ${AROBJS} 98 | 99 | %: util/%.c ${LIBS} 100 | ${CC} -I. ${CFLAGS} ${CPPFLAGS} ${XFLAGS} \ 101 | util/$@.c -o $@ ${LDFLAGS} -L. -lsysdev 102 | 103 | .PHONY: all clean install 104 | -------------------------------------------------------------------------------- /libsysdev.3: -------------------------------------------------------------------------------- 1 | .\" Copyright (c) 2015 A.D. Isaac Dunham, no rights reserved 2 | .\" Released under the libsysdev license 3 | .TH "LIBSYSDEV" 3 2015 "libsysdev" 4 | .SH NAME 5 | libsysdev \- library to access sysfs information about devices 6 | .SH SYNOPSIS 7 | .nf 8 | .B #include 9 | .sp 10 | .BI "char *sysdev_getsyspath(unsigned int " major ", unsigned int " minor ", int ischar);" 11 | .BI "char *sysdev_devfd_to_syspath(int " devfd ");" 12 | .BI "int sysdev_devfd_to_sysfd(int " devfd ");" 13 | .BI "int sysdev_devfd_to_pciid(int *" vendor_id ", int *" device_id ", int " devfd ");" 14 | .BI "int sysdev_getproductids(int *" vendor_id ", int *" device_id ", int " sysfd ");" 15 | .fi 16 | .SH DESCRIPTION 17 | In general, 18 | .I devfd 19 | means a file descriptor referring to a device. 20 | .I syspath 21 | means a string containing an absolute path within 22 | .I /sys. 23 | .I sysfd 24 | means a file descriptor referring to a syspath. 25 | 26 | .BI "sysdev_getsyspath( " major ", " minor ", " ischar ")" 27 | takes as its first two arguments 28 | the 29 | .I major 30 | and 31 | .I minor 32 | of a device; 33 | .I ischar 34 | should be nonzero if the device is a character device, 35 | 0 if it is a block device. 36 | On success it returns a 37 | .BR calloc (3)ed 38 | buffer of length 39 | .BR PATH_MAX , 40 | containing 41 | a path of the general form 42 | .I /sys/devices/.../device 43 | that corresponds to the device described by the arguments. 44 | 45 | Note that, for simplicity of implementation, this version of 46 | .BR libsysdev () 47 | returns a syspath of the form 48 | .IR /sys//devices/... 49 | (note the double slash); relying on a fixed offset from the start is wrong, 50 | and this behavior may well change in future. 51 | 52 | .BI sysdev_devfd_to_syspath( devfd ) 53 | takes as its only argument a file descriptor 54 | referring to a device node. It returns the same output as 55 | .BR sysdev_getsyspath (). 56 | 57 | .BI sysdev_devfd_to_sysfd( devfd ) 58 | takes as its only argument a file descriptor 59 | referring to a device node. It returns a file descriptor referring to a 60 | corresponding directory in 61 | .IR /sys . 62 | 63 | .BI "sysdev_getproductids(int *" vendor_id ", int *" device_id ", int " sysfd ) 64 | fills 65 | .I vendor_id 66 | with the PCI vendor number and 67 | .I device_id 68 | with the PCI device number found in 69 | the sysfs directory pointed to by 70 | .IR sysfd . 71 | It returns 0 if it is successful, 72 | nonzero if it fails. 73 | 74 | .BI "sysdev_devfd_to_pciid(int *" vendor_id ", int *" device_id ", int " devfd ) 75 | fills 76 | .I vendor_id 77 | with the PCI vendor number and 78 | .I device_id 79 | with the PCI device number for the device to which 80 | .I devfd 81 | refers. 82 | It returns 0 on success, nonzero on failure. 83 | 84 | .SH RETURN VALUE 85 | .BR sysdev_getsyspath () 86 | and 87 | .BR sysdev_devfd_to_syspath () 88 | return the sysfs directory 89 | corresponding to the device referred to by their arguments. 90 | If it cannot be determined, they return NULL. 91 | 92 | .BR sysdev_devfd_to_sysfd () 93 | returns a file descriptor for the sysfs directory 94 | corresponding to the device of which 95 | .I devfd 96 | is a file descriptor. 97 | 98 | .BR sysdev_getproductids () 99 | fills its first two arguments with the PCI ids 100 | found in the sysfs directory pointed to by 101 | .IR sysfd . 102 | It returns 0 if it is successful, nonzero if it fails. 103 | .BI "sysdev_devfd_to_pciid(int *" vend ", int *" chip ", int " devfd ); 104 | is equivalent to 105 | .BI "sysdev_getproductids(int *" vend ", int *" chip ", sysdev_devfd_to_sysfd(" devfd )); 106 | and has the same return values. 107 | 108 | .SH ERRORS 109 | Functions that take a device fd as an argument ( 110 | .BR sysdev_devfd_to_syspath (), 111 | .BR sysdev_devfd_to_sysfd (), 112 | and 113 | .BR sysdev_devfd_to_pciid ()) 114 | will set 115 | .I errno 116 | = 117 | .B EINVAL 118 | if 119 | .I devfd 120 | does not refer to a device. 121 | 122 | Functions that take a device fd as an argument call 123 | .BR fstat (3) 124 | internally and can fail with any failure that 125 | .BR fstat (3) 126 | encounters. 127 | 128 | .BR sysdev_devfd_to_sysfd () 129 | and 130 | .BR sysdev_getproductids () 131 | call 132 | .BR open (2) 133 | internally and can fail with any failure that 134 | .BR open (2) 135 | encounters. 136 | 137 | .BR sysdev_getsyspath (), 138 | .BR sysdev_devfd_to_syspath (), 139 | .BR sysdev_devfd_to_sysfd (), 140 | and 141 | .BR sysdev_devfd_to_pciid () 142 | use 143 | .BR calloc(3) 144 | internally and can theoretically set any error which it sets. 145 | --------------------------------------------------------------------------------