From: Alexey Morozov <alex-hp@idisys.iae.nsk.su>
To: linux-hotplug@vger.kernel.org
Subject: Several fixes and enhancements for extented naming rules parameters
Date: Fri, 07 Jan 2005 17:07:46 +0000 [thread overview]
Message-ID: <41DEC1E2.3060806@idisys.iae.nsk.su> (raw)
[-- Attachment #1: Type: text/plain, Size: 2903 bytes --]
Hello!
Playing with udev naming rules, I notices that existing '%e' macro can't
be really used in several cases (important at least for me). This
'extended' macro is quite useful if e.g. we try to build nice
"human-friendly" device naming scheme and strictly separate devices
names and permissions assignment (to rules.d/* and permissions.d/*
respectively)
First of all, if one tries to give several names to a device (say,
create additional symlinks for a CD-RW device like /dev/cdrom,
/dev/cdwriter) udev ends up w/ errors.
Also I really doubt if %e w/ existing rules processing code can be used
in constructions like /dev/discs/disc%e/disc and other devfs-like naming
schemes.
So I decided to patch it a bit to achieve such functionality. You can
find this patch in the attachment.
Also I'd like to have another macro. While %e is substituted w/ nothing for
'mydevice%e' if /dev/mydevice doesn't exist yet, this new macro always
substituted w/ a non-negative number. I called it %N, but in fact these
names can be changed in future. This is particularly useful for names
like /dev/discs/disc%N/{.....} and allows to simplify devfs-like naming
scripts.
And the last macro I have invented so far ;-) (don't be scared, I'm
almost satisfied ;-)), is also about unique file names. I'd like to
create entries like /dev/cdrom (i.e. only for a first CD-ROM in the
system) w/o extra script work, just because udev anyway has all required
info in its database. So this macro (which I called %U) just does a
small subset of what %e does.
I should note, that all these three macros should be used only once per
name token (currently, constructions like discs/disc%N/part%N are
prohibited, I doubt this is a real limitation anyway), but the could be
freely used in constructions like the following: SYMLINK="cdroms/cdrom%N
cdroms/cdwriter%N cdrom/cdrom%U".
Also I made a patch for (optional) compilation of udev w/ a system-wide
installed sysfs libraries. I'm not sure it's a good idea 'for everyone'
but if we anyway have libsysfs and it's fresh enough to seamlessly work
w/ udev, I don't see any reasons to have a separate copy right in udev
source tree. Probably I make a mistake, but it worked /for me/ so far,
and hey, it's optional anyway.
Hopefully, I'm not just another another wheel re-inventer, and if so,
please tell me that, I'll try to be more cautious next time ;-).
In the attachments you'll find described patches (for the udev-0.50),
sample rules file and scripts, mentioned in rules files. Patches should
be applied in next order:
%patch -p1 -b .system_sysfs (optional)
%patch1 -p1 -b .efmt_fixes
%patch2 -p1 -b .Nfmt
%patch3 -p1 -b .Ufmt
%patch4 -p1 -b .compile_warnings (probably, also optional)
These patches probably could peacefully co-exist w/ recent Mandrake's
patches for udev.
Thank you for your attention.
Sincerely yours,
Alexey Morozov.
[-- Attachment #2: cd-names.conf --]
[-- Type: text/plain, Size: 1692 bytes --]
# -*- mode: shell-script; coding: utf-8 -*-
# Configuration options for cd-names.sh
#
# DRIVETYPE_PRIO (= <string>)
# Allows to change order in which capabilities will be examined (and
# thus reported). This can lead to naming schemes with different
# primary names. Possible capabilities names are: CD, DVD, CDRW and
# DVDRW. CDROMs are always assumed as being capable to handle CD
# (obvious :-))
# If value isn't set "DVDRW CDRW DVD" is used by default.
DRIVETYPE_PRIO="DVDRW CDRW DVD"
# DO_ALL_LINKS (= 0/1)
# Report all possible names for a given device, not only one for most
# priority capability supported by the device. This can lean to e.g.
# DVD-RW drive to get '/dev/cdroms/dvdwriter0' as its name and
# '/dev/cdroms/dvd0', '/dev/cdroms/cdwriter0' and '/dev/cdroms/cdrom0'
# as symlinks to '/dev/cdroms/dvdwriter0'
# Default is to report all names
#DO_ALL_LINKS=0
# DO_ROOT_LINKS (= 0/1)
# Additionally to all entries in '/dev/cdroms/' folder, make symbolic
# links to a given device right from '/dev/'. This allows to have
# links like '/dev/cdrom' -> '/dev/cdroms/cdrom0' etc
# Default is to do root links
#DO_ROOT_LINKS=0
# PRIMARY_SUFFIX (= <udev device pattern>)
# This suffix will be appended to all device names from '/dev/cdroms/'
# folder. See 'man 8 udev' for more info.
# Default value is '%N' (NOTE: '%N' requires additional patch to
# udev as of version 046!)
#PRIMARY_SUFFIX="%e"
# SECONDARY_SUFFIX (= <udev device pattern>)
# This suffix will be appended to all device names from '/dev/' if
# such entries are to be created (see DO_ROOT_LINKS)
# Default value is '%V" (NOTE: '%U' requires additional patch to
# udev as of version 046!)
#SECONDARY_SUFFIX="%e"
[-- Attachment #3: cd-names.sh --]
[-- Type: application/x-shellscript, Size: 5678 bytes --]
[-- Attachment #4: drive-names.sh --]
[-- Type: application/x-shellscript, Size: 3247 bytes --]
[-- Attachment #5: udev-0.46-alt-Nfmt.patch --]
[-- Type: text/x-patch, Size: 3494 bytes --]
diff -urN udev-046.orig/namedev.c udev-046/namedev.c
--- udev-046.orig/namedev.c 2004-12-28 02:44:57 +0600
+++ udev-046/namedev.c 2004-12-28 02:48:45 +0600
@@ -178,19 +178,13 @@
return -1;
}
-/** Finds the lowest positive N such that <name>N isn't present in
- * $(udevroot) either as a file or a symlink.
- *
- * @param name Name to check for
- * @return 0 if <name> didn't exist and N otherwise.
+/** Internal function used by find_free_number and
+ * find_free_number_zerobase
*/
-static int find_free_number(struct udevice *udev, const char *name, const char *tail)
+static int find_free_number_internal(struct udevice *udev, const char *name, const char* tail, char *filename, int maxsize)
{
- char filename[NAME_SIZE];
int num = 0;
struct udevice db_udev;
-
- snprintf(filename, NAME_SIZE, "%s%s", name, tail);
while (1) {
dbg("look for existing node '%s'", filename);
memset(&db_udev, 0x00, sizeof(struct udevice));
@@ -204,11 +198,36 @@
info("find_free_number gone crazy (num=%d), aborted", num);
return -1;
}
- snprintf(filename, NAME_SIZE, "%s%d%s", name, num, tail);
- filename[NAME_SIZE-1] = '\0';
+ snprintf(filename, maxsize, "%s%d%s", name, num, tail);
}
}
+/** Finds the lowest positive N such that <name>N isn't present in
+ * $(udevroot) either as a file or a symlink.
+ *
+ * @param name Name to check for
+ * @return 0 if <name> didn't exist and N otherwise.
+ */
+static int find_free_number(struct udevice *udev, const char *name, const char *tail)
+{
+ char filename[NAME_SIZE];
+ snprintf(filename, NAME_SIZE, "%s%s", name, tail);
+ return find_free_number_internal(udev, name, tail, filename, NAME_SIZE);
+}
+
+/** Finds the lowest non-negative N such that <name>N isn't present in
+ * $(udevroot) either as a file or a symlink.
+ *
+ * @param name Name to check for
+ * @return 0 if <name> didn't exist and N otherwise.
+ */
+static int find_free_number_zerobase(struct udevice *udev, const char *name, const char *tail)
+{
+ char filename[NAME_SIZE];
+ snprintf(filename, NAME_SIZE, "%s%d%s", name, 0, tail);
+ return find_free_number_internal(udev, name, tail, filename, NAME_SIZE);
+}
+
static void apply_format(struct udevice *udev, char *string, size_t maxsize,
struct sysfs_class_device *class_dev,
struct sysfs_device *sysfs_device);
@@ -344,6 +363,18 @@
}
strfieldcatmax(string, tail, maxsize);
return;
+ case 'N':
+ if (!use_ext) {
+ dbg("prohibited usage of attribute %%e");
+ break;
+ }
+ /* prohibite "extended" attributes in tail */
+ apply_format_token(udev, tail, NAME_SIZE, class_dev, sysfs_device, 0);
+ next_free_number = find_free_number_zerobase(udev, string, tail);
+ sprintf(temp2, "%d", next_free_number);
+ strfieldcatmax(string, temp2, maxsize);
+ strfieldcatmax(string, tail, maxsize);
+ return;
default:
dbg("unknown substitution type '%%%c'", c);
break;
diff -urN udev-046.orig/udev.8.in udev-046/udev.8.in
--- udev-046.orig/udev.8.in 2004-11-19 01:39:15 +0600
+++ udev-046/udev.8.in 2004-12-28 02:49:59 +0600
@@ -285,6 +285,10 @@
can be used to create compatibility symlinks and enumerate devices of
the same type originating from different kernel subsystems.
.TP
+.B %N
+Similar to %e but always substituted by a smallest non-negative number
+giving an unique device node.
+.TP
.B %%
The '%' character itself.
.P
[-- Attachment #6: udev-0.46-alt-Ufmt.patch --]
[-- Type: text/x-patch, Size: 1318 bytes --]
diff -urN udev-046.orig/namedev.c udev-046/namedev.c
--- udev-046.orig/namedev.c 2004-12-28 02:50:52 +0600
+++ udev-046/namedev.c 2004-12-28 02:51:21 +0600
@@ -375,6 +375,22 @@
strfieldcatmax(string, temp2, maxsize);
strfieldcatmax(string, tail, maxsize);
return;
+ case 'U':
+ if (!use_ext) {
+ dbg("prohibited usage of attribute %%e");
+ break;
+ }
+ /* prohibite "extended" attributes in tail */
+ apply_format_token(udev, tail, NAME_SIZE, class_dev, sysfs_device, 0);
+ {
+ struct udevice db_udev;
+ strfieldcatmax(string, tail, maxsize);
+ if (0 == udev_db_get_device_byname(&db_udev, string)) {
+ /* device exists */
+ string[0] = '\0';
+ }
+ }
+ return;
default:
dbg("unknown substitution type '%%%c'", c);
break;
diff -urN udev-046.orig/udev.8.in udev-046/udev.8.in
--- udev-046.orig/udev.8.in 2004-12-28 02:50:52 +0600
+++ udev-046/udev.8.in 2004-12-28 02:52:36 +0600
@@ -289,6 +289,11 @@
similar to %e but always substituted by a smallest non-negative number
giving an unique device node.
.TP
+.B %N
+If a device node already exists with the name, the entire name is skipped.
+This allows to create, say, /dev/cdrom (usually a link) but not /dev/cdrom1
+and only if /dev/cdrom doesn't exist before
+.TP
.B %%
The '%' character itself.
.P
[-- Attachment #7: udev-0.46-alt-compile_warnings.patch --]
[-- Type: text/x-patch, Size: 307 bytes --]
diff -urN udev-046.orig/udev_db.c udev-046/udev_db.c
--- udev-046.orig/udev_db.c 2004-12-09 22:10:53 +0600
+++ udev-046/udev_db.c 2004-12-09 22:12:28 +0600
@@ -30,6 +30,7 @@
#include <string.h>
#include <errno.h>
#include <dirent.h>
+#include <unistd.h>
#include <sysfs/libsysfs.h>
#include "udev.h"
[-- Attachment #8: udev-0.50-alt-system_sysfs.patch --]
[-- Type: text/x-patch, Size: 26971 bytes --]
diff -urN udev-050.orig/extras/scsi_id/Makefile udev-050/extras/scsi_id/Makefile
--- udev-050.orig/extras/scsi_id/Makefile 2004-12-18 11:53:07 +0600
+++ udev-050/extras/scsi_id/Makefile 2005-01-02 22:15:19 +0600
@@ -31,6 +31,11 @@
override CFLAGS+=-Wall -fno-builtin
PROG=scsi_id
+
+ifeq ($(strip $(SYS_SYSFS)),)
+CPPFLAGS = -I../../libsysfs
+endif
+
SYSFS=-lsysfs
#
@@ -53,7 +58,7 @@
echo $(INSTALL_DATA) -D ./scsi_id.config $(DESTDIR)$(etcdir); \
$(INSTALL_DATA) -D ./scsi_id.config $(DESTDIR)$(etcdir)/scsi_id.config; \
fi
-
+
uninstall:
-rm $(DESTDIR)$(sbindir)/$(PROG)
-rm $(DESTDIR)$(mandir)/man8/scsi_id.8
@@ -73,7 +78,7 @@
spotless: clean
.c.o:
- $(QUIET) $(CC) $(CFLAGS) -c -o $@ $<
+ $(QUIET) $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
$(PROG): $(OBJS)
$(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS)
diff -urN udev-050.orig/extras/volume_id/Makefile udev-050/extras/volume_id/Makefile
--- udev-050.orig/extras/volume_id/Makefile 2004-12-18 11:53:07 +0600
+++ udev-050/extras/volume_id/Makefile 2005-01-02 22:13:39 +0600
@@ -28,14 +28,24 @@
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+ifeq ($(strip $(SYS_SYSFS)),)
+CPPFLAGS = -I../../libsysfs
+endif
+
override CFLAGS+=-Wall -fno-builtin -Wchar-subscripts \
-Wpointer-arith -Wcast-align -Wsign-compare
override CFLAGS+=-D_FILE_OFFSET_BITS=64
-OBJS = volume_id.o udev_volume_id.o dasdlabel.o $(SYSFS)
+OBJS = volume_id.o udev_volume_id.o dasdlabel.o
HEADERS = volume_id.h dasdlabel.h
+ifeq ($(strip $(SYS_SYSFS)),)
+OBJS += $(SYSFS)
+else
+LDFLAGS += $(SYS_SYSFS)
+endif
+
$(OBJS): $(HEADERS)
.c.o:
diff -urN udev-050.orig/extras/volume_id/udev_volume_id.c udev-050/extras/volume_id/udev_volume_id.c
--- udev-050.orig/extras/volume_id/udev_volume_id.c 2004-12-18 11:53:07 +0600
+++ udev-050/extras/volume_id/udev_volume_id.c 2005-01-02 20:09:11 +0600
@@ -28,7 +28,7 @@
#include <ctype.h>
#include <sys/ioctl.h>
-#include "../../libsysfs/sysfs/libsysfs.h"
+#include <sysfs/libsysfs.h>
#include "../../udev_utils.h"
#include "../../logging.h"
#include "volume_id.h"
diff -urN udev-050.orig/libsysfs/dlist.c udev-050/libsysfs/dlist.c
--- udev-050.orig/libsysfs/dlist.c 2004-12-18 11:53:07 +0600
+++ udev-050/libsysfs/dlist.c 2005-01-02 20:09:11 +0600
@@ -27,7 +27,7 @@
* delete function. Otherwise dlist will just use free.
*/
-#include "dlist.h"
+#include "sysfs/dlist.h"
/*
* Return pointer to node at marker.
diff -urN udev-050.orig/libsysfs/dlist.h udev-050/libsysfs/dlist.h
--- udev-050.orig/libsysfs/dlist.h 2004-12-18 11:53:07 +0600
+++ udev-050/libsysfs/dlist.h 1970-01-01 07:00:00 +0700
@@ -1,205 +0,0 @@
-/*
- * dlist.h
- *
- * Copyright (C) 2003 Eric J Bohm
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#ifndef _DLIST_H_
-#define _DLIST_H_
-
-/* Double linked list header.
-
-* navigate your list with DLIST_PREV and DLIST_NEXT. These are macros
-* so function call overhead is minimized.
-
-* Supports perl style push, pop, shift, unshift list semantics.
-
-* You allocate the data and give dlist the pointer. If your data is
-* complex set the dlist->del_func to a an appropriate delete using
-* dlist_new_with_delete. Your delete function must match
-(void * )(del(void *)
-*Otherwise dlist will just use free.
-
-* NOTE: The small amount of pain involved in doing that allows us to
-* avoid copy in copy out semantics.
-
-* Dlist uses an internal mark pointer to keep track of where you are
-* in the list.
-
-* insert and delete take a directional parameter. Where direction
-* corresponds to the direction in which you want the list to go.
-* true direction corresponded to progressing forward in the last
-* false to regressing in the list.
-* so a dlist_insert(yourlist,item,1) will insert it after the mark
-* so a dlist_insert(yourlist,item,0) will insert it before the mark
-* any insert will move the mark to the new node regardless of the direction.
-
-* Just use the dlist_(insert|delete)_(before|after) macros if you do not want
-* to think about it.
-
-*/
-#include <malloc.h>
-typedef struct dl_node {
- struct dl_node *prev;
- struct dl_node *next;
- void *data;
-} DL_node;
-
-typedef struct dlist {
- DL_node *marker;
- unsigned long count;
- size_t data_size;
- void (*del_func)(void *);
- DL_node headnode;
- DL_node *head;
-} Dlist;
-
-Dlist *dlist_new(size_t datasize);
-Dlist *dlist_new_with_delete(size_t datasize,void (*del_func)(void*));
-void *_dlist_mark_move(Dlist *list,int direction);
-void *dlist_mark(Dlist *);
-void dlist_start(Dlist *);
-void dlist_end(Dlist *);
-void dlist_move(struct dlist *source, struct dlist *dest, struct dl_node *target,int direction);
-void *dlist_insert(Dlist *,void *,int) ;
-
-void *dlist_insert_sorted(struct dlist *list, void *new_elem, int (*sorter)(void *, void *));
-
-void dlist_delete(Dlist *,int);
-
-void dlist_push(Dlist *,void *);
-
-void dlist_unshift(Dlist *,void *);
-void dlist_unshift_sorted(Dlist *,void *,int (*sorter)(void *, void *));
-
-void *dlist_pop(Dlist *);
-
-void *dlist_shift(Dlist *);
-
-void dlist_destroy(Dlist *);
-
-int _dlist_merge(struct dlist *listsource, struct dlist *listdest, unsigned int passcount, int (*compare)(void *, void *));
-
-void *dlist_find_custom(struct dlist *list, void *target, int (*comp)(void *, void *));
-
-void dlist_sort_custom(struct dlist *list, int (*compare)(void *, void *));
-
-
-void _dlist_swap(struct dlist *list, struct dl_node *a, struct dl_node *b);
-
-void dlist_transform(struct dlist *list, void (*node_operation)(void *));
-
-
-/*
- * _dlist_remove is for internal use only
- * _dlist_mark_move is for internal use only
- */
-void *_dlist_remove(struct dlist *,struct dl_node *,int );
-void *_dlist_insert_dlnode(struct dlist *list,struct dl_node *new_node,int direction);
-
-#define dlist_prev(A) _dlist_mark_move((A),0)
-#define dlist_next(A) _dlist_mark_move((A),1)
-
-#define dlist_insert_before(A,B) dlist_insert((A),(B),0)
-#define dlist_insert_after(A,B) dlist_insert((A),(B),1)
-
-#define dlist_delete_before(A) dlist_delete((A),0)
-#define dlist_delete_after(A) dlist_delete((A),1)
-
-/**
- * provide for loop header which iterates the mark from start to end
- * list: the dlist pointer, use dlist_mark(list) to get iterator
- */
-#define dlist_for_each(list) \
- for(dlist_start(list),dlist_next(list); \
- (list)->marker!=(list)->head;dlist_next(list))
-
-/**
- * provide for loop header which iterates the mark from end to start
- * list: the dlist pointer, use dlist_mark(list) to get iterator
- */
-#define dlist_for_each_rev(list) \
- for(dlist_end(list),dlist_prev(list); \
- (list)->marker!=(list)->head;dlist_prev(list))
-
-/**
- * provide for loop header which iterates through the list without moving mark
- * list: the dlist_pointer
- * iterator: dl_node pointer to iterate
- */
-#define dlist_for_each_nomark(list,iterator) \
- for((iterator)=(list)->head->next; (iterator)!=(list)->head; \
- (iterator)=(iterator)->next)
-
-/**
- * provide for loop header which iterates through the list without moving mark
- * in reverse
- * list: the dlist_pointer
- * iterator: dl_node pointer to iterate
- */
-#define dlist_for_each_nomark_rev(list,iterator) \
- for((iterator)=(list)->head->prev; (iterator)!=(list)->head; \
- (iterator)=(iterator)->prev)
-/**
- * provide for loop header which iterates through the list providing a
- * data iterator
- * list: the dlist pointer
- * data_iterator: the pointer of type datatype to iterate
- * datatype: actual type of the contents in the dl_node->data
- */
-
-#define dlist_for_each_data(list,data_iterator,datatype) \
- for(dlist_start(list), (data_iterator)=(datatype *) dlist_next(list); \
- (list)->marker!=(list)->head;(data_iterator)=(datatype *) dlist_next(list))
-
-/**
- * provide for loop header which iterates through the list providing a
- * data iterator in reverse
- * list: the dlist pointer
- * data_iterator: the pointer of type datatype to iterate
- * datatype: actual type of the contents in the dl_node->data
- */
-#define dlist_for_each_data_rev(list,data_iterator,datatype) \
- for(dlist_end(list), (data_iterator)=(datatype *) dlist_prev(list); \
- (list)->marker!=(list)->head;(data_iterator)=(datatype *) dlist_prev(list))
-
-/**
- * provide for loop header which iterates through the list providing a
- * data iterator without moving the mark
- * list: the dlist pointer
- * iterator: the dl_node pointer to iterate
- * data_iterator: the pointer of type datatype to iterate
- * datatype: actual type of the contents in the dl_node->data
- */
-
-#define dlist_for_each_data_nomark(list,iterator,data_iterator,datatype) \
- for((iterator)=(list)->head->next, (data_iterator)=(datatype *) (iterator)->data; \
- (iterator)!=(list)->head;(iterator)=(iterator)->next,(data_iterator)=(datatype *) (iterator))
-
-/**
- * provide for loop header which iterates through the list providing a
- * data iterator in reverse without moving the mark
- * list: the dlist pointer
- * iterator: the dl_node pointer to iterate
- * data_iterator: the pointer of type datatype to iterate
- * datatype: actual type of the contents in the dl_node->data
- */
-#define dlist_for_each_data_nomark_rev(list,iterator, data_iterator,datatype) \
- for((iterator)=(list)->head->prev, (data_iterator)=(datatype *) (iterator)->data; \
- (iterator)!=(list)->head;(iterator)=(iterator)->prev,(data_iterator)=(datatype *) (iterator))
-
-#endif /* _DLIST_H_ */
diff -urN udev-050.orig/libsysfs/sysfs/dlist.h udev-050/libsysfs/sysfs/dlist.h
--- udev-050.orig/libsysfs/sysfs/dlist.h 1970-01-01 07:00:00 +0700
+++ udev-050/libsysfs/sysfs/dlist.h 2005-01-02 20:09:11 +0600
@@ -0,0 +1,205 @@
+/*
+ * dlist.h
+ *
+ * Copyright (C) 2003 Eric J Bohm
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef _DLIST_H_
+#define _DLIST_H_
+
+/* Double linked list header.
+
+* navigate your list with DLIST_PREV and DLIST_NEXT. These are macros
+* so function call overhead is minimized.
+
+* Supports perl style push, pop, shift, unshift list semantics.
+
+* You allocate the data and give dlist the pointer. If your data is
+* complex set the dlist->del_func to a an appropriate delete using
+* dlist_new_with_delete. Your delete function must match
+(void * )(del(void *)
+*Otherwise dlist will just use free.
+
+* NOTE: The small amount of pain involved in doing that allows us to
+* avoid copy in copy out semantics.
+
+* Dlist uses an internal mark pointer to keep track of where you are
+* in the list.
+
+* insert and delete take a directional parameter. Where direction
+* corresponds to the direction in which you want the list to go.
+* true direction corresponded to progressing forward in the last
+* false to regressing in the list.
+* so a dlist_insert(yourlist,item,1) will insert it after the mark
+* so a dlist_insert(yourlist,item,0) will insert it before the mark
+* any insert will move the mark to the new node regardless of the direction.
+
+* Just use the dlist_(insert|delete)_(before|after) macros if you do not want
+* to think about it.
+
+*/
+#include <malloc.h>
+typedef struct dl_node {
+ struct dl_node *prev;
+ struct dl_node *next;
+ void *data;
+} DL_node;
+
+typedef struct dlist {
+ DL_node *marker;
+ unsigned long count;
+ size_t data_size;
+ void (*del_func)(void *);
+ DL_node headnode;
+ DL_node *head;
+} Dlist;
+
+Dlist *dlist_new(size_t datasize);
+Dlist *dlist_new_with_delete(size_t datasize,void (*del_func)(void*));
+void *_dlist_mark_move(Dlist *list,int direction);
+void *dlist_mark(Dlist *);
+void dlist_start(Dlist *);
+void dlist_end(Dlist *);
+void dlist_move(struct dlist *source, struct dlist *dest, struct dl_node *target,int direction);
+void *dlist_insert(Dlist *,void *,int) ;
+
+void *dlist_insert_sorted(struct dlist *list, void *new_elem, int (*sorter)(void *, void *));
+
+void dlist_delete(Dlist *,int);
+
+void dlist_push(Dlist *,void *);
+
+void dlist_unshift(Dlist *,void *);
+void dlist_unshift_sorted(Dlist *,void *,int (*sorter)(void *, void *));
+
+void *dlist_pop(Dlist *);
+
+void *dlist_shift(Dlist *);
+
+void dlist_destroy(Dlist *);
+
+int _dlist_merge(struct dlist *listsource, struct dlist *listdest, unsigned int passcount, int (*compare)(void *, void *));
+
+void *dlist_find_custom(struct dlist *list, void *target, int (*comp)(void *, void *));
+
+void dlist_sort_custom(struct dlist *list, int (*compare)(void *, void *));
+
+
+void _dlist_swap(struct dlist *list, struct dl_node *a, struct dl_node *b);
+
+void dlist_transform(struct dlist *list, void (*node_operation)(void *));
+
+
+/*
+ * _dlist_remove is for internal use only
+ * _dlist_mark_move is for internal use only
+ */
+void *_dlist_remove(struct dlist *,struct dl_node *,int );
+void *_dlist_insert_dlnode(struct dlist *list,struct dl_node *new_node,int direction);
+
+#define dlist_prev(A) _dlist_mark_move((A),0)
+#define dlist_next(A) _dlist_mark_move((A),1)
+
+#define dlist_insert_before(A,B) dlist_insert((A),(B),0)
+#define dlist_insert_after(A,B) dlist_insert((A),(B),1)
+
+#define dlist_delete_before(A) dlist_delete((A),0)
+#define dlist_delete_after(A) dlist_delete((A),1)
+
+/**
+ * provide for loop header which iterates the mark from start to end
+ * list: the dlist pointer, use dlist_mark(list) to get iterator
+ */
+#define dlist_for_each(list) \
+ for(dlist_start(list),dlist_next(list); \
+ (list)->marker!=(list)->head;dlist_next(list))
+
+/**
+ * provide for loop header which iterates the mark from end to start
+ * list: the dlist pointer, use dlist_mark(list) to get iterator
+ */
+#define dlist_for_each_rev(list) \
+ for(dlist_end(list),dlist_prev(list); \
+ (list)->marker!=(list)->head;dlist_prev(list))
+
+/**
+ * provide for loop header which iterates through the list without moving mark
+ * list: the dlist_pointer
+ * iterator: dl_node pointer to iterate
+ */
+#define dlist_for_each_nomark(list,iterator) \
+ for((iterator)=(list)->head->next; (iterator)!=(list)->head; \
+ (iterator)=(iterator)->next)
+
+/**
+ * provide for loop header which iterates through the list without moving mark
+ * in reverse
+ * list: the dlist_pointer
+ * iterator: dl_node pointer to iterate
+ */
+#define dlist_for_each_nomark_rev(list,iterator) \
+ for((iterator)=(list)->head->prev; (iterator)!=(list)->head; \
+ (iterator)=(iterator)->prev)
+/**
+ * provide for loop header which iterates through the list providing a
+ * data iterator
+ * list: the dlist pointer
+ * data_iterator: the pointer of type datatype to iterate
+ * datatype: actual type of the contents in the dl_node->data
+ */
+
+#define dlist_for_each_data(list,data_iterator,datatype) \
+ for(dlist_start(list), (data_iterator)=(datatype *) dlist_next(list); \
+ (list)->marker!=(list)->head;(data_iterator)=(datatype *) dlist_next(list))
+
+/**
+ * provide for loop header which iterates through the list providing a
+ * data iterator in reverse
+ * list: the dlist pointer
+ * data_iterator: the pointer of type datatype to iterate
+ * datatype: actual type of the contents in the dl_node->data
+ */
+#define dlist_for_each_data_rev(list,data_iterator,datatype) \
+ for(dlist_end(list), (data_iterator)=(datatype *) dlist_prev(list); \
+ (list)->marker!=(list)->head;(data_iterator)=(datatype *) dlist_prev(list))
+
+/**
+ * provide for loop header which iterates through the list providing a
+ * data iterator without moving the mark
+ * list: the dlist pointer
+ * iterator: the dl_node pointer to iterate
+ * data_iterator: the pointer of type datatype to iterate
+ * datatype: actual type of the contents in the dl_node->data
+ */
+
+#define dlist_for_each_data_nomark(list,iterator,data_iterator,datatype) \
+ for((iterator)=(list)->head->next, (data_iterator)=(datatype *) (iterator)->data; \
+ (iterator)!=(list)->head;(iterator)=(iterator)->next,(data_iterator)=(datatype *) (iterator))
+
+/**
+ * provide for loop header which iterates through the list providing a
+ * data iterator in reverse without moving the mark
+ * list: the dlist pointer
+ * iterator: the dl_node pointer to iterate
+ * data_iterator: the pointer of type datatype to iterate
+ * datatype: actual type of the contents in the dl_node->data
+ */
+#define dlist_for_each_data_nomark_rev(list,iterator, data_iterator,datatype) \
+ for((iterator)=(list)->head->prev, (data_iterator)=(datatype *) (iterator)->data; \
+ (iterator)!=(list)->head;(iterator)=(iterator)->prev,(data_iterator)=(datatype *) (iterator))
+
+#endif /* _DLIST_H_ */
diff -urN udev-050.orig/libsysfs/sysfs_bus.c udev-050/libsysfs/sysfs_bus.c
--- udev-050.orig/libsysfs/sysfs_bus.c 2004-12-18 11:53:07 +0600
+++ udev-050/libsysfs/sysfs_bus.c 2005-01-02 20:09:11 +0600
@@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
-#include "libsysfs.h"
+#include "sysfs/libsysfs.h"
#include "sysfs.h"
static void sysfs_close_dev(void *dev)
diff -urN udev-050.orig/libsysfs/sysfs_class.c udev-050/libsysfs/sysfs_class.c
--- udev-050.orig/libsysfs/sysfs_class.c 2004-12-18 11:53:07 +0600
+++ udev-050/libsysfs/sysfs_class.c 2005-01-02 20:09:11 +0600
@@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
-#include "libsysfs.h"
+#include "sysfs/libsysfs.h"
#include "sysfs.h"
static void sysfs_close_cls_dev(void *dev)
diff -urN udev-050.orig/libsysfs/sysfs_device.c udev-050/libsysfs/sysfs_device.c
--- udev-050.orig/libsysfs/sysfs_device.c 2004-12-18 11:53:07 +0600
+++ udev-050/libsysfs/sysfs_device.c 2005-01-02 20:09:11 +0600
@@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
-#include "libsysfs.h"
+#include "sysfs/libsysfs.h"
#include "sysfs.h"
/**
diff -urN udev-050.orig/libsysfs/sysfs_dir.c udev-050/libsysfs/sysfs_dir.c
--- udev-050.orig/libsysfs/sysfs_dir.c 2004-12-18 11:53:07 +0600
+++ udev-050/libsysfs/sysfs_dir.c 2005-01-02 20:09:11 +0600
@@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
-#include "libsysfs.h"
+#include "sysfs/libsysfs.h"
#include "sysfs.h"
/**
diff -urN udev-050.orig/libsysfs/sysfs_driver.c udev-050/libsysfs/sysfs_driver.c
--- udev-050.orig/libsysfs/sysfs_driver.c 2004-12-18 11:53:07 +0600
+++ udev-050/libsysfs/sysfs_driver.c 2005-01-02 20:09:11 +0600
@@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
-#include "libsysfs.h"
+#include "sysfs/libsysfs.h"
#include "sysfs.h"
static void sysfs_close_driver_device(void *device)
diff -urN udev-050.orig/libsysfs/sysfs_utils.c udev-050/libsysfs/sysfs_utils.c
--- udev-050.orig/libsysfs/sysfs_utils.c 2004-12-18 11:53:07 +0600
+++ udev-050/libsysfs/sysfs_utils.c 2005-01-02 20:09:11 +0600
@@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
-#include "libsysfs.h"
+#include "sysfs/libsysfs.h"
#include "sysfs.h"
static int sort_char(void *new, void *old)
diff -urN udev-050.orig/Makefile udev-050/Makefile
--- udev-050.orig/Makefile 2004-12-18 11:53:07 +0600
+++ udev-050/Makefile 2005-01-02 22:12:55 +0600
@@ -92,7 +92,11 @@
RANLIB = $(CROSS)ranlib
HOSTCC = gcc
-export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS ARCH_LIB_OBJS CRT0
+ifeq ($(strip $(SYS_SYSFS)),)
+CPPFLAGS = -I`pwd`/libsysfs
+endif
+
+export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS ARCH_LIB_OBJS CRT0 CPPFLAGS
# code taken from uClibc to determine the current arch
ARCH := ${shell $(CC) -dumpmachine | sed -e s'/-.*//' -e 's/i.86/i386/' -e 's/sparc.*/sparc/' \
@@ -170,9 +174,6 @@
LIB_OBJS += -lselinux
endif
-CFLAGS += -I$(PWD)/libsysfs/sysfs \
- -I$(PWD)/libsysfs
-
# config files automatically generated
GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf
@@ -182,6 +183,7 @@
$(MAKE) prefix=$(prefix) \
LD="$(LD)" \
SYSFS="$(SYSFS)" \
+ SYS_SYSFS=$(SYS_SYSFS) \
KERNEL_DIR="$(KERNEL_DIR)" \
QUIET="$(QUIET)" \
-C $$target $@ ; \
@@ -227,11 +229,13 @@
namedev.o \
namedev_parse.o
-OBJS = \
- libsysfs/sysfs.a \
- udev.a
-
+ifneq ($(strip $(SYS_SYSFS)),)
+LIB_OBJS += $(SYS_SYSFS)
+else
SYSFS = $(PWD)/libsysfs/sysfs.a
+endif
+
+OBJS = udev.a $(SYSFS)
ifeq ($(strip $(USE_KLIBC)),true)
HEADERS += \
@@ -258,7 +262,7 @@
$(QUIET) $(AR) cq $@ $(UDEV_OBJS)
$(QUIET) $(RANLIB) $@
-libsysfs/sysfs.a: $(SYSFS_OBJS)
+$(PWD)/libsysfs/sysfs.a: $(SYSFS_OBJS)
rm -f $@
$(QUIET) $(AR) cq $@ $(SYSFS_OBJS)
$(QUIET) $(RANLIB) $@
@@ -331,7 +335,7 @@
$(QUIET) $(STRIPCMD) $@
.c.o:
- $(QUIET) $(CC) $(CFLAGS) -c -o $@ $<
+ $(QUIET) $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
clean:
@@ -342,7 +346,7 @@
$(MAKE) -C klibc SUBDIRS=klibc clean
@extras="$(EXTRAS)" ; for target in $$extras ; do \
echo $$target ; \
- $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \
+ $(MAKE) prefix=$(prefix) LD="$(LD)" SYS_SYSFS=$(SYS_SYSFS) SYSFS="$(SYSFS)" \
-C $$target $@ ; \
done ; \
@@ -437,7 +441,7 @@
endif
@extras="$(EXTRAS)" ; for target in $$extras ; do \
echo $$target ; \
- $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \
+ $(MAKE) prefix=$(prefix) LD="$(LD)" SYS_SYSFS=$(SYS_SYSFS) SYSFS="$(SYSFS)" \
-C $$target $@ ; \
done ; \
@@ -461,7 +465,7 @@
- killall $(DAEMON)
@extras="$(EXTRAS)" ; for target in $$extras ; do \
echo $$target ; \
- $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \
+ $(MAKE) prefix=$(prefix) LD="$(LD)" SYS_SYSFS=$(SYS_SYSFS) SYSFS="$(SYSFS)" \
-C $$target $@ ; \
done ; \
diff -urN udev-050.orig/namedev.c udev-050/namedev.c
--- udev-050.orig/namedev.c 2004-12-18 11:53:07 +0600
+++ udev-050/namedev.c 2005-01-02 20:09:11 +0600
@@ -32,7 +32,7 @@
#include <sys/wait.h>
#include <sys/stat.h>
-#include "libsysfs/sysfs/libsysfs.h"
+#include <sysfs/libsysfs.h>
#include "list.h"
#include "udev.h"
#include "udev_utils.h"
diff -urN udev-050.orig/udev_add.c udev-050/udev_add.c
--- udev-050.orig/udev_add.c 2004-12-18 11:53:07 +0600
+++ udev-050/udev_add.c 2005-01-02 20:09:11 +0600
@@ -36,7 +36,7 @@
#include <linux/sockios.h>
#include <pwd.h>
-#include "libsysfs/sysfs/libsysfs.h"
+#include <sysfs/libsysfs.h>
#include "udev.h"
#include "udev_utils.h"
#include "udev_version.h"
diff -urN udev-050.orig/udev.c udev-050/udev.c
--- udev-050.orig/udev.c 2004-12-18 11:53:07 +0600
+++ udev-050/udev.c 2005-01-02 20:09:11 +0600
@@ -31,7 +31,7 @@
#include <signal.h>
#include <unistd.h>
-#include "libsysfs/sysfs/libsysfs.h"
+#include <sysfs/libsysfs.h>
#include "udev.h"
#include "udev_utils.h"
#include "udev_sysfs.h"
diff -urN udev-050.orig/udev_config.c udev-050/udev_config.c
--- udev-050.orig/udev_config.c 2004-12-18 11:53:07 +0600
+++ udev-050/udev_config.c 2005-01-02 20:09:11 +0600
@@ -32,7 +32,7 @@
#include <errno.h>
#include <ctype.h>
-#include "libsysfs/sysfs/libsysfs.h"
+#include <sysfs/libsysfs.h>
#include "udev.h"
#include "udev_utils.h"
#include "udev_version.h"
diff -urN udev-050.orig/udev_db.c udev-050/udev_db.c
--- udev-050.orig/udev_db.c 2004-12-18 11:53:07 +0600
+++ udev-050/udev_db.c 2005-01-02 20:09:11 +0600
@@ -31,7 +31,7 @@
#include <errno.h>
#include <dirent.h>
-#include "libsysfs/sysfs/libsysfs.h"
+#include <sysfs/libsysfs.h>
#include "udev.h"
#include "udev_utils.h"
#include "logging.h"
diff -urN udev-050.orig/udev.h udev-050/udev.h
--- udev-050.orig/udev.h 2004-12-18 11:53:07 +0600
+++ udev-050/udev.h 2005-01-02 20:09:11 +0600
@@ -24,7 +24,7 @@
#define _UDEV_H_
#include <sys/param.h>
-#include "libsysfs/sysfs/libsysfs.h"
+#include <sysfs/libsysfs.h>
#define ALARM_TIMEOUT 120
#define COMMENT_CHARACTER '#'
diff -urN udev-050.orig/udevinfo.c udev-050/udevinfo.c
--- udev-050.orig/udevinfo.c 2004-12-18 11:53:07 +0600
+++ udev-050/udevinfo.c 2005-01-02 20:09:11 +0600
@@ -27,8 +27,8 @@
#include <unistd.h>
#include <errno.h>
-#include "libsysfs/sysfs/libsysfs.h"
-#include "libsysfs/dlist.h"
+#include <sysfs/libsysfs.h>
+#include <sysfs/dlist.h>
#include "udev.h"
#include "udev_utils.h"
#include "udev_version.h"
diff -urN udev-050.orig/udev_start.c udev-050/udev_start.c
--- udev-050.orig/udev_start.c 2004-12-18 11:53:07 +0600
+++ udev-050/udev_start.c 2005-01-02 20:09:11 +0600
@@ -33,7 +33,7 @@
#include <sys/types.h>
#include <unistd.h>
-#include "libsysfs/sysfs/libsysfs.h"
+#include <sysfs/libsysfs.h>
#include "logging.h"
#include "udev_utils.h"
#include "list.h"
diff -urN udev-050.orig/udev_sysfs.c udev-050/udev_sysfs.c
--- udev-050.orig/udev_sysfs.c 2004-12-18 11:53:07 +0600
+++ udev-050/udev_sysfs.c 2005-01-02 20:09:11 +0600
@@ -28,7 +28,7 @@
#include <errno.h>
#include <sys/stat.h>
-#include "libsysfs/sysfs/libsysfs.h"
+#include <sysfs/libsysfs.h>
#include "udev_version.h"
#include "udev_sysfs.h"
#include "udev_utils.h"
diff -urN udev-050.orig/udev_sysfs.h udev-050/udev_sysfs.h
--- udev-050.orig/udev_sysfs.h 2004-12-18 11:53:07 +0600
+++ udev-050/udev_sysfs.h 2005-01-02 20:09:11 +0600
@@ -22,7 +22,7 @@
#ifndef _UDEV_SYSFS_H_
#define _UDEV_SYSFS_H_
-#include "libsysfs/sysfs/libsysfs.h"
+#include <sysfs/libsysfs.h>
#define WAIT_MAX_SECONDS 5
#define WAIT_LOOP_PER_SECOND 20
diff -urN udev-050.orig/udevtest.c udev-050/udevtest.c
--- udev-050.orig/udevtest.c 2004-12-18 11:53:07 +0600
+++ udev-050/udevtest.c 2005-01-02 20:09:11 +0600
@@ -27,7 +27,7 @@
#include <ctype.h>
#include <signal.h>
-#include "libsysfs/sysfs/libsysfs.h"
+#include <sysfs/libsysfs.h>
#include "udev.h"
#include "udev_sysfs.h"
#include "udev_utils.h"
[-- Attachment #9: udev-0.46-alt-efmt_fixes.patch --]
[-- Type: text/x-patch, Size: 5002 bytes --]
diff -urN udev-046.orig/namedev.c udev-046/namedev.c
--- udev-046.orig/namedev.c 2004-12-28 02:43:18 +0600
+++ udev-046/namedev.c 2004-12-28 02:43:54 +0600
@@ -184,13 +184,13 @@
* @param name Name to check for
* @return 0 if <name> didn't exist and N otherwise.
*/
-static int find_free_number(struct udevice *udev, const char *name)
+static int find_free_number(struct udevice *udev, const char *name, const char *tail)
{
char filename[NAME_SIZE];
int num = 0;
struct udevice db_udev;
- strfieldcpy(filename, name);
+ snprintf(filename, NAME_SIZE, "%s%s", name, tail);
while (1) {
dbg("look for existing node '%s'", filename);
memset(&db_udev, 0x00, sizeof(struct udevice));
@@ -204,14 +204,18 @@
info("find_free_number gone crazy (num=%d), aborted", num);
return -1;
}
- snprintf(filename, NAME_SIZE, "%s%d", name, num);
+ snprintf(filename, NAME_SIZE, "%s%d%s", name, num, tail);
filename[NAME_SIZE-1] = '\0';
}
}
static void apply_format(struct udevice *udev, char *string, size_t maxsize,
struct sysfs_class_device *class_dev,
- struct sysfs_device *sysfs_device)
+ struct sysfs_device *sysfs_device);
+
+static void apply_format_token(struct udevice *udev, char *string, size_t maxsize,
+ struct sysfs_class_device *class_dev,
+ struct sysfs_device *sysfs_device, int use_ext)
{
char temp[NAME_SIZE];
char temp2[NAME_SIZE];
@@ -291,12 +295,12 @@
strfieldcpy(temp2, spos);
else
strfieldcpymax(temp2, spos, slen+1);
- strfieldcatmax(string, temp2, maxsize);
- dbg("substitute part of result string '%s'", temp2);
} else {
- strfieldcatmax(string, udev->program_result, maxsize);
- dbg("substitute result string '%s'", udev->program_result);
+ strfieldcpy(temp2, udev->program_result);
}
+ apply_format(udev, temp2, NAME_SIZE, class_dev, sysfs_device);
+ strfieldcatmax(string, temp2, maxsize);
+ dbg("substitute part of result string '%s'", temp2);
break;
case 's':
if (attr != NULL) {
@@ -327,12 +331,19 @@
pos++;
break;
case 'e':
- next_free_number = find_free_number(udev, string);
+ if (!use_ext) {
+ dbg("prohibited usage of attribute %%e");
+ break;
+ }
+ /* prohibite "extended" attributes in tail */
+ apply_format_token(udev, tail, NAME_SIZE, class_dev, sysfs_device, 0);
+ next_free_number = find_free_number(udev, string, tail);
if (next_free_number > 0) {
sprintf(temp2, "%d", next_free_number);
strfieldcatmax(string, temp2, maxsize);
}
- break;
+ strfieldcatmax(string, tail, maxsize);
+ return;
default:
dbg("unknown substitution type '%%%c'", c);
break;
@@ -345,6 +356,67 @@
}
}
+#define declare_string_size(strname, strsize) char (strname)[strsize]
+/* A decimal number can't be more then 30 symbols wide */
+#define maxint_digits 30
+static void apply_format(struct udevice *udev, char *string, size_t maxsize,
+ struct sysfs_class_device *class_dev,
+ struct sysfs_device *sysfs_device)
+{
+ int consumed;
+ char *tokenptr;
+ size_t tokenspace;
+ size_t tokenlen;
+ char *stringptr = string;
+ char sscanf_ptrn[5 + maxint_digits];
+ declare_string_size(token, maxsize);
+ snprintf(sscanf_ptrn, 5 + maxint_digits, "%%%ds%%n", maxsize - 1);
+ tokenptr = token;
+ tokenptr[0] = '\0';
+ tokenspace = maxsize;
+ while (0 < sscanf(stringptr, sscanf_ptrn, tokenptr, &consumed)) {
+ /* next token now has been put into 'token'
+ * let's process it...
+ */
+ apply_format_token(udev, tokenptr, tokenspace, class_dev, sysfs_device, 1);
+
+ /* Now we need to add a trailing whitespace to the
+ * processed token and advance to the next string's
+ * token...
+ */
+ stringptr += consumed;
+ tokenlen = strlen(tokenptr);
+ /* hopefully I didn't make a mistake in bound
+ * checks... tokenlen is always less than tokenspace
+ * at least by one. But we need to check if there's a
+ * space for additional whitespace and next token
+ * (i.e. tokenlen must be at least 3 bytes less than
+ * tokenspace). Additionally we should prevent int
+ * overflow errors...
+ */
+ if (tokenspace < 3 || tokenspace - 3 <= tokenlen) {
+ if (*stringptr)
+ dbg("Space exhausted while some trailing data left in format string");
+ break;
+ }
+ strncat(tokenptr + tokenlen, " ", tokenspace - tokenlen - 1);
+ tokenptr += tokenlen + 1;
+ tokenspace -= tokenlen + 1;
+ /* and finally adjust sscanf_ptrn to prevent buffer
+ * overflow in sscanf
+ */
+ snprintf(sscanf_ptrn, 5 + maxint_digits, "%%%ds%%n", tokenspace - 1);
+ }
+ /* remove leading and trailing whitespace. They do matter sometimes */
+ for(tokenptr = token;isspace(*tokenptr);tokenptr++);
+ tokenlen = strlen(tokenptr);
+ if (tokenlen > 0)
+ tokenptr[tokenlen - 1] = '\0';
+ strncpy(string, tokenptr, maxsize);
+}
+#undef declare_string_size
+#undef maxint_digits
+
static void fix_kernel_name(struct udevice *udev)
{
char *temp = udev->kernel_name;
next reply other threads:[~2005-01-07 17:07 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-01-07 17:07 Alexey Morozov [this message]
2005-01-08 5:11 ` Several fixes and enhancements for extented naming rules Kay Sievers
2005-01-08 8:34 ` Several fixes and enhancements for extented naming rules parameters Alexey Morozov
2005-01-08 14:53 ` Several fixes and enhancements for extented naming Kay Sievers
2005-01-10 8:37 ` Several fixes and enhancements for extented naming rules parameters Alexey Morozov
2005-01-10 12:03 ` Several fixes and enhancements for extented naming rules Kay Sievers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=41DEC1E2.3060806@idisys.iae.nsk.su \
--to=alex-hp@idisys.iae.nsk.su \
--cc=linux-hotplug@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).