import udev repository

This commit is contained in:
Kay Sievers 2012-04-03 21:08:04 +02:00
commit 19c5f19d69
210 changed files with 43585 additions and 0 deletions

40
src/udev/.gitignore vendored Normal file
View File

@ -0,0 +1,40 @@
*~
*.o
*.a
*.lo
*.la
.libs
.deps
.dirstamp
Makefile
Makefile.in
/aclocal.m4
/autom4te.cache
/config.h
/config.h.in
/config.log
/config.status
/config.guess
/config.sub
/libtool
/ltmain.sh
/install-sh
/missing
/configure
/stamp-h1
/depcomp
/gtk-doc.make
/build-aux
/udev-test-install
/udevd
/udevadm
/test-udev
/test-libudev
/accelerometer
/ata_id
/cdrom_id
/collect
/mtd_probe
/v4l_id
/keymap
/scsi_id

4
src/udev/.vimrc Normal file
View File

@ -0,0 +1,4 @@
" 'set exrc' in ~/.vimrc will read .vimrc from the current directory
set tabstop=8
set shiftwidth=8
set expandtab

339
src/udev/COPYING Normal file
View File

@ -0,0 +1,339 @@
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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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.
<signature of Ty Coon>, 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.

6387
src/udev/ChangeLog Normal file

File diff suppressed because it is too large Load Diff

44
src/udev/INSTALL Normal file
View File

@ -0,0 +1,44 @@
The options used usually look like:
%configure \
--prefix=/usr \
--sysconfdir=/etc \
--bindir=/usr/bin \
--libdir=/usr/lib64 \
--libexecdir=/usr/lib \
--with-systemdsystemunitdir=/usr/lib/systemd/system \
--with-selinux
The options used in a RPM spec file look like:
%configure \
--prefix=%{_prefix} \
--sysconfdir=%{_sysconfdir} \
--bindir=%{_bindir} \
--libdir=%{_libdir} \
--libexecdir=%{_prefix}/lib \
--with-systemdsystemunitdir=%{_prefix}/lib/systemd/system \
--with-selinux
The options to install udev in the rootfs instead of /usr,
and udevadm in /sbin:
--prefix=%{_prefix} \
--with-rootprefix= \
--sysconfdir=%{_sysconfdir} \
--bindir=/sbin \
--libdir=%{_libdir} \
--with-rootlibdir=/lib64 \
--libexecdir=/lib \
--with-systemdsystemunitdir=/lib/systemd/system \
--with-selinux
Some tools expect udevadm in 'sbin'. A symlink to udevadm in 'bin'
needs to be manually created if needed.
The defined location for scripts and binaries which are called
from rules is (/usr)/lib/udev/ on all systems and architectures. Any
other location will break other packages, who rightfully expect
the (/usr)/lib/udev/ directory, to install their rule helper and udev
rule files.
Default udev rules and persistent device naming rules may be required
by other software that depends on the data udev collects from the
devices.

712
src/udev/Makefile.am Normal file
View File

@ -0,0 +1,712 @@
# Copyright (C) 2008-2012 Kay Sievers <kay.sievers@vrfy.org>
# Copyright (C) 2009 Diego Elio 'Flameeyes' Pettenò <flameeyes@gmail.com>
SUBDIRS = .
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
AM_MAKEFLAGS = --no-print-directory
LIBUDEV_CURRENT=13
LIBUDEV_REVISION=2
LIBUDEV_AGE=13
LIBGUDEV_CURRENT=1
LIBGUDEV_REVISION=1
LIBGUDEV_AGE=1
AM_CPPFLAGS = \
-include $(top_builddir)/config.h \
-I$(top_srcdir)/src \
-DSYSCONFDIR=\""$(sysconfdir)"\" \
-DPKGLIBEXECDIR=\""$(libexecdir)/udev"\"
AM_CFLAGS = \
${my_CFLAGS} \
-fvisibility=hidden \
-ffunction-sections \
-fdata-sections
AM_LDFLAGS = \
-Wl,--gc-sections \
-Wl,--as-needed
DISTCHECK_CONFIGURE_FLAGS = \
--enable-debug \
--enable-rule_generator \
--enable-floppy \
--with-selinux \
--enable-gtk-doc \
--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
BUILT_SOURCES =
EXTRA_DIST =
CLEANFILES =
INSTALL_EXEC_HOOKS =
INSTALL_DATA_HOOKS =
UNINSTALL_EXEC_HOOKS =
DISTCHECK_HOOKS =
DISTCLEAN_LOCAL_HOOKS =
udevhomedir = $(libexecdir)/udev
udevhome_SCRIPTS =
dist_udevhome_SCRIPTS =
dist_udevhome_DATA =
dist_man_MANS =
SED_PROCESS = \
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && $(SED) \
-e 's,@VERSION\@,$(VERSION),g' \
-e 's,@prefix\@,$(prefix),g' \
-e 's,@rootprefix\@,$(rootprefix),g' \
-e 's,@exec_prefix\@,$(exec_prefix),g' \
-e 's,@libdir\@,$(libdir),g' \
-e 's,@includedir\@,$(includedir),g' \
-e 's,@bindir\@,$(bindir),g' \
-e 's,@pkglibexecdir\@,$(libexecdir)/udev,g' \
< $< > $@ || rm $@
%.pc: %.pc.in Makefile
$(SED_PROCESS)
%.rules: %.rules.in Makefile
$(SED_PROCESS)
%.service: %.service.in Makefile
$(SED_PROCESS)
%.sh: %.sh.in Makefile
$(SED_PROCESS)
$(AM_V_GEN)chmod +x $@
%.pl: %.pl.in Makefile
$(SED_PROCESS)
$(AM_V_GEN)chmod +x $@
# ------------------------------------------------------------------------------
SUBDIRS += src/docs
include_HEADERS = src/libudev.h
lib_LTLIBRARIES = libudev.la
noinst_LTLIBRARIES = libudev-private.la
libudev_la_SOURCES =\
src/libudev-private.h \
src/libudev.c \
src/libudev-list.c \
src/libudev-util.c \
src/libudev-device.c \
src/libudev-enumerate.c \
src/libudev-monitor.c \
src/libudev-queue.c
libudev_la_LDFLAGS = \
$(AM_LDFLAGS) \
-version-info $(LIBUDEV_CURRENT):$(LIBUDEV_REVISION):$(LIBUDEV_AGE)
libudev_private_la_SOURCES =\
$(libudev_la_SOURCES) \
src/libudev-util-private.c \
src/libudev-device-private.c \
src/libudev-queue-private.c
if WITH_SELINUX
libudev_private_la_SOURCES += src/libudev-selinux-private.c
libudev_private_la_LIBADD = $(SELINUX_LIBS)
endif
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = src/libudev.pc
EXTRA_DIST += src/libudev.pc.in
CLEANFILES += src/libudev.pc
EXTRA_DIST += src/COPYING
# move lib from $(libdir) to $(rootlib_execdir) and update devel link, if needed
libudev-install-move-hook:
if test "$(libdir)" != "$(rootlib_execdir)"; then \
mkdir -p $(DESTDIR)$(rootlib_execdir) && \
so_img_name=$$(readlink $(DESTDIR)$(libdir)/libudev.so) && \
so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \
ln -sf $$so_img_rel_target_prefix$(rootlib_execdir)/$$so_img_name $(DESTDIR)$(libdir)/libudev.so && \
mv $(DESTDIR)$(libdir)/libudev.so.* $(DESTDIR)$(rootlib_execdir); \
fi
libudev-uninstall-move-hook:
rm -f $(DESTDIR)$(rootlib_execdir)/libudev.so*
INSTALL_EXEC_HOOKS += libudev-install-move-hook
UNINSTALL_EXEC_HOOKS += libudev-uninstall-move-hook
# ------------------------------------------------------------------------------
udev-confdirs:
-mkdir -p $(DESTDIR)$(sysconfdir)/udev/rules.d
-mkdir -p $(DESTDIR)$(libexecdir)/udev/devices
INSTALL_DATA_HOOKS += udev-confdirs
udevrulesdir = $(libexecdir)/udev/rules.d
dist_udevrules_DATA = \
rules/42-usb-hid-pm.rules \
rules/50-udev-default.rules \
rules/60-persistent-storage-tape.rules \
rules/60-persistent-serial.rules \
rules/60-persistent-input.rules \
rules/60-persistent-alsa.rules \
rules/60-persistent-storage.rules \
rules/75-net-description.rules \
rules/75-tty-description.rules \
rules/78-sound-card.rules \
rules/80-drivers.rules \
rules/95-udev-late.rules
udevconfdir = $(sysconfdir)/udev
dist_udevconf_DATA = src/udev.conf
sharepkgconfigdir = $(datadir)/pkgconfig
sharepkgconfig_DATA = src/udev.pc
EXTRA_DIST += src/udev.pc.in
CLEANFILES += src/udev.pc
if WITH_SYSTEMD
dist_systemdsystemunit_DATA = \
src/udev-control.socket \
src/udev-kernel.socket
systemdsystemunit_DATA = \
src/udev.service \
src/udev-trigger.service \
src/udev-settle.service
EXTRA_DIST += \
src/udev.service.in \
src/udev-trigger.service.in \
src/udev-settle.service.in
CLEANFILES += \
src/udev.service \
src/udev-trigger.service \
src/udev-settle.service
systemd-install-hook:
mkdir -p $(DESTDIR)$(systemdsystemunitdir)/sockets.target.wants
ln -sf ../udev-control.socket $(DESTDIR)$(systemdsystemunitdir)/sockets.target.wants/udev-control.socket
ln -sf ../udev-kernel.socket $(DESTDIR)$(systemdsystemunitdir)/sockets.target.wants/udev-kernel.socket
mkdir -p $(DESTDIR)$(systemdsystemunitdir)/basic.target.wants
ln -sf ../udev.service $(DESTDIR)$(systemdsystemunitdir)/basic.target.wants/udev.service
ln -sf ../udev-trigger.service $(DESTDIR)$(systemdsystemunitdir)/basic.target.wants/udev-trigger.service
INSTALL_DATA_HOOKS += systemd-install-hook
endif
bin_PROGRAMS = \
udevadm
pkglibexec_PROGRAMS = \
udevd
udev_common_sources = \
src/udev.h \
src/udev-event.c \
src/udev-watch.c \
src/udev-node.c \
src/udev-rules.c \
src/udev-ctrl.c \
src/udev-builtin.c \
src/udev-builtin-blkid.c \
src/udev-builtin-firmware.c \
src/udev-builtin-hwdb.c \
src/udev-builtin-input_id.c \
src/udev-builtin-kmod.c \
src/udev-builtin-path_id.c \
src/udev-builtin-usb_id.c
udev_common_CFLAGS = \
$(BLKID_CFLAGS) \
$(KMOD_CFLAGS)
udev_common_LDADD = \
libudev-private.la \
$(BLKID_LIBS) \
$(KMOD_LIBS)
udev_common_CPPFLAGS = \
$(AM_CPPFLAGS) \
-DFIRMWARE_PATH="$(FIRMWARE_PATH)" \
-DUSB_DATABASE=\"$(USB_DATABASE)\" -DPCI_DATABASE=\"$(PCI_DATABASE)\"
udevd_SOURCES = \
$(udev_common_sources) \
src/udevd.c \
src/sd-daemon.h \
src/sd-daemon.c
udevd_CFLAGS = $(udev_common_CFLAGS)
udevd_LDADD = $(udev_common_LDADD)
udevd_CPPFLAGS = $(udev_common_CPPFLAGS)
udevadm_SOURCES = \
$(udev_common_sources) \
src/udevadm.c \
src/udevadm-info.c \
src/udevadm-control.c \
src/udevadm-monitor.c \
src/udevadm-settle.c \
src/udevadm-trigger.c \
src/udevadm-test.c \
src/udevadm-test-builtin.c
udevadm_CFLAGS = $(udev_common_CFLAGS)
udevadm_LDADD = $(udev_common_LDADD)
udevadm_CPPFLAGS = $(udev_common_CPPFLAGS)
# ------------------------------------------------------------------------------
if ENABLE_MANPAGES
dist_man_MANS += \
src/udev.7 \
src/udevadm.8 \
src/udevd.8
endif
EXTRA_DIST += \
src/udev.xml \
src/udevadm.xml \
src/udevd.xml
if HAVE_XSLTPROC
dist_noinst_DATA = \
src/udev.html \
src/udevadm.html \
src/udevd.html
src/%.7 src/%.8 : src/%.xml
$(AM_V_GEN)$(XSLTPROC) -o $@ -nonet http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
src/%.html : src/%.xml
$(AM_V_GEN)$(XSLTPROC) -o $@ -nonet http://docbook.sourceforge.net/release/xsl/current/xhtml-1_1/docbook.xsl $<
endif
# ------------------------------------------------------------------------------
TESTS = \
test/udev-test.pl \
test/rules-test.sh
check_PROGRAMS = \
test-libudev \
test-udev
test_libudev_SOURCES = src/test-libudev.c
test_libudev_LDADD = libudev.la
test_udev_SOURCES = \
$(udev_common_sources) \
src/test-udev.c
test_udev_CFLAGS = $(udev_common_CFLAGS)
test_udev_LDADD = $(udev_common_LDADD)
test_udev_CPPFLAGS = $(udev_common_CPPFLAGS)
test_udev_DEPENDENCIES = test/sys
# packed sysfs test tree
test/sys:
$(AM_V_GEN)mkdir -p test && tar -C test/ -xJf $(top_srcdir)/test/sys.tar.xz
test-sys-distclean:
-rm -rf test/sys
DISTCLEAN_LOCAL_HOOKS += test-sys-distclean
EXTRA_DIST += test/sys.tar.xz
# ------------------------------------------------------------------------------
ata_id_SOURCES = src/ata_id/ata_id.c
ata_id_LDADD = libudev-private.la
pkglibexec_PROGRAMS += ata_id
# ------------------------------------------------------------------------------
cdrom_id_SOURCES = src/cdrom_id/cdrom_id.c
cdrom_id_LDADD = libudev-private.la
pkglibexec_PROGRAMS += cdrom_id
dist_udevrules_DATA += src/cdrom_id/60-cdrom_id.rules
# ------------------------------------------------------------------------------
collect_SOURCES = src/collect/collect.c
collect_LDADD = libudev-private.la
pkglibexec_PROGRAMS += collect
# ------------------------------------------------------------------------------
scsi_id_SOURCES =\
src/scsi_id/scsi_id.c \
src/scsi_id/scsi_serial.c \
src/scsi_id/scsi.h \
src/scsi_id/scsi_id.h
scsi_id_LDADD = libudev-private.la
pkglibexec_PROGRAMS += scsi_id
dist_man_MANS += src/scsi_id/scsi_id.8
EXTRA_DIST += src/scsi_id/README
# ------------------------------------------------------------------------------
v4l_id_SOURCES = src/v4l_id/v4l_id.c
v4l_id_LDADD = libudev-private.la
pkglibexec_PROGRAMS += v4l_id
dist_udevrules_DATA += src/v4l_id/60-persistent-v4l.rules
# ------------------------------------------------------------------------------
accelerometer_SOURCES = src/accelerometer/accelerometer.c
accelerometer_LDADD = libudev-private.la -lm
pkglibexec_PROGRAMS += accelerometer
dist_udevrules_DATA += src/accelerometer/61-accelerometer.rules
# ------------------------------------------------------------------------------
if ENABLE_GUDEV
SUBDIRS += src/gudev/docs
libgudev_includedir=$(includedir)/gudev-1.0/gudev
libgudev_include_HEADERS = \
src/gudev/gudev.h \
src/gudev/gudevenums.h \
src/gudev/gudevenumtypes.h \
src/gudev/gudevtypes.h \
src/gudev/gudevclient.h \
src/gudev/gudevdevice.h \
src/gudev/gudevenumerator.h
lib_LTLIBRARIES += libgudev-1.0.la
pkgconfig_DATA += src/gudev/gudev-1.0.pc
EXTRA_DIST += src/gudev/gudev-1.0.pc.in
CLEANFILES += src/gudev/gudev-1.0.pc
libgudev_1_0_la_SOURCES = \
src/gudev/gudevenums.h \
src/gudev/gudevenumtypes.h \
src/gudev/gudevenumtypes.h\
src/gudev/gudevtypes.h \
src/gudev/gudevclient.h \
src/gudev/gudevclient.c \
src/gudev/gudevdevice.h \
src/gudev/gudevdevice.c \
src/gudev/gudevenumerator.h \
src/gudev/gudevenumerator.c \
src/gudev/gudevprivate.h
nodist_libgudev_1_0_la_SOURCES = \
src/gudev/gudevmarshal.h \
src/gudev/gudevmarshal.c \
src/gudev/gudevenumtypes.h \
src/gudev/gudevenumtypes.c
BUILT_SOURCES += $(nodist_libgudev_1_0_la_SOURCES)
libgudev_1_0_la_CPPFLAGS = \
$(AM_CPPFLAGS) \
-I$(top_builddir)/src\
-I$(top_srcdir)/src\
-I$(top_builddir)/src/gudev \
-I$(top_srcdir)/src/gudev \
-D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
-D_GUDEV_COMPILATION \
-DG_LOG_DOMAIN=\"GUdev\"
libgudev_1_0_la_CFLAGS = \
-fvisibility=default \
$(GLIB_CFLAGS)
libgudev_1_0_la_LIBADD = libudev.la $(GLIB_LIBS)
libgudev_1_0_la_LDFLAGS = \
-version-info $(LIBGUDEV_CURRENT):$(LIBGUDEV_REVISION):$(LIBGUDEV_AGE) \
-export-dynamic -no-undefined \
-export-symbols-regex '^g_udev_.*'
EXTRA_DIST += \
src/gudev/COPYING \
src/gudev/gudevmarshal.list \
src/gudev/gudevenumtypes.h.template \
src/gudev/gudevenumtypes.c.template \
src/gudev/gjs-example.js \
src/gudev/seed-example-enum.js \
src/gudev/seed-example.js
src/gudev/gudevmarshal.h: src/gudev/gudevmarshal.list
$(AM_V_GEN)glib-genmarshal $< --prefix=g_udev_marshal --header > $@
src/gudev/gudevmarshal.c: src/gudev/gudevmarshal.list
$(AM_V_GEN)echo "#include \"gudevmarshal.h\"" > $@ && \
glib-genmarshal $< --prefix=g_udev_marshal --body >> $@
src/gudev/gudevenumtypes.h: src/gudev/gudevenumtypes.h.template src/gudev/gudevenums.h
$(AM_V_GEN)glib-mkenums --template $^ > \
$@.tmp && mv $@.tmp $@
src/gudev/gudevenumtypes.c: src/gudev/gudevenumtypes.c.template src/gudev/gudevenums.h
$(AM_V_GEN)glib-mkenums --template $^ > \
$@.tmp && mv $@.tmp $@
if ENABLE_INTROSPECTION
src/gudev/GUdev-1.0.gir: libgudev-1.0.la $(G_IR_SCANNER)
$(AM_V_GEN)$(G_IR_SCANNER) -v \
--warn-all \
--namespace GUdev \
--nsversion=1.0 \
--include=GObject-2.0 \
--library=gudev-1.0 \
--library-path=$(top_builddir)/src \
--library-path=$(top_builddir)/src/gudev \
--output $@ \
--pkg=glib-2.0 \
--pkg=gobject-2.0 \
--pkg-export=gudev-1.0 \
--c-include=gudev/gudev.h \
-I$(top_srcdir)/src/\
-I$(top_builddir)/src/\
-D_GUDEV_COMPILATION \
-D_GUDEV_WORK_AROUND_DEV_T_BUG \
$(top_srcdir)/src/gudev/gudev.h \
$(top_srcdir)/src/gudev/gudevtypes.h \
$(top_srcdir)/src/gudev/gudevenums.h \
$(or $(wildcard $(top_builddir)/src/gudev/gudevenumtypes.h),$(top_srcdir)/src/gudev/gudevenumtypes.h) \
$(top_srcdir)/src/gudev/gudevclient.h \
$(top_srcdir)/src/gudev/gudevdevice.h \
$(top_srcdir)/src/gudev/gudevenumerator.h \
$(top_srcdir)/src/gudev/gudevclient.c \
$(top_srcdir)/src/gudev/gudevdevice.c \
$(top_srcdir)/src/gudev/gudevenumerator.c
src/gudev/GUdev-1.0.typelib: src/gudev/GUdev-1.0.gir $(G_IR_COMPILER)
$(AM_V_GEN)g-ir-compiler $< -o $@
girdir = $(GIRDIR)
gir_DATA = src/gudev/GUdev-1.0.gir
typelibsdir = $(GIRTYPELIBDIR)
typelibs_DATA = src/gudev/GUdev-1.0.typelib
CLEANFILES += $(gir_DATA) $(typelibs_DATA)
endif # ENABLE_INTROSPECTION
# move lib from $(libdir) to $(rootlib_execdir) and update devel link, if needed
libgudev-install-move-hook:
if test "$(libdir)" != "$(rootlib_execdir)"; then \
mkdir -p $(DESTDIR)$(rootlib_execdir) && \
so_img_name=$$(readlink $(DESTDIR)$(libdir)/libgudev-1.0.so) && \
so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \
ln -sf $$so_img_rel_target_prefix$(rootlib_execdir)/$$so_img_name $(DESTDIR)$(libdir)/libgudev-1.0.so && \
mv $(DESTDIR)$(libdir)/libgudev-1.0.so.* $(DESTDIR)$(rootlib_execdir); \
fi
libgudev-uninstall-move-hook:
rm -f $(DESTDIR)$(rootlib_execdir)/libgudev-1.0.so*
INSTALL_EXEC_HOOKS += libgudev-install-move-hook
UNINSTALL_EXEC_HOOKS += libgudev-uninstall-move-hook
endif
# ------------------------------------------------------------------------------
if ENABLE_KEYMAP
keymap_SOURCES = src/keymap/keymap.c
keymap_CPPFLAGS = $(AM_CPPFLAGS) -I src/keymap
nodist_keymap_SOURCES = \
src/keymap/keys-from-name.h \
src/keymap/keys-to-name.h
BUILT_SOURCES += $(nodist_keymap_SOURCES)
pkglibexec_PROGRAMS += keymap
dist_doc_DATA = src/keymap/README.keymap.txt
dist_udevrules_DATA += \
src/keymap/95-keymap.rules \
src/keymap/95-keyboard-force-release.rules
dist_udevhome_SCRIPTS += src/keymap/findkeyboards
udevhome_SCRIPTS += src/keymap/keyboard-force-release.sh
EXTRA_DIST += \
src/keymap/check-keymaps.sh \
src/keymap/keyboard-force-release.sh.in
CLEANFILES += \
src/keymap/keys.txt \
src/keymap/keys-from-name.gperf \
src/keymap/keyboard-force-release.sh
udevkeymapdir = $(libexecdir)/udev/keymaps
dist_udevkeymap_DATA = \
src/keymap/keymaps/acer \
src/keymap/keymaps/acer-aspire_5720 \
src/keymap/keymaps/acer-aspire_8930 \
src/keymap/keymaps/acer-aspire_5920g \
src/keymap/keymaps/acer-aspire_6920 \
src/keymap/keymaps/acer-travelmate_c300 \
src/keymap/keymaps/asus \
src/keymap/keymaps/compaq-e_evo \
src/keymap/keymaps/dell \
src/keymap/keymaps/dell-latitude-xt2 \
src/keymap/keymaps/everex-xt5000 \
src/keymap/keymaps/fujitsu-amilo_li_2732 \
src/keymap/keymaps/fujitsu-amilo_pa_2548 \
src/keymap/keymaps/fujitsu-amilo_pro_edition_v3505 \
src/keymap/keymaps/fujitsu-amilo_pro_v3205 \
src/keymap/keymaps/fujitsu-amilo_si_1520 \
src/keymap/keymaps/fujitsu-esprimo_mobile_v5 \
src/keymap/keymaps/fujitsu-esprimo_mobile_v6 \
src/keymap/keymaps/genius-slimstar-320 \
src/keymap/keymaps/hewlett-packard \
src/keymap/keymaps/hewlett-packard-2510p_2530p \
src/keymap/keymaps/hewlett-packard-compaq_elitebook \
src/keymap/keymaps/hewlett-packard-pavilion \
src/keymap/keymaps/hewlett-packard-presario-2100 \
src/keymap/keymaps/hewlett-packard-tablet \
src/keymap/keymaps/hewlett-packard-tx2 \
src/keymap/keymaps/ibm-thinkpad-usb-keyboard-trackpoint \
src/keymap/keymaps/inventec-symphony_6.0_7.0 \
src/keymap/keymaps/lenovo-3000 \
src/keymap/keymaps/lenovo-ideapad \
src/keymap/keymaps/lenovo-thinkpad-usb-keyboard-trackpoint \
src/keymap/keymaps/lenovo-thinkpad_x6_tablet \
src/keymap/keymaps/lenovo-thinkpad_x200_tablet \
src/keymap/keymaps/lg-x110 \
src/keymap/keymaps/logitech-wave \
src/keymap/keymaps/logitech-wave-cordless \
src/keymap/keymaps/logitech-wave-pro-cordless \
src/keymap/keymaps/maxdata-pro_7000 \
src/keymap/keymaps/medion-fid2060 \
src/keymap/keymaps/medionnb-a555 \
src/keymap/keymaps/micro-star \
src/keymap/keymaps/module-asus-w3j \
src/keymap/keymaps/module-ibm \
src/keymap/keymaps/module-lenovo \
src/keymap/keymaps/module-sony \
src/keymap/keymaps/module-sony-old \
src/keymap/keymaps/module-sony-vgn \
src/keymap/keymaps/olpc-xo \
src/keymap/keymaps/onkyo \
src/keymap/keymaps/oqo-model2 \
src/keymap/keymaps/samsung-other \
src/keymap/keymaps/samsung-90x3a \
src/keymap/keymaps/samsung-sq1us \
src/keymap/keymaps/samsung-sx20s \
src/keymap/keymaps/toshiba-satellite_a100 \
src/keymap/keymaps/toshiba-satellite_a110 \
src/keymap/keymaps/toshiba-satellite_m30x \
src/keymap/keymaps/zepto-znote
udevkeymapforcereldir = $(libexecdir)/udev/keymaps/force-release
dist_udevkeymapforcerel_DATA = \
src/keymap/force-release-maps/dell-touchpad \
src/keymap/force-release-maps/hp-other \
src/keymap/force-release-maps/samsung-other \
src/keymap/force-release-maps/samsung-90x3a \
src/keymap/force-release-maps/common-volume-keys
src/keymap/keys.txt: $(INCLUDE_PREFIX)/linux/input.h
$(AM_V_at)mkdir -p src/keymap
$(AM_V_GEN)$(AWK) '/^#define.*KEY_[^ ]+[ \t]+[0-9]/ { if ($$2 != "KEY_MAX") { print $$2 } }' < $< | sed 's/^KEY_COFFEE$$/KEY_SCREENLOCK/' > $@
src/keymap/keys-from-name.gperf: src/keymap/keys.txt
$(AM_V_GEN)$(AWK) 'BEGIN{ print "struct key { const char* name; unsigned short id; };"; print "%null-strings"; print "%%";} { print $$1 ", " $$1 }' < $< > $@
src/keymap/keys-from-name.h: src/keymap/keys-from-name.gperf Makefile
$(AM_V_GEN)$(GPERF) -L ANSI-C -t --ignore-case -N lookup_key -H hash_key_name -p -C < $< > $@
src/keymap/keys-to-name.h: src/keymap/keys.txt Makefile
$(AM_V_GEN)$(AWK) 'BEGIN{ print "const char* const key_names[KEY_CNT] = { "} { print "[" $$1 "] = \"" $$1 "\"," } END{print "};"}' < $< > $@
keymaps-distcheck-hook: src/keymap/keys.txt
$(top_srcdir)/src/keymap/check-keymaps.sh $(top_srcdir) $^
DISTCHECK_HOOKS += keymaps-distcheck-hook
endif
if ENABLE_MTD_PROBE
# ------------------------------------------------------------------------------
mtd_probe_SOURCES = \
src/mtd_probe/mtd_probe.c \
src/mtd_probe/mtd_probe.h \
src/mtd_probe/probe_smartmedia.c
mtd_probe_CPPFLAGS = $(AM_CPPFLAGS)
dist_udevrules_DATA += src/mtd_probe/75-probe_mtd.rules
pkglibexec_PROGRAMS += mtd_probe
endif
# ------------------------------------------------------------------------------
if ENABLE_RULE_GENERATOR
dist_udevhome_SCRIPTS += \
src/rule_generator/write_cd_rules \
src/rule_generator/write_net_rules
dist_udevhome_DATA += \
src/rule_generator/rule_generator.functions
dist_udevrules_DATA += \
src/rule_generator/75-cd-aliases-generator.rules \
src/rule_generator/75-persistent-net-generator.rules
endif
# ------------------------------------------------------------------------------
if ENABLE_FLOPPY
create_floppy_devices_SOURCES = src/floppy/create_floppy_devices.c
create_floppy_devices_LDADD = libudev-private.la
pkglibexec_PROGRAMS += create_floppy_devices
dist_udevrules_DATA += src/floppy/60-floppy.rules
endif
# ------------------------------------------------------------------------------
clean-local:
rm -rf udev-test-install
distclean-local:
rm -rf autom4te.cache
EXTRA_DIST += \
$(TESTS) \
test/rule-syntax-check.py
CLEANFILES += \
$(BUILT_SOURCES)
install-exec-hook: $(INSTALL_EXEC_HOOKS)
install-data-hook: $(INSTALL_DATA_HOOKS)
uninstall-hook: $(UNINSTALL_EXEC_HOOKS)
distcheck-hook: $(DISTCHECK_HOOKS)
distclean-local: $(DISTCLEAN_LOCAL_HOOKS)
# ------------------------------------------------------------------------------
PREVIOUS_VERSION = `expr $(VERSION) - 1`
changelog:
@ head -1 ChangeLog | grep -q "to v$(PREVIOUS_VERSION)"
@ mv ChangeLog ChangeLog.tmp
@ echo "Summary of changes from v$(PREVIOUS_VERSION) to v$(VERSION)" >> ChangeLog
@ echo "============================================" >> ChangeLog
@ echo >> ChangeLog
@ git log --pretty=short $(PREVIOUS_VERSION)..HEAD | git shortlog >> ChangeLog
@ echo >> ChangeLog
@ cat ChangeLog
@ cat ChangeLog.tmp >> ChangeLog
@ rm ChangeLog.tmp
test-install:
rm -rf $(PWD)/udev-test-install/
make DESTDIR=$(PWD)/udev-test-install install
tree $(PWD)/udev-test-install/
git-release:
head -1 ChangeLog | grep -q "to v$(VERSION)"
head -1 NEWS | grep -q "udev $(VERSION)"
git commit -a -m "release $(VERSION)"
git tag -m "udev $(VERSION)" -s $(VERSION)
git gc --prune=0
git-sync:
git push
git push --tags
tar-sync:
rm -f udev-$(VERSION).tar.sign
xz -d -c udev-$(VERSION).tar.xz | gpg --armor --detach-sign --output udev-$(VERSION).tar.sign
kup put udev-$(VERSION).tar.xz udev-$(VERSION).tar.sign /pub/linux/utils/kernel/hotplug/
doc-sync:
for i in src/*.html; do rm -f $$i.sign; gpg --armor --detach-sign --output=$$i.sign $$i; done
for i in src/*.html; do echo $$i; kup put $$i $$i.sign /pub/linux/utils/kernel/hotplug/udev/; done
for i in src/docs/html/*.{html,css,png}; do rm -f $$i.sign; gpg --armor --detach-sign --output=$$i.sign $$i; done
for i in src/docs/html/*.{html,css,png}; do echo $$i; kup put $$i $$i.sign /pub/linux/utils/kernel/hotplug/libudev/; done
for i in src/gudev/docs/html/*.{html,css,png}; do rm -f $$i.sign; gpg --armor --detach-sign --output=$$i.sign $$i; done
for i in src/gudev/docs/html/*.{html,css,png}; do echo $$i; kup put $$i $$i.sign /pub/linux/utils/kernel/hotplug/gudev/; done

1735
src/udev/NEWS Normal file

File diff suppressed because it is too large Load Diff

101
src/udev/README Normal file
View File

@ -0,0 +1,101 @@
udev - Linux userspace device management
Integrating udev in the system has complex dependencies and may differ from
distribution to distribution. A system may not be able to boot up or work
reliably without a properly installed udev version. The upstream udev project
does not recommend replacing a distro's udev installation with the upstream
version.
The upstream udev project's set of default rules may require a most recent
kernel release to work properly.
Tools and rules shipped by udev are not public API and may change at any time.
Never call any private tool in /usr/lib/udev from any external application; it
might just go away in the next release. Access to udev information is only offered
by udevadm and libudev. Tools and rules in /usr/lib/udev and the entire contents
of the /run/udev directory are private to udev and do change whenever needed.
Requirements:
- Version 2.6.34 of the Linux kernel with sysfs, procfs, signalfd, inotify,
unix domain sockets, networking and hotplug enabled
- Some architectures might need a later kernel, that supports accept4(),
or need to backport the accept4() syscall wiring in the kernel.
- These options are required:
CONFIG_DEVTMPFS=y
CONFIG_HOTPLUG=y
CONFIG_INOTIFY_USER=y
CONFIG_NET=y
CONFIG_PROC_FS=y
CONFIG_SIGNALFD=y
CONFIG_SYSFS=y
CONFIG_SYSFS_DEPRECATED*=n
CONFIG_UEVENT_HELPER_PATH=""
- These options might be needed:
CONFIG_BLK_DEV_BSG=y (SCSI devices)
CONFIG_TMPFS_POSIX_ACL=y (user ACLs for device nodes)
- The /dev directory needs the 'devtmpfs' filesystem mounted.
Udev only manages the permissions and ownership of the
kernel-provided device nodes, and possibly creates additional symlinks.
- Udev requires /run to be writable, which is usually done by mounting a
'tmpfs' filesystem.
- This version of udev does not work properly with the CONFIG_SYSFS_DEPRECATED*
option enabled.
- The deprecated hotplug helper /sbin/hotplug should be disabled in the
kernel configuration, it is not needed today, and may render the system
unusable because the kernel may create too many processes in parallel
so that the system runs out-of-memory.
- The proc filesystem must be mounted on /proc, and the sysfs filesystem must
be mounted at /sys. No other locations are supported by a standard
udev installation.
- The default rule sset requires the following group names resolvable at udev startup:
disk, cdrom, floppy, tape, audio, video, lp, tty, dialout, and kmem.
Especially in LDAP setups, it is required that getgrnam() be able to resolve
these group names with only the rootfs mounted and while no network is
available.
- Some udev extras have external dependencies like:
libglib2, usbutils, pciutils, and gperf.
All these extras can be disabled with configure options.
Setup:
- The udev daemon should be started to handle device events sent by the kernel.
During bootup, the events for already existing devices can be replayed, so
that they are configured by udev. The systemd service files contain the
needed commands to start the udev daemon and the coldplug sequence.
- Restarting the daemon never applies any rules to existing devices.
- New/changed rule files are picked up automatically; there is usually no
daemon restart or signal needed.
Operation:
- Based on events the kernel sends out on device creation/removal, udev
creates/removes device nodes and symlinks in the /dev directory.
- All kernel events are matched against a set of specified rules, which
possibly hook into the event processing and load required kernel
modules to set up devices. For all devices, the kernel exports a major/minor
number; if needed, udev creates a device node with the default kernel
device name. If specified, udev applies permissions/ownership to the device
node, creates additional symlinks pointing to the node, and executes
programs to handle the device.
- The events udev handles, and the information udev merges into its device
database, can be accessed with libudev:
http://www.kernel.org/pub/linux/utils/kernel/hotplug/libudev/
http://www.kernel.org/pub/linux/utils/kernel/hotplug/gudev/
For more details about udev and udev rules, see the udev man pages:
http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev/
Please direct any comment/question to the linux-hotplug mailing list at:
linux-hotplug@vger.kernel.org

22
src/udev/TODO Normal file
View File

@ -0,0 +1,22 @@
- find a way to tell udev to not cancel firmware
requests in initramfs
- scsi_id -> sg3_utils?
- make gtk-doc optional like kmod
- move /usr/lib/udev/devices/ to tmpfiles
- trigger --subsystem-match=usb/usb_device
- kill rules_generator
- have a $attrs{} ?
- remove RUN+="socket:"
- libudev.so.1
- symbol versioning
- return object with *_unref()
- udev_monitor_from_socket()
- udev_queue_get_failed_list_entry()

44
src/udev/autogen.sh Executable file
View File

@ -0,0 +1,44 @@
#!/bin/sh -e
if [ -f .git/hooks/pre-commit.sample -a ! -f .git/hooks/pre-commit ] ; then
cp -p .git/hooks/pre-commit.sample .git/hooks/pre-commit && \
chmod +x .git/hooks/pre-commit && \
echo "Activated pre-commit hook."
fi
gtkdocize
autoreconf --install --symlink
libdir() {
echo $(cd $1/$(gcc -print-multi-os-directory); pwd)
}
args="$args \
--prefix=/usr \
--sysconfdir=/etc \
--libdir=$(libdir /usr/lib) \
--with-selinux \
--enable-gtk-doc"
if [ -L /bin ]; then
args="$args \
--libexecdir=/usr/lib \
--with-systemdsystemunitdir=/usr/lib/systemd/system \
"
else
args="$args \
--with-rootprefix= \
---with-rootlibdir=$(libdir /lib) \
--bindir=/sbin \
--libexecdir=/lib \
--with-systemdsystemunitdir=/lib/systemd/system \
"
fi
echo
echo "----------------------------------------------------------------"
echo "Initialized build system. For a common configuration please run:"
echo "----------------------------------------------------------------"
echo
echo "./configure CFLAGS='-g -O1' $args"
echo

242
src/udev/configure.ac Normal file
View File

@ -0,0 +1,242 @@
AC_PREREQ(2.60)
AC_INIT([udev],
[182],
[linux-hotplug@vger.kernel.org],
[udev],
[http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html])
AC_CONFIG_SRCDIR([src/udevd.c])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([check-news foreign 1.11 -Wall -Wno-portability silent-rules tar-pax no-dist-gzip dist-xz subdir-objects])
AC_USE_SYSTEM_EXTENSIONS
AC_SYS_LARGEFILE
AC_CONFIG_MACRO_DIR([m4])
AM_SILENT_RULES([yes])
LT_INIT([disable-static])
AC_PROG_AWK
AC_PROG_SED
AC_PROG_MKDIR_P
GTK_DOC_CHECK(1.10)
AC_PREFIX_DEFAULT([/usr])
AC_PATH_PROG([XSLTPROC], [xsltproc])
AM_CONDITIONAL(HAVE_XSLTPROC, test x"$XSLTPROC" != x)
AC_SEARCH_LIBS([clock_gettime], [rt], [], [AC_MSG_ERROR([POSIX RT library not found])])
PKG_CHECK_MODULES(BLKID, blkid >= 2.20)
PKG_CHECK_MODULES(KMOD, libkmod >= 5)
AC_ARG_WITH([rootprefix],
AS_HELP_STRING([--with-rootprefix=DIR], [rootfs directory prefix for config files and kernel modules]),
[], [with_rootprefix=${ac_default_prefix}])
AC_SUBST([rootprefix], [$with_rootprefix])
AC_ARG_WITH([rootlibdir],
AS_HELP_STRING([--with-rootlibdir=DIR], [rootfs directory to install shared libraries]),
[], [with_rootlibdir=$libdir])
AC_SUBST([rootlib_execdir], [$with_rootlibdir])
AC_ARG_WITH([selinux],
AS_HELP_STRING([--with-selinux], [enable SELinux support]),
[], [with_selinux=no])
AS_IF([test "x$with_selinux" = "xyes"], [
LIBS_save=$LIBS
AC_CHECK_LIB(selinux, getprevcon,
[],
AC_MSG_ERROR([SELinux selected but libselinux not found]))
LIBS=$LIBS_save
SELINUX_LIBS="-lselinux -lsepol"
AC_DEFINE(WITH_SELINUX, [1] ,[SELinux support.])
])
AC_SUBST([SELINUX_LIBS])
AM_CONDITIONAL(WITH_SELINUX, [test "x$with_selinux" = "xyes"])
AC_ARG_ENABLE([debug],
AS_HELP_STRING([--enable-debug], [enable debug messages @<:@default=disabled@:>@]),
[], [enable_debug=no])
AS_IF([test "x$enable_debug" = "xyes"], [ AC_DEFINE(ENABLE_DEBUG, [1], [Debug messages.]) ])
AC_ARG_ENABLE([logging],
AS_HELP_STRING([--disable-logging], [disable system logging @<:@default=enabled@:>@]),
[], enable_logging=yes)
AS_IF([test "x$enable_logging" = "xyes"], [ AC_DEFINE(ENABLE_LOGGING, [1], [System logging.]) ])
AC_ARG_ENABLE([manpages],
AS_HELP_STRING([--disable-manpages], [disable man pages @<:@default=enabled@:>@]),
[], enable_manpages=yes)
AM_CONDITIONAL([ENABLE_MANPAGES], [test "x$enable_manpages" = "xyes"])
if test "x$cross_compiling" = "xno" ; then
AC_CHECK_FILES([/usr/share/pci.ids], [pciids=/usr/share/pci.ids])
AC_CHECK_FILES([/usr/share/hwdata/pci.ids], [pciids=/usr/share/hwdata/pci.ids])
AC_CHECK_FILES([/usr/share/misc/pci.ids], [pciids=/usr/share/misc/pci.ids])
fi
AC_ARG_WITH(usb-ids-path,
[AS_HELP_STRING([--with-usb-ids-path=DIR], [Path to usb.ids file])],
[USB_DATABASE=${withval}],
[if test -n "$usbids" ; then
USB_DATABASE="$usbids"
else
PKG_CHECK_MODULES(USBUTILS, usbutils >= 0.82)
AC_SUBST([USB_DATABASE], [$($PKG_CONFIG --variable=usbids usbutils)])
fi])
AC_MSG_CHECKING([for USB database location])
AC_MSG_RESULT([$USB_DATABASE])
AC_SUBST(USB_DATABASE)
AC_ARG_WITH(pci-ids-path,
[AS_HELP_STRING([--with-pci-ids-path=DIR], [Path to pci.ids file])],
[PCI_DATABASE=${withval}],
[if test -n "$pciids" ; then
PCI_DATABASE="$pciids"
else
AC_MSG_ERROR([pci.ids not found, try --with-pci-ids-path=])
fi])
AC_MSG_CHECKING([for PCI database location])
AC_MSG_RESULT([$PCI_DATABASE])
AC_SUBST(PCI_DATABASE)
AC_ARG_WITH(firmware-path,
AS_HELP_STRING([--with-firmware-path=DIR[[[:DIR[...]]]]],
[Firmware search path (default=ROOTPREFIX/lib/firmware/updates:ROOTPREFIX/lib/firmware)]),
[], [with_firmware_path="$rootprefix/lib/firmware/updates:$rootprefix/lib/firmware"])
OLD_IFS=$IFS
IFS=:
for i in $with_firmware_path; do
if test "x${FIRMWARE_PATH}" = "x"; then
FIRMWARE_PATH="\\\"${i}/\\\""
else
FIRMWARE_PATH="${FIRMWARE_PATH}, \\\"${i}/\\\""
fi
done
IFS=$OLD_IFS
AC_SUBST([FIRMWARE_PATH], [$FIRMWARE_PATH])
AC_ARG_WITH([systemdsystemunitdir],
AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
[], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)])
AS_IF([test "x$with_systemdsystemunitdir" != "xno"], [ AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir]) ])
AM_CONDITIONAL(WITH_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != "xno" ])
# ------------------------------------------------------------------------------
# GUdev - libudev gobject interface
# ------------------------------------------------------------------------------
AC_ARG_ENABLE([gudev],
AS_HELP_STRING([--disable-gudev], [disable Gobject libudev support @<:@default=enabled@:>@]),
[], [enable_gudev=yes])
AS_IF([test "x$enable_gudev" = "xyes"], [ PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.22.0 gobject-2.0 >= 2.22.0]) ])
AC_ARG_ENABLE([introspection],
AS_HELP_STRING([--disable-introspection], [disable GObject introspection @<:@default=enabled@:>@]),
[], [enable_introspection=yes])
AS_IF([test "x$enable_introspection" = "xyes"], [
PKG_CHECK_MODULES([INTROSPECTION], [gobject-introspection-1.0 >= 0.6.2])
AC_DEFINE([ENABLE_INTROSPECTION], [1], [enable GObject introspection support])
AC_SUBST([G_IR_SCANNER], [$($PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0)])
AC_SUBST([G_IR_COMPILER], [$($PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0)])
AC_SUBST([G_IR_GENERATE], [$($PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0)])
AC_SUBST([GIRDIR], [$($PKG_CONFIG --define-variable=datadir=${datadir} --variable=girdir gobject-introspection-1.0)])
AC_SUBST([GIRTYPELIBDIR], [$($PKG_CONFIG --define-variable=libdir=${libdir} --variable=typelibdir gobject-introspection-1.0)])
])
AM_CONDITIONAL([ENABLE_INTROSPECTION], [test "x$enable_introspection" = "xyes"])
AM_CONDITIONAL([ENABLE_GUDEV], [test "x$enable_gudev" = "xyes"])
# ------------------------------------------------------------------------------
# keymap - map custom hardware's multimedia keys
# ------------------------------------------------------------------------------
AC_ARG_ENABLE([keymap],
AS_HELP_STRING([--disable-keymap], [disable keymap fixup support @<:@default=enabled@:>@]),
[], [enable_keymap=yes])
AS_IF([test "x$enable_keymap" = "xyes"], [
AC_PATH_PROG([GPERF], [gperf])
if test -z "$GPERF"; then
AC_MSG_ERROR([gperf is needed])
fi
AC_CHECK_HEADER([linux/input.h], [:], AC_MSG_ERROR([kernel headers not found]))
AC_SUBST([INCLUDE_PREFIX], [$(echo '#include <linux/input.h>' | eval $ac_cpp -E - | sed -n '/linux\/input.h/ {s:.*"\(.*\)/linux/input.h".*:\1:; p; q}')])
])
AM_CONDITIONAL([ENABLE_KEYMAP], [test "x$enable_keymap" = "xyes"])
# ------------------------------------------------------------------------------
# mtd_probe - autoloads FTL module for mtd devices
# ------------------------------------------------------------------------------
AC_ARG_ENABLE([mtd_probe],
AS_HELP_STRING([--disable-mtd_probe], [disable MTD support @<:@default=enabled@:>@]),
[], [enable_mtd_probe=yes])
AM_CONDITIONAL([ENABLE_MTD_PROBE], [test "x$enable_mtd_probe" = "xyes"])
# ------------------------------------------------------------------------------
# rule_generator - persistent network and optical device rule generator
# ------------------------------------------------------------------------------
AC_ARG_ENABLE([rule_generator],
AS_HELP_STRING([--enable-rule_generator], [enable persistent network + cdrom links support @<:@default=disabled@:>@]),
[], [enable_rule_generator=no])
AM_CONDITIONAL([ENABLE_RULE_GENERATOR], [test "x$enable_rule_generator" = "xyes"])
# ------------------------------------------------------------------------------
# create_floppy_devices - historical floppy kernel device nodes (/dev/fd0h1440, ...)
# ------------------------------------------------------------------------------
AC_ARG_ENABLE([floppy],
AS_HELP_STRING([--enable-floppy], [enable legacy floppy support @<:@default=disabled@:>@]),
[], [enable_floppy=no])
AM_CONDITIONAL([ENABLE_FLOPPY], [test "x$enable_floppy" = "xyes"])
my_CFLAGS="-Wall \
-Wmissing-declarations -Wmissing-prototypes \
-Wnested-externs -Wpointer-arith \
-Wpointer-arith -Wsign-compare -Wchar-subscripts \
-Wstrict-prototypes -Wshadow \
-Wformat-security -Wtype-limits"
AC_SUBST([my_CFLAGS])
AC_CONFIG_HEADERS(config.h)
AC_CONFIG_FILES([
Makefile
src/docs/Makefile
src/docs/version.xml
src/gudev/docs/Makefile
src/gudev/docs/version.xml
])
AC_OUTPUT
AC_MSG_RESULT([
$PACKAGE $VERSION
========
prefix: ${prefix}
rootprefix: ${rootprefix}
sysconfdir: ${sysconfdir}
bindir: ${bindir}
libdir: ${libdir}
rootlibdir: ${rootlib_execdir}
libexecdir: ${libexecdir}
datarootdir: ${datarootdir}
mandir: ${mandir}
includedir: ${includedir}
include_prefix: ${INCLUDE_PREFIX}
systemdsystemunitdir: ${systemdsystemunitdir}
firmware path: ${FIRMWARE_PATH}
usb.ids: ${USB_DATABASE}
pci.ids: ${PCI_DATABASE}
compiler: ${CC}
cflags: ${CFLAGS}
ldflags: ${LDFLAGS}
xsltproc: ${XSLTPROC}
gperf: ${GPERF}
logging: ${enable_logging}
debug: ${enable_debug}
selinux: ${with_selinux}
man pages ${enable_manpages}
gudev: ${enable_gudev}
gintrospection: ${enable_introspection}
keymap: ${enable_keymap}
mtd_probe: ${enable_mtd_probe}
rule_generator: ${enable_rule_generator}
floppy: ${enable_floppy}
])

4
src/udev/m4/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
libtool.m4
lt*m4
gtk-doc.m4

View File

@ -0,0 +1,49 @@
#
# Enable autosuspend for qemu emulated usb hid devices.
#
# Note that there are buggy qemu versions which advertise remote
# wakeup support but don't actually implement it correctly. This
# is the reason why we need a match for the serial number here.
# The serial number "42" is used to tag the implementations where
# remote wakeup is working.
#
ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Mouse", ATTR{serial}=="42", TEST=="power/control", ATTR{power/control}="auto"
ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Tablet", ATTR{serial}=="42", TEST=="power/control", ATTR{power/control}="auto"
ACTION=="add", SUBSYSTEM=="usb", ATTR{product}=="QEMU USB Keyboard", ATTR{serial}=="42", TEST=="power/control", ATTR{power/control}="auto"
#
# Enable autosuspend for KVM and iLO usb hid devices. These are
# effectively self-powered (despite what some claim in their USB
# profiles) and so it's safe to do so.
#
# AMI 046b:ff10
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="046b", ATTR{idProduct}=="ff10", TEST=="power/control", ATTR{power/control}="auto"
#
# Catch-all for Avocent HID devices. Keyed off interface in order to only
# trigger on HID class devices.
#
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="0624", ATTR{bInterfaceClass}=="03", TEST=="../power/control", ATTR{../power/control}="auto"
# Dell DRAC 4
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="413c", ATTR{idProduct}=="2500", TEST=="power/control", ATTR{power/control}="auto"
# Dell DRAC 5
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="413c", ATTR{idProduct}=="0000", TEST=="power/control", ATTR{power/control}="auto"
# Hewlett Packard iLO
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="03f0", ATTR{idProduct}=="7029", TEST=="power/control", ATTR{power/control}="auto"
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="03f0", ATTR{idProduct}=="1027", TEST=="power/control", ATTR{power/control}="auto"
# IBM remote access
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="04b3", ATTR{idProduct}=="4001", TEST=="power/control", ATTR{power/control}="auto"
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="04b3", ATTR{idProduct}=="4002", TEST=="power/control", ATTR{power/control}="auto"
ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="04b3", ATTR{idProduct}=="4012", TEST=="power/control", ATTR{power/control}="auto"
# Raritan Computer, Inc KVM.
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="14dd", ATTR{idProduct}="0002", TEST=="power/control", ATTR{power/control}="auto"
# USB HID devices that are internal to the machine should also be safe to autosuspend
ACTION=="add", SUBSYSTEM=="usb", ATTR{bInterfaceClass}=="03", ATTRS{removable}=="fixed", TEST=="../power/control", ATTR{../power/control}="auto"

View File

@ -0,0 +1,107 @@
# do not edit this file, it will be overwritten on update
KERNEL=="pty[pqrstuvwxyzabcdef][0123456789abcdef]", GROUP="tty", MODE="0660"
KERNEL=="tty[pqrstuvwxyzabcdef][0123456789abcdef]", GROUP="tty", MODE="0660"
KERNEL=="ptmx", GROUP="tty", MODE="0666"
KERNEL=="tty", GROUP="tty", MODE="0666"
KERNEL=="tty[0-9]*", GROUP="tty", MODE="0620"
KERNEL=="vcs|vcs[0-9]*|vcsa|vcsa[0-9]*", GROUP="tty"
# serial
KERNEL=="tty[A-Z]*[0-9]|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*|rfcomm[0-9]*", GROUP="dialout"
KERNEL=="mwave", GROUP="dialout"
KERNEL=="hvc*|hvsi*", GROUP="dialout"
# virtio serial / console ports
KERNEL=="vport*", ATTR{name}=="?*", SYMLINK+="virtio-ports/$attr{name}"
# mem
KERNEL=="null|zero|full|random|urandom", MODE="0666"
KERNEL=="mem|kmem|port|nvram", GROUP="kmem", MODE="0640"
# input
SUBSYSTEM=="input", ENV{ID_INPUT}=="", IMPORT{builtin}="input_id"
KERNEL=="mouse*|mice|event*", MODE="0640"
KERNEL=="ts[0-9]*|uinput", MODE="0640"
KERNEL=="js[0-9]*", MODE="0644"
# video4linux
SUBSYSTEM=="video4linux", GROUP="video"
KERNEL=="vttuner*", GROUP="video"
KERNEL=="vtx*|vbi*", GROUP="video"
KERNEL=="winradio*", GROUP="video"
# graphics
KERNEL=="agpgart", GROUP="video"
KERNEL=="pmu", GROUP="video"
KERNEL=="nvidia*|nvidiactl*", GROUP="video"
SUBSYSTEM=="graphics", GROUP="video"
SUBSYSTEM=="drm", GROUP="video"
# sound
SUBSYSTEM=="sound", GROUP="audio", \
OPTIONS+="static_node=snd/seq", OPTIONS+="static_node=snd/timer"
# DVB (video)
SUBSYSTEM=="dvb", GROUP="video"
# FireWire (firewire-core driver: IIDC devices, AV/C devices)
SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x00010*", GROUP="video"
SUBSYSTEM=="firewire", ATTR{units}=="*0x00b09d:0x00010*", GROUP="video"
SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x010001*", GROUP="video"
SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x014001*", GROUP="video"
# 'libusb' device nodes
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0664"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id"
# printer
KERNEL=="parport[0-9]*", GROUP="lp"
SUBSYSTEM=="printer", KERNEL=="lp*", GROUP="lp"
SUBSYSTEM=="ppdev", GROUP="lp"
KERNEL=="lp[0-9]*", GROUP="lp"
KERNEL=="irlpt[0-9]*", GROUP="lp"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??:*", GROUP="lp"
# block
SUBSYSTEM=="block", GROUP="disk"
# floppy
SUBSYSTEM=="block", KERNEL=="fd[0-9]", GROUP="floppy"
# cdrom
SUBSYSTEM=="block", KERNEL=="sr[0-9]*", GROUP="cdrom"
SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="4|5", GROUP="cdrom"
KERNEL=="pktcdvd[0-9]*", GROUP="cdrom"
KERNEL=="pktcdvd", GROUP="cdrom"
# tape
KERNEL=="ht[0-9]*|nht[0-9]*", GROUP="tape"
KERNEL=="pt[0-9]*|npt[0-9]*|pht[0-9]*", GROUP="tape"
SUBSYSTEM=="scsi_generic|scsi_tape", SUBSYSTEMS=="scsi", ATTRS{type}=="1|8", GROUP="tape"
# block-related
KERNEL=="sch[0-9]*", GROUP="disk"
SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="0", GROUP="disk"
KERNEL=="pg[0-9]*", GROUP="disk"
KERNEL=="qft[0-9]*|nqft[0-9]*|zqft[0-9]*|nzqft[0-9]*|rawqft[0-9]*|nrawqft[0-9]*", GROUP="disk"
KERNEL=="rawctl", GROUP="disk"
SUBSYSTEM=="raw", KERNEL=="raw[0-9]*", GROUP="disk"
SUBSYSTEM=="aoe", GROUP="disk", MODE="0220"
SUBSYSTEM=="aoe", KERNEL=="err", MODE="0440"
# network
KERNEL=="tun", MODE="0666", OPTIONS+="static_node=net/tun"
KERNEL=="rfkill", MODE="0644"
# CPU
KERNEL=="cpu[0-9]*", MODE="0444"
KERNEL=="fuse", ACTION=="add", MODE="0666", OPTIONS+="static_node=fuse"
SUBSYSTEM=="rtc", ATTR{hctosys}=="1", SYMLINK+="rtc"
KERNEL=="mmtimer", MODE="0644"
KERNEL=="rflash[0-9]*", MODE="0400"
KERNEL=="rrom[0-9]*", MODE="0400"
SUBSYSTEM=="firmware", ACTION=="add", IMPORT{builtin}="firmware"

View File

@ -0,0 +1,14 @@
# do not edit this file, it will be overwritten on update
ACTION=="remove", GOTO="persistent_alsa_end"
SUBSYSTEM!="sound", GOTO="persistent_alsa_end"
KERNEL!="controlC[0-9]*", GOTO="persistent_alsa_end"
SUBSYSTEMS=="usb", ENV{ID_MODEL}=="", IMPORT{builtin}="usb_id"
ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="?*", SYMLINK+="snd/by-id/$env{ID_BUS}-$env{ID_SERIAL}-$env{ID_USB_INTERFACE_NUM}"
ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="", SYMLINK+="snd/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
IMPORT{builtin}="path_id"
ENV{ID_PATH}=="?*", SYMLINK+="snd/by-path/$env{ID_PATH}"
LABEL="persistent_alsa_end"

View File

@ -0,0 +1,38 @@
# do not edit this file, it will be overwritten on update
ACTION=="remove", GOTO="persistent_input_end"
SUBSYSTEM!="input", GOTO="persistent_input_end"
SUBSYSTEMS=="bluetooth", GOTO="persistent_input_end"
SUBSYSTEMS=="usb", ENV{ID_BUS}=="", IMPORT{builtin}="usb_id"
# determine class name for persistent symlinks
ENV{ID_INPUT_KEYBOARD}=="?*", ENV{.INPUT_CLASS}="kbd"
ENV{ID_INPUT_MOUSE}=="?*", ENV{.INPUT_CLASS}="mouse"
ENV{ID_INPUT_TOUCHPAD}=="?*", ENV{.INPUT_CLASS}="mouse"
ENV{ID_INPUT_TABLET}=="?*", ENV{.INPUT_CLASS}="mouse"
ENV{ID_INPUT_JOYSTICK}=="?*", ENV{.INPUT_CLASS}="joystick"
DRIVERS=="pcspkr", ENV{.INPUT_CLASS}="spkr"
ATTRS{name}=="*dvb*|*DVB*|* IR *", ENV{.INPUT_CLASS}="ir"
# fill empty serial number
ENV{.INPUT_CLASS}=="?*", ENV{ID_SERIAL}=="", ENV{ID_SERIAL}="noserial"
# by-id links
KERNEL=="mouse*|js*", ENV{ID_BUS}=="?*", ENV{.INPUT_CLASS}=="?*", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-$env{.INPUT_CLASS}"
KERNEL=="mouse*|js*", ENV{ID_BUS}=="?*", ENV{.INPUT_CLASS}=="?*", ATTRS{bInterfaceNumber}=="?*", ATTRS{bInterfaceNumber}!="00", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$attr{bInterfaceNumber}-$env{.INPUT_CLASS}"
KERNEL=="event*", ENV{ID_BUS}=="?*", ENV{.INPUT_CLASS}=="?*", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-event-$env{.INPUT_CLASS}"
KERNEL=="event*", ENV{ID_BUS}=="?*", ENV{.INPUT_CLASS}=="?*", ATTRS{bInterfaceNumber}=="?*", ATTRS{bInterfaceNumber}!="00", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$attr{bInterfaceNumber}-event-$env{.INPUT_CLASS}"
# allow empty class for USB devices, by appending the interface number
SUBSYSTEMS=="usb", ENV{ID_BUS}=="?*", KERNEL=="event*", ENV{.INPUT_CLASS}=="", ATTRS{bInterfaceNumber}=="?*", \
SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-event-if$attr{bInterfaceNumber}"
# by-path
SUBSYSTEMS=="pci|usb|platform|acpi", IMPORT{builtin}="path_id"
ENV{ID_PATH}=="?*", KERNEL=="mouse*|js*", ENV{.INPUT_CLASS}=="?*", SYMLINK+="input/by-path/$env{ID_PATH}-$env{.INPUT_CLASS}"
ENV{ID_PATH}=="?*", KERNEL=="event*", ENV{.INPUT_CLASS}=="?*", SYMLINK+="input/by-path/$env{ID_PATH}-event-$env{.INPUT_CLASS}"
# allow empty class for platform and usb devices; platform supports only a single interface that way
SUBSYSTEMS=="usb|platform", ENV{ID_PATH}=="?*", KERNEL=="event*", ENV{.INPUT_CLASS}=="", \
SYMLINK+="input/by-path/$env{ID_PATH}-event"
LABEL="persistent_input_end"

View File

@ -0,0 +1,20 @@
# do not edit this file, it will be overwritten on update
ACTION=="remove", GOTO="persistent_serial_end"
SUBSYSTEM!="tty", GOTO="persistent_serial_end"
KERNEL!="ttyUSB[0-9]*|ttyACM[0-9]*", GOTO="persistent_serial_end"
SUBSYSTEMS=="usb-serial", ENV{.ID_PORT}="$attr{port_number}"
IMPORT{builtin}="path_id"
ENV{ID_PATH}=="?*", ENV{.ID_PORT}=="", SYMLINK+="serial/by-path/$env{ID_PATH}"
ENV{ID_PATH}=="?*", ENV{.ID_PORT}=="?*", SYMLINK+="serial/by-path/$env{ID_PATH}-port$env{.ID_PORT}"
IMPORT{builtin}="usb_id"
ENV{ID_SERIAL}=="", GOTO="persistent_serial_end"
SUBSYSTEMS=="usb", ENV{ID_USB_INTERFACE_NUM}="$attr{bInterfaceNumber}"
ENV{ID_USB_INTERFACE_NUM}=="", GOTO="persistent_serial_end"
ENV{.ID_PORT}=="", SYMLINK+="serial/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$env{ID_USB_INTERFACE_NUM}"
ENV{.ID_PORT}=="?*", SYMLINK+="serial/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$env{ID_USB_INTERFACE_NUM}-port$env{.ID_PORT}"
LABEL="persistent_serial_end"

View File

@ -0,0 +1,25 @@
# do not edit this file, it will be overwritten on update
# persistent storage links: /dev/tape/{by-id,by-path}
ACTION=="remove", GOTO="persistent_storage_tape_end"
# type 8 devices are "Medium Changers"
SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="8", IMPORT{program}="scsi_id --sg-version=3 --export --whitelisted -d $devnode", \
SYMLINK+="tape/by-id/scsi-$env{ID_SERIAL}"
SUBSYSTEM!="scsi_tape", GOTO="persistent_storage_tape_end"
KERNEL=="st*[0-9]|nst*[0-9]", ATTRS{ieee1394_id}=="?*", ENV{ID_SERIAL}="$attr{ieee1394_id}", ENV{ID_BUS}="ieee1394"
KERNEL=="st*[0-9]|nst*[0-9]", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id"
KERNEL=="st*[0-9]|nst*[0-9]", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="scsi", KERNELS=="[0-9]*:*[0-9]", ENV{.BSG_DEV}="$root/bsg/$id"
KERNEL=="st*[0-9]|nst*[0-9]", ENV{ID_SERIAL}!="?*", IMPORT{program}="scsi_id --whitelisted --export --device=$env{.BSG_DEV}", ENV{ID_BUS}="scsi"
KERNEL=="st*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="tape/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
KERNEL=="nst*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="tape/by-id/$env{ID_BUS}-$env{ID_SERIAL}-nst"
# by-path (parent device path)
KERNEL=="st*[0-9]|nst*[0-9]", IMPORT{builtin}="path_id"
KERNEL=="st*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH}"
KERNEL=="nst*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH}-nst"
LABEL="persistent_storage_tape_end"

View File

@ -0,0 +1,89 @@
# do not edit this file, it will be overwritten on update
# persistent storage links: /dev/disk/{by-id,by-uuid,by-label,by-path}
# scheme based on "Linux persistent device names", 2004, Hannes Reinecke <hare@suse.de>
# forward scsi device event to corresponding block device
ACTION=="change", SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST=="block", ATTR{block/*/uevent}="change"
ACTION=="remove", GOTO="persistent_storage_end"
# enable in-kernel media-presence polling
ACTION=="add", SUBSYSTEM=="module", KERNEL=="block", ATTR{parameters/events_dfl_poll_msecs}=="0", ATTR{parameters/events_dfl_poll_msecs}="2000"
SUBSYSTEM!="block", GOTO="persistent_storage_end"
# skip rules for inappropriate block devices
KERNEL=="fd*|mtd*|nbd*|gnbd*|btibm*|dm-*|md*", GOTO="persistent_storage_end"
# ignore partitions that span the entire disk
TEST=="whole_disk", GOTO="persistent_storage_end"
# for partitions import parent information
ENV{DEVTYPE}=="partition", IMPORT{parent}="ID_*"
# virtio-blk
KERNEL=="vd*[!0-9]", ATTRS{serial}=="?*", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/virtio-$env{ID_SERIAL}"
KERNEL=="vd*[0-9]", ATTRS{serial}=="?*", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/virtio-$env{ID_SERIAL}-part%n"
# ATA devices with their own "ata" kernel subsystem
KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="ata", IMPORT{program}="ata_id --export $devnode"
# ATA devices using the "scsi" subsystem
KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", IMPORT{program}="ata_id --export $devnode"
# ATA/ATAPI devices (SPC-3 or later) using the "scsi" subsystem
KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="scsi", ATTRS{type}=="5", ATTRS{scsi_level}=="[6-9]*", IMPORT{program}="ata_id --export $devnode"
# Run ata_id on non-removable USB Mass Storage (SATA/PATA disks in enclosures)
KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", ATTR{removable}=="0", SUBSYSTEMS=="usb", IMPORT{program}="ata_id --export $devnode"
# Otherwise fall back to using usb_id for USB devices
KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id"
# scsi devices
KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", IMPORT{program}="scsi_id --export --whitelisted -d $devnode", ENV{ID_BUS}="scsi"
KERNEL=="cciss*", ENV{DEVTYPE}=="disk", ENV{ID_SERIAL}!="?*", IMPORT{program}="scsi_id --export --whitelisted -d $devnode", ENV{ID_BUS}="cciss"
KERNEL=="sd*|sr*|cciss*", ENV{DEVTYPE}=="disk", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
KERNEL=="sd*|cciss*", ENV{DEVTYPE}=="partition", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n"
# firewire
KERNEL=="sd*[!0-9]|sr*", ATTRS{ieee1394_id}=="?*", SYMLINK+="disk/by-id/ieee1394-$attr{ieee1394_id}"
KERNEL=="sd*[0-9]", ATTRS{ieee1394_id}=="?*", SYMLINK+="disk/by-id/ieee1394-$attr{ieee1394_id}-part%n"
KERNEL=="mmcblk[0-9]", SUBSYSTEMS=="mmc", ATTRS{name}=="?*", ATTRS{serial}=="?*", ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}"
KERNEL=="mmcblk[0-9]p[0-9]", ENV{ID_NAME}=="?*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}-part%n"
KERNEL=="mspblk[0-9]", SUBSYSTEMS=="memstick", ATTRS{name}=="?*", ATTRS{serial}=="?*", ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/memstick-$env{ID_NAME}_$env{ID_SERIAL}"
KERNEL=="mspblk[0-9]p[0-9]", ENV{ID_NAME}=="?*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/memstick-$env{ID_NAME}_$env{ID_SERIAL}-part%n"
# by-path (parent device path)
ENV{DEVTYPE}=="disk", DEVPATH!="*/virtual/*", IMPORT{builtin}="path_id"
ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}"
ENV{DEVTYPE}=="partition", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n"
# skip unpartitioned removable media devices from drivers which do not send "change" events
ENV{DEVTYPE}=="disk", KERNEL!="sd*|sr*", ATTR{removable}=="1", GOTO="persistent_storage_end"
# probe filesystem metadata of optical drives which have a media inserted
KERNEL=="sr*", ENV{DISK_EJECT_REQUEST}!="?*", ENV{ID_CDROM_MEDIA_TRACK_COUNT_DATA}=="?*", ENV{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}=="?*", \
IMPORT{builtin}="blkid --offset=$env{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}"
# single-session CDs do not have ID_CDROM_MEDIA_SESSION_LAST_OFFSET
KERNEL=="sr*", ENV{DISK_EJECT_REQUEST}!="?*", ENV{ID_CDROM_MEDIA_TRACK_COUNT_DATA}=="?*", ENV{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}=="", \
IMPORT{builtin}="blkid --noraid"
# probe filesystem metadata of disks
KERNEL!="sr*", IMPORT{builtin}="blkid"
# watch metadata changes by tools closing the device after writing
KERNEL!="sr*", OPTIONS+="watch"
# by-label/by-uuid links (filesystem metadata)
ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}"
ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}"
# by-id (World Wide Name)
ENV{DEVTYPE}=="disk", ENV{ID_WWN_WITH_EXTENSION}=="?*", SYMLINK+="disk/by-id/wwn-$env{ID_WWN_WITH_EXTENSION}"
ENV{DEVTYPE}=="partition", ENV{ID_WWN_WITH_EXTENSION}=="?*", SYMLINK+="disk/by-id/wwn-$env{ID_WWN_WITH_EXTENSION}-part%n"
# by-partlabel/by-partuuid links (partition metadata)
ENV{ID_PART_ENTRY_SCHEME}=="gpt", ENV{ID_PART_ENTRY_UUID}=="?*", SYMLINK+="disk/by-partuuid/$env{ID_PART_ENTRY_UUID}"
ENV{ID_PART_ENTRY_SCHEME}=="gpt", ENV{ID_PART_ENTRY_NAME}=="?*", SYMLINK+="disk/by-partlabel/$env{ID_PART_ENTRY_NAME}"
LABEL="persistent_storage_end"

View File

@ -0,0 +1,14 @@
# do not edit this file, it will be overwritten on update
ACTION=="remove", GOTO="net_end"
SUBSYSTEM!="net", GOTO="net_end"
SUBSYSTEMS=="usb", ENV{ID_MODEL}=="", IMPORT{builtin}="usb_id"
SUBSYSTEMS=="usb", IMPORT{builtin}="usb-db"
SUBSYSTEMS=="usb", ATTRS{idVendor}!="", ATTRS{idProduct}!="", ENV{ID_VENDOR_ID}="$attr{idVendor}", ENV{ID_MODEL_ID}="$attr{idProduct}"
SUBSYSTEMS=="usb", GOTO="net_end"
SUBSYSTEMS=="pci", IMPORT{builtin}="pci-db"
SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}"
LABEL="net_end"

View File

@ -0,0 +1,14 @@
# do not edit this file, it will be overwritten on update
ACTION=="remove", GOTO="tty_end"
SUBSYSTEM!="tty", GOTO="tty_end"
SUBSYSTEMS=="usb", ENV{ID_MODEL}=="", IMPORT{builtin}="usb_id"
SUBSYSTEMS=="usb", IMPORT{builtin}="usb-db"
SUBSYSTEMS=="usb", ATTRS{idVendor}!="", ATTRS{idProduct}!="", ENV{ID_VENDOR_ID}="$attr{idVendor}", ENV{ID_MODEL_ID}="$attr{idProduct}"
SUBSYSTEMS=="usb", GOTO="tty_end"
SUBSYSTEMS=="pci", IMPORT{builtin}="pci-db"
SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}"
LABEL="tty_end"

View File

@ -0,0 +1,89 @@
# do not edit this file, it will be overwritten on update
SUBSYSTEM!="sound", GOTO="sound_end"
ACTION=="add|change", KERNEL=="controlC*", ATTR{../uevent}="change"
ACTION!="change", GOTO="sound_end"
# Ok, we probably need a little explanation here for what the two lines above
# are good for.
#
# The story goes like this: when ALSA registers a new sound card it emits a
# series of 'add' events to userspace, for the main card device and for all the
# child device nodes that belong to it. udev relays those to applications,
# however only maintains the order between father and child, but not between
# the siblings. The control device node creation can be used as synchronization
# point. All other devices that belong to a card are created in the kernel
# before it. However unfortunately due to the fact that siblings are forwarded
# out of order by udev this fact is lost to applications.
#
# OTOH before an application can open a device it needs to make sure that all
# its device nodes are completely created and set up.
#
# As a workaround for this issue we have added the udev rule above which will
# generate a 'change' event on the main card device from the 'add' event of the
# card's control device. Due to the ordering semantics of udev this event will
# only be relayed after all child devices have finished processing properly.
# When an application needs to listen for appearing devices it can hence look
# for 'change' events only, and ignore the actual 'add' events.
#
# When the application is initialized at the same time as a device is plugged
# in it may need to figure out if the 'change' event has already been triggered
# or not for a card. To find that out we store the flag environment variable
# SOUND_INITIALIZED on the device which simply tells us if the card 'change'
# event has already been processed.
KERNEL!="card*", GOTO="sound_end"
ENV{SOUND_INITIALIZED}="1"
SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id"
SUBSYSTEMS=="usb", IMPORT{builtin}="usb-db"
SUBSYSTEMS=="usb", GOTO="skip_pci"
SUBSYSTEMS=="firewire", ATTRS{vendor_name}=="?*", ATTRS{model_name}=="?*", \
ENV{ID_BUS}="firewire", ENV{ID_VENDOR}="$attr{vendor_name}", ENV{ID_MODEL}="$attr{model_name}"
SUBSYSTEMS=="firewire", ATTRS{guid}=="?*", ENV{ID_ID}="firewire-$attr{guid}"
SUBSYSTEMS=="firewire", GOTO="skip_pci"
SUBSYSTEMS=="pci", IMPORT{builtin}="pci-db"
SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}"
LABEL="skip_pci"
ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="?*", ENV{ID_ID}="$env{ID_BUS}-$env{ID_SERIAL}-$env{ID_USB_INTERFACE_NUM}-$attr{id}"
ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="", ENV{ID_ID}="$env{ID_BUS}-$env{ID_SERIAL}-$attr{id}"
IMPORT{builtin}="path_id"
# The values used here for $SOUND_FORM_FACTOR and $SOUND_CLASS should be kept
# in sync with those defined for PulseAudio's src/pulse/proplist.h
# PA_PROP_DEVICE_FORM_FACTOR, PA_PROP_DEVICE_CLASS properties.
# If the first PCM device of this card has the pcm class 'modem', then the card is a modem
ATTR{pcmC%nD0p/pcm_class}=="modem", ENV{SOUND_CLASS}="modem", GOTO="sound_end"
# Identify cards on the internal PCI bus as internal
SUBSYSTEMS=="pci", DEVPATH=="*/0000:00:??.?/sound/*", ENV{SOUND_FORM_FACTOR}="internal", GOTO="sound_end"
# Devices that also support Image/Video interfaces are most likely webcams
SUBSYSTEMS=="usb", ENV{ID_USB_INTERFACES}=="*:0e????:*", ENV{SOUND_FORM_FACTOR}="webcam", GOTO="sound_end"
# Matching on the model strings is a bit ugly, I admit
ENV{ID_MODEL}=="*[Ss]peaker*", ENV{SOUND_FORM_FACTOR}="speaker", GOTO="sound_end"
ENV{ID_MODEL_FROM_DATABASE}=="*[Ss]peaker*", ENV{SOUND_FORM_FACTOR}="speaker", GOTO="sound_end"
ENV{ID_MODEL}=="*[Hh]eadphone*", ENV{SOUND_FORM_FACTOR}="headphone", GOTO="sound_end"
ENV{ID_MODEL_FROM_DATABASE}=="*[Hh]eadphone*", ENV{SOUND_FORM_FACTOR}="headphone", GOTO="sound_end"
ENV{ID_MODEL}=="*[Hh]eadset*", ENV{SOUND_FORM_FACTOR}="headset", GOTO="sound_end"
ENV{ID_MODEL_FROM_DATABASE}=="*[Hh]eadset*", ENV{SOUND_FORM_FACTOR}="headset", GOTO="sound_end"
ENV{ID_MODEL}=="*[Hh]andset*", ENV{SOUND_FORM_FACTOR}="handset", GOTO="sound_end"
ENV{ID_MODEL_FROM_DATABASE}=="*[Hh]andset*", ENV{SOUND_FORM_FACTOR}="handset", GOTO="sound_end"
ENV{ID_MODEL}=="*[Mm]icrophone*", ENV{SOUND_FORM_FACTOR}="microphone", GOTO="sound_end"
ENV{ID_MODEL_FROM_DATABASE}=="*[Mm]icrophone*", ENV{SOUND_FORM_FACTOR}="microphone", GOTO="sound_end"
LABEL="sound_end"

View File

@ -0,0 +1,12 @@
# do not edit this file, it will be overwritten on update
ACTION=="remove", GOTO="drivers_end"
DRIVER!="?*", ENV{MODALIAS}=="?*", IMPORT{builtin}="kmod load $env{MODALIAS}"
SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="SD", IMPORT{builtin}="kmod load tifm_sd"
SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="MS", IMPORT{builtin}="kmod load tifm_ms"
SUBSYSTEM=="memstick", IMPORT{builtin}="kmod load ms_block mspro_block"
SUBSYSTEM=="i2o", IMPORT{builtin}="kmod load i2o_block"
SUBSYSTEM=="module", KERNEL=="parport_pc", IMPORT{builtin}="kmod load ppdev"
LABEL="drivers_end"

View File

@ -0,0 +1,4 @@
# do not edit this file, it will be overwritten on update
# run a command on remove events
ACTION=="remove", ENV{REMOVE_CMD}!="", RUN+="$env{REMOVE_CMD}"

5
src/udev/src/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
*.[78]
*.html
udev.pc
libudev.pc
udev*.service

502
src/udev/src/COPYING Normal file
View File

@ -0,0 +1,502 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin St, 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.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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 St, 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.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@ -0,0 +1,3 @@
# do not edit this file, it will be overwritten on update
SUBSYSTEM=="input", ACTION!="remove", ENV{ID_INPUT_ACCELEROMETER}=="1", IMPORT{program}="accelerometer %p"

View File

@ -0,0 +1,357 @@
/*
* accelerometer - exports device orientation through property
*
* When an "change" event is received on an accelerometer,
* open its device node, and from the value, as well as the previous
* value of the property, calculate the device's new orientation,
* and export it as ID_INPUT_ACCELEROMETER_ORIENTATION.
*
* Possible values are:
* undefined
* * normal
* * bottom-up
* * left-up
* * right-up
*
* The property will be persistent across sessions, and the new
* orientations can be deducted from the previous one (it allows
* for a threshold for switching between opposite ends of the
* orientation).
*
* Copyright (C) 2011 Red Hat, Inc.
* Author:
* Bastien Nocera <hadess@hadess.net>
*
* orientation_calc() from the sensorfw package
* Copyright (C) 2009-2010 Nokia Corporation
* Authors:
* Üstün Ergenoglu <ext-ustun.ergenoglu@nokia.com>
* Timo Rongas <ext-timo.2.rongas@nokia.com>
* Lihan Guo <lihan.guo@digia.com>
*
* 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 keymap; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <limits.h>
#include <linux/limits.h>
#include <linux/input.h>
#include "libudev.h"
#include "libudev-private.h"
/* we must use this kernel-compatible implementation */
#define BITS_PER_LONG (sizeof(unsigned long) * 8)
#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
#define OFF(x) ((x)%BITS_PER_LONG)
#define BIT(x) (1UL<<OFF(x))
#define LONG(x) ((x)/BITS_PER_LONG)
#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
static int debug = 0;
static void log_fn(struct udev *udev, int priority,
const char *file, int line, const char *fn,
const char *format, va_list args)
{
if (debug) {
fprintf(stderr, "%s: ", fn);
vfprintf(stderr, format, args);
} else {
vsyslog(priority, format, args);
}
}
typedef enum {
ORIENTATION_UNDEFINED,
ORIENTATION_NORMAL,
ORIENTATION_BOTTOM_UP,
ORIENTATION_LEFT_UP,
ORIENTATION_RIGHT_UP
} OrientationUp;
static const char *orientations[] = {
"undefined",
"normal",
"bottom-up",
"left-up",
"right-up",
NULL
};
#define ORIENTATION_UP_UP ORIENTATION_NORMAL
#define DEFAULT_THRESHOLD 250
#define RADIANS_TO_DEGREES 180.0/M_PI
#define SAME_AXIS_LIMIT 5
#define THRESHOLD_LANDSCAPE 25
#define THRESHOLD_PORTRAIT 20
static const char *
orientation_to_string (OrientationUp o)
{
return orientations[o];
}
static OrientationUp
string_to_orientation (const char *orientation)
{
int i;
if (orientation == NULL)
return ORIENTATION_UNDEFINED;
for (i = 0; orientations[i] != NULL; i++) {
if (strcmp (orientation, orientations[i]) == 0)
return i;
}
return ORIENTATION_UNDEFINED;
}
static OrientationUp
orientation_calc (OrientationUp prev,
int x, int y, int z)
{
int rotation;
OrientationUp ret = prev;
/* Portrait check */
rotation = round(atan((double) x / sqrt(y * y + z * z)) * RADIANS_TO_DEGREES);
if (abs(rotation) > THRESHOLD_PORTRAIT) {
ret = (rotation < 0) ? ORIENTATION_LEFT_UP : ORIENTATION_RIGHT_UP;
/* Some threshold to switching between portrait modes */
if (prev == ORIENTATION_LEFT_UP || prev == ORIENTATION_RIGHT_UP) {
if (abs(rotation) < SAME_AXIS_LIMIT) {
ret = prev;
}
}
} else {
/* Landscape check */
rotation = round(atan((double) y / sqrt(x * x + z * z)) * RADIANS_TO_DEGREES);
if (abs(rotation) > THRESHOLD_LANDSCAPE) {
ret = (rotation < 0) ? ORIENTATION_BOTTOM_UP : ORIENTATION_NORMAL;
/* Some threshold to switching between landscape modes */
if (prev == ORIENTATION_BOTTOM_UP || prev == ORIENTATION_NORMAL) {
if (abs(rotation) < SAME_AXIS_LIMIT) {
ret = prev;
}
}
}
}
return ret;
}
static OrientationUp
get_prev_orientation(struct udev_device *dev)
{
const char *value;
value = udev_device_get_property_value(dev, "ID_INPUT_ACCELEROMETER_ORIENTATION");
if (value == NULL)
return ORIENTATION_UNDEFINED;
return string_to_orientation(value);
}
#define SET_AXIS(axis, code_) if (ev[i].code == code_) { if (got_##axis == 0) { axis = ev[i].value; got_##axis = 1; } }
/* accelerometers */
static void test_orientation(struct udev *udev,
struct udev_device *dev,
const char *devpath)
{
OrientationUp old, new;
int fd, r;
struct input_event ev[64];
int got_syn = 0;
int got_x, got_y, got_z;
int x = 0, y = 0, z = 0;
char text[64];
old = get_prev_orientation(dev);
if ((fd = open(devpath, O_RDONLY)) < 0)
return;
got_x = got_y = got_z = 0;
while (1) {
int i;
r = read(fd, ev, sizeof(struct input_event) * 64);
if (r < (int) sizeof(struct input_event))
return;
for (i = 0; i < r / (int) sizeof(struct input_event); i++) {
if (got_syn == 1) {
if (ev[i].type == EV_ABS) {
SET_AXIS(x, ABS_X);
SET_AXIS(y, ABS_Y);
SET_AXIS(z, ABS_Z);
}
}
if (ev[i].type == EV_SYN && ev[i].code == SYN_REPORT) {
got_syn = 1;
}
if (got_x && got_y && got_z)
goto read_dev;
}
}
read_dev:
close(fd);
if (!got_x || !got_y || !got_z)
return;
new = orientation_calc(old, x, y, z);
snprintf(text, sizeof(text), "ID_INPUT_ACCELEROMETER_ORIENTATION=%s", orientation_to_string(new));
puts(text);
}
static void help(void)
{
printf("Usage: accelerometer [options] <device path>\n"
" --debug debug to stderr\n"
" --help print this help text\n\n");
}
int main (int argc, char** argv)
{
struct udev *udev;
struct udev_device *dev;
static const struct option options[] = {
{ "debug", no_argument, NULL, 'd' },
{ "help", no_argument, NULL, 'h' },
{}
};
char devpath[PATH_MAX];
char *devnode;
const char *id_path;
struct udev_enumerate *enumerate;
struct udev_list_entry *list_entry;
udev = udev_new();
if (udev == NULL)
return 1;
udev_log_init("input_id");
udev_set_log_fn(udev, log_fn);
/* CLI argument parsing */
while (1) {
int option;
option = getopt_long(argc, argv, "dxh", options, NULL);
if (option == -1)
break;
switch (option) {
case 'd':
debug = 1;
if (udev_get_log_priority(udev) < LOG_INFO)
udev_set_log_priority(udev, LOG_INFO);
break;
case 'h':
help();
exit(0);
default:
exit(1);
}
}
if (argv[optind] == NULL) {
help();
exit(1);
}
/* get the device */
snprintf(devpath, sizeof(devpath), "%s/%s", udev_get_sys_path(udev), argv[optind]);
dev = udev_device_new_from_syspath(udev, devpath);
if (dev == NULL) {
fprintf(stderr, "unable to access '%s'\n", devpath);
return 1;
}
id_path = udev_device_get_property_value(dev, "ID_PATH");
if (id_path == NULL) {
fprintf (stderr, "unable to get property ID_PATH for '%s'", devpath);
return 0;
}
/* Get the children devices and find the devnode
* FIXME: use udev_enumerate_add_match_children() instead
* when it's available */
devnode = NULL;
enumerate = udev_enumerate_new(udev);
udev_enumerate_add_match_property(enumerate, "ID_PATH", id_path);
udev_enumerate_add_match_subsystem(enumerate, "input");
udev_enumerate_scan_devices(enumerate);
udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
struct udev_device *device;
const char *node;
device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
udev_list_entry_get_name(list_entry));
if (device == NULL)
continue;
/* Already found it */
if (devnode != NULL) {
udev_device_unref(device);
continue;
}
node = udev_device_get_devnode(device);
if (node == NULL) {
udev_device_unref(device);
continue;
}
/* Use the event sub-device */
if (strstr(node, "/event") == NULL) {
udev_device_unref(device);
continue;
}
devnode = strdup(node);
udev_device_unref(device);
}
if (devnode == NULL) {
fprintf(stderr, "unable to get device node for '%s'\n", devpath);
return 0;
}
info(udev, "Opening accelerometer device %s\n", devnode);
test_orientation(udev, dev, devnode);
free(devnode);
return 0;
}

View File

@ -0,0 +1,721 @@
/*
* ata_id - reads product/serial number from ATA drives
*
* Copyright (C) 2005-2008 Kay Sievers <kay.sievers@vrfy.org>
* Copyright (C) 2009 Lennart Poettering <lennart@poettering.net>
* Copyright (C) 2009-2010 David Zeuthen <zeuthen@gmail.com>
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include <scsi/scsi.h>
#include <scsi/sg.h>
#include <scsi/scsi_ioctl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/types.h>
#include <linux/hdreg.h>
#include <linux/fs.h>
#include <linux/cdrom.h>
#include <linux/bsg.h>
#include <arpa/inet.h>
#include "libudev.h"
#include "libudev-private.h"
#define COMMAND_TIMEOUT_MSEC (30 * 1000)
static int disk_scsi_inquiry_command(int fd,
void *buf,
size_t buf_len)
{
struct sg_io_v4 io_v4;
uint8_t cdb[6];
uint8_t sense[32];
int ret;
/*
* INQUIRY, see SPC-4 section 6.4
*/
memset(cdb, 0, sizeof(cdb));
cdb[0] = 0x12; /* OPERATION CODE: INQUIRY */
cdb[3] = (buf_len >> 8); /* ALLOCATION LENGTH */
cdb[4] = (buf_len & 0xff);
memset(sense, 0, sizeof(sense));
memset(&io_v4, 0, sizeof(struct sg_io_v4));
io_v4.guard = 'Q';
io_v4.protocol = BSG_PROTOCOL_SCSI;
io_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD;
io_v4.request_len = sizeof (cdb);
io_v4.request = (uintptr_t) cdb;
io_v4.max_response_len = sizeof (sense);
io_v4.response = (uintptr_t) sense;
io_v4.din_xfer_len = buf_len;
io_v4.din_xferp = (uintptr_t) buf;
io_v4.timeout = COMMAND_TIMEOUT_MSEC;
ret = ioctl(fd, SG_IO, &io_v4);
if (ret != 0) {
/* could be that the driver doesn't do version 4, try version 3 */
if (errno == EINVAL) {
struct sg_io_hdr io_hdr;
memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
io_hdr.interface_id = 'S';
io_hdr.cmdp = (unsigned char*) cdb;
io_hdr.cmd_len = sizeof (cdb);
io_hdr.dxferp = buf;
io_hdr.dxfer_len = buf_len;
io_hdr.sbp = sense;
io_hdr.mx_sb_len = sizeof (sense);
io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
io_hdr.timeout = COMMAND_TIMEOUT_MSEC;
ret = ioctl(fd, SG_IO, &io_hdr);
if (ret != 0)
goto out;
/* even if the ioctl succeeds, we need to check the return value */
if (!(io_hdr.status == 0 &&
io_hdr.host_status == 0 &&
io_hdr.driver_status == 0)) {
errno = EIO;
ret = -1;
goto out;
}
} else {
goto out;
}
}
/* even if the ioctl succeeds, we need to check the return value */
if (!(io_v4.device_status == 0 &&
io_v4.transport_status == 0 &&
io_v4.driver_status == 0)) {
errno = EIO;
ret = -1;
goto out;
}
out:
return ret;
}
static int disk_identify_command(int fd,
void *buf,
size_t buf_len)
{
struct sg_io_v4 io_v4;
uint8_t cdb[12];
uint8_t sense[32];
uint8_t *desc = sense+8;
int ret;
/*
* ATA Pass-Through 12 byte command, as described in
*
* T10 04-262r8 ATA Command Pass-Through
*
* from http://www.t10.org/ftp/t10/document.04/04-262r8.pdf
*/
memset(cdb, 0, sizeof(cdb));
cdb[0] = 0xa1; /* OPERATION CODE: 12 byte pass through */
cdb[1] = 4 << 1; /* PROTOCOL: PIO Data-in */
cdb[2] = 0x2e; /* OFF_LINE=0, CK_COND=1, T_DIR=1, BYT_BLOK=1, T_LENGTH=2 */
cdb[3] = 0; /* FEATURES */
cdb[4] = 1; /* SECTORS */
cdb[5] = 0; /* LBA LOW */
cdb[6] = 0; /* LBA MID */
cdb[7] = 0; /* LBA HIGH */
cdb[8] = 0 & 0x4F; /* SELECT */
cdb[9] = 0xEC; /* Command: ATA IDENTIFY DEVICE */;
memset(sense, 0, sizeof(sense));
memset(&io_v4, 0, sizeof(struct sg_io_v4));
io_v4.guard = 'Q';
io_v4.protocol = BSG_PROTOCOL_SCSI;
io_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD;
io_v4.request_len = sizeof (cdb);
io_v4.request = (uintptr_t) cdb;
io_v4.max_response_len = sizeof (sense);
io_v4.response = (uintptr_t) sense;
io_v4.din_xfer_len = buf_len;
io_v4.din_xferp = (uintptr_t) buf;
io_v4.timeout = COMMAND_TIMEOUT_MSEC;
ret = ioctl(fd, SG_IO, &io_v4);
if (ret != 0) {
/* could be that the driver doesn't do version 4, try version 3 */
if (errno == EINVAL) {
struct sg_io_hdr io_hdr;
memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
io_hdr.interface_id = 'S';
io_hdr.cmdp = (unsigned char*) cdb;
io_hdr.cmd_len = sizeof (cdb);
io_hdr.dxferp = buf;
io_hdr.dxfer_len = buf_len;
io_hdr.sbp = sense;
io_hdr.mx_sb_len = sizeof (sense);
io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
io_hdr.timeout = COMMAND_TIMEOUT_MSEC;
ret = ioctl(fd, SG_IO, &io_hdr);
if (ret != 0)
goto out;
} else {
goto out;
}
}
if (!(sense[0] == 0x72 && desc[0] == 0x9 && desc[1] == 0x0c)) {
errno = EIO;
ret = -1;
goto out;
}
out:
return ret;
}
static int disk_identify_packet_device_command(int fd,
void *buf,
size_t buf_len)
{
struct sg_io_v4 io_v4;
uint8_t cdb[16];
uint8_t sense[32];
uint8_t *desc = sense+8;
int ret;
/*
* ATA Pass-Through 16 byte command, as described in
*
* T10 04-262r8 ATA Command Pass-Through
*
* from http://www.t10.org/ftp/t10/document.04/04-262r8.pdf
*/
memset(cdb, 0, sizeof(cdb));
cdb[0] = 0x85; /* OPERATION CODE: 16 byte pass through */
cdb[1] = 4 << 1; /* PROTOCOL: PIO Data-in */
cdb[2] = 0x2e; /* OFF_LINE=0, CK_COND=1, T_DIR=1, BYT_BLOK=1, T_LENGTH=2 */
cdb[3] = 0; /* FEATURES */
cdb[4] = 0; /* FEATURES */
cdb[5] = 0; /* SECTORS */
cdb[6] = 1; /* SECTORS */
cdb[7] = 0; /* LBA LOW */
cdb[8] = 0; /* LBA LOW */
cdb[9] = 0; /* LBA MID */
cdb[10] = 0; /* LBA MID */
cdb[11] = 0; /* LBA HIGH */
cdb[12] = 0; /* LBA HIGH */
cdb[13] = 0; /* DEVICE */
cdb[14] = 0xA1; /* Command: ATA IDENTIFY PACKET DEVICE */;
cdb[15] = 0; /* CONTROL */
memset(sense, 0, sizeof(sense));
memset(&io_v4, 0, sizeof(struct sg_io_v4));
io_v4.guard = 'Q';
io_v4.protocol = BSG_PROTOCOL_SCSI;
io_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD;
io_v4.request_len = sizeof (cdb);
io_v4.request = (uintptr_t) cdb;
io_v4.max_response_len = sizeof (sense);
io_v4.response = (uintptr_t) sense;
io_v4.din_xfer_len = buf_len;
io_v4.din_xferp = (uintptr_t) buf;
io_v4.timeout = COMMAND_TIMEOUT_MSEC;
ret = ioctl(fd, SG_IO, &io_v4);
if (ret != 0) {
/* could be that the driver doesn't do version 4, try version 3 */
if (errno == EINVAL) {
struct sg_io_hdr io_hdr;
memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
io_hdr.interface_id = 'S';
io_hdr.cmdp = (unsigned char*) cdb;
io_hdr.cmd_len = sizeof (cdb);
io_hdr.dxferp = buf;
io_hdr.dxfer_len = buf_len;
io_hdr.sbp = sense;
io_hdr.mx_sb_len = sizeof (sense);
io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
io_hdr.timeout = COMMAND_TIMEOUT_MSEC;
ret = ioctl(fd, SG_IO, &io_hdr);
if (ret != 0)
goto out;
} else {
goto out;
}
}
if (!(sense[0] == 0x72 && desc[0] == 0x9 && desc[1] == 0x0c)) {
errno = EIO;
ret = -1;
goto out;
}
out:
return ret;
}
/**
* disk_identify_get_string:
* @identify: A block of IDENTIFY data
* @offset_words: Offset of the string to get, in words.
* @dest: Destination buffer for the string.
* @dest_len: Length of destination buffer, in bytes.
*
* Copies the ATA string from @identify located at @offset_words into @dest.
*/
static void disk_identify_get_string(uint8_t identify[512],
unsigned int offset_words,
char *dest,
size_t dest_len)
{
unsigned int c1;
unsigned int c2;
assert(identify != NULL);
assert(dest != NULL);
assert((dest_len & 1) == 0);
while (dest_len > 0) {
c1 = identify[offset_words * 2 + 1];
c2 = identify[offset_words * 2];
*dest = c1;
dest++;
*dest = c2;
dest++;
offset_words++;
dest_len -= 2;
}
}
static void disk_identify_fixup_string(uint8_t identify[512],
unsigned int offset_words,
size_t len)
{
disk_identify_get_string(identify, offset_words,
(char *) identify + offset_words * 2, len);
}
static void disk_identify_fixup_uint16 (uint8_t identify[512], unsigned int offset_words)
{
uint16_t *p;
p = (uint16_t *) identify;
p[offset_words] = le16toh (p[offset_words]);
}
/**
* disk_identify:
* @udev: The libudev context.
* @fd: File descriptor for the block device.
* @out_identify: Return location for IDENTIFY data.
* @out_is_packet_device: Return location for whether returned data is from a IDENTIFY PACKET DEVICE.
*
* Sends the IDENTIFY DEVICE or IDENTIFY PACKET DEVICE command to the
* device represented by @fd. If successful, then the result will be
* copied into @out_identify and @out_is_packet_device.
*
* This routine is based on code from libatasmart, Copyright 2008
* Lennart Poettering, LGPL v2.1.
*
* Returns: 0 if the data was successfully obtained, otherwise
* non-zero with errno set.
*/
static int disk_identify(struct udev *udev,
int fd,
uint8_t out_identify[512],
int *out_is_packet_device)
{
int ret;
uint8_t inquiry_buf[36];
int peripheral_device_type;
int all_nul_bytes;
int n;
int is_packet_device;
assert(out_identify != NULL);
/* init results */
ret = -1;
memset(out_identify, '\0', 512);
is_packet_device = 0;
/* If we were to use ATA PASS_THROUGH (12) on an ATAPI device
* we could accidentally blank media. This is because MMC's BLANK
* command has the same op-code (0x61).
*
* To prevent this from happening we bail out if the device
* isn't a Direct Access Block Device, e.g. SCSI type 0x00
* (CD/DVD devices are type 0x05). So we send a SCSI INQUIRY
* command first... libata is handling this via its SCSI
* emulation layer.
*
* This also ensures that we're actually dealing with a device
* that understands SCSI commands.
*
* (Yes, it is a bit perverse that we're tunneling the ATA
* command through SCSI and relying on the ATA driver
* emulating SCSI well-enough...)
*
* (See commit 160b069c25690bfb0c785994c7c3710289179107 for
* the original bug-fix and see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=556635
* for the original bug-report.)
*/
ret = disk_scsi_inquiry_command (fd, inquiry_buf, sizeof (inquiry_buf));
if (ret != 0)
goto out;
/* SPC-4, section 6.4.2: Standard INQUIRY data */
peripheral_device_type = inquiry_buf[0] & 0x1f;
if (peripheral_device_type == 0x05)
{
is_packet_device = 1;
ret = disk_identify_packet_device_command(fd, out_identify, 512);
goto check_nul_bytes;
}
if (peripheral_device_type != 0x00) {
ret = -1;
errno = EIO;
goto out;
}
/* OK, now issue the IDENTIFY DEVICE command */
ret = disk_identify_command(fd, out_identify, 512);
if (ret != 0)
goto out;
check_nul_bytes:
/* Check if IDENTIFY data is all NUL bytes - if so, bail */
all_nul_bytes = 1;
for (n = 0; n < 512; n++) {
if (out_identify[n] != '\0') {
all_nul_bytes = 0;
break;
}
}
if (all_nul_bytes) {
ret = -1;
errno = EIO;
goto out;
}
out:
if (out_is_packet_device != NULL)
*out_is_packet_device = is_packet_device;
return ret;
}
static void log_fn(struct udev *udev, int priority,
const char *file, int line, const char *fn,
const char *format, va_list args)
{
vsyslog(priority, format, args);
}
int main(int argc, char *argv[])
{
struct udev *udev;
struct hd_driveid id;
uint8_t identify[512];
uint16_t *identify_words;
char model[41];
char model_enc[256];
char serial[21];
char revision[9];
const char *node = NULL;
int export = 0;
int fd;
uint16_t word;
int rc = 0;
int is_packet_device = 0;
static const struct option options[] = {
{ "export", no_argument, NULL, 'x' },
{ "help", no_argument, NULL, 'h' },
{}
};
udev = udev_new();
if (udev == NULL)
goto exit;
udev_log_init("ata_id");
udev_set_log_fn(udev, log_fn);
while (1) {
int option;
option = getopt_long(argc, argv, "xh", options, NULL);
if (option == -1)
break;
switch (option) {
case 'x':
export = 1;
break;
case 'h':
printf("Usage: ata_id [--export] [--help] <device>\n"
" --export print values as environment keys\n"
" --help print this help text\n\n");
goto exit;
}
}
node = argv[optind];
if (node == NULL) {
err(udev, "no node specified\n");
rc = 1;
goto exit;
}
fd = open(node, O_RDONLY|O_NONBLOCK);
if (fd < 0) {
err(udev, "unable to open '%s'\n", node);
rc = 1;
goto exit;
}
if (disk_identify(udev, fd, identify, &is_packet_device) == 0) {
/*
* fix up only the fields from the IDENTIFY data that we are going to
* use and copy it into the hd_driveid struct for convenience
*/
disk_identify_fixup_string (identify, 10, 20); /* serial */
disk_identify_fixup_string (identify, 23, 6); /* fwrev */
disk_identify_fixup_string (identify, 27, 40); /* model */
disk_identify_fixup_uint16 (identify, 0); /* configuration */
disk_identify_fixup_uint16 (identify, 75); /* queue depth */
disk_identify_fixup_uint16 (identify, 75); /* SATA capabilities */
disk_identify_fixup_uint16 (identify, 82); /* command set supported */
disk_identify_fixup_uint16 (identify, 83); /* command set supported */
disk_identify_fixup_uint16 (identify, 84); /* command set supported */
disk_identify_fixup_uint16 (identify, 85); /* command set supported */
disk_identify_fixup_uint16 (identify, 86); /* command set supported */
disk_identify_fixup_uint16 (identify, 87); /* command set supported */
disk_identify_fixup_uint16 (identify, 89); /* time required for SECURITY ERASE UNIT */
disk_identify_fixup_uint16 (identify, 90); /* time required for enhanced SECURITY ERASE UNIT */
disk_identify_fixup_uint16 (identify, 91); /* current APM values */
disk_identify_fixup_uint16 (identify, 94); /* current AAM value */
disk_identify_fixup_uint16 (identify, 128); /* device lock function */
disk_identify_fixup_uint16 (identify, 217); /* nominal media rotation rate */
memcpy(&id, identify, sizeof id);
} else {
/* If this fails, then try HDIO_GET_IDENTITY */
if (ioctl(fd, HDIO_GET_IDENTITY, &id) != 0) {
info(udev, "HDIO_GET_IDENTITY failed for '%s': %m\n", node);
rc = 2;
goto close;
}
}
identify_words = (uint16_t *) identify;
memcpy (model, id.model, 40);
model[40] = '\0';
udev_util_encode_string(model, model_enc, sizeof(model_enc));
util_replace_whitespace((char *) id.model, model, 40);
util_replace_chars(model, NULL);
util_replace_whitespace((char *) id.serial_no, serial, 20);
util_replace_chars(serial, NULL);
util_replace_whitespace((char *) id.fw_rev, revision, 8);
util_replace_chars(revision, NULL);
if (export) {
/* Set this to convey the disk speaks the ATA protocol */
printf("ID_ATA=1\n");
if ((id.config >> 8) & 0x80) {
/* This is an ATAPI device */
switch ((id.config >> 8) & 0x1f) {
case 0:
printf("ID_TYPE=cd\n");
break;
case 1:
printf("ID_TYPE=tape\n");
break;
case 5:
printf("ID_TYPE=cd\n");
break;
case 7:
printf("ID_TYPE=optical\n");
break;
default:
printf("ID_TYPE=generic\n");
break;
}
} else {
printf("ID_TYPE=disk\n");
}
printf("ID_BUS=ata\n");
printf("ID_MODEL=%s\n", model);
printf("ID_MODEL_ENC=%s\n", model_enc);
printf("ID_REVISION=%s\n", revision);
if (serial[0] != '\0') {
printf("ID_SERIAL=%s_%s\n", model, serial);
printf("ID_SERIAL_SHORT=%s\n", serial);
} else {
printf("ID_SERIAL=%s\n", model);
}
if (id.command_set_1 & (1<<5)) {
printf ("ID_ATA_WRITE_CACHE=1\n");
printf ("ID_ATA_WRITE_CACHE_ENABLED=%d\n", (id.cfs_enable_1 & (1<<5)) ? 1 : 0);
}
if (id.command_set_1 & (1<<10)) {
printf("ID_ATA_FEATURE_SET_HPA=1\n");
printf("ID_ATA_FEATURE_SET_HPA_ENABLED=%d\n", (id.cfs_enable_1 & (1<<10)) ? 1 : 0);
/*
* TODO: use the READ NATIVE MAX ADDRESS command to get the native max address
* so it is easy to check whether the protected area is in use.
*/
}
if (id.command_set_1 & (1<<3)) {
printf("ID_ATA_FEATURE_SET_PM=1\n");
printf("ID_ATA_FEATURE_SET_PM_ENABLED=%d\n", (id.cfs_enable_1 & (1<<3)) ? 1 : 0);
}
if (id.command_set_1 & (1<<1)) {
printf("ID_ATA_FEATURE_SET_SECURITY=1\n");
printf("ID_ATA_FEATURE_SET_SECURITY_ENABLED=%d\n", (id.cfs_enable_1 & (1<<1)) ? 1 : 0);
printf("ID_ATA_FEATURE_SET_SECURITY_ERASE_UNIT_MIN=%d\n", id.trseuc * 2);
if ((id.cfs_enable_1 & (1<<1))) /* enabled */ {
if (id.dlf & (1<<8))
printf("ID_ATA_FEATURE_SET_SECURITY_LEVEL=maximum\n");
else
printf("ID_ATA_FEATURE_SET_SECURITY_LEVEL=high\n");
}
if (id.dlf & (1<<5))
printf("ID_ATA_FEATURE_SET_SECURITY_ENHANCED_ERASE_UNIT_MIN=%d\n", id.trsEuc * 2);
if (id.dlf & (1<<4))
printf("ID_ATA_FEATURE_SET_SECURITY_EXPIRE=1\n");
if (id.dlf & (1<<3))
printf("ID_ATA_FEATURE_SET_SECURITY_FROZEN=1\n");
if (id.dlf & (1<<2))
printf("ID_ATA_FEATURE_SET_SECURITY_LOCKED=1\n");
}
if (id.command_set_1 & (1<<0)) {
printf("ID_ATA_FEATURE_SET_SMART=1\n");
printf("ID_ATA_FEATURE_SET_SMART_ENABLED=%d\n", (id.cfs_enable_1 & (1<<0)) ? 1 : 0);
}
if (id.command_set_2 & (1<<9)) {
printf("ID_ATA_FEATURE_SET_AAM=1\n");
printf("ID_ATA_FEATURE_SET_AAM_ENABLED=%d\n", (id.cfs_enable_2 & (1<<9)) ? 1 : 0);
printf("ID_ATA_FEATURE_SET_AAM_VENDOR_RECOMMENDED_VALUE=%d\n", id.acoustic >> 8);
printf("ID_ATA_FEATURE_SET_AAM_CURRENT_VALUE=%d\n", id.acoustic & 0xff);
}
if (id.command_set_2 & (1<<5)) {
printf("ID_ATA_FEATURE_SET_PUIS=1\n");
printf("ID_ATA_FEATURE_SET_PUIS_ENABLED=%d\n", (id.cfs_enable_2 & (1<<5)) ? 1 : 0);
}
if (id.command_set_2 & (1<<3)) {
printf("ID_ATA_FEATURE_SET_APM=1\n");
printf("ID_ATA_FEATURE_SET_APM_ENABLED=%d\n", (id.cfs_enable_2 & (1<<3)) ? 1 : 0);
if ((id.cfs_enable_2 & (1<<3)))
printf("ID_ATA_FEATURE_SET_APM_CURRENT_VALUE=%d\n", id.CurAPMvalues & 0xff);
}
if (id.command_set_2 & (1<<0))
printf("ID_ATA_DOWNLOAD_MICROCODE=1\n");
/*
* Word 76 indicates the capabilities of a SATA device. A PATA device shall set
* word 76 to 0000h or FFFFh. If word 76 is set to 0000h or FFFFh, then
* the device does not claim compliance with the Serial ATA specification and words
* 76 through 79 are not valid and shall be ignored.
*/
word = *((uint16_t *) identify + 76);
if (word != 0x0000 && word != 0xffff) {
printf("ID_ATA_SATA=1\n");
/*
* If bit 2 of word 76 is set to one, then the device supports the Gen2
* signaling rate of 3.0 Gb/s (see SATA 2.6).
*
* If bit 1 of word 76 is set to one, then the device supports the Gen1
* signaling rate of 1.5 Gb/s (see SATA 2.6).
*/
if (word & (1<<2))
printf("ID_ATA_SATA_SIGNAL_RATE_GEN2=1\n");
if (word & (1<<1))
printf("ID_ATA_SATA_SIGNAL_RATE_GEN1=1\n");
}
/* Word 217 indicates the nominal media rotation rate of the device */
word = *((uint16_t *) identify + 217);
if (word != 0x0000) {
if (word == 0x0001) {
printf ("ID_ATA_ROTATION_RATE_RPM=0\n"); /* non-rotating e.g. SSD */
} else if (word >= 0x0401 && word <= 0xfffe) {
printf ("ID_ATA_ROTATION_RATE_RPM=%d\n", word);
}
}
/*
* Words 108-111 contain a mandatory World Wide Name (WWN) in the NAA IEEE Registered identifier
* format. Word 108 bits (15:12) shall contain 5h, indicating that the naming authority is IEEE.
* All other values are reserved.
*/
word = *((uint16_t *) identify + 108);
if ((word & 0xf000) == 0x5000) {
uint64_t wwwn;
wwwn = *((uint16_t *) identify + 108);
wwwn <<= 16;
wwwn |= *((uint16_t *) identify + 109);
wwwn <<= 16;
wwwn |= *((uint16_t *) identify + 110);
wwwn <<= 16;
wwwn |= *((uint16_t *) identify + 111);
printf("ID_WWN=0x%llx\n", (unsigned long long int) wwwn);
/* ATA devices have no vendor extension */
printf("ID_WWN_WITH_EXTENSION=0x%llx\n", (unsigned long long int) wwwn);
}
/* from Linux's include/linux/ata.h */
if (identify_words[0] == 0x848a || identify_words[0] == 0x844a) {
printf("ID_ATA_CFA=1\n");
} else {
if ((identify_words[83] & 0xc004) == 0x4004) {
printf("ID_ATA_CFA=1\n");
}
}
} else {
if (serial[0] != '\0')
printf("%s_%s\n", model, serial);
else
printf("%s\n", model);
}
close:
close(fd);
exit:
udev_unref(udev);
udev_log_close();
return rc;
}

View File

@ -0,0 +1,20 @@
# do not edit this file, it will be overwritten on update
ACTION=="remove", GOTO="cdrom_end"
SUBSYSTEM!="block", GOTO="cdrom_end"
KERNEL!="sr[0-9]*|xvd*", GOTO="cdrom_end"
ENV{DEVTYPE}!="disk", GOTO="cdrom_end"
# unconditionally tag device as CDROM
KERNEL=="sr[0-9]*", ENV{ID_CDROM}="1"
# media eject button pressed
ENV{DISK_EJECT_REQUEST}=="?*", RUN+="cdrom_id --eject-media $devnode", GOTO="cdrom_end"
# import device and media properties and lock tray to
# enable the receiving of media eject button events
IMPORT{program}="cdrom_id --lock-media $devnode"
KERNEL=="sr0", SYMLINK+="cdrom", OPTIONS+="link_priority=-100"
LABEL="cdrom_end"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,473 @@
/*
* Collect variables across events.
*
* usage: collect [--add|--remove] <checkpoint> <id> <idlist>
*
* Adds ID <id> to the list governed by <checkpoint>.
* <id> must be part of the ID list <idlist>.
* If all IDs given by <idlist> are listed (ie collect has been
* invoked for each ID in <idlist>) collect returns 0, the
* number of missing IDs otherwise.
* A negative number is returned on error.
*
* Copyright(C) 2007, Hannes Reinecke <hare@suse.de>
*
* 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.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "libudev.h"
#include "libudev-private.h"
#define BUFSIZE 16
#define UDEV_ALARM_TIMEOUT 180
enum collect_state {
STATE_NONE,
STATE_OLD,
STATE_CONFIRMED,
};
struct _mate {
struct udev_list_node node;
char *name;
enum collect_state state;
};
static struct udev_list_node bunch;
static int debug;
/* This can increase dynamically */
static size_t bufsize = BUFSIZE;
static struct _mate *node_to_mate(struct udev_list_node *node)
{
char *mate;
mate = (char *)node;
mate -= offsetof(struct _mate, node);
return (struct _mate *)mate;
}
static void sig_alrm(int signo)
{
exit(4);
}
static void usage(void)
{
printf("usage: collect [--add|--remove] [--debug] <checkpoint> <id> <idlist>\n"
"\n"
" Adds ID <id> to the list governed by <checkpoint>.\n"
" <id> must be part of the list <idlist>.\n"
" If all IDs given by <idlist> are listed (ie collect has been\n"
" invoked for each ID in <idlist>) collect returns 0, the\n"
" number of missing IDs otherwise.\n"
" On error a negative number is returned.\n"
"\n");
}
/*
* prepare
*
* Prepares the database file
*/
static int prepare(char *dir, char *filename)
{
struct stat statbuf;
char buf[512];
int fd;
if (stat(dir, &statbuf) < 0)
mkdir(dir, 0700);
sprintf(buf, "%s/%s", dir, filename);
fd = open(buf,O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
if (fd < 0)
fprintf(stderr, "Cannot open %s: %s\n", buf, strerror(errno));
if (lockf(fd,F_TLOCK,0) < 0) {
if (debug)
fprintf(stderr, "Lock taken, wait for %d seconds\n", UDEV_ALARM_TIMEOUT);
if (errno == EAGAIN || errno == EACCES) {
alarm(UDEV_ALARM_TIMEOUT);
lockf(fd, F_LOCK, 0);
if (debug)
fprintf(stderr, "Acquired lock on %s\n", buf);
} else {
if (debug)
fprintf(stderr, "Could not get lock on %s: %s\n", buf, strerror(errno));
}
}
return fd;
}
/*
* Read checkpoint file
*
* Tricky reading this. We allocate a buffer twice as large
* as we're going to read. Then we read into the upper half
* of that buffer and start parsing.
* Once we do _not_ find end-of-work terminator (whitespace
* character) we move the upper half to the lower half,
* adjust the read pointer and read the next bit.
* Quite clever methinks :-)
* I should become a programmer ...
*
* Yes, one could have used fgets() for this. But then we'd
* have to use freopen etc which I found quite tedious.
*/
static int checkout(int fd)
{
int len;
char *buf, *ptr, *word = NULL;
struct _mate *him;
restart:
len = bufsize >> 1;
buf = calloc(1,bufsize + 1);
if (!buf) {
fprintf(stderr, "Out of memory\n");
return -1;
}
memset(buf, ' ', bufsize);
ptr = buf + len;
while ((read(fd, buf + len, len)) > 0) {
while (ptr && *ptr) {
word = ptr;
ptr = strpbrk(word," \n\t\r");
if (!ptr && word < (buf + len)) {
bufsize = bufsize << 1;
if (debug)
fprintf(stderr, "ID overflow, restarting with size %zi\n", bufsize);
free(buf);
lseek(fd, 0, SEEK_SET);
goto restart;
}
if (ptr) {
*ptr = '\0';
ptr++;
if (!strlen(word))
continue;
if (debug)
fprintf(stderr, "Found word %s\n", word);
him = malloc(sizeof (struct _mate));
him->name = strdup(word);
him->state = STATE_OLD;
udev_list_node_append(&him->node, &bunch);
word = NULL;
}
}
memcpy(buf, buf + len, len);
memset(buf + len, ' ', len);
if (!ptr)
ptr = word;
if (!ptr)
break;
ptr -= len;
}
free(buf);
return 0;
}
/*
* invite
*
* Adds a new ID 'us' to the internal list,
* marks it as confirmed.
*/
static void invite(char *us)
{
struct udev_list_node *him_node;
struct _mate *who = NULL;
if (debug)
fprintf(stderr, "Adding ID '%s'\n", us);
udev_list_node_foreach(him_node, &bunch) {
struct _mate *him = node_to_mate(him_node);
if (!strcmp(him->name, us)) {
him->state = STATE_CONFIRMED;
who = him;
}
}
if (debug && !who)
fprintf(stderr, "ID '%s' not in database\n", us);
}
/*
* reject
*
* Marks the ID 'us' as invalid,
* causing it to be removed when the
* list is written out.
*/
static void reject(char *us)
{
struct udev_list_node *him_node;
struct _mate *who = NULL;
if (debug)
fprintf(stderr, "Removing ID '%s'\n", us);
udev_list_node_foreach(him_node, &bunch) {
struct _mate *him = node_to_mate(him_node);
if (!strcmp(him->name, us)) {
him->state = STATE_NONE;
who = him;
}
}
if (debug && !who)
fprintf(stderr, "ID '%s' not in database\n", us);
}
/*
* kickout
*
* Remove all IDs in the internal list which are not part
* of the list passed via the commandline.
*/
static void kickout(void)
{
struct udev_list_node *him_node;
struct udev_list_node *tmp;
udev_list_node_foreach_safe(him_node, tmp, &bunch) {
struct _mate *him = node_to_mate(him_node);
if (him->state == STATE_OLD) {
udev_list_node_remove(&him->node);
free(him->name);
free(him);
}
}
}
/*
* missing
*
* Counts all missing IDs in the internal list.
*/
static int missing(int fd)
{
char *buf;
int ret = 0;
struct udev_list_node *him_node;
buf = malloc(bufsize);
if (!buf)
return -1;
udev_list_node_foreach(him_node, &bunch) {
struct _mate *him = node_to_mate(him_node);
if (him->state == STATE_NONE) {
ret++;
} else {
while (strlen(him->name)+1 >= bufsize) {
char *tmpbuf;
bufsize = bufsize << 1;
tmpbuf = realloc(buf, bufsize);
if (!tmpbuf) {
free(buf);
return -1;
}
buf = tmpbuf;
}
snprintf(buf, strlen(him->name)+2, "%s ", him->name);
write(fd, buf, strlen(buf));
}
}
free(buf);
return ret;
}
/*
* everybody
*
* Prints out the status of the internal list.
*/
static void everybody(void)
{
struct udev_list_node *him_node;
const char *state = "";
udev_list_node_foreach(him_node, &bunch) {
struct _mate *him = node_to_mate(him_node);
switch (him->state) {
case STATE_NONE:
state = "none";
break;
case STATE_OLD:
state = "old";
break;
case STATE_CONFIRMED:
state = "confirmed";
break;
}
fprintf(stderr, "ID: %s=%s\n", him->name, state);
}
}
int main(int argc, char **argv)
{
struct udev *udev;
static const struct option options[] = {
{ "add", no_argument, NULL, 'a' },
{ "remove", no_argument, NULL, 'r' },
{ "debug", no_argument, NULL, 'd' },
{ "help", no_argument, NULL, 'h' },
{}
};
int argi;
char *checkpoint, *us;
int fd;
int i;
int ret = EXIT_SUCCESS;
int prune = 0;
char tmpdir[UTIL_PATH_SIZE];
udev = udev_new();
if (udev == NULL) {
ret = EXIT_FAILURE;
goto exit;
}
while (1) {
int option;
option = getopt_long(argc, argv, "ardh", options, NULL);
if (option == -1)
break;
switch (option) {
case 'a':
prune = 0;
break;
case 'r':
prune = 1;
break;
case 'd':
debug = 1;
break;
case 'h':
usage();
goto exit;
default:
ret = 1;
goto exit;
}
}
argi = optind;
if (argi + 2 > argc) {
printf("Missing parameter(s)\n");
ret = 1;
goto exit;
}
checkpoint = argv[argi++];
us = argv[argi++];
if (signal(SIGALRM, sig_alrm) == SIG_ERR) {
fprintf(stderr, "Cannot set SIGALRM: %s\n", strerror(errno));
ret = 2;
goto exit;
}
udev_list_node_init(&bunch);
if (debug)
fprintf(stderr, "Using checkpoint '%s'\n", checkpoint);
util_strscpyl(tmpdir, sizeof(tmpdir), udev_get_run_path(udev), "/collect", NULL);
fd = prepare(tmpdir, checkpoint);
if (fd < 0) {
ret = 3;
goto out;
}
if (checkout(fd) < 0) {
ret = 2;
goto out;
}
for (i = argi; i < argc; i++) {
struct udev_list_node *him_node;
struct _mate *who;
who = NULL;
udev_list_node_foreach(him_node, &bunch) {
struct _mate *him = node_to_mate(him_node);
if (!strcmp(him->name, argv[i]))
who = him;
}
if (!who) {
struct _mate *him;
if (debug)
fprintf(stderr, "ID %s: not in database\n", argv[i]);
him = malloc(sizeof (struct _mate));
him->name = malloc(strlen(argv[i]) + 1);
strcpy(him->name, argv[i]);
him->state = STATE_NONE;
udev_list_node_append(&him->node, &bunch);
} else {
if (debug)
fprintf(stderr, "ID %s: found in database\n", argv[i]);
who->state = STATE_CONFIRMED;
}
}
if (prune)
reject(us);
else
invite(us);
if (debug) {
everybody();
fprintf(stderr, "Prune lists\n");
}
kickout();
lseek(fd, 0, SEEK_SET);
ftruncate(fd, 0);
ret = missing(fd);
lockf(fd, F_ULOCK, 0);
close(fd);
out:
if (debug)
everybody();
if (ret >= 0)
printf("COLLECT_%s=%d\n", checkpoint, ret);
exit:
udev_unref(udev);
return ret;
}

17
src/udev/src/docs/.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
libudev-overrides.txt
html/
tmpl/
xml/
*.stamp
*.bak
version.xml
libudev-decl-list.txt
libudev-decl.txt
libudev-undeclared.txt
libudev-undocumented.txt
libudev-unused.txt
libudev.args
libudev.hierarchy
libudev.interfaces
libudev.prerequisites
libudev.signals

View File

@ -0,0 +1,99 @@
## Process this file with automake to produce Makefile.in
# We require automake 1.10 at least.
AUTOMAKE_OPTIONS = 1.10
# This is a blank Makefile.am for using gtk-doc.
# Copy this to your project's API docs directory and modify the variables to
# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
# of using the various options.
# The name of the module, e.g. 'glib'.
DOC_MODULE=libudev
# Uncomment for versioned docs and specify the version of the module, e.g. '2'.
#DOC_MODULE_VERSION=2
# The top-level SGML file. You can change this if you want to.
DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml
# The directory containing the source code. Relative to $(srcdir).
# gtk-doc will search all .c & .h files beneath here for inline comments
# documenting the functions and macros.
# e.g. DOC_SOURCE_DIR=../../../gtk
DOC_SOURCE_DIR=$(top_srcdir)/src
# Extra options to pass to gtkdoc-scangobj. Not normally needed.
SCANGOBJ_OPTIONS=
# Extra options to supply to gtkdoc-scan.
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
SCAN_OPTIONS=
# Extra options to supply to gtkdoc-mkdb.
# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
MKDB_OPTIONS=--sgml-mode --output-format=xml --name-space udev
# Extra options to supply to gtkdoc-mktmpl
# e.g. MKTMPL_OPTIONS=--only-section-tmpl
MKTMPL_OPTIONS=
# Extra options to supply to gtkdoc-mkhtml
MKHTML_OPTIONS=--path=$(abs_srcdir) --path=$(abs_builddir)
# Extra options to supply to gtkdoc-fixref. Not normally needed.
# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
FIXXREF_OPTIONS=
# Used for dependencies. The docs will be rebuilt if any of these change.
# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
HFILE_GLOB=$(top_srcdir)/src/libudev*.h
CFILE_GLOB=$(top_srcdir)/src/libudev*.c
# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
EXTRA_HFILES=
# Header files to ignore when scanning. Use base file name, no paths
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
IGNORE_HFILES= libudev-private.h
# Images to copy into HTML directory.
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
HTML_IMAGES=
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
content_files = version.xml
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
# These files must be listed here *and* in content_files
# e.g. expand_content_files=running.sgml
expand_content_files=
# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
# Only needed if you are using gtkdoc-scangobj to dynamically query widget
# signals and properties.
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
GTKDOC_CFLAGS=
GTKDOC_LIBS=
# This includes the standard gtk-doc make rules, copied by gtkdocize.
include $(top_srcdir)/gtk-doc.make
# Other files to distribute
# e.g. EXTRA_DIST += version.xml.in
EXTRA_DIST += version.xml.in
# Files not to distribute
# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
#DISTCLEANFILES +=
# Comment this out if you want your docs-status tested during 'make check'
if ENABLE_GTK_DOC
#TESTS_ENVIRONMENT = cd $(srcsrc)
#TESTS = $(GTKDOC_CHECK)
endif

View File

@ -0,0 +1,32 @@
<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
[
<!ENTITY version SYSTEM "version.xml">
]>
<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
<bookinfo>
<title>libudev Reference Manual</title>
<releaseinfo>for libudev version &version;</releaseinfo>
<copyright>
<year>2009-2011</year>
<holder>Kay Sievers &lt;kay.sievers@vrfy.org&gt;</holder>
</copyright>
</bookinfo>
<chapter>
<title>libudev</title>
<xi:include href="xml/libudev.xml"/>
<xi:include href="xml/libudev-list.xml"/>
<xi:include href="xml/libudev-device.xml"/>
<xi:include href="xml/libudev-monitor.xml"/>
<xi:include href="xml/libudev-enumerate.xml"/>
<xi:include href="xml/libudev-queue.xml"/>
<xi:include href="xml/libudev-util.xml"/>
</chapter>
<index id="api-index-full">
<title>API Index</title>
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
</index>
</book>

View File

@ -0,0 +1,127 @@
<SECTION>
<FILE>libudev</FILE>
<TITLE>udev</TITLE>
udev
udev_ref
udev_unref
udev_new
udev_set_log_fn
udev_get_log_priority
udev_set_log_priority
udev_get_sys_path
udev_get_dev_path
udev_get_run_path
udev_get_userdata
udev_set_userdata
</SECTION>
<SECTION>
<FILE>libudev-list</FILE>
<TITLE>udev_list</TITLE>
udev_list_entry
udev_list_entry_get_next
udev_list_entry_get_by_name
udev_list_entry_get_name
udev_list_entry_get_value
udev_list_entry_foreach
</SECTION>
<SECTION>
<FILE>libudev-device</FILE>
<TITLE>udev_device</TITLE>
udev_device
udev_device_ref
udev_device_unref
udev_device_get_udev
udev_device_new_from_syspath
udev_device_new_from_devnum
udev_device_new_from_subsystem_sysname
udev_device_new_from_environment
udev_device_get_parent
udev_device_get_parent_with_subsystem_devtype
udev_device_get_devpath
udev_device_get_subsystem
udev_device_get_devtype
udev_device_get_syspath
udev_device_get_sysname
udev_device_get_sysnum
udev_device_get_devnode
udev_device_get_is_initialized
udev_device_get_devlinks_list_entry
udev_device_get_properties_list_entry
udev_device_get_tags_list_entry
udev_device_get_property_value
udev_device_get_driver
udev_device_get_devnum
udev_device_get_action
udev_device_get_sysattr_value
udev_device_get_sysattr_list_entry
udev_device_get_seqnum
udev_device_get_usec_since_initialized
udev_device_has_tag
</SECTION>
<SECTION>
<FILE>libudev-monitor</FILE>
<TITLE>udev_monitor</TITLE>
udev_monitor
udev_monitor_ref
udev_monitor_unref
udev_monitor_get_udev
udev_monitor_new_from_netlink
udev_monitor_new_from_socket
udev_monitor_enable_receiving
udev_monitor_set_receive_buffer_size
udev_monitor_get_fd
udev_monitor_receive_device
udev_monitor_filter_add_match_subsystem_devtype
udev_monitor_filter_add_match_tag
udev_monitor_filter_update
udev_monitor_filter_remove
</SECTION>
<SECTION>
<FILE>libudev-enumerate</FILE>
<TITLE>udev_enumerate</TITLE>
udev_enumerate
udev_enumerate_ref
udev_enumerate_unref
udev_enumerate_get_udev
udev_enumerate_new
udev_enumerate_add_match_subsystem
udev_enumerate_add_nomatch_subsystem
udev_enumerate_add_match_sysattr
udev_enumerate_add_nomatch_sysattr
udev_enumerate_add_match_property
udev_enumerate_add_match_tag
udev_enumerate_add_match_parent
udev_enumerate_add_match_is_initialized
udev_enumerate_add_match_sysname
udev_enumerate_add_syspath
udev_enumerate_scan_devices
udev_enumerate_scan_subsystems
udev_enumerate_get_list_entry
</SECTION>
<SECTION>
<FILE>libudev-queue</FILE>
<TITLE>udev_queue</TITLE>
udev_queue
udev_queue_ref
udev_queue_unref
udev_queue_get_udev
udev_queue_new
udev_queue_get_udev_is_active
udev_queue_get_queue_is_empty
udev_queue_get_seqnum_is_finished
udev_queue_get_seqnum_sequence_is_finished
udev_queue_get_queued_list_entry
udev_queue_get_kernel_seqnum
udev_queue_get_udev_seqnum
</SECTION>
<SECTION>
<FILE>libudev-util</FILE>
<TITLE>udev_util</TITLE>
udev_util_encode_string
</SECTION>

View File

View File

@ -0,0 +1 @@
@VERSION@

View File

@ -0,0 +1,4 @@
# do not edit this file, it will be overwritten on update
SUBSYSTEM=="block", KERNEL=="fd[0-9]", ACTION=="add", ATTRS{cmos}=="?*", ENV{CMOS_TYPE}="$attr{cmos}", \
RUN+="create_floppy_devices -c -t $env{CMOS_TYPE} -m %M -M 0660 -G floppy $root/%k"

View File

@ -0,0 +1,177 @@
/*
* Create all possible floppy device based on the CMOS type.
* Based upon code from drivers/block/floppy.c
*
* Copyright(C) 2005, SUSE Linux Products GmbH
*
* Author: Hannes Reinecke <hare@suse.de>
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include "libudev.h"
#include "libudev-private.h"
static char *table[] = {
"", "d360", "h1200", "u360", "u720", "h360", "h720",
"u1440", "u2880", "CompaQ", "h1440", "u1680", "h410",
"u820", "h1476", "u1722", "h420", "u830", "h1494", "u1743",
"h880", "u1040", "u1120", "h1600", "u1760", "u1920",
"u3200", "u3520", "u3840", "u1840", "u800", "u1600",
NULL
};
static int t360[] = { 1, 0 };
static int t1200[] = { 2, 5, 6, 10, 12, 14, 16, 18, 20, 23, 0 };
static int t3in[] = { 8, 9, 26, 27, 28, 7, 11, 15, 19, 24, 25, 29, 31, 3, 4, 13, 17, 21, 22, 30, 0 };
static int *table_sup[] = { NULL, t360, t1200, t3in+5+8, t3in+5, t3in, t3in };
static void log_fn(struct udev *udev, int priority,
const char *file, int line, const char *fn,
const char *format, va_list args)
{
vsyslog(priority, format, args);
}
int main(int argc, char **argv)
{
struct udev *udev;
char *dev;
char *devname;
char node[64];
int type = 0, i, fdnum, c;
int major = 2, minor;
uid_t uid = 0;
gid_t gid = 0;
mode_t mode = 0660;
int create_nodes = 0;
int print_nodes = 0;
int is_err = 0;
udev = udev_new();
if (udev == NULL)
goto exit;
udev_log_init("create_floppy_devices");
udev_set_log_fn(udev, log_fn);
udev_selinux_init(udev);
while ((c = getopt(argc, argv, "cudm:U:G:M:t:")) != -1) {
switch (c) {
case 'c':
create_nodes = 1;
break;
case 'd':
print_nodes = 1;
break;
case 'U':
uid = util_lookup_user(udev, optarg);
break;
case 'G':
gid = util_lookup_group(udev, optarg);
break;
case 'M':
mode = strtol(optarg, NULL, 0);
mode = mode & 0666;
break;
case 'm':
major = strtol(optarg, NULL, 0);
break;
case 't':
type = strtol(optarg, NULL, 0);
break;
default:
is_err++;
break;
}
}
if (is_err || optind >= argc) {
printf("Usage: %s [OPTION] device\n"
" -c create\n"
" -d debug\n"
" -m Major number\n"
" -t floppy type number\n"
" -U device node user ownership\n"
" -G device node group owner\n"
" -M device node mode\n"
"\n", argv[0]);
return 1;
}
dev = argv[optind];
devname = strrchr(dev, '/');
if (devname != NULL)
devname = &devname[1];
else
devname = dev;
if (strncmp(devname, "fd", 2) != 0) {
fprintf(stderr,"Device '%s' is not a floppy device\n", dev);
return 1;
}
fdnum = strtol(&devname[2], NULL, 10);
if (fdnum < 0 || fdnum > 7) {
fprintf(stderr,"Floppy device number %d out of range (0-7)\n", fdnum);
return 1;
}
if (fdnum > 3)
fdnum += 124;
if (major < 1) {
fprintf(stderr,"Invalid major number %d\n", major);
return 1;
}
if (type < 0 || type >= (int) ARRAY_SIZE(table_sup)) {
fprintf(stderr,"Invalid CMOS type %d\n", type);
return 1;
}
if (type == 0)
return 0;
i = 0;
while (table_sup[type][i]) {
sprintf(node, "%s%s", dev, table[table_sup[type][i]]);
minor = (table_sup[type][i] << 2) + fdnum;
if (print_nodes)
printf("%s b %.4o %d %d\n", node, mode, major, minor);
if (create_nodes) {
unlink(node);
udev_selinux_setfscreatecon(udev, node, S_IFBLK | mode);
mknod(node, S_IFBLK | mode, makedev(major,minor));
udev_selinux_resetfscreatecon(udev);
chown(node, uid, gid);
chmod(node, S_IFBLK | mode);
}
i++;
}
udev_selinux_exit(udev);
udev_unref(udev);
udev_log_close();
exit:
return 0;
}

9
src/udev/src/gudev/.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
gtk-doc.make
docs/version.xml
gudev-1.0.pc
gudevenumtypes.c
gudevenumtypes.h
gudevmarshal.c
gudevmarshal.h
GUdev-1.0.gir
GUdev-1.0.typelib

502
src/udev/src/gudev/COPYING Normal file
View File

@ -0,0 +1,502 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin St, 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.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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 St, 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.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

16
src/udev/src/gudev/docs/.gitignore vendored Normal file
View File

@ -0,0 +1,16 @@
gudev-overrides.txt
gudev-decl-list.txt
gudev-decl.txt
gudev-undeclared.txt
gudev-undocumented.txt
gudev-unused.txt
gudev.args
gudev.hierarchy
gudev.interfaces
gudev.prerequisites
gudev.signals
html.stamp
html/*
xml/*
tmpl/*
*.stamp

View File

@ -0,0 +1,106 @@
## Process this file with automake to produce Makefile.in
# We require automake 1.10 at least.
AUTOMAKE_OPTIONS = 1.10
# This is a blank Makefile.am for using gtk-doc.
# Copy this to your project's API docs directory and modify the variables to
# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
# of using the various options.
# The name of the module, e.g. 'glib'.
DOC_MODULE=gudev
# Uncomment for versioned docs and specify the version of the module, e.g. '2'.
#DOC_MODULE_VERSION=2
# The top-level SGML file. You can change this if you want to.
DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml
# The directory containing the source code. Relative to $(srcdir).
# gtk-doc will search all .c & .h files beneath here for inline comments
# documenting the functions and macros.
# e.g. DOC_SOURCE_DIR=../../../gtk
DOC_SOURCE_DIR=$(top_srcdir)/src
# Extra options to pass to gtkdoc-scangobj. Not normally needed.
SCANGOBJ_OPTIONS=
# Extra options to supply to gtkdoc-scan.
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
SCAN_OPTIONS=
# Extra options to supply to gtkdoc-mkdb.
# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
MKDB_OPTIONS=--sgml-mode --output-format=xml --name-space=g_udev
# Extra options to supply to gtkdoc-mktmpl
# e.g. MKTMPL_OPTIONS=--only-section-tmpl
MKTMPL_OPTIONS=
# Extra options to supply to gtkdoc-mkhtml
MKHTML_OPTIONS=--path=$(abs_srcdir) --path=$(abs_builddir)
# Extra options to supply to gtkdoc-fixref. Not normally needed.
# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
FIXXREF_OPTIONS=
# Used for dependencies. The docs will be rebuilt if any of these change.
# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
HFILE_GLOB=$(top_srcdir)/src/gudev/*.h
CFILE_GLOB=$(top_srcdir)/src/gudev/*.c
# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
EXTRA_HFILES=
# Header files to ignore when scanning. Use base file name, no paths
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
IGNORE_HFILES=
# Images to copy into HTML directory.
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
HTML_IMAGES=
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
content_files = version.xml
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
# These files must be listed here *and* in content_files
# e.g. expand_content_files=running.sgml
expand_content_files=
# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
# Only needed if you are using gtkdoc-scangobj to dynamically query widget
# signals and properties.
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
GTKDOC_CFLAGS = \
$(DBUS_GLIB_CFLAGS) \
$(GLIB_CFLAGS) \
-I$(top_srcdir)/src/gudev \
-I$(top_builddir)/src/gudev
GTKDOC_LIBS = \
$(GLIB_LIBS) \
$(top_builddir)/libgudev-1.0.la
# This includes the standard gtk-doc make rules, copied by gtkdocize.
include $(top_srcdir)/gtk-doc.make
# Other files to distribute
# e.g. EXTRA_DIST += version.xml.in
EXTRA_DIST += version.xml.in
# Files not to distribute
# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
#DISTCLEANFILES +=
# Comment this out if you want your docs-status tested during 'make check'
if ENABLE_GTK_DOC
#TESTS_ENVIRONMENT = cd $(srcsrc)
#TESTS = $(GTKDOC_CHECK)
endif

View File

@ -0,0 +1,93 @@
<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
<!ENTITY version SYSTEM "version.xml">
]>
<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
<bookinfo>
<title>GUDev Reference Manual</title>
<releaseinfo>For GUdev version &version;</releaseinfo>
<authorgroup>
<author>
<firstname>David</firstname>
<surname>Zeuthen</surname>
<affiliation>
<address>
<email>davidz@redhat.com</email>
</address>
</affiliation>
</author>
<author>
<firstname>Bastien</firstname>
<surname>Nocera</surname>
<affiliation>
<address>
<email>hadess@hadess.net</email>
</address>
</affiliation>
</author>
</authorgroup>
<copyright>
<year>2011</year>
<holder>The GUDev Authors</holder>
</copyright>
<legalnotice>
<para>
Permission is granted to copy, distribute and/or modify this
document under the terms of the <citetitle>GNU Free
Documentation License</citetitle>, Version 1.1 or any later
version published by the Free Software Foundation with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover
Texts. You may obtain a copy of the <citetitle>GNU Free
Documentation License</citetitle> from the Free Software
Foundation by visiting <ulink type="http"
url="http://www.fsf.org">their Web site</ulink> or by writing
to:
<address>
The Free Software Foundation, Inc.,
<street>59 Temple Place</street> - Suite 330,
<city>Boston</city>, <state>MA</state> <postcode>02111-1307</postcode>,
<country>USA</country>
</address>
</para>
<para>
Many of the names used by companies to distinguish their
products and services are claimed as trademarks. Where those
names appear in any freedesktop.org documentation, and those
trademarks are made aware to the members of the
freedesktop.org Project, the names have been printed in caps
or initial caps.
</para>
</legalnotice>
</bookinfo>
<reference id="ref-API">
<title>API Reference</title>
<partintro>
<para>
This part presents the class and function reference for the
<literal>libgudev</literal> library.
</para>
</partintro>
<xi:include href="xml/gudevclient.xml"/>
<xi:include href="xml/gudevdevice.xml"/>
<xi:include href="xml/gudevenumerator.xml"/>
</reference>
<chapter id="gudev-hierarchy">
<title>Object Hierarchy</title>
<xi:include href="xml/tree_index.sgml"/>
</chapter>
<index>
<title>Index</title>
</index>
<index role="165">
<title>Index of new symbols in 165</title>
<xi:include href="xml/api-index-165.xml"><xi:fallback /></xi:include>
</index>
</book>

View File

@ -0,0 +1,113 @@
<SECTION>
<FILE>gudevclient</FILE>
<TITLE>GUdevClient</TITLE>
GUdevClient
GUdevClientClass
GUdevDeviceType
GUdevDeviceNumber
g_udev_client_new
g_udev_client_query_by_subsystem
g_udev_client_query_by_device_number
g_udev_client_query_by_device_file
g_udev_client_query_by_sysfs_path
g_udev_client_query_by_subsystem_and_name
<SUBSECTION Standard>
G_UDEV_CLIENT
G_UDEV_IS_CLIENT
G_UDEV_TYPE_CLIENT
g_udev_client_get_type
G_UDEV_CLIENT_CLASS
G_UDEV_IS_CLIENT_CLASS
G_UDEV_CLIENT_GET_CLASS
<SUBSECTION Private>
GUdevClientPrivate
</SECTION>
<SECTION>
<FILE>gudevdevice</FILE>
<TITLE>GUdevDevice</TITLE>
GUdevDevice
GUdevDeviceClass
g_udev_device_get_subsystem
g_udev_device_get_devtype
g_udev_device_get_name
g_udev_device_get_number
g_udev_device_get_sysfs_path
g_udev_device_get_driver
g_udev_device_get_action
g_udev_device_get_seqnum
g_udev_device_get_device_type
g_udev_device_get_device_number
g_udev_device_get_device_file
g_udev_device_get_device_file_symlinks
g_udev_device_get_parent
g_udev_device_get_parent_with_subsystem
g_udev_device_get_tags
g_udev_device_get_is_initialized
g_udev_device_get_usec_since_initialized
g_udev_device_get_property_keys
g_udev_device_has_property
g_udev_device_get_property
g_udev_device_get_property_as_int
g_udev_device_get_property_as_uint64
g_udev_device_get_property_as_double
g_udev_device_get_property_as_boolean
g_udev_device_get_property_as_strv
g_udev_device_get_sysfs_attr
g_udev_device_get_sysfs_attr_as_int
g_udev_device_get_sysfs_attr_as_uint64
g_udev_device_get_sysfs_attr_as_double
g_udev_device_get_sysfs_attr_as_boolean
g_udev_device_get_sysfs_attr_as_strv
<SUBSECTION Standard>
G_UDEV_DEVICE
G_UDEV_IS_DEVICE
G_UDEV_TYPE_DEVICE
g_udev_device_get_type
G_UDEV_DEVICE_CLASS
G_UDEV_IS_DEVICE_CLASS
G_UDEV_DEVICE_GET_CLASS
<SUBSECTION Private>
GUdevDevicePrivate
</SECTION>
<SECTION>
<FILE>gudevenumerator</FILE>
<TITLE>GUdevEnumerator</TITLE>
GUdevEnumerator
GUdevEnumeratorClass
g_udev_enumerator_new
g_udev_enumerator_add_match_subsystem
g_udev_enumerator_add_nomatch_subsystem
g_udev_enumerator_add_match_sysfs_attr
g_udev_enumerator_add_nomatch_sysfs_attr
g_udev_enumerator_add_match_property
g_udev_enumerator_add_match_name
g_udev_enumerator_add_match_tag
g_udev_enumerator_add_match_is_initialized
g_udev_enumerator_add_sysfs_path
g_udev_enumerator_execute
<SUBSECTION Standard>
G_UDEV_ENUMERATOR
G_UDEV_IS_ENUMERATOR
G_UDEV_TYPE_ENUMERATOR
g_udev_enumerator_get_type
G_UDEV_ENUMERATOR_CLASS
G_UDEV_IS_ENUMERATOR_CLASS
G_UDEV_ENUMERATOR_GET_CLASS
<SUBSECTION Private>
GUdevEnumeratorPrivate
</SECTION>
<SECTION>
<FILE>gudevmarshal</FILE>
<SUBSECTION Private>
g_udev_marshal_VOID__STRING_OBJECT
</SECTION>
<SECTION>
<FILE>gudevenumtypes</FILE>
<SUBSECTION Private>
G_TYPE_UDEV_DEVICE_TYPE
g_udev_device_type_get_type
</SECTION>

View File

@ -0,0 +1,4 @@
g_udev_device_type_get_type
g_udev_device_get_type
g_udev_client_get_type
g_udev_enumerator_get_type

View File

@ -0,0 +1 @@
@VERSION@

View File

@ -0,0 +1,75 @@
#!/usr/bin/env gjs-console
// This currently depends on the following patches to gjs
//
// http://bugzilla.gnome.org/show_bug.cgi?id=584558
// http://bugzilla.gnome.org/show_bug.cgi?id=584560
// http://bugzilla.gnome.org/show_bug.cgi?id=584568
const GUdev = imports.gi.GUdev;
const Mainloop = imports.mainloop;
function print_device (device) {
print (" subsystem: " + device.get_subsystem ());
print (" devtype: " + device.get_devtype ());
print (" name: " + device.get_name ());
print (" number: " + device.get_number ());
print (" sysfs_path: " + device.get_sysfs_path ());
print (" driver: " + device.get_driver ());
print (" action: " + device.get_action ());
print (" seqnum: " + device.get_seqnum ());
print (" device type: " + device.get_device_type ());
print (" device number: " + device.get_device_number ());
print (" device file: " + device.get_device_file ());
print (" device file symlinks: " + device.get_device_file_symlinks ());
print (" foo: " + device.get_sysfs_attr_as_strv ("stat"));
var keys = device.get_property_keys ();
for (var n = 0; n < keys.length; n++) {
print (" " + keys[n] + "=" + device.get_property (keys[n]));
}
}
function on_uevent (client, action, device) {
print ("action " + action + " on device " + device.get_sysfs_path());
print_device (device);
print ("");
}
var client = new GUdev.Client ({subsystems: ["block", "usb/usb_interface"]});
client.connect ("uevent", on_uevent);
var block_devices = client.query_by_subsystem ("block");
for (var n = 0; n < block_devices.length; n++) {
print ("block device: " + block_devices[n].get_device_file ());
}
var d;
d = client.query_by_device_number (GUdev.DeviceType.BLOCK, 0x0810);
if (d == null) {
print ("query_by_device_number 0x810 -> null");
} else {
print ("query_by_device_number 0x810 -> " + d.get_device_file ());
var dd = d.get_parent_with_subsystem ("usb", null);
print_device (dd);
print ("--------------------------------------------------------------------------");
while (d != null) {
print_device (d);
print ("");
d = d.get_parent ();
}
}
d = client.query_by_sysfs_path ("/sys/block/sda/sda1");
print ("query_by_sysfs_path (\"/sys/block/sda1\") -> " + d.get_device_file ());
d = client.query_by_subsystem_and_name ("block", "sda2");
print ("query_by_subsystem_and_name (\"block\", \"sda2\") -> " + d.get_device_file ());
d = client.query_by_device_file ("/dev/sda");
print ("query_by_device_file (\"/dev/sda\") -> " + d.get_device_file ());
d = client.query_by_device_file ("/dev/block/8:0");
print ("query_by_device_file (\"/dev/block/8:0\") -> " + d.get_device_file ());
Mainloop.run('udev-example');

View File

@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: gudev-1.0
Description: GObject bindings for libudev
Version: @VERSION@
Requires: glib-2.0, gobject-2.0
Libs: -L${libdir} -lgudev-1.0
Cflags: -I${includedir}/gudev-1.0

View File

@ -0,0 +1,33 @@
/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
*
* 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 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 __G_UDEV_H__
#define __G_UDEV_H__
#define _GUDEV_INSIDE_GUDEV_H 1
#include <gudev/gudevenums.h>
#include <gudev/gudevenumtypes.h>
#include <gudev/gudevtypes.h>
#include <gudev/gudevclient.h>
#include <gudev/gudevdevice.h>
#include <gudev/gudevenumerator.h>
#undef _GUDEV_INSIDE_GUDEV_H
#endif /* __G_UDEV_H__ */

View File

@ -0,0 +1,527 @@
/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2008-2010 David Zeuthen <davidz@redhat.com>
*
* 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 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.
*
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include "gudevclient.h"
#include "gudevdevice.h"
#include "gudevmarshal.h"
#include "gudevprivate.h"
/**
* SECTION:gudevclient
* @short_description: Query devices and listen to uevents
*
* #GUdevClient is used to query information about devices on a Linux
* system from the Linux kernel and the udev device
* manager.
*
* Device information is retrieved from the kernel (through the
* <literal>sysfs</literal> filesystem) and the udev daemon (through a
* <literal>tmpfs</literal> filesystem) and presented through
* #GUdevDevice objects. This means that no blocking IO ever happens
* (in both cases, we are essentially just reading data from kernel
* memory) and as such there are no asynchronous versions of the
* provided methods.
*
* To get #GUdevDevice objects, use
* g_udev_client_query_by_subsystem(),
* g_udev_client_query_by_device_number(),
* g_udev_client_query_by_device_file(),
* g_udev_client_query_by_sysfs_path(),
* g_udev_client_query_by_subsystem_and_name()
* or the #GUdevEnumerator type.
*
* To listen to uevents, connect to the #GUdevClient::uevent signal.
*/
struct _GUdevClientPrivate
{
GSource *watch_source;
struct udev *udev;
struct udev_monitor *monitor;
gchar **subsystems;
};
enum
{
PROP_0,
PROP_SUBSYSTEMS,
};
enum
{
UEVENT_SIGNAL,
LAST_SIGNAL,
};
static guint signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (GUdevClient, g_udev_client, G_TYPE_OBJECT)
/* ---------------------------------------------------------------------------------------------------- */
static gboolean
monitor_event (GIOChannel *source,
GIOCondition condition,
gpointer data)
{
GUdevClient *client = (GUdevClient *) data;
GUdevDevice *device;
struct udev_device *udevice;
if (client->priv->monitor == NULL)
goto out;
udevice = udev_monitor_receive_device (client->priv->monitor);
if (udevice == NULL)
goto out;
device = _g_udev_device_new (udevice);
udev_device_unref (udevice);
g_signal_emit (client,
signals[UEVENT_SIGNAL],
0,
g_udev_device_get_action (device),
device);
g_object_unref (device);
out:
return TRUE;
}
static void
g_udev_client_finalize (GObject *object)
{
GUdevClient *client = G_UDEV_CLIENT (object);
if (client->priv->watch_source != NULL)
{
g_source_destroy (client->priv->watch_source);
client->priv->watch_source = NULL;
}
if (client->priv->monitor != NULL)
{
udev_monitor_unref (client->priv->monitor);
client->priv->monitor = NULL;
}
if (client->priv->udev != NULL)
{
udev_unref (client->priv->udev);
client->priv->udev = NULL;
}
g_strfreev (client->priv->subsystems);
if (G_OBJECT_CLASS (g_udev_client_parent_class)->finalize != NULL)
G_OBJECT_CLASS (g_udev_client_parent_class)->finalize (object);
}
static void
g_udev_client_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GUdevClient *client = G_UDEV_CLIENT (object);
switch (prop_id)
{
case PROP_SUBSYSTEMS:
if (client->priv->subsystems != NULL)
g_strfreev (client->priv->subsystems);
client->priv->subsystems = g_strdupv (g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
g_udev_client_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GUdevClient *client = G_UDEV_CLIENT (object);
switch (prop_id)
{
case PROP_SUBSYSTEMS:
g_value_set_boxed (value, client->priv->subsystems);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
g_udev_client_constructed (GObject *object)
{
GUdevClient *client = G_UDEV_CLIENT (object);
GIOChannel *channel;
guint n;
client->priv->udev = udev_new ();
/* connect to event source */
client->priv->monitor = udev_monitor_new_from_netlink (client->priv->udev, "udev");
//g_debug ("ss = %p", client->priv->subsystems);
if (client->priv->subsystems != NULL)
{
/* install subsystem filters to only wake up for certain events */
for (n = 0; client->priv->subsystems[n] != NULL; n++)
{
gchar *subsystem;
gchar *devtype;
gchar *s;
subsystem = g_strdup (client->priv->subsystems[n]);
devtype = NULL;
//g_debug ("s = '%s'", subsystem);
s = strstr (subsystem, "/");
if (s != NULL)
{
devtype = s + 1;
*s = '\0';
}
if (client->priv->monitor != NULL)
udev_monitor_filter_add_match_subsystem_devtype (client->priv->monitor, subsystem, devtype);
g_free (subsystem);
}
/* listen to events, and buffer them */
if (client->priv->monitor != NULL)
{
udev_monitor_enable_receiving (client->priv->monitor);
channel = g_io_channel_unix_new (udev_monitor_get_fd (client->priv->monitor));
client->priv->watch_source = g_io_create_watch (channel, G_IO_IN);
g_io_channel_unref (channel);
g_source_set_callback (client->priv->watch_source, (GSourceFunc) monitor_event, client, NULL);
g_source_attach (client->priv->watch_source, g_main_context_get_thread_default ());
g_source_unref (client->priv->watch_source);
}
else
{
client->priv->watch_source = NULL;
}
}
if (G_OBJECT_CLASS (g_udev_client_parent_class)->constructed != NULL)
G_OBJECT_CLASS (g_udev_client_parent_class)->constructed (object);
}
static void
g_udev_client_class_init (GUdevClientClass *klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
gobject_class->constructed = g_udev_client_constructed;
gobject_class->set_property = g_udev_client_set_property;
gobject_class->get_property = g_udev_client_get_property;
gobject_class->finalize = g_udev_client_finalize;
/**
* GUdevClient:subsystems:
*
* The subsystems to listen for uevents on.
*
* To listen for only a specific DEVTYPE for a given SUBSYSTEM, use
* "subsystem/devtype". For example, to only listen for uevents
* where SUBSYSTEM is usb and DEVTYPE is usb_interface, use
* "usb/usb_interface".
*
* If this property is %NULL, then no events will be reported. If
* it's the empty array, events from all subsystems will be
* reported.
*/
g_object_class_install_property (gobject_class,
PROP_SUBSYSTEMS,
g_param_spec_boxed ("subsystems",
"The subsystems to listen for changes on",
"The subsystems to listen for changes on",
G_TYPE_STRV,
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE));
/**
* GUdevClient::uevent:
* @client: The #GUdevClient receiving the event.
* @action: The action for the uevent e.g. "add", "remove", "change", "move", etc.
* @device: Details about the #GUdevDevice the event is for.
*
* Emitted when @client receives an uevent.
*
* This signal is emitted in the
* <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
* of the thread that @client was created in.
*/
signals[UEVENT_SIGNAL] = g_signal_new ("uevent",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GUdevClientClass, uevent),
NULL,
NULL,
g_udev_marshal_VOID__STRING_OBJECT,
G_TYPE_NONE,
2,
G_TYPE_STRING,
G_UDEV_TYPE_DEVICE);
g_type_class_add_private (klass, sizeof (GUdevClientPrivate));
}
static void
g_udev_client_init (GUdevClient *client)
{
client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client,
G_UDEV_TYPE_CLIENT,
GUdevClientPrivate);
}
/**
* g_udev_client_new:
* @subsystems: (array zero-terminated=1) (element-type utf8) (transfer none) (allow-none): A %NULL terminated string array of subsystems to listen for uevents on, %NULL to not listen on uevents at all, or an empty array to listen to uevents on all subsystems. See the documentation for the #GUdevClient:subsystems property for details on this parameter.
*
* Constructs a #GUdevClient object that can be used to query
* information about devices. Connect to the #GUdevClient::uevent
* signal to listen for uevents. Note that signals are emitted in the
* <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
* of the thread that you call this constructor from.
*
* Returns: A new #GUdevClient object. Free with g_object_unref().
*/
GUdevClient *
g_udev_client_new (const gchar * const *subsystems)
{
return G_UDEV_CLIENT (g_object_new (G_UDEV_TYPE_CLIENT, "subsystems", subsystems, NULL));
}
/**
* g_udev_client_query_by_subsystem:
* @client: A #GUdevClient.
* @subsystem: (allow-none): The subsystem to get devices for or %NULL to get all devices.
*
* Gets all devices belonging to @subsystem.
*
* Returns: (element-type GUdevDevice) (transfer full): A list of #GUdevDevice objects. The caller should free the result by using g_object_unref() on each element in the list and then g_list_free() on the list.
*/
GList *
g_udev_client_query_by_subsystem (GUdevClient *client,
const gchar *subsystem)
{
struct udev_enumerate *enumerate;
struct udev_list_entry *l, *devices;
GList *ret;
g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
ret = NULL;
/* prepare a device scan */
enumerate = udev_enumerate_new (client->priv->udev);
/* filter for subsystem */
if (subsystem != NULL)
udev_enumerate_add_match_subsystem (enumerate, subsystem);
/* retrieve the list */
udev_enumerate_scan_devices (enumerate);
/* add devices to the list */
devices = udev_enumerate_get_list_entry (enumerate);
for (l = devices; l != NULL; l = udev_list_entry_get_next (l))
{
struct udev_device *udevice;
GUdevDevice *device;
udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerate),
udev_list_entry_get_name (l));
if (udevice == NULL)
continue;
device = _g_udev_device_new (udevice);
udev_device_unref (udevice);
ret = g_list_prepend (ret, device);
}
udev_enumerate_unref (enumerate);
ret = g_list_reverse (ret);
return ret;
}
/**
* g_udev_client_query_by_device_number:
* @client: A #GUdevClient.
* @type: A value from the #GUdevDeviceType enumeration.
* @number: A device number.
*
* Looks up a device for a type and device number.
*
* Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
*/
GUdevDevice *
g_udev_client_query_by_device_number (GUdevClient *client,
GUdevDeviceType type,
GUdevDeviceNumber number)
{
struct udev_device *udevice;
GUdevDevice *device;
g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
device = NULL;
udevice = udev_device_new_from_devnum (client->priv->udev, type, number);
if (udevice == NULL)
goto out;
device = _g_udev_device_new (udevice);
udev_device_unref (udevice);
out:
return device;
}
/**
* g_udev_client_query_by_device_file:
* @client: A #GUdevClient.
* @device_file: A device file.
*
* Looks up a device for a device file.
*
* Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
*/
GUdevDevice *
g_udev_client_query_by_device_file (GUdevClient *client,
const gchar *device_file)
{
struct stat stat_buf;
GUdevDevice *device;
g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
g_return_val_if_fail (device_file != NULL, NULL);
device = NULL;
if (stat (device_file, &stat_buf) != 0)
goto out;
if (stat_buf.st_rdev == 0)
goto out;
if (S_ISBLK (stat_buf.st_mode))
device = g_udev_client_query_by_device_number (client, G_UDEV_DEVICE_TYPE_BLOCK, stat_buf.st_rdev);
else if (S_ISCHR (stat_buf.st_mode))
device = g_udev_client_query_by_device_number (client, G_UDEV_DEVICE_TYPE_CHAR, stat_buf.st_rdev);
out:
return device;
}
/**
* g_udev_client_query_by_sysfs_path:
* @client: A #GUdevClient.
* @sysfs_path: A sysfs path.
*
* Looks up a device for a sysfs path.
*
* Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
*/
GUdevDevice *
g_udev_client_query_by_sysfs_path (GUdevClient *client,
const gchar *sysfs_path)
{
struct udev_device *udevice;
GUdevDevice *device;
g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
g_return_val_if_fail (sysfs_path != NULL, NULL);
device = NULL;
udevice = udev_device_new_from_syspath (client->priv->udev, sysfs_path);
if (udevice == NULL)
goto out;
device = _g_udev_device_new (udevice);
udev_device_unref (udevice);
out:
return device;
}
/**
* g_udev_client_query_by_subsystem_and_name:
* @client: A #GUdevClient.
* @subsystem: A subsystem name.
* @name: The name of the device.
*
* Looks up a device for a subsystem and name.
*
* Returns: (transfer full): A #GUdevDevice object or %NULL if the device was not found. Free with g_object_unref().
*/
GUdevDevice *
g_udev_client_query_by_subsystem_and_name (GUdevClient *client,
const gchar *subsystem,
const gchar *name)
{
struct udev_device *udevice;
GUdevDevice *device;
g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
g_return_val_if_fail (subsystem != NULL, NULL);
g_return_val_if_fail (name != NULL, NULL);
device = NULL;
udevice = udev_device_new_from_subsystem_sysname (client->priv->udev, subsystem, name);
if (udevice == NULL)
goto out;
device = _g_udev_device_new (udevice);
udev_device_unref (udevice);
out:
return device;
}
struct udev *
_g_udev_client_get_udev (GUdevClient *client)
{
g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
return client->priv->udev;
}

View File

@ -0,0 +1,100 @@
/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
*
* 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 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.
*/
#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
#endif
#ifndef __G_UDEV_CLIENT_H__
#define __G_UDEV_CLIENT_H__
#include <gudev/gudevtypes.h>
G_BEGIN_DECLS
#define G_UDEV_TYPE_CLIENT (g_udev_client_get_type ())
#define G_UDEV_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_UDEV_TYPE_CLIENT, GUdevClient))
#define G_UDEV_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_CLIENT, GUdevClientClass))
#define G_UDEV_IS_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_CLIENT))
#define G_UDEV_IS_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_UDEV_TYPE_CLIENT))
#define G_UDEV_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_UDEV_TYPE_CLIENT, GUdevClientClass))
typedef struct _GUdevClientClass GUdevClientClass;
typedef struct _GUdevClientPrivate GUdevClientPrivate;
/**
* GUdevClient:
*
* The #GUdevClient struct is opaque and should not be accessed directly.
*/
struct _GUdevClient
{
GObject parent;
/*< private >*/
GUdevClientPrivate *priv;
};
/**
* GUdevClientClass:
* @parent_class: Parent class.
* @uevent: Signal class handler for the #GUdevClient::uevent signal.
*
* Class structure for #GUdevClient.
*/
struct _GUdevClientClass
{
GObjectClass parent_class;
/* signals */
void (*uevent) (GUdevClient *client,
const gchar *action,
GUdevDevice *device);
/*< private >*/
/* Padding for future expansion */
void (*reserved1) (void);
void (*reserved2) (void);
void (*reserved3) (void);
void (*reserved4) (void);
void (*reserved5) (void);
void (*reserved6) (void);
void (*reserved7) (void);
void (*reserved8) (void);
};
GType g_udev_client_get_type (void) G_GNUC_CONST;
GUdevClient *g_udev_client_new (const gchar* const *subsystems);
GList *g_udev_client_query_by_subsystem (GUdevClient *client,
const gchar *subsystem);
GUdevDevice *g_udev_client_query_by_device_number (GUdevClient *client,
GUdevDeviceType type,
GUdevDeviceNumber number);
GUdevDevice *g_udev_client_query_by_device_file (GUdevClient *client,
const gchar *device_file);
GUdevDevice *g_udev_client_query_by_sysfs_path (GUdevClient *client,
const gchar *sysfs_path);
GUdevDevice *g_udev_client_query_by_subsystem_and_name (GUdevClient *client,
const gchar *subsystem,
const gchar *name);
G_END_DECLS
#endif /* __G_UDEV_CLIENT_H__ */

View File

@ -0,0 +1,963 @@
/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
*
* 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 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.
*
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include "gudevdevice.h"
#include "gudevprivate.h"
/**
* SECTION:gudevdevice
* @short_description: Get information about a device
*
* The #GUdevDevice class is used to get information about a specific
* device. Note that you cannot instantiate a #GUdevDevice object
* yourself. Instead you must use #GUdevClient to obtain #GUdevDevice
* objects.
*
* To get basic information about a device, use
* g_udev_device_get_subsystem(), g_udev_device_get_devtype(),
* g_udev_device_get_name(), g_udev_device_get_number(),
* g_udev_device_get_sysfs_path(), g_udev_device_get_driver(),
* g_udev_device_get_action(), g_udev_device_get_seqnum(),
* g_udev_device_get_device_type(), g_udev_device_get_device_number(),
* g_udev_device_get_device_file(),
* g_udev_device_get_device_file_symlinks().
*
* To navigate the device tree, use g_udev_device_get_parent() and
* g_udev_device_get_parent_with_subsystem().
*
* To access udev properties for the device, use
* g_udev_device_get_property_keys(),
* g_udev_device_has_property(),
* g_udev_device_get_property(),
* g_udev_device_get_property_as_int(),
* g_udev_device_get_property_as_uint64(),
* g_udev_device_get_property_as_double(),
* g_udev_device_get_property_as_boolean() and
* g_udev_device_get_property_as_strv().
*
* To access sysfs attributes for the device, use
* g_udev_device_get_sysfs_attr(),
* g_udev_device_get_sysfs_attr_as_int(),
* g_udev_device_get_sysfs_attr_as_uint64(),
* g_udev_device_get_sysfs_attr_as_double(),
* g_udev_device_get_sysfs_attr_as_boolean() and
* g_udev_device_get_sysfs_attr_as_strv().
*
* Note that all getters on #GUdevDevice are non-reffing returned
* values are owned by the object, should not be freed and are only
* valid as long as the object is alive.
*
* By design, #GUdevDevice will not react to changes for a device it
* only contains a snapshot of information when the #GUdevDevice
* object was created. To work with changes, you typically connect to
* the #GUdevClient::uevent signal on a #GUdevClient and get a new
* #GUdevDevice whenever an event happens.
*/
struct _GUdevDevicePrivate
{
struct udev_device *udevice;
/* computed ondemand and cached */
gchar **device_file_symlinks;
gchar **property_keys;
gchar **tags;
GHashTable *prop_strvs;
GHashTable *sysfs_attr_strvs;
};
G_DEFINE_TYPE (GUdevDevice, g_udev_device, G_TYPE_OBJECT)
static void
g_udev_device_finalize (GObject *object)
{
GUdevDevice *device = G_UDEV_DEVICE (object);
g_strfreev (device->priv->device_file_symlinks);
g_strfreev (device->priv->property_keys);
g_strfreev (device->priv->tags);
if (device->priv->udevice != NULL)
udev_device_unref (device->priv->udevice);
if (device->priv->prop_strvs != NULL)
g_hash_table_unref (device->priv->prop_strvs);
if (device->priv->sysfs_attr_strvs != NULL)
g_hash_table_unref (device->priv->sysfs_attr_strvs);
if (G_OBJECT_CLASS (g_udev_device_parent_class)->finalize != NULL)
(* G_OBJECT_CLASS (g_udev_device_parent_class)->finalize) (object);
}
static void
g_udev_device_class_init (GUdevDeviceClass *klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
gobject_class->finalize = g_udev_device_finalize;
g_type_class_add_private (klass, sizeof (GUdevDevicePrivate));
}
static void
g_udev_device_init (GUdevDevice *device)
{
device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device,
G_UDEV_TYPE_DEVICE,
GUdevDevicePrivate);
}
GUdevDevice *
_g_udev_device_new (struct udev_device *udevice)
{
GUdevDevice *device;
device = G_UDEV_DEVICE (g_object_new (G_UDEV_TYPE_DEVICE, NULL));
device->priv->udevice = udev_device_ref (udevice);
return device;
}
/**
* g_udev_device_get_subsystem:
* @device: A #GUdevDevice.
*
* Gets the subsystem for @device.
*
* Returns: The subsystem for @device.
*/
const gchar *
g_udev_device_get_subsystem (GUdevDevice *device)
{
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
return udev_device_get_subsystem (device->priv->udevice);
}
/**
* g_udev_device_get_devtype:
* @device: A #GUdevDevice.
*
* Gets the device type for @device.
*
* Returns: The devtype for @device.
*/
const gchar *
g_udev_device_get_devtype (GUdevDevice *device)
{
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
return udev_device_get_devtype (device->priv->udevice);
}
/**
* g_udev_device_get_name:
* @device: A #GUdevDevice.
*
* Gets the name of @device, e.g. "sda3".
*
* Returns: The name of @device.
*/
const gchar *
g_udev_device_get_name (GUdevDevice *device)
{
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
return udev_device_get_sysname (device->priv->udevice);
}
/**
* g_udev_device_get_number:
* @device: A #GUdevDevice.
*
* Gets the number of @device, e.g. "3" if g_udev_device_get_name() returns "sda3".
*
* Returns: The number of @device.
*/
const gchar *
g_udev_device_get_number (GUdevDevice *device)
{
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
return udev_device_get_sysnum (device->priv->udevice);
}
/**
* g_udev_device_get_sysfs_path:
* @device: A #GUdevDevice.
*
* Gets the sysfs path for @device.
*
* Returns: The sysfs path for @device.
*/
const gchar *
g_udev_device_get_sysfs_path (GUdevDevice *device)
{
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
return udev_device_get_syspath (device->priv->udevice);
}
/**
* g_udev_device_get_driver:
* @device: A #GUdevDevice.
*
* Gets the name of the driver used for @device.
*
* Returns: The name of the driver for @device or %NULL if unknown.
*/
const gchar *
g_udev_device_get_driver (GUdevDevice *device)
{
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
return udev_device_get_driver (device->priv->udevice);
}
/**
* g_udev_device_get_action:
* @device: A #GUdevDevice.
*
* Gets the most recent action (e.g. "add", "remove", "change", etc.) for @device.
*
* Returns: An action string.
*/
const gchar *
g_udev_device_get_action (GUdevDevice *device)
{
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
return udev_device_get_action (device->priv->udevice);
}
/**
* g_udev_device_get_seqnum:
* @device: A #GUdevDevice.
*
* Gets the most recent sequence number for @device.
*
* Returns: A sequence number.
*/
guint64
g_udev_device_get_seqnum (GUdevDevice *device)
{
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
return udev_device_get_seqnum (device->priv->udevice);
}
/**
* g_udev_device_get_device_type:
* @device: A #GUdevDevice.
*
* Gets the type of the device file, if any, for @device.
*
* Returns: The device number for @device or #G_UDEV_DEVICE_TYPE_NONE if the device does not have a device file.
*/
GUdevDeviceType
g_udev_device_get_device_type (GUdevDevice *device)
{
struct stat stat_buf;
const gchar *device_file;
GUdevDeviceType type;
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), G_UDEV_DEVICE_TYPE_NONE);
type = G_UDEV_DEVICE_TYPE_NONE;
/* TODO: would be better to have support for this in libudev... */
device_file = g_udev_device_get_device_file (device);
if (device_file == NULL)
goto out;
if (stat (device_file, &stat_buf) != 0)
goto out;
if (S_ISBLK (stat_buf.st_mode))
type = G_UDEV_DEVICE_TYPE_BLOCK;
else if (S_ISCHR (stat_buf.st_mode))
type = G_UDEV_DEVICE_TYPE_CHAR;
out:
return type;
}
/**
* g_udev_device_get_device_number:
* @device: A #GUdevDevice.
*
* Gets the device number, if any, for @device.
*
* Returns: The device number for @device or 0 if unknown.
*/
GUdevDeviceNumber
g_udev_device_get_device_number (GUdevDevice *device)
{
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
return udev_device_get_devnum (device->priv->udevice);
}
/**
* g_udev_device_get_device_file:
* @device: A #GUdevDevice.
*
* Gets the device file for @device.
*
* Returns: The device file for @device or %NULL if no device file
* exists.
*/
const gchar *
g_udev_device_get_device_file (GUdevDevice *device)
{
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
return udev_device_get_devnode (device->priv->udevice);
}
/**
* g_udev_device_get_device_file_symlinks:
* @device: A #GUdevDevice.
*
* Gets a list of symlinks (in <literal>/dev</literal>) that points to
* the device file for @device.
*
* Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of symlinks. This array is owned by @device and should not be freed by the caller.
*/
const gchar * const *
g_udev_device_get_device_file_symlinks (GUdevDevice *device)
{
struct udev_list_entry *l;
GPtrArray *p;
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
if (device->priv->device_file_symlinks != NULL)
goto out;
p = g_ptr_array_new ();
for (l = udev_device_get_devlinks_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
{
g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
}
g_ptr_array_add (p, NULL);
device->priv->device_file_symlinks = (gchar **) g_ptr_array_free (p, FALSE);
out:
return (const gchar * const *) device->priv->device_file_symlinks;
}
/* ---------------------------------------------------------------------------------------------------- */
/**
* g_udev_device_get_parent:
* @device: A #GUdevDevice.
*
* Gets the immediate parent of @device, if any.
*
* Returns: (transfer full): A #GUdevDevice or %NULL if @device has no parent. Free with g_object_unref().
*/
GUdevDevice *
g_udev_device_get_parent (GUdevDevice *device)
{
GUdevDevice *ret;
struct udev_device *udevice;
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
ret = NULL;
udevice = udev_device_get_parent (device->priv->udevice);
if (udevice == NULL)
goto out;
ret = _g_udev_device_new (udevice);
out:
return ret;
}
/**
* g_udev_device_get_parent_with_subsystem:
* @device: A #GUdevDevice.
* @subsystem: The subsystem of the parent to get.
* @devtype: (allow-none): The devtype of the parent to get or %NULL.
*
* Walks up the chain of parents of @device and returns the first
* device encountered where @subsystem and @devtype matches, if any.
*
* Returns: (transfer full): A #GUdevDevice or %NULL if @device has no parent with @subsystem and @devtype. Free with g_object_unref().
*/
GUdevDevice *
g_udev_device_get_parent_with_subsystem (GUdevDevice *device,
const gchar *subsystem,
const gchar *devtype)
{
GUdevDevice *ret;
struct udev_device *udevice;
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
g_return_val_if_fail (subsystem != NULL, NULL);
ret = NULL;
udevice = udev_device_get_parent_with_subsystem_devtype (device->priv->udevice,
subsystem,
devtype);
if (udevice == NULL)
goto out;
ret = _g_udev_device_new (udevice);
out:
return ret;
}
/* ---------------------------------------------------------------------------------------------------- */
/**
* g_udev_device_get_property_keys:
* @device: A #GUdevDevice.
*
* Gets all keys for properties on @device.
*
* Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of property keys. This array is owned by @device and should not be freed by the caller.
*/
const gchar* const *
g_udev_device_get_property_keys (GUdevDevice *device)
{
struct udev_list_entry *l;
GPtrArray *p;
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
if (device->priv->property_keys != NULL)
goto out;
p = g_ptr_array_new ();
for (l = udev_device_get_properties_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
{
g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
}
g_ptr_array_add (p, NULL);
device->priv->property_keys = (gchar **) g_ptr_array_free (p, FALSE);
out:
return (const gchar * const *) device->priv->property_keys;
}
/**
* g_udev_device_has_property:
* @device: A #GUdevDevice.
* @key: Name of property.
*
* Check if a the property with the given key exists.
*
* Returns: %TRUE only if the value for @key exist.
*/
gboolean
g_udev_device_has_property (GUdevDevice *device,
const gchar *key)
{
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
g_return_val_if_fail (key != NULL, FALSE);
return udev_device_get_property_value (device->priv->udevice, key) != NULL;
}
/**
* g_udev_device_get_property:
* @device: A #GUdevDevice.
* @key: Name of property.
*
* Look up the value for @key on @device.
*
* Returns: The value for @key or %NULL if @key doesn't exist on @device. Do not free this string, it is owned by @device.
*/
const gchar *
g_udev_device_get_property (GUdevDevice *device,
const gchar *key)
{
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
g_return_val_if_fail (key != NULL, NULL);
return udev_device_get_property_value (device->priv->udevice, key);
}
/**
* g_udev_device_get_property_as_int:
* @device: A #GUdevDevice.
* @key: Name of property.
*
* Look up the value for @key on @device and convert it to an integer
* using strtol().
*
* Returns: The value for @key or 0 if @key doesn't exist or
* isn't an integer.
*/
gint
g_udev_device_get_property_as_int (GUdevDevice *device,
const gchar *key)
{
gint result;
const gchar *s;
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
g_return_val_if_fail (key != NULL, 0);
result = 0;
s = g_udev_device_get_property (device, key);
if (s == NULL)
goto out;
result = strtol (s, NULL, 0);
out:
return result;
}
/**
* g_udev_device_get_property_as_uint64:
* @device: A #GUdevDevice.
* @key: Name of property.
*
* Look up the value for @key on @device and convert it to an unsigned
* 64-bit integer using g_ascii_strtoull().
*
* Returns: The value for @key or 0 if @key doesn't exist or isn't a
* #guint64.
*/
guint64
g_udev_device_get_property_as_uint64 (GUdevDevice *device,
const gchar *key)
{
guint64 result;
const gchar *s;
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
g_return_val_if_fail (key != NULL, 0);
result = 0;
s = g_udev_device_get_property (device, key);
if (s == NULL)
goto out;
result = g_ascii_strtoull (s, NULL, 0);
out:
return result;
}
/**
* g_udev_device_get_property_as_double:
* @device: A #GUdevDevice.
* @key: Name of property.
*
* Look up the value for @key on @device and convert it to a double
* precision floating point number using strtod().
*
* Returns: The value for @key or 0.0 if @key doesn't exist or isn't a
* #gdouble.
*/
gdouble
g_udev_device_get_property_as_double (GUdevDevice *device,
const gchar *key)
{
gdouble result;
const gchar *s;
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0.0);
g_return_val_if_fail (key != NULL, 0.0);
result = 0.0;
s = g_udev_device_get_property (device, key);
if (s == NULL)
goto out;
result = strtod (s, NULL);
out:
return result;
}
/**
* g_udev_device_get_property_as_boolean:
* @device: A #GUdevDevice.
* @key: Name of property.
*
* Look up the value for @key on @device and convert it to an
* boolean. This is done by doing a case-insensitive string comparison
* on the string value against "1" and "true".
*
* Returns: The value for @key or %FALSE if @key doesn't exist or
* isn't a #gboolean.
*/
gboolean
g_udev_device_get_property_as_boolean (GUdevDevice *device,
const gchar *key)
{
gboolean result;
const gchar *s;
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
g_return_val_if_fail (key != NULL, FALSE);
result = FALSE;
s = g_udev_device_get_property (device, key);
if (s == NULL)
goto out;
if (strcmp (s, "1") == 0 || g_ascii_strcasecmp (s, "true") == 0)
result = TRUE;
out:
return result;
}
static gchar **
split_at_whitespace (const gchar *s)
{
gchar **result;
guint n;
guint m;
result = g_strsplit_set (s, " \v\t\r\n", 0);
/* remove empty strings, thanks GLib */
for (n = 0; result[n] != NULL; n++)
{
if (strlen (result[n]) == 0)
{
g_free (result[n]);
for (m = n; result[m] != NULL; m++)
result[m] = result[m + 1];
n--;
}
}
return result;
}
/**
* g_udev_device_get_property_as_strv:
* @device: A #GUdevDevice.
* @key: Name of property.
*
* Look up the value for @key on @device and return the result of
* splitting it into non-empty tokens split at white space (only space
* (' '), form-feed ('\f'), newline ('\n'), carriage return ('\r'),
* horizontal tab ('\t'), and vertical tab ('\v') are considered; the
* locale is not taken into account).
*
* Returns: (transfer none) (array zero-terminated=1) (element-type utf8): The value of @key on @device split into tokens or %NULL if @key doesn't exist. This array is owned by @device and should not be freed by the caller.
*/
const gchar* const *
g_udev_device_get_property_as_strv (GUdevDevice *device,
const gchar *key)
{
gchar **result;
const gchar *s;
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
g_return_val_if_fail (key != NULL, NULL);
if (device->priv->prop_strvs != NULL)
{
result = g_hash_table_lookup (device->priv->prop_strvs, key);
if (result != NULL)
goto out;
}
result = NULL;
s = g_udev_device_get_property (device, key);
if (s == NULL)
goto out;
result = split_at_whitespace (s);
if (result == NULL)
goto out;
if (device->priv->prop_strvs == NULL)
device->priv->prop_strvs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev);
g_hash_table_insert (device->priv->prop_strvs, g_strdup (key), result);
out:
return (const gchar* const *) result;
}
/* ---------------------------------------------------------------------------------------------------- */
/**
* g_udev_device_get_sysfs_attr:
* @device: A #GUdevDevice.
* @name: Name of the sysfs attribute.
*
* Look up the sysfs attribute with @name on @device.
*
* Returns: The value of the sysfs attribute or %NULL if there is no
* such attribute. Do not free this string, it is owned by @device.
*/
const gchar *
g_udev_device_get_sysfs_attr (GUdevDevice *device,
const gchar *name)
{
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
g_return_val_if_fail (name != NULL, NULL);
return udev_device_get_sysattr_value (device->priv->udevice, name);
}
/**
* g_udev_device_get_sysfs_attr_as_int:
* @device: A #GUdevDevice.
* @name: Name of the sysfs attribute.
*
* Look up the sysfs attribute with @name on @device and convert it to an integer
* using strtol().
*
* Returns: The value of the sysfs attribute or 0 if there is no such
* attribute.
*/
gint
g_udev_device_get_sysfs_attr_as_int (GUdevDevice *device,
const gchar *name)
{
gint result;
const gchar *s;
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
g_return_val_if_fail (name != NULL, 0);
result = 0;
s = g_udev_device_get_sysfs_attr (device, name);
if (s == NULL)
goto out;
result = strtol (s, NULL, 0);
out:
return result;
}
/**
* g_udev_device_get_sysfs_attr_as_uint64:
* @device: A #GUdevDevice.
* @name: Name of the sysfs attribute.
*
* Look up the sysfs attribute with @name on @device and convert it to an unsigned
* 64-bit integer using g_ascii_strtoull().
*
* Returns: The value of the sysfs attribute or 0 if there is no such
* attribute.
*/
guint64
g_udev_device_get_sysfs_attr_as_uint64 (GUdevDevice *device,
const gchar *name)
{
guint64 result;
const gchar *s;
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
g_return_val_if_fail (name != NULL, 0);
result = 0;
s = g_udev_device_get_sysfs_attr (device, name);
if (s == NULL)
goto out;
result = g_ascii_strtoull (s, NULL, 0);
out:
return result;
}
/**
* g_udev_device_get_sysfs_attr_as_double:
* @device: A #GUdevDevice.
* @name: Name of the sysfs attribute.
*
* Look up the sysfs attribute with @name on @device and convert it to a double
* precision floating point number using strtod().
*
* Returns: The value of the sysfs attribute or 0.0 if there is no such
* attribute.
*/
gdouble
g_udev_device_get_sysfs_attr_as_double (GUdevDevice *device,
const gchar *name)
{
gdouble result;
const gchar *s;
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0.0);
g_return_val_if_fail (name != NULL, 0.0);
result = 0.0;
s = g_udev_device_get_sysfs_attr (device, name);
if (s == NULL)
goto out;
result = strtod (s, NULL);
out:
return result;
}
/**
* g_udev_device_get_sysfs_attr_as_boolean:
* @device: A #GUdevDevice.
* @name: Name of the sysfs attribute.
*
* Look up the sysfs attribute with @name on @device and convert it to an
* boolean. This is done by doing a case-insensitive string comparison
* on the string value against "1" and "true".
*
* Returns: The value of the sysfs attribute or %FALSE if there is no such
* attribute.
*/
gboolean
g_udev_device_get_sysfs_attr_as_boolean (GUdevDevice *device,
const gchar *name)
{
gboolean result;
const gchar *s;
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
g_return_val_if_fail (name != NULL, FALSE);
result = FALSE;
s = g_udev_device_get_sysfs_attr (device, name);
if (s == NULL)
goto out;
if (strcmp (s, "1") == 0 || g_ascii_strcasecmp (s, "true") == 0)
result = TRUE;
out:
return result;
}
/**
* g_udev_device_get_sysfs_attr_as_strv:
* @device: A #GUdevDevice.
* @name: Name of the sysfs attribute.
*
* Look up the sysfs attribute with @name on @device and return the result of
* splitting it into non-empty tokens split at white space (only space (' '),
* form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal
* tab ('\t'), and vertical tab ('\v') are considered; the locale is
* not taken into account).
*
* Returns: (transfer none) (array zero-terminated=1) (element-type utf8): The value of the sysfs attribute split into tokens or %NULL if there is no such attribute. This array is owned by @device and should not be freed by the caller.
*/
const gchar * const *
g_udev_device_get_sysfs_attr_as_strv (GUdevDevice *device,
const gchar *name)
{
gchar **result;
const gchar *s;
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
g_return_val_if_fail (name != NULL, NULL);
if (device->priv->sysfs_attr_strvs != NULL)
{
result = g_hash_table_lookup (device->priv->sysfs_attr_strvs, name);
if (result != NULL)
goto out;
}
result = NULL;
s = g_udev_device_get_sysfs_attr (device, name);
if (s == NULL)
goto out;
result = split_at_whitespace (s);
if (result == NULL)
goto out;
if (device->priv->sysfs_attr_strvs == NULL)
device->priv->sysfs_attr_strvs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev);
g_hash_table_insert (device->priv->sysfs_attr_strvs, g_strdup (name), result);
out:
return (const gchar* const *) result;
}
/**
* g_udev_device_get_tags:
* @device: A #GUdevDevice.
*
* Gets all tags for @device.
*
* Returns: (transfer none) (array zero-terminated=1) (element-type utf8): A %NULL terminated string array of tags. This array is owned by @device and should not be freed by the caller.
*
* Since: 165
*/
const gchar* const *
g_udev_device_get_tags (GUdevDevice *device)
{
struct udev_list_entry *l;
GPtrArray *p;
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
if (device->priv->tags != NULL)
goto out;
p = g_ptr_array_new ();
for (l = udev_device_get_tags_list_entry (device->priv->udevice); l != NULL; l = udev_list_entry_get_next (l))
{
g_ptr_array_add (p, g_strdup (udev_list_entry_get_name (l)));
}
g_ptr_array_add (p, NULL);
device->priv->tags = (gchar **) g_ptr_array_free (p, FALSE);
out:
return (const gchar * const *) device->priv->tags;
}
/**
* g_udev_device_get_is_initialized:
* @device: A #GUdevDevice.
*
* Gets whether @device has been initalized.
*
* Returns: Whether @device has been initialized.
*
* Since: 165
*/
gboolean
g_udev_device_get_is_initialized (GUdevDevice *device)
{
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), FALSE);
return udev_device_get_is_initialized (device->priv->udevice);
}
/**
* g_udev_device_get_usec_since_initialized:
* @device: A #GUdevDevice.
*
* Gets number of micro-seconds since @device was initialized.
*
* This only works for devices with properties in the udev
* database. All other devices return 0.
*
* Returns: Number of micro-seconds since @device was initialized or 0 if unknown.
*
* Since: 165
*/
guint64
g_udev_device_get_usec_since_initialized (GUdevDevice *device)
{
g_return_val_if_fail (G_UDEV_IS_DEVICE (device), 0);
return udev_device_get_usec_since_initialized (device->priv->udevice);
}

View File

@ -0,0 +1,128 @@
/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
*
* 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 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.
*/
#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
#endif
#ifndef __G_UDEV_DEVICE_H__
#define __G_UDEV_DEVICE_H__
#include <gudev/gudevtypes.h>
G_BEGIN_DECLS
#define G_UDEV_TYPE_DEVICE (g_udev_device_get_type ())
#define G_UDEV_DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_UDEV_TYPE_DEVICE, GUdevDevice))
#define G_UDEV_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_DEVICE, GUdevDeviceClass))
#define G_UDEV_IS_DEVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_DEVICE))
#define G_UDEV_IS_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_UDEV_TYPE_DEVICE))
#define G_UDEV_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_UDEV_TYPE_DEVICE, GUdevDeviceClass))
typedef struct _GUdevDeviceClass GUdevDeviceClass;
typedef struct _GUdevDevicePrivate GUdevDevicePrivate;
/**
* GUdevDevice:
*
* The #GUdevDevice struct is opaque and should not be accessed directly.
*/
struct _GUdevDevice
{
GObject parent;
/*< private >*/
GUdevDevicePrivate *priv;
};
/**
* GUdevDeviceClass:
* @parent_class: Parent class.
*
* Class structure for #GUdevDevice.
*/
struct _GUdevDeviceClass
{
GObjectClass parent_class;
/*< private >*/
/* Padding for future expansion */
void (*reserved1) (void);
void (*reserved2) (void);
void (*reserved3) (void);
void (*reserved4) (void);
void (*reserved5) (void);
void (*reserved6) (void);
void (*reserved7) (void);
void (*reserved8) (void);
};
GType g_udev_device_get_type (void) G_GNUC_CONST;
gboolean g_udev_device_get_is_initialized (GUdevDevice *device);
guint64 g_udev_device_get_usec_since_initialized (GUdevDevice *device);
const gchar *g_udev_device_get_subsystem (GUdevDevice *device);
const gchar *g_udev_device_get_devtype (GUdevDevice *device);
const gchar *g_udev_device_get_name (GUdevDevice *device);
const gchar *g_udev_device_get_number (GUdevDevice *device);
const gchar *g_udev_device_get_sysfs_path (GUdevDevice *device);
const gchar *g_udev_device_get_driver (GUdevDevice *device);
const gchar *g_udev_device_get_action (GUdevDevice *device);
guint64 g_udev_device_get_seqnum (GUdevDevice *device);
GUdevDeviceType g_udev_device_get_device_type (GUdevDevice *device);
GUdevDeviceNumber g_udev_device_get_device_number (GUdevDevice *device);
const gchar *g_udev_device_get_device_file (GUdevDevice *device);
const gchar* const *g_udev_device_get_device_file_symlinks (GUdevDevice *device);
GUdevDevice *g_udev_device_get_parent (GUdevDevice *device);
GUdevDevice *g_udev_device_get_parent_with_subsystem (GUdevDevice *device,
const gchar *subsystem,
const gchar *devtype);
const gchar* const *g_udev_device_get_property_keys (GUdevDevice *device);
gboolean g_udev_device_has_property (GUdevDevice *device,
const gchar *key);
const gchar *g_udev_device_get_property (GUdevDevice *device,
const gchar *key);
gint g_udev_device_get_property_as_int (GUdevDevice *device,
const gchar *key);
guint64 g_udev_device_get_property_as_uint64 (GUdevDevice *device,
const gchar *key);
gdouble g_udev_device_get_property_as_double (GUdevDevice *device,
const gchar *key);
gboolean g_udev_device_get_property_as_boolean (GUdevDevice *device,
const gchar *key);
const gchar* const *g_udev_device_get_property_as_strv (GUdevDevice *device,
const gchar *key);
const gchar *g_udev_device_get_sysfs_attr (GUdevDevice *device,
const gchar *name);
gint g_udev_device_get_sysfs_attr_as_int (GUdevDevice *device,
const gchar *name);
guint64 g_udev_device_get_sysfs_attr_as_uint64 (GUdevDevice *device,
const gchar *name);
gdouble g_udev_device_get_sysfs_attr_as_double (GUdevDevice *device,
const gchar *name);
gboolean g_udev_device_get_sysfs_attr_as_boolean (GUdevDevice *device,
const gchar *name);
const gchar* const *g_udev_device_get_sysfs_attr_as_strv (GUdevDevice *device,
const gchar *name);
const gchar* const *g_udev_device_get_tags (GUdevDevice *device);
G_END_DECLS
#endif /* __G_UDEV_DEVICE_H__ */

View File

@ -0,0 +1,431 @@
/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2008-2010 David Zeuthen <davidz@redhat.com>
*
* 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 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.
*
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include "gudevclient.h"
#include "gudevenumerator.h"
#include "gudevdevice.h"
#include "gudevmarshal.h"
#include "gudevprivate.h"
/**
* SECTION:gudevenumerator
* @short_description: Lookup and sort devices
*
* #GUdevEnumerator is used to lookup and sort devices.
*
* Since: 165
*/
struct _GUdevEnumeratorPrivate
{
GUdevClient *client;
struct udev_enumerate *e;
};
enum
{
PROP_0,
PROP_CLIENT,
};
G_DEFINE_TYPE (GUdevEnumerator, g_udev_enumerator, G_TYPE_OBJECT)
/* ---------------------------------------------------------------------------------------------------- */
static void
g_udev_enumerator_finalize (GObject *object)
{
GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
if (enumerator->priv->client != NULL)
{
g_object_unref (enumerator->priv->client);
enumerator->priv->client = NULL;
}
if (enumerator->priv->e != NULL)
{
udev_enumerate_unref (enumerator->priv->e);
enumerator->priv->e = NULL;
}
if (G_OBJECT_CLASS (g_udev_enumerator_parent_class)->finalize != NULL)
G_OBJECT_CLASS (g_udev_enumerator_parent_class)->finalize (object);
}
static void
g_udev_enumerator_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
switch (prop_id)
{
case PROP_CLIENT:
if (enumerator->priv->client != NULL)
g_object_unref (enumerator->priv->client);
enumerator->priv->client = g_value_dup_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
g_udev_enumerator_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
switch (prop_id)
{
case PROP_CLIENT:
g_value_set_object (value, enumerator->priv->client);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
g_udev_enumerator_constructed (GObject *object)
{
GUdevEnumerator *enumerator = G_UDEV_ENUMERATOR (object);
g_assert (G_UDEV_IS_CLIENT (enumerator->priv->client));
enumerator->priv->e = udev_enumerate_new (_g_udev_client_get_udev (enumerator->priv->client));
if (G_OBJECT_CLASS (g_udev_enumerator_parent_class)->constructed != NULL)
G_OBJECT_CLASS (g_udev_enumerator_parent_class)->constructed (object);
}
static void
g_udev_enumerator_class_init (GUdevEnumeratorClass *klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
gobject_class->finalize = g_udev_enumerator_finalize;
gobject_class->set_property = g_udev_enumerator_set_property;
gobject_class->get_property = g_udev_enumerator_get_property;
gobject_class->constructed = g_udev_enumerator_constructed;
/**
* GUdevEnumerator:client:
*
* The #GUdevClient to enumerate devices from.
*
* Since: 165
*/
g_object_class_install_property (gobject_class,
PROP_CLIENT,
g_param_spec_object ("client",
"The client to enumerate devices from",
"The client to enumerate devices from",
G_UDEV_TYPE_CLIENT,
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE));
g_type_class_add_private (klass, sizeof (GUdevEnumeratorPrivate));
}
static void
g_udev_enumerator_init (GUdevEnumerator *enumerator)
{
enumerator->priv = G_TYPE_INSTANCE_GET_PRIVATE (enumerator,
G_UDEV_TYPE_ENUMERATOR,
GUdevEnumeratorPrivate);
}
/**
* g_udev_enumerator_new:
* @client: A #GUdevClient to enumerate devices from.
*
* Constructs a #GUdevEnumerator object that can be used to enumerate
* and sort devices. Use the add_match_*() and add_nomatch_*() methods
* and execute the query to get a list of devices with
* g_udev_enumerator_execute().
*
* Returns: A new #GUdevEnumerator object. Free with g_object_unref().
*
* Since: 165
*/
GUdevEnumerator *
g_udev_enumerator_new (GUdevClient *client)
{
g_return_val_if_fail (G_UDEV_IS_CLIENT (client), NULL);
return G_UDEV_ENUMERATOR (g_object_new (G_UDEV_TYPE_ENUMERATOR, "client", client, NULL));
}
/**
* g_udev_enumerator_add_match_subsystem:
* @enumerator: A #GUdevEnumerator.
* @subsystem: Wildcard for subsystem name e.g. 'scsi' or 'a*'.
*
* All returned devices will match the given @subsystem.
*
* Returns: (transfer none): The passed in @enumerator.
*
* Since: 165
*/
GUdevEnumerator *
g_udev_enumerator_add_match_subsystem (GUdevEnumerator *enumerator,
const gchar *subsystem)
{
g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
g_return_val_if_fail (subsystem != NULL, NULL);
udev_enumerate_add_match_subsystem (enumerator->priv->e, subsystem);
return enumerator;
}
/**
* g_udev_enumerator_add_nomatch_subsystem:
* @enumerator: A #GUdevEnumerator.
* @subsystem: Wildcard for subsystem name e.g. 'scsi' or 'a*'.
*
* All returned devices will not match the given @subsystem.
*
* Returns: (transfer none): The passed in @enumerator.
*
* Since: 165
*/
GUdevEnumerator *
g_udev_enumerator_add_nomatch_subsystem (GUdevEnumerator *enumerator,
const gchar *subsystem)
{
g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
g_return_val_if_fail (subsystem != NULL, NULL);
udev_enumerate_add_nomatch_subsystem (enumerator->priv->e, subsystem);
return enumerator;
}
/**
* g_udev_enumerator_add_match_sysfs_attr:
* @enumerator: A #GUdevEnumerator.
* @name: Wildcard filter for sysfs attribute key.
* @value: Wildcard filter for sysfs attribute value.
*
* All returned devices will have a sysfs attribute matching the given @name and @value.
*
* Returns: (transfer none): The passed in @enumerator.
*
* Since: 165
*/
GUdevEnumerator *
g_udev_enumerator_add_match_sysfs_attr (GUdevEnumerator *enumerator,
const gchar *name,
const gchar *value)
{
g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (value != NULL, NULL);
udev_enumerate_add_match_sysattr (enumerator->priv->e, name, value);
return enumerator;
}
/**
* g_udev_enumerator_add_nomatch_sysfs_attr:
* @enumerator: A #GUdevEnumerator.
* @name: Wildcard filter for sysfs attribute key.
* @value: Wildcard filter for sysfs attribute value.
*
* All returned devices will not have a sysfs attribute matching the given @name and @value.
*
* Returns: (transfer none): The passed in @enumerator.
*
* Since: 165
*/
GUdevEnumerator *
g_udev_enumerator_add_nomatch_sysfs_attr (GUdevEnumerator *enumerator,
const gchar *name,
const gchar *value)
{
g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (value != NULL, NULL);
udev_enumerate_add_nomatch_sysattr (enumerator->priv->e, name, value);
return enumerator;
}
/**
* g_udev_enumerator_add_match_property:
* @enumerator: A #GUdevEnumerator.
* @name: Wildcard filter for property name.
* @value: Wildcard filter for property value.
*
* All returned devices will have a property matching the given @name and @value.
*
* Returns: (transfer none): The passed in @enumerator.
*
* Since: 165
*/
GUdevEnumerator *
g_udev_enumerator_add_match_property (GUdevEnumerator *enumerator,
const gchar *name,
const gchar *value)
{
g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (value != NULL, NULL);
udev_enumerate_add_match_property (enumerator->priv->e, name, value);
return enumerator;
}
/**
* g_udev_enumerator_add_match_name:
* @enumerator: A #GUdevEnumerator.
* @name: Wildcard filter for kernel name e.g. "sda*".
*
* All returned devices will match the given @name.
*
* Returns: (transfer none): The passed in @enumerator.
*
* Since: 165
*/
GUdevEnumerator *
g_udev_enumerator_add_match_name (GUdevEnumerator *enumerator,
const gchar *name)
{
g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
g_return_val_if_fail (name != NULL, NULL);
udev_enumerate_add_match_sysname (enumerator->priv->e, name);
return enumerator;
}
/**
* g_udev_enumerator_add_sysfs_path:
* @enumerator: A #GUdevEnumerator.
* @sysfs_path: A sysfs path, e.g. "/sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda"
*
* Add a device to the list of devices, to retrieve it back sorted in dependency order.
*
* Returns: (transfer none): The passed in @enumerator.
*
* Since: 165
*/
GUdevEnumerator *
g_udev_enumerator_add_sysfs_path (GUdevEnumerator *enumerator,
const gchar *sysfs_path)
{
g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
g_return_val_if_fail (sysfs_path != NULL, NULL);
udev_enumerate_add_syspath (enumerator->priv->e, sysfs_path);
return enumerator;
}
/**
* g_udev_enumerator_add_match_tag:
* @enumerator: A #GUdevEnumerator.
* @tag: A udev tag e.g. "udev-acl".
*
* All returned devices will match the given @tag.
*
* Returns: (transfer none): The passed in @enumerator.
*
* Since: 165
*/
GUdevEnumerator *
g_udev_enumerator_add_match_tag (GUdevEnumerator *enumerator,
const gchar *tag)
{
g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
g_return_val_if_fail (tag != NULL, NULL);
udev_enumerate_add_match_tag (enumerator->priv->e, tag);
return enumerator;
}
/**
* g_udev_enumerator_add_match_is_initialized:
* @enumerator: A #GUdevEnumerator.
*
* All returned devices will be initialized.
*
* Returns: (transfer none): The passed in @enumerator.
*
* Since: 165
*/
GUdevEnumerator *
g_udev_enumerator_add_match_is_initialized (GUdevEnumerator *enumerator)
{
g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
udev_enumerate_add_match_is_initialized (enumerator->priv->e);
return enumerator;
}
/**
* g_udev_enumerator_execute:
* @enumerator: A #GUdevEnumerator.
*
* Executes the query in @enumerator.
*
* Returns: (element-type GUdevDevice) (transfer full): A list of #GUdevDevice objects. The caller should free the result by using g_object_unref() on each element in the list and then g_list_free() on the list.
*
* Since: 165
*/
GList *
g_udev_enumerator_execute (GUdevEnumerator *enumerator)
{
GList *ret;
struct udev_list_entry *l, *devices;
g_return_val_if_fail (G_UDEV_IS_ENUMERATOR (enumerator), NULL);
ret = NULL;
/* retrieve the list */
udev_enumerate_scan_devices (enumerator->priv->e);
devices = udev_enumerate_get_list_entry (enumerator->priv->e);
for (l = devices; l != NULL; l = udev_list_entry_get_next (l))
{
struct udev_device *udevice;
GUdevDevice *device;
udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerator->priv->e),
udev_list_entry_get_name (l));
if (udevice == NULL)
continue;
device = _g_udev_device_new (udevice);
udev_device_unref (udevice);
ret = g_list_prepend (ret, device);
}
ret = g_list_reverse (ret);
return ret;
}

View File

@ -0,0 +1,107 @@
/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2008-2010 David Zeuthen <davidz@redhat.com>
*
* 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 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.
*/
#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
#endif
#ifndef __G_UDEV_ENUMERATOR_H__
#define __G_UDEV_ENUMERATOR_H__
#include <gudev/gudevtypes.h>
G_BEGIN_DECLS
#define G_UDEV_TYPE_ENUMERATOR (g_udev_enumerator_get_type ())
#define G_UDEV_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_UDEV_TYPE_ENUMERATOR, GUdevEnumerator))
#define G_UDEV_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_ENUMERATOR, GUdevEnumeratorClass))
#define G_UDEV_IS_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_ENUMERATOR))
#define G_UDEV_IS_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_UDEV_TYPE_ENUMERATOR))
#define G_UDEV_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_UDEV_TYPE_ENUMERATOR, GUdevEnumeratorClass))
typedef struct _GUdevEnumeratorClass GUdevEnumeratorClass;
typedef struct _GUdevEnumeratorPrivate GUdevEnumeratorPrivate;
/**
* GUdevEnumerator:
*
* The #GUdevEnumerator struct is opaque and should not be accessed directly.
*
* Since: 165
*/
struct _GUdevEnumerator
{
GObject parent;
/*< private >*/
GUdevEnumeratorPrivate *priv;
};
/**
* GUdevEnumeratorClass:
* @parent_class: Parent class.
*
* Class structure for #GUdevEnumerator.
*
* Since: 165
*/
struct _GUdevEnumeratorClass
{
GObjectClass parent_class;
/*< private >*/
/* Padding for future expansion */
void (*reserved1) (void);
void (*reserved2) (void);
void (*reserved3) (void);
void (*reserved4) (void);
void (*reserved5) (void);
void (*reserved6) (void);
void (*reserved7) (void);
void (*reserved8) (void);
};
GType g_udev_enumerator_get_type (void) G_GNUC_CONST;
GUdevEnumerator *g_udev_enumerator_new (GUdevClient *client);
GUdevEnumerator *g_udev_enumerator_add_match_subsystem (GUdevEnumerator *enumerator,
const gchar *subsystem);
GUdevEnumerator *g_udev_enumerator_add_nomatch_subsystem (GUdevEnumerator *enumerator,
const gchar *subsystem);
GUdevEnumerator *g_udev_enumerator_add_match_sysfs_attr (GUdevEnumerator *enumerator,
const gchar *name,
const gchar *value);
GUdevEnumerator *g_udev_enumerator_add_nomatch_sysfs_attr (GUdevEnumerator *enumerator,
const gchar *name,
const gchar *value);
GUdevEnumerator *g_udev_enumerator_add_match_property (GUdevEnumerator *enumerator,
const gchar *name,
const gchar *value);
GUdevEnumerator *g_udev_enumerator_add_match_name (GUdevEnumerator *enumerator,
const gchar *name);
GUdevEnumerator *g_udev_enumerator_add_match_tag (GUdevEnumerator *enumerator,
const gchar *tag);
GUdevEnumerator *g_udev_enumerator_add_match_is_initialized (GUdevEnumerator *enumerator);
GUdevEnumerator *g_udev_enumerator_add_sysfs_path (GUdevEnumerator *enumerator,
const gchar *sysfs_path);
GList *g_udev_enumerator_execute (GUdevEnumerator *enumerator);
G_END_DECLS
#endif /* __G_UDEV_ENUMERATOR_H__ */

View File

@ -0,0 +1,49 @@
/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
*
* 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 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.
*/
#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
#endif
#ifndef __G_UDEV_ENUMS_H__
#define __G_UDEV_ENUMS_H__
#include <glib-object.h>
G_BEGIN_DECLS
/**
* GUdevDeviceType:
* @G_UDEV_DEVICE_TYPE_NONE: Device does not have a device file.
* @G_UDEV_DEVICE_TYPE_BLOCK: Device is a block device.
* @G_UDEV_DEVICE_TYPE_CHAR: Device is a character device.
*
* Enumeration used to specify a the type of a device.
*/
typedef enum
{
G_UDEV_DEVICE_TYPE_NONE = 0,
G_UDEV_DEVICE_TYPE_BLOCK = 'b',
G_UDEV_DEVICE_TYPE_CHAR = 'c',
} GUdevDeviceType;
G_END_DECLS
#endif /* __G_UDEV_ENUMS_H__ */

View File

@ -0,0 +1,39 @@
/*** BEGIN file-header ***/
#include <gudev.h>
/*** END file-header ***/
/*** BEGIN file-production ***/
/* enumerations from "@filename@" */
/*** END file-production ***/
/*** BEGIN value-header ***/
GType
@enum_name@_get_type (void)
{
static volatile gsize g_define_type_id__volatile = 0;
if (g_once_init_enter (&g_define_type_id__volatile))
{
static const G@Type@Value values[] = {
/*** END value-header ***/
/*** BEGIN value-production ***/
{ @VALUENAME@, "@VALUENAME@", "@valuenick@" },
/*** END value-production ***/
/*** BEGIN value-tail ***/
{ 0, NULL, NULL }
};
GType g_define_type_id =
g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
}
return g_define_type_id__volatile;
}
/*** END value-tail ***/
/*** BEGIN file-tail ***/
/*** END file-tail ***/

View File

@ -0,0 +1,24 @@
/*** BEGIN file-header ***/
#ifndef __GUDEV_ENUM_TYPES_H__
#define __GUDEV_ENUM_TYPES_H__
#include <glib-object.h>
G_BEGIN_DECLS
/*** END file-header ***/
/*** BEGIN file-production ***/
/* enumerations from "@filename@" */
/*** END file-production ***/
/*** BEGIN value-header ***/
GType @enum_name@_get_type (void) G_GNUC_CONST;
#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
/*** END value-header ***/
/*** BEGIN file-tail ***/
G_END_DECLS
#endif /* __GUDEV_ENUM_TYPES_H__ */
/*** END file-tail ***/

View File

@ -0,0 +1 @@
VOID:STRING,OBJECT

View File

@ -0,0 +1,41 @@
/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
*
* 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 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.
*/
#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
#endif
#ifndef __G_UDEV_PRIVATE_H__
#define __G_UDEV_PRIVATE_H__
#include <gudev/gudevtypes.h>
#include <libudev.h>
G_BEGIN_DECLS
GUdevDevice *
_g_udev_device_new (struct udev_device *udevice);
struct udev *_g_udev_client_get_udev (GUdevClient *client);
G_END_DECLS
#endif /* __G_UDEV_PRIVATE_H__ */

View File

@ -0,0 +1,51 @@
/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
*
* 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 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.
*/
#if !defined (_GUDEV_COMPILATION) && !defined(_GUDEV_INSIDE_GUDEV_H)
#error "Only <gudev/gudev.h> can be included directly, this file may disappear or change contents."
#endif
#ifndef __G_UDEV_TYPES_H__
#define __G_UDEV_TYPES_H__
#include <gudev/gudevenums.h>
#include <sys/types.h>
G_BEGIN_DECLS
typedef struct _GUdevClient GUdevClient;
typedef struct _GUdevDevice GUdevDevice;
typedef struct _GUdevEnumerator GUdevEnumerator;
/**
* GUdevDeviceNumber:
*
* Corresponds to the standard #dev_t type as defined by POSIX (Until
* bug 584517 is resolved this work-around is needed).
*/
#ifdef _GUDEV_WORK_AROUND_DEV_T_BUG
typedef guint64 GUdevDeviceNumber; /* __UQUAD_TYPE */
#else
typedef dev_t GUdevDeviceNumber;
#endif
G_END_DECLS
#endif /* __G_UDEV_TYPES_H__ */

View File

@ -0,0 +1,38 @@
#!/usr/bin/env seed
const GLib = imports.gi.GLib;
const GUdev = imports.gi.GUdev;
function print_device(device) {
print(" initialized: " + device.get_is_initialized());
print(" usec since initialized: " + device.get_usec_since_initialized());
print(" subsystem: " + device.get_subsystem());
print(" devtype: " + device.get_devtype());
print(" name: " + device.get_name());
print(" number: " + device.get_number());
print(" sysfs_path: " + device.get_sysfs_path());
print(" driver: " + device.get_driver());
print(" action: " + device.get_action());
print(" seqnum: " + device.get_seqnum());
print(" device type: " + device.get_device_type());
print(" device number: " + device.get_device_number());
print(" device file: " + device.get_device_file());
print(" device file symlinks: " + device.get_device_file_symlinks());
print(" tags: " + device.get_tags());
var keys = device.get_property_keys();
for (var n = 0; n < keys.length; n++) {
print(" " + keys[n] + "=" + device.get_property(keys[n]));
}
}
var client = new GUdev.Client({subsystems: []});
var enumerator = new GUdev.Enumerator({client: client});
enumerator.add_match_subsystem('b*')
var devices = enumerator.execute();
for (var n=0; n < devices.length; n++) {
var device = devices[n];
print_device(device);
print("");
}

View File

@ -0,0 +1,72 @@
#!/usr/bin/env seed
// seed example
const GLib = imports.gi.GLib;
const GUdev = imports.gi.GUdev;
function print_device (device) {
print (" subsystem: " + device.get_subsystem ());
print (" devtype: " + device.get_devtype ());
print (" name: " + device.get_name ());
print (" number: " + device.get_number ());
print (" sysfs_path: " + device.get_sysfs_path ());
print (" driver: " + device.get_driver ());
print (" action: " + device.get_action ());
print (" seqnum: " + device.get_seqnum ());
print (" device type: " + device.get_device_type ());
print (" device number: " + device.get_device_number ());
print (" device file: " + device.get_device_file ());
print (" device file symlinks: " + device.get_device_file_symlinks ());
print (" foo: " + device.get_sysfs_attr_as_strv ("stat"));
var keys = device.get_property_keys ();
for (var n = 0; n < keys.length; n++) {
print (" " + keys[n] + "=" + device.get_property (keys[n]));
}
}
function on_uevent (client, action, device) {
print ("action " + action + " on device " + device.get_sysfs_path());
print_device (device);
print ("");
}
var client = new GUdev.Client ({subsystems: ["block", "usb/usb_interface"]});
client.signal.connect ("uevent", on_uevent);
var block_devices = client.query_by_subsystem ("block");
for (var n = 0; n < block_devices.length; n++) {
print ("block device: " + block_devices[n].get_device_file ());
}
var d;
d = client.query_by_device_number (GUdev.DeviceType.BLOCK, 0x0810);
if (d == null) {
print ("query_by_device_number 0x810 -> null");
} else {
print ("query_by_device_number 0x810 -> " + d.get_device_file ());
dd = d.get_parent_with_subsystem ("usb", null);
print_device (dd);
print ("--------------------------------------------------------------------------");
while (d != null) {
print_device (d);
print ("");
d = d.get_parent ();
}
}
d = client.query_by_sysfs_path ("/sys/block/sda/sda1");
print ("query_by_sysfs_path (\"/sys/block/sda1\") -> " + d.get_device_file ());
d = client.query_by_subsystem_and_name ("block", "sda2");
print ("query_by_subsystem_and_name (\"block\", \"sda2\") -> " + d.get_device_file ());
d = client.query_by_device_file ("/dev/sda");
print ("query_by_device_file (\"/dev/sda\") -> " + d.get_device_file ());
d = client.query_by_device_file ("/dev/block/8:0");
print ("query_by_device_file (\"/dev/block/8:0\") -> " + d.get_device_file ());
var mainloop = GLib.main_loop_new ();
GLib.main_loop_run (mainloop);

5
src/udev/src/keymap/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
keyboard-force-release.sh
keys-from-name.gperf
keys-from-name.h
keys-to-name.h
keys.txt

View File

@ -0,0 +1,54 @@
# Set model specific atkbd force_release quirk
#
# Several laptops have hotkeys which don't generate release events,
# which can cause problems with software key repeat.
# The atkbd driver has a quirk handler for generating synthetic
# release events, which can be configured via sysfs since 2.6.32.
# Simply add a file with a list of scancodes for your laptop model
# in /usr/lib/udev/keymaps, and add a rule here.
# If the hotkeys also need a keymap assignment you can copy the
# scancodes from the keymap file, otherwise you can run
# /usr/lib/udev/keymap -i /dev/input/eventX
# on a Linux vt to find out.
ACTION=="remove", GOTO="force_release_end"
SUBSYSTEM!="serio", GOTO="force_release_end"
KERNEL!="serio*", GOTO="force_release_end"
DRIVER!="atkbd", GOTO="force_release_end"
ENV{DMI_VENDOR}="$attr{[dmi/id]sys_vendor}"
ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", RUN+="keyboard-force-release.sh $devpath samsung-other"
ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*", RUN+="keyboard-force-release.sh $devpath samsung-90x3a"
ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="Studio 1557|Studio 1558", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
ENV{DMI_VENDOR}=="Dell Inc.", ATTR{[dmi/id]product_name}=="Latitude E*|Precision M*", RUN+="keyboard-force-release.sh $devpath dell-touchpad"
ENV{DMI_VENDOR}=="FUJITSU SIEMENS", ATTR{[dmi/id]product_name}=="AMILO Si 1848+u|AMILO Xi 2428", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
ENV{DMI_VENDOR}=="FOXCONN", ATTR{[dmi/id]product_name}=="QBOOK", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
ENV{DMI_VENDOR}=="MTC", ATTR{[dmi/id]product_version}=="A0", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
ENV{DMI_VENDOR}=="PEGATRON CORP.", ATTR{[dmi/id]product_name}=="Spring Peak", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="Satellite [uU]300*|Satellite Pro [uU]300*|Satellite [uU]305*|SATELLITE [uU]500*", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
ENV{DMI_VENDOR}=="Viooo Corporation", ATTR{[dmi/id]product_name}=="PT17", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
# These are all the HP laptops that setup a touchpad toggle key
ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[pP][aA][vV][iI][lL][iI][oO][nN]*", RUN+="keyboard-force-release.sh $devpath hp-other"
ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[tT][xX]2*", RUN+="keyboard-force-release.sh $devpath hp-other"
ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*2510p*|*2530p*|HP G60 Notebook PC", RUN+="keyboard-force-release.sh $devpath hp-other"
ENV{DMI_VENDOR}=="Zepto", ATTR{[dmi/id]product_name}=="Znote 6615WD", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
ENV{DMI_VENDOR}=="Zepto", ATTR{[dmi/id]product_name}=="Znote", ATTR{[dmi/id]product_version}=="6625WD", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
ENV{DMI_VENDOR}=="HANNspree", ATTR{[dmi/id]product_name}=="SN10E100", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
ENV{DMI_VENDOR}=="GIGABYTE", ATTR{[dmi/id]product_name}=="i1520M", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
ENV{DMI_VENDOR}=="BenQ", ATTR{[dmi/id]product_name}=="*nScreen*", RUN+="keyboard-force-release.sh $devpath common-volume-keys"
LABEL="force_release_end"

View File

@ -0,0 +1,170 @@
# Set model specific hotkey keycodes.
#
# Key map overrides can be specified by either giving scancode/keyname pairs
# directly as keymap arguments (if there are just one or two to change), or as
# a file name (in /usr/lib/udev/keymaps), which has to contain scancode/keyname
# pairs.
ACTION=="remove", GOTO="keyboard_end"
KERNEL!="event*", GOTO="keyboard_end"
ENV{ID_INPUT_KEY}=="", GOTO="keyboard_end"
SUBSYSTEMS=="bluetooth", GOTO="keyboard_end"
SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id"
SUBSYSTEMS=="usb", GOTO="keyboard_usbcheck"
GOTO="keyboard_modulecheck"
#
# The following are external USB keyboards
#
LABEL="keyboard_usbcheck"
ENV{ID_VENDOR}=="Genius", ENV{ID_MODEL_ID}=="0708", ENV{ID_USB_INTERFACE_NUM}=="01", RUN+="keymap $name genius-slimstar-320"
ENV{ID_VENDOR}=="Logitech*", ATTRS{name}=="Logitech USB Multimedia Keyboard", RUN+="keymap $name logitech-wave"
ENV{ID_VENDOR}=="Logitech*", ATTRS{name}=="Logitech USB Receiver", RUN+="keymap $name logitech-wave-cordless"
# Logitech Cordless Wave Pro looks slightly weird; some hotkeys are coming through the mouse interface
ENV{ID_VENDOR_ID}=="046d", ENV{ID_MODEL_ID}=="c52[9b]", ATTRS{name}=="Logitech USB Receiver", RUN+="keymap $name logitech-wave-pro-cordless"
ENV{ID_VENDOR}=="Lite-On_Technology_Corp*", ATTRS{name}=="Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint", RUN+="keymap $name lenovo-thinkpad-usb-keyboard-trackpoint"
ENV{ID_VENDOR_ID}=="04b3", ENV{ID_MODEL_ID}=="301[89]", RUN+="keymap $name ibm-thinkpad-usb-keyboard-trackpoint"
ENV{ID_VENDOR}=="Microsoft", ENV{ID_MODEL_ID}=="00db", RUN+="keymap $name 0xc022d zoomin 0xc022e zoomout"
GOTO="keyboard_end"
#
# The following are exposed as separate input devices with low key codes, thus
# we need to check their input device product name
#
LABEL="keyboard_modulecheck"
ENV{DMI_VENDOR}="$attr{[dmi/id]sys_vendor}"
ENV{DMI_VENDOR}=="", GOTO="keyboard_end"
ENV{DMI_VENDOR}=="LENOVO*", KERNELS=="input*", ATTRS{name}=="ThinkPad Extra Buttons", RUN+="keymap $name module-lenovo"
ENV{DMI_VENDOR}=="LENOVO*", KERNELS=="input*", ATTRS{name}=="Lenovo ThinkPad SL Series extra buttons", RUN+="keymap $name 0x0E bluetooth"
ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Asus Extra Buttons", ATTR{[dmi/id]product_name}=="W3J", RUN+="keymap $name module-asus-w3j"
ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Eee PC WMI hotkeys|Asus Laptop Support|Asus*WMI*", RUN+="keymap $name 0x6B f21"
ENV{DMI_VENDOR}=="ASUS*", KERNELS=="input*", ATTRS{name}=="Eee PC Hotkey Driver", RUN+="keymap $name 0x37 f21"
ENV{DMI_VENDOR}=="IBM*", KERNELS=="input*", ATTRS{name}=="ThinkPad Extra Buttons", RUN+="keymap $name module-ibm"
ENV{DMI_VENDOR}=="Sony*", KERNELS=="input*", ATTRS{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony"
ENV{DMI_VENDOR}=="Acer*", KERNELS=="input*", ATTRS{name}=="Acer WMI hotkeys", RUN+="keymap $name 0x82 f21"
ENV{DMI_VENDOR}=="MICRO-STAR*|Micro-Star*", KERNELS=="input*", ATTRS{name}=="MSI Laptop hotkeys", RUN+="keymap $name 0x213 f22 0x214 f23"
# Older Vaios have some different keys
ENV{DMI_VENDOR}=="Sony*", ATTR{[dmi/id]product_name}=="*PCG-C1*|*PCG-K25*|*PCG-F1*|*PCG-F2*|*PCG-F3*|*PCG-F4*|*PCG-F5*|*PCG-F6*|*PCG-FX*|*PCG-FRV*|*PCG-GR*|*PCG-TR*|*PCG-NV*|*PCG-Z*|*VGN-S360*", ATTRS{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony-old"
# Some Sony VGN models have yet another one
ENV{DMI_VENDOR}=="Sony*", ATTR{[dmi/id]product_name}=="VGN-AR71*|VGN-FW*|VGN-Z21*", ATTRS{name}=="Sony Vaio Keys", RUN+="keymap $name module-sony-vgn"
#
# The following rules belong to standard i8042 AT keyboard with high key codes.
#
DRIVERS=="atkbd", GOTO="keyboard_vendorcheck"
GOTO="keyboard_end"
LABEL="keyboard_vendorcheck"
ENV{DMI_VENDOR}=="Dell*", RUN+="keymap $name dell"
ENV{DMI_VENDOR}=="Dell*", ATTR{[dmi/id]product_name}=="Inspiron 910|Inspiron 1010|Inspiron 1011|Inspiron 1012|Inspiron 1110|Inspiron 1210", RUN+="keymap $name 0x84 wlan"
ENV{DMI_VENDOR}=="Dell*", ATTR{[dmi/id]product_name}=="Latitude XT2", RUN+="keymap $name dell-latitude-xt2"
ENV{DMI_VENDOR}=="Compaq*", ATTR{[dmi/id]product_name}=="*E500*|*Evo N*", RUN+="keymap $name compaq-e_evo"
ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="*3000*", RUN+="keymap $name lenovo-3000"
ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="ThinkPad X6*", ATTR{[dmi/id]product_version}=="* Tablet", RUN+="keymap $name lenovo-thinkpad_x6_tablet"
ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="ThinkPad X2[02]* Tablet*", ATTR{[dmi/id]product_version}=="* Tablet", RUN+="keymap $name lenovo-thinkpad_x200_tablet"
ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_version}=="*IdeaPad*", RUN+="keymap $name lenovo-ideapad"
ENV{DMI_VENDOR}=="LENOVO*", ATTR{[dmi/id]product_name}=="S10-*", RUN+="keymap $name lenovo-ideapad"
ENV{DMI_VENDOR}=="LENOVO", ATTR{[dmi/id]product_version}=="*IdeaPad Y550*", RUN+="keymap $name 0x95 media 0xA3 play"
ENV{DMI_VENDOR}=="Hewlett-Packard*", RUN+="keymap $name hewlett-packard"
ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[tT][aA][bB][lL][eE][tT]*", RUN+="keymap $name hewlett-packard-tablet"
ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[pP][aA][vV][iI][lL][iI][oO][nN]*", RUN+="keymap $name hewlett-packard-pavilion"
ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*Compaq*|*EliteBook*|*2230s*", RUN+="keymap $name hewlett-packard-compaq_elitebook"
ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*2510p*|*2530p*|HP G60 Notebook PC", RUN+="keymap $name hewlett-packard-2510p_2530p"
ENV{DMI_VENDOR}=="Hewlett-Packard*", ATTR{[dmi/id]product_name}=="*[tT][xX]2*", RUN+="keymap $name hewlett-packard-tx2"
ENV{DMI_VENDOR}=="Hewlett-Packard", ATTR{[dmi/id]product_name}=="Presario 2100*", RUN+="keymap $name hewlett-packard-presario-2100"
ENV{DMI_VENDOR}=="Hewlett-Packard", ATTR{[dmi/id]product_name}=="HP G62 Notebook PC", RUN+="keymap $name 0xB2 www"
ENV{DMI_VENDOR}=="Hewlett-Packard", ATTR{[dmi/id]product_name}=="HP ProBook*", RUN+="keymap $name 0xF8 rfkill"
# HP Pavillion dv6315ea has empty DMI_VENDOR
ATTR{[dmi/id]board_vendor}=="Quanta", ATTR{[dmi/id]board_name}=="30B7", ATTR{[dmi/id]board_version}=="65.2B", RUN+="keymap $name 0x88 media" # "quick play
# Gateway clone of Acer Aspire One AOA110/AOA150
ENV{DMI_VENDOR}=="Gateway*", ATTR{[dmi/id]product_name}=="*AOA1*", RUN+="keymap $name acer"
ENV{DMI_VENDOR}=="Acer*", RUN+="keymap $name acer"
ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Extensa*", ATTR{[dmi/id]product_name}=="*5210*|*5220*|*5610*|*5620*|*5720*", RUN+="keymap $name 0xEE screenlock"
ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="TravelMate*C3[01]0*", RUN+="keymap $name acer-travelmate_c300"
ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="TravelMate*6292*|TravelMate*8471*|TravelMate*4720*|TravelMate*7720*|Aspire 1810T*|AO751h|AO531h", RUN+="keymap $name 0xD9 bluetooth"
ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="TravelMate*4720*", RUN+="keymap $name 0xB2 www 0xEE screenlock"
ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="TravelMate 6593|Aspire 1640", RUN+="keymap $name 0xB2 www 0xEE screenlock"
ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Aspire 6920", RUN+="keymap $name acer-aspire_6920"
ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Aspire 5920G", RUN+="keymap $name acer-aspire_5920g"
ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Aspire 5720*", RUN+="keymap $name acer-aspire_5720"
ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_name}=="Aspire 8930", RUN+="keymap $name acer-aspire_8930"
ENV{DMI_VENDOR}=="Acer*", ATTR{[dmi/id]product_serial}=="ZG8*", RUN+="keymap $name acer-aspire_5720"
ENV{DMI_VENDOR}=="*BenQ*", ATTR{[dmi/id]product_name}=="*Joybook R22*", RUN+="keymap $name 0x6E wlan"
ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*AMILO Pro V3205*", RUN+="keymap $name fujitsu-amilo_pro_v3205"
ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*AMILO Pa 2548*", RUN+="keymap $name fujitsu-amilo_pa_2548"
ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*ESPRIMO Mobile V5*", RUN+="keymap $name fujitsu-esprimo_mobile_v5"
ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*ESPRIMO Mobile V6*", RUN+="keymap $name fujitsu-esprimo_mobile_v6"
ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*AMILO Pro Edition V3505*", RUN+="keymap $name fujitsu-amilo_pro_edition_v3505"
ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="*Amilo Si 1520*", RUN+="keymap $name fujitsu-amilo_si_1520"
ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="AMILO*M*", RUN+="keymap $name 0x97 prog2 0x9F prog1"
ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="Amilo Li 1718", RUN+="keymap $name 0xD6 wlan"
ENV{DMI_VENDOR}=="FUJITSU*", ATTR{[dmi/id]product_name}=="AMILO Li 2732", RUN+="keymap $name fujitsu-amilo_li_2732"
ENV{DMI_VENDOR}=="LG*", ATTR{[dmi/id]product_name}=="*X110*", RUN+="keymap $name lg-x110"
ENV{DMI_VENDOR}=="MEDION*", ATTR{[dmi/id]product_name}=="*FID2060*", RUN+="keymap $name medion-fid2060"
ENV{DMI_VENDOR}=="MEDIONNB", ATTR{[dmi/id]product_name}=="A555*", RUN+="keymap $name medionnb-a555"
ENV{DMI_VENDOR}=="MICRO-STAR*|Micro-Star*", RUN+="keymap $name micro-star"
# some MSI models generate ACPI/input events on the LNXVIDEO input devices,
# plus some extra synthesized ones on atkbd as an echo of actually changing the
# brightness; so ignore those atkbd ones, to avoid loops
ENV{DMI_VENDOR}=="MICRO-STAR*", ATTR{[dmi/id]product_name}=="*U-100*|*U100*|*N033", RUN+="keymap $name 0xF7 reserved 0xF8 reserved"
ENV{DMI_VENDOR}=="INVENTEC", ATTR{[dmi/id]product_name}=="SYMPHONY 6.0/7.0", RUN+="keymap $name inventec-symphony_6.0_7.0"
ENV{DMI_VENDOR}=="MAXDATA", ATTR{[dmi/id]product_name}=="Pro 7000*", RUN+="keymap $name maxdata-pro_7000"
ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", RUN+="keymap $name samsung-other"
ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*SX20S*", RUN+="keymap $name samsung-sx20s"
ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="SQ1US", RUN+="keymap $name samsung-sq1us"
ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*700Z*", RUN+="keymap $name 0xBA ejectcd 0x96 keyboardbrightnessup 0x97 keyboardbrightnessdown"
ENV{DMI_VENDOR}=="[sS][aA][mM][sS][uU][nN][gG]*", ATTR{[dmi/id]product_name}=="*90X3A*", RUN+="keymap $name samsung-90x3a"
ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="SATELLITE A100", RUN+="keymap $name toshiba-satellite_a100"
ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="Satellite A110", RUN+="keymap $name toshiba-satellite_a110"
ENV{DMI_VENDOR}=="TOSHIBA", ATTR{[dmi/id]product_name}=="Satellite M30X", RUN+="keymap $name toshiba-satellite_m30x"
ENV{DMI_VENDOR}=="OQO Inc.*", ATTR{[dmi/id]product_name}=="OQO Model 2*", RUN+="keymap $name oqo-model2"
ENV{DMI_VENDOR}=="ONKYO CORPORATION", ATTR{[dmi/id]product_name}=="ONKYOPC", RUN+="keymap $name onkyo"
ENV{DMI_VENDOR}=="ASUS", RUN+="keymap $name asus"
ENV{DMI_VENDOR}=="VIA", ATTR{[dmi/id]product_name}=="K8N800", ATTR{[dmi/id]product_version}=="VT8204B", RUN+="keymap $name 0x81 prog1"
ENV{DMI_VENDOR}=="Zepto", ATTR{[dmi/id]product_name}=="Znote", ATTR{[dmi/id]product_version}=="62*|63*", RUN+="keymap $name zepto-znote"
ENV{DMI_VENDOR}=="Everex", ATTR{[dmi/id]product_name}=="XT5000*", RUN+="keymap $name everex-xt5000"
ENV{DMI_VENDOR}=="COMPAL", ATTR{[dmi/id]product_name}=="HEL80I", RUN+="keymap $name 0x84 wlan"
ENV{DMI_VENDOR}=="OLPC", ATTR{[dmi/id]product_name}=="XO", RUN+="keymap $name olpc-xo"
ENV{DMI_VENDOR}=="Alienware*", ATTR{[dmi/id]product_name}=="M14xR1", RUN+="keymap $name 0x8A ejectcd"
LABEL="keyboard_end"

View File

@ -0,0 +1,101 @@
= The udev keymap tool =
== Introduction ==
This udev extension configures computer model specific key mappings. This is
particularly necessary for the non-standard extra keys found on many laptops,
such as "brightness up", "next song", "www browser", or "suspend". Often these
are accessed with the Fn key.
Every key produces a "scan code", which is highly vendor/model specific for the
nonstandard keys. This tool maintains mappings for these scan codes to standard
"key codes", which denote the "meaning" of the key. The key codes are defined
in /usr/include/linux/input.h.
If some of your keys on your keyboard are not working at all, or produce the
wrong effect, then a very likely cause of this is that the scan code -> key
code mapping is incorrect on your computer.
== Structure ==
udev-keymap consists of the following parts:
keymaps/*:: mappings of scan codes to key code names
95-keymap.rules:: udev rules for mapping system vendor/product names and
input module names to one of the keymaps above
keymap:: manipulate an evdev input device:
* write a key map file into a device (used by udev rules)
* dump current scan → key code mapping
* interactively display scan and key codes of pressed keys
findkeyboards:: display evdev input devices which belong to actual keyboards,
i. e. those suitable for the keymap program
fdi2rules.py:: convert hal keymap FDIs into udev rules and key map files
(Please note that this is far from perfect, since the mapping between fdi and
udev rules is not straightforward, and impossible in some cases.)
== Fixing broken keys ==
In order to make a broken key work on your system and send it back to upstream
for inclusion you need to do the following steps:
1. Find the keyboard device.
Run /usr/lib/udev/findkeyboards. This should always give you an "AT
keyboard" and possibly a "module". Some laptops (notably Thinkpads, Sonys, and
Acers) have multimedia/function keys on a separate input device instead of the
primary keyboard. The keyboard device should have a name like "input/event3".
In the following commands, the name will be written as "input/eventX" (replace
X with the appropriate number).
2. Find broken scan codes:
sudo /usr/lib/udev/keymap -i input/eventX
Press all multimedia/function keys and check if the key name that gets printed
out is plausible. If it is unknown or wrong, write down the scan code (looks
like "0x1E") and the intended functionality of this key. Look in
/usr/include/linux/input.h for an available KEY_XXXXX constant which most
closely approximates this functionality and write it down as the new key code.
For example, you might press a key labeled "web browser" which currently
produces "unknown". Note down this:
0x1E www # Fn+F2 web browser
Repeat that for all other keys. Write the resulting list into a file. Look at
/usr/lib/udev/keymaps/ for existing key map files and make sure that you use the
same structure.
If the key only ever works once and then your keyboard (or the entire desktop)
gets stuck for a long time, then it is likely that the BIOS fails to send a
corresponding "key release" event after the key press event. Please note down
this case as well, as it can be worked around in
/usr/lib/udev/keymaps/95-keyboard-force-release.rules .
3. Find out your system vendor and product:
cat /sys/class/dmi/id/sys_vendor
cat /sys/class/dmi/id/product_name
4. Generate a device dump with "udevadm info --export-db > /tmp/udev-db.txt".
6. Send the system vendor/product names, the key mapping from step 2,
and /tmp/udev-db.txt from step 4 to the linux-hotplug@vger.kernel.org mailing
list, so that they can be included in the next release.
For local testing, copy your map file to /usr/lib/udev/keymaps/ with an appropriate
name, and add an appropriate udev rule to /usr/lib/udev/rules.d/95-keymap.rules:
* If you selected an "AT keyboard", add the rule to the section after
'LABEL="keyboard_vendorcheck"'.
* If you selected a "module", add the rule to the top section where the
"ThinkPad Extra Buttons" are.
== Author ==
keymap is written and maintained by Martin Pitt <martin.pitt@ubuntu.com>.

View File

@ -0,0 +1,38 @@
#!/bin/bash
# check that all key names in keymaps/* are known in <linux/input.h>
# and that all key maps listed in the rules are valid and present in
# Makefile.am
SRCDIR=${1:-.}
KEYLIST=${2:-src/keymap/keys.txt}
KEYMAPS_DIR=$SRCDIR/src/keymap/keymaps
RULES=$SRCDIR/src/keymap/95-keymap.rules
[ -e "$KEYLIST" ] || {
echo "need $KEYLIST please build first" >&2
exit 1
}
missing=$(join -v 2 <(awk '{print tolower(substr($1,5))}' $KEYLIST | sort -u) \
<(grep -hv '^#' ${KEYMAPS_DIR}/*| awk '{print $2}' | sort -u))
[ -z "$missing" ] || {
echo "ERROR: unknown key names in src/keymap/keymaps/*:" >&2
echo "$missing" >&2
exit 1
}
# check that all maps referred to in $RULES exist
maps=$(sed -rn '/keymap \$name/ { s/^.*\$name ([^"[:space:]]+).*$/\1/; p }' $RULES)
for m in $maps; do
# ignore inline mappings
[ "$m" = "${m#0x}" ] || continue
[ -e ${KEYMAPS_DIR}/$m ] || {
echo "ERROR: unknown map name in $RULES: $m" >&2
exit 1
}
grep -q "src/keymap/keymaps/$m\>" $SRCDIR/Makefile.am || {
echo "ERROR: map file $m is not added to Makefile.am" >&2
exit 1
}
done

View File

@ -0,0 +1,68 @@
#!/bin/sh -e
# Find "real" keyboard devices and print their device path.
# Author: Martin Pitt <martin.pitt@ubuntu.com>
#
# Copyright (C) 2009, Canonical Ltd.
#
# 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.
# returns OK if $1 contains $2
strstr() {
[ "${1#*$2*}" != "$1" ]
}
# returns OK if $1 contains $2 at the beginning
str_starts() {
[ "${1#$2*}" != "$1" ]
}
str_line_starts() {
while read a; do str_starts "$a" "$1" && return 0;done
return 1;
}
# print a list of input devices which are keyboard-like
keyboard_devices() {
# standard AT keyboard
for dev in `udevadm trigger --dry-run --verbose --property-match=ID_INPUT_KEYBOARD=1`; do
walk=`udevadm info --attribute-walk --path=$dev`
env=`udevadm info --query=env --path=$dev`
# filter out non-event devices, such as the parent input devices which have no devnode
if ! echo "$env" | str_line_starts 'DEVNAME='; then
continue
fi
if strstr "$walk" 'DRIVERS=="atkbd"'; then
echo -n 'AT keyboard: '
elif echo "$env" | str_line_starts 'ID_USB_DRIVER=usbhid'; then
echo -n 'USB keyboard: '
else
echo -n 'Unknown type: '
fi
udevadm info --query=name --path=$dev
done
# modules
module=$(udevadm trigger --verbose --dry-run --subsystem-match=input --attr-match=name='*Extra Buttons')
module="$module
$(udevadm trigger --verbose --dry-run --subsystem-match=input --attr-match=name='*extra buttons')"
module="$module
$(udevadm trigger --verbose --dry-run --subsystem-match=input --attr-match=name='Sony Vaio Keys')"
for m in $module; do
for evdev in $m/event*/dev; do
if [ -e "$evdev" ]; then
echo -n 'module: '
udevadm info --query=name --path=${evdev%%/dev}
fi
done
done
}
keyboard_devices

View File

@ -0,0 +1,3 @@
0xa0 #mute
0xae #volume down
0xb0 #volume up

View File

@ -0,0 +1 @@
0x9E

View File

@ -0,0 +1,3 @@
# list of scancodes (hex or decimal), optional comment
0xd8 # Touchpad off
0xd9 # Touchpad on

View File

@ -0,0 +1,6 @@
# list of scancodes (hex or decimal), optional comment
0xCE # Fn+F8 keyboard backlit up
0x8D # Fn+F7 keyboard backlit down
0x97 # Fn+F12 wifi on/off
0x96 # Fn+F1 performance mode (?)
0xD5 # Fn+F6 battery life extender

View File

@ -0,0 +1,10 @@
# list of scancodes (hex or decimal), optional comment
0x82 # Fn+F4 CRT/LCD
0x83 # Fn+F2 battery
0x84 # Fn+F5 backlight on/off
0x86 # Fn+F9 WLAN
0x88 # Fn-Up brightness up
0x89 # Fn-Down brightness down
0xB3 # Fn+F8 switch power mode (battery/dynamic/performance)
0xF7 # Fn+F10 Touchpad on
0xF9 # Fn+F10 Touchpad off

View File

@ -0,0 +1,22 @@
#!@rootprefix@/bin/sh -e
# read list of scancodes, convert hex to decimal and
# append to the atkbd force_release sysfs attribute
# $1 sysfs devpath for serioX
# $2 file with scancode list (hex or dec)
case "$2" in
/*) scf="$2" ;;
*) scf="@pkglibexecdir@/keymaps/force-release/$2" ;;
esac
read attr <"/sys/$1/force_release"
while read scancode dummy; do
case "$scancode" in
\#*) ;;
*)
scancode=$(($scancode))
attr="$attr${attr:+,}$scancode"
;;
esac
done <"$scf"
echo "$attr" >"/sys/$1/force_release"

View File

@ -0,0 +1,447 @@
/*
* keymap - dump keymap of an evdev device or set a new keymap from a file
*
* Based on keyfuzz by Lennart Poettering <mzqrovna@0pointer.net>
* Adapted for udev-extras by Martin Pitt <martin.pitt@ubuntu.com>
*
* Copyright (C) 2006, Lennart Poettering
* Copyright (C) 2009, Canonical Ltd.
*
* keymap 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.
*
* keymap 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 keymap; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <ctype.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <fcntl.h>
#include <getopt.h>
#include <sys/ioctl.h>
#include <linux/limits.h>
#include <linux/input.h>
const struct key* lookup_key (const char *str, unsigned int len);
#include "keys-from-name.h"
#include "keys-to-name.h"
#define MAX_SCANCODES 1024
static int evdev_open(const char *dev)
{
int fd;
char fn[PATH_MAX];
if (strncmp(dev, "/dev", 4) != 0) {
snprintf(fn, sizeof(fn), "/dev/%s", dev);
dev = fn;
}
if ((fd = open(dev, O_RDWR)) < 0) {
fprintf(stderr, "error open('%s'): %m\n", dev);
return -1;
}
return fd;
}
static int evdev_get_keycode(int fd, int scancode, int e)
{
int codes[2];
codes[0] = scancode;
if (ioctl(fd, EVIOCGKEYCODE, codes) < 0) {
if (e && errno == EINVAL) {
return -2;
} else {
fprintf(stderr, "EVIOCGKEYCODE: %m\n");
return -1;
}
}
return codes[1];
}
static int evdev_set_keycode(int fd, int scancode, int keycode)
{
int codes[2];
codes[0] = scancode;
codes[1] = keycode;
if (ioctl(fd, EVIOCSKEYCODE, codes) < 0) {
fprintf(stderr, "EVIOCSKEYCODE: %m\n");
return -1;
}
return 0;
}
static int evdev_driver_version(int fd, char *v, size_t l)
{
int version;
if (ioctl(fd, EVIOCGVERSION, &version)) {
fprintf(stderr, "EVIOCGVERSION: %m\n");
return -1;
}
snprintf(v, l, "%i.%i.%i.", version >> 16, (version >> 8) & 0xff, version & 0xff);
return 0;
}
static int evdev_device_name(int fd, char *n, size_t l)
{
if (ioctl(fd, EVIOCGNAME(l), n) < 0) {
fprintf(stderr, "EVIOCGNAME: %m\n");
return -1;
}
return 0;
}
/* Return a lower-case string with KEY_ prefix removed */
static const char* format_keyname(const char* key) {
static char result[101];
const char* s;
int len;
for (s = key+4, len = 0; *s && len < 100; ++len, ++s)
result[len] = tolower(*s);
result[len] = '\0';
return result;
}
static int dump_table(int fd) {
char version[256], name[256];
int scancode, r = -1;
if (evdev_driver_version(fd, version, sizeof(version)) < 0)
goto fail;
if (evdev_device_name(fd, name, sizeof(name)) < 0)
goto fail;
printf("### evdev %s, driver '%s'\n", version, name);
r = 0;
for (scancode = 0; scancode < MAX_SCANCODES; scancode++) {
int keycode;
if ((keycode = evdev_get_keycode(fd, scancode, 1)) < 0) {
if (keycode == -2)
continue;
r = -1;
break;
}
if (keycode < KEY_MAX && key_names[keycode])
printf("0x%03x %s\n", scancode, format_keyname(key_names[keycode]));
else
printf("0x%03x 0x%03x\n", scancode, keycode);
}
fail:
return r;
}
static void set_key(int fd, const char* scancode_str, const char* keyname)
{
unsigned scancode;
char *endptr;
char t[105] = "KEY_UNKNOWN";
const struct key *k;
scancode = (unsigned) strtol(scancode_str, &endptr, 0);
if (*endptr != '\0') {
fprintf(stderr, "ERROR: Invalid scancode\n");
exit(1);
}
snprintf(t, sizeof(t), "KEY_%s", keyname);
if (!(k = lookup_key(t, strlen(t)))) {
fprintf(stderr, "ERROR: Unknown key name '%s'\n", keyname);
exit(1);
}
if (evdev_set_keycode(fd, scancode, k->id) < 0)
fprintf(stderr, "setting scancode 0x%2X to key code %i failed\n",
scancode, k->id);
else
printf("setting scancode 0x%2X to key code %i\n",
scancode, k->id);
}
static int merge_table(int fd, FILE *f) {
int r = 0;
int line = 0;
while (!feof(f)) {
char s[256], *p;
int scancode, new_keycode, old_keycode;
if (!fgets(s, sizeof(s), f))
break;
line++;
p = s+strspn(s, "\t ");
if (*p == '#' || *p == '\n')
continue;
if (sscanf(p, "%i %i", &scancode, &new_keycode) != 2) {
char t[105] = "KEY_UNKNOWN";
const struct key *k;
if (sscanf(p, "%i %100s", &scancode, t+4) != 2) {
fprintf(stderr, "WARNING: Parse failure at line %i, ignoring.\n", line);
r = -1;
continue;
}
if (!(k = lookup_key(t, strlen(t)))) {
fprintf(stderr, "WARNING: Unknown key '%s' at line %i, ignoring.\n", t, line);
r = -1;
continue;
}
new_keycode = k->id;
}
if ((old_keycode = evdev_get_keycode(fd, scancode, 0)) < 0) {
r = -1;
goto fail;
}
if (evdev_set_keycode(fd, scancode, new_keycode) < 0) {
r = -1;
goto fail;
}
if (new_keycode != old_keycode)
fprintf(stderr, "Remapped scancode 0x%02x to 0x%02x (prior: 0x%02x)\n",
scancode, new_keycode, old_keycode);
}
fail:
fclose(f);
return r;
}
/* read one event; return 1 if valid */
static int read_event(int fd, struct input_event* ev)
{
int ret;
ret = read(fd, ev, sizeof(struct input_event));
if (ret < 0) {
perror("read");
return 0;
}
if (ret != sizeof(struct input_event)) {
fprintf(stderr, "did not get enough data for event struct, aborting\n");
return 0;
}
return 1;
}
static void print_key(uint32_t scancode, uint16_t keycode, int has_scan, int has_key)
{
const char *keyname;
/* ignore key release events */
if (has_key == 1)
return;
if (has_key == 0 && has_scan != 0) {
fprintf(stderr, "got scan code event 0x%02X without a key code event\n",
scancode);
return;
}
if (has_scan != 0)
printf("scan code: 0x%02X ", scancode);
else
printf("(no scan code received) ");
keyname = key_names[keycode];
if (keyname != NULL)
printf("key code: %s\n", format_keyname(keyname));
else
printf("key code: %03X\n", keycode);
}
static void interactive(int fd)
{
struct input_event ev;
uint32_t last_scan = 0;
uint16_t last_key = 0;
int has_scan; /* boolean */
int has_key; /* 0: none, 1: release, 2: press */
/* grab input device */
ioctl(fd, EVIOCGRAB, 1);
puts("Press ESC to finish, or Control-C if this device is not your primary keyboard");
has_scan = has_key = 0;
while (read_event(fd, &ev)) {
/* Drivers usually send the scan code first, then the key code,
* then a SYN. Some drivers (like thinkpad_acpi) send the key
* code first, and some drivers might not send SYN events, so
* keep a robust state machine which can deal with any of those
*/
if (ev.type == EV_MSC && ev.code == MSC_SCAN) {
if (has_scan) {
fputs("driver did not send SYN event in between key events; previous event:\n",
stderr);
print_key(last_scan, last_key, has_scan, has_key);
has_key = 0;
}
last_scan = ev.value;
has_scan = 1;
/*printf("--- got scan %u; has scan %i key %i\n", last_scan, has_scan, has_key); */
}
else if (ev.type == EV_KEY) {
if (has_key) {
fputs("driver did not send SYN event in between key events; previous event:\n",
stderr);
print_key(last_scan, last_key, has_scan, has_key);
has_scan = 0;
}
last_key = ev.code;
has_key = 1 + ev.value;
/*printf("--- got key %hu; has scan %i key %i\n", last_key, has_scan, has_key);*/
/* Stop on ESC */
if (ev.code == KEY_ESC && ev.value == 0)
break;
}
else if (ev.type == EV_SYN) {
/*printf("--- got SYN; has scan %i key %i\n", has_scan, has_key);*/
print_key(last_scan, last_key, has_scan, has_key);
has_scan = has_key = 0;
}
}
/* release input device */
ioctl(fd, EVIOCGRAB, 0);
}
static void help(int error)
{
const char* h = "Usage: keymap <event device> [<map file>]\n"
" keymap <event device> scancode keyname [...]\n"
" keymap -i <event device>\n";
if (error) {
fputs(h, stderr);
exit(2);
} else {
fputs(h, stdout);
exit(0);
}
}
int main(int argc, char **argv)
{
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "interactive", no_argument, NULL, 'i' },
{}
};
int fd = -1;
int opt_interactive = 0;
int i;
while (1) {
int option;
option = getopt_long(argc, argv, "hi", options, NULL);
if (option == -1)
break;
switch (option) {
case 'h':
help(0);
case 'i':
opt_interactive = 1;
break;
default:
return 1;
}
}
if (argc < optind+1)
help (1);
if ((fd = evdev_open(argv[optind])) < 0)
return 3;
/* one argument (device): dump or interactive */
if (argc == optind+1) {
if (opt_interactive)
interactive(fd);
else
dump_table(fd);
return 0;
}
/* two arguments (device, mapfile): set map file */
if (argc == optind+2) {
const char *filearg = argv[optind+1];
if (strchr(filearg, '/')) {
/* Keymap file argument is a path */
FILE *f = fopen(filearg, "r");
if (f)
merge_table(fd, f);
else
perror(filearg);
} else {
/* Keymap file argument is a filename */
/* Open override file if present, otherwise default file */
char keymap_path[PATH_MAX];
snprintf(keymap_path, sizeof(keymap_path), "%s%s", SYSCONFDIR "/udev/keymaps/", filearg);
FILE *f = fopen(keymap_path, "r");
if (f) {
merge_table(fd, f);
} else {
snprintf(keymap_path, sizeof(keymap_path), "%s%s", PKGLIBEXECDIR "/keymaps/", filearg);
f = fopen(keymap_path, "r");
if (f)
merge_table(fd, f);
else
perror(keymap_path);
}
}
return 0;
}
/* more arguments (device, scancode/keyname pairs): set keys directly */
if ((argc - optind - 1) % 2 == 0) {
for (i = optind+1; i < argc; i += 2)
set_key(fd, argv[i], argv[i+1]);
return 0;
}
/* invalid number of arguments */
help(1);
return 1; /* not reached */
}

View File

@ -0,0 +1,22 @@
0xA5 help # Fn+F1
0xA6 setup # Fn+F2 Acer eSettings
0xA7 battery # Fn+F3 Power Management
0xA9 switchvideomode # Fn+F5
0xB3 euro
0xB4 dollar
0xCE brightnessup # Fn+Right
0xD4 bluetooth # (toggle) off-to-on
0xD5 wlan # (toggle) on-to-off
0xD6 wlan # (toggle) off-to-on
0xD7 bluetooth # (toggle) on-to-off
0xD8 bluetooth # (toggle) off-to-on
0xD9 brightnessup # Fn+Right
0xEE brightnessup # Fn+Right
0xEF brightnessdown # Fn+Left
0xF1 f22 # Fn+F7 Touchpad toggle (off-to-on)
0xF2 f23 # Fn+F7 Touchpad toggle (on-to-off)
0xF3 prog2 # "P2" programmable button
0xF4 prog1 # "P1" programmable button
0xF5 presentation
0xF8 fn
0xF9 f23 # Launch NTI shadow

View File

@ -0,0 +1,4 @@
0x84 bluetooth # sent when bluetooth module missing, and key pressed
0x92 media # acer arcade
0xD4 bluetooth # bluetooth on
0xD9 bluetooth # bluetooth off

View File

@ -0,0 +1,5 @@
0x8A media
0x92 media
0xA6 setup
0xB2 www
0xD9 bluetooth # (toggle) on-to-off

View File

@ -0,0 +1,5 @@
0xD9 bluetooth # (toggle) on-to-off
0x92 media
0x9E back
0x83 rewind
0x89 fastforward

View File

@ -0,0 +1,5 @@
0xCA prog3 # key 'HOLD' on cine dash media console
0x83 rewind
0x89 fastforward
0x92 media # key 'ARCADE' on cine dash media console
0x9E back

View File

@ -0,0 +1,5 @@
0x67 f24 # FIXME: rotate screen
0x68 up
0x69 down
0x6B fn
0x6C screenlock # FIXME: lock tablet device/buttons

View File

@ -0,0 +1,3 @@
0xED volumeup
0xEE volumedown
0xEF mute

View File

@ -0,0 +1,4 @@
0xA3 www # I key
0x9A search
0x9E email
0x9F homepage

View File

@ -0,0 +1,29 @@
0x81 playpause # Play/Pause
0x82 stopcd # Stop
0x83 previoussong # Previous song
0x84 nextsong # Next song
0x85 brightnessdown # Fn+Down arrow Brightness Down
0x86 brightnessup # Fn+Up arrow Brightness Up
0x87 battery # Fn+F3 battery icon
0x88 unknown # Fn+F2 Turn On/Off Wireless - handled in hardware
0x89 ejectclosecd # Fn+F10 Eject CD
0x8A suspend # Fn+F1 hibernate
0x8B switchvideomode # Fn+F8 CRT/LCD (high keycode: "displaytoggle")
0x8C f23 # Fn+Right arrow Auto Brightness
0x8F switchvideomode # Fn+F7 aspect ratio
0x90 previoussong # Front panel previous song
0x91 prog1 # Wifi Catcher (DELL Specific)
0x92 media # MediaDirect button (house icon)
0x93 f23 # FIXME Fn+Left arrow Auto Brightness
0x95 camera # Shutter button Takes a picture if optional camera available
0x97 email # Tablet email button
0x98 f21 # FIXME: Tablet screen rotatation
0x99 nextsong # Front panel next song
0x9A setup # Tablet tools button
0x9B switchvideomode # Display Toggle button
0x9E f21 #touchpad toggle
0xA2 playpause # Front panel play/pause
0xA4 stopcd # Front panel stop
0xED media # MediaDirect button
0xD8 screenlock # FIXME: Tablet lock button
0xD9 f21 # touchpad toggle

View File

@ -0,0 +1,4 @@
0x9B up # tablet rocker up
0x9E enter # tablet rocker press
0x9F back # tablet back
0xA3 down # tablet rocker down

View File

@ -0,0 +1,7 @@
0x5C media
0x65 f21 # Fn+F5 Touchpad toggle
0x67 prog3 # Fan Speed Control button
0x6F brightnessup
0x7F brightnessdown
0xB2 www
0xEC mail

View File

@ -0,0 +1,3 @@
0xD9 brightnessdown # Fn+F8 brightness down
0xEF brightnessup # Fn+F9 brightness up
0xA9 switchvideomode # Fn+F10 Cycle between available video outputs

View File

@ -0,0 +1,3 @@
0xE0 volumedown
0xE1 volumeup
0xE5 prog1

View File

@ -0,0 +1,4 @@
0xA5 help # Fn-F1
0xA9 switchvideomode # Fn-F3
0xD9 brightnessdown # Fn-F8
0xE0 brightnessup # Fn-F9

View File

@ -0,0 +1,2 @@
0xF4 f21 # FIXME: silent-mode decrease CPU/GPU clock
0xF7 switchvideomode # Fn+F3

View File

@ -0,0 +1,6 @@
0xE1 wlan
0xF3 wlan
0xEE brightnessdown
0xE0 brightnessup
0xE2 bluetooth
0xF7 video

View File

@ -0,0 +1,4 @@
0xA9 switchvideomode
0xD9 brightnessdown
0xDF sleep
0xEF brightnessup

View File

@ -0,0 +1,2 @@
0xCE brightnessup
0xEF brightnessdown

View File

@ -0,0 +1,35 @@
# Genius SlimStar 320
#
# Only buttons which are not properly mapped yet are configured below
# "Scroll wheel", a circular up/down/left/right button. Aimed for scolling,
# but since there are no scrollleft/scrollright, let's map to back/forward.
0x900f0 scrollup
0x900f1 scrolldown
0x900f3 back
0x900f2 forward
# Multimedia buttons, left side (from left to right)
# [W]
0x900f5 wordprocessor
# [Ex]
0x900f6 spreadsheet
# [P]
0x900f4 presentation
# Other five (calculator, playpause, stop, mute and eject) are OK
# Right side, from left to right
# [e]
0xc0223 www
# "man"
0x900f7 chat
# "Y"
0x900fb prog1
# [X]
0x900f8 close
# "picture"
0x900f9 graphicseditor
# "two windows"
0x900fd scale
# "lock"
0x900fc screenlock

View File

@ -0,0 +1,12 @@
0x81 fn_esc
0x89 battery # FnF8
0x8A screenlock # FnF6
0x8B camera
0x8C media # music
0x8E dvd
0xB1 help
0xB3 f23 # FIXME: Auto brightness
0xD7 wlan
0x92 brightnessdown # FnF7 (FnF9 on 6730b)
0x97 brightnessup # FnF8 (FnF10 on 6730b)
0xEE switchvideomode # FnF4

View File

@ -0,0 +1,2 @@
0xD8 f23 # touchpad off
0xD9 f22 # touchpad on

View File

@ -0,0 +1,2 @@
0x88 presentation
0xD9 help # I key (high keycode: "info")

Some files were not shown because too many files have changed in this diff Show More