diff options
author | kay.sievers@vrfy.org <kay.sievers@vrfy.org> | 2004-10-20 13:15:26 +0200 |
---|---|---|
committer | Greg KH <gregkh@suse.de> | 2005-04-26 22:06:44 -0700 |
commit | 993a633ab848487b8e546f66087595e2dc5aa4af (patch) | |
tree | ee1303c8a6b13cbcc9ac97f7a58bcc67d1aee2fd /libsysfs | |
parent | f8c1ccde6aaf08c858616c9a8a83c06d609f52f5 (diff) |
[PATCH] update to libsysfs 1.2.0 and add some stuff klib_fixup
Diffstat (limited to 'libsysfs')
-rw-r--r-- | libsysfs/dlist.c | 267 | ||||
-rw-r--r-- | libsysfs/dlist.h | 12 | ||||
-rw-r--r-- | libsysfs/sysfs.h | 7 | ||||
-rw-r--r-- | libsysfs/sysfs/libsysfs.h | 1 | ||||
-rw-r--r-- | libsysfs/sysfs_bus.c | 2 | ||||
-rw-r--r-- | libsysfs/sysfs_class.c | 2 | ||||
-rw-r--r-- | libsysfs/sysfs_device.c | 6 | ||||
-rw-r--r-- | libsysfs/sysfs_dir.c | 8 | ||||
-rw-r--r-- | libsysfs/sysfs_driver.c | 2 | ||||
-rw-r--r-- | libsysfs/sysfs_utils.c | 20 |
10 files changed, 299 insertions, 28 deletions
diff --git a/libsysfs/dlist.c b/libsysfs/dlist.c index b440d65bed..5f2c00be9b 100644 --- a/libsysfs/dlist.c +++ b/libsysfs/dlist.c @@ -27,7 +27,6 @@ * delete function. Otherwise dlist will just use free. */ -#include <stdlib.h> #include "dlist.h" /* @@ -207,6 +206,46 @@ void *dlist_insert(Dlist *list,void *data,int direction) return(list->marker->data); } +/* internal use only + * Insert dl_node at marker. + * If direction true it inserts after. + * If direction false it inserts before. + * move marker to inserted node + * return pointer to inserted node + */ +void *_dlist_insert_dlnode(struct dlist *list,struct dl_node *new_node,int direction) +{ + if(list==NULL || new_node==NULL) + return(NULL); + if(list->marker==NULL) //in case the marker ends up unset + list->marker=list->head; + list->count++; + if(list->head->next==NULL) + { + list->head->next=list->head->prev=new_node; + new_node->prev=list->head; + new_node->next=list->head; + } + else if(direction) + { + new_node->next=list->marker->next; + new_node->prev=list->marker; + list->marker->next->prev=new_node; + list->marker->next=new_node; + } + else + { + new_node->prev=list->marker->prev; + new_node->next=list->marker; + list->marker->prev->next=new_node; + list->marker->prev=new_node; + } + list->marker=new_node; + return(list->marker); +} + + + /* * Remove DL_node from list without deallocating data. * if marker == killme . @@ -239,6 +278,54 @@ void *_dlist_remove(Dlist *list,DL_node *killme,int direction) return (NULL); } +/* + * move dl_node from source to dest + * if marker == target . + * when direction true it moves marker after + * when direction false it moves marker before. + * to previous if there is no next. + */ +void dlist_move(struct dlist *source, struct dlist *dest, struct dl_node *target,int direction) +{ + + if(target!=NULL) + { + if(target==source->head) + { + //not even going to try + } + else + { + // take care of head and marker pointers. + if(source->marker==target) + _dlist_mark_move(source,direction); + if(target ==source->head->next) + source->head->next=target->next; + if(target==source->head->prev) + source->head->prev=target->prev; + // remove from list + if(source->count==1) + { + target->prev=NULL; + target->next=NULL; + source->head->next=NULL; + source->head->prev=NULL; + } + else + { + if(target->prev !=NULL) + target->prev->next=target->next; + if(target->next !=NULL) + target->next->prev=target->prev; + target->prev=NULL; + target->next=NULL; + } + source->count--; + _dlist_insert_dlnode(dest,target,direction); + } + } +} + /* * Insert node containing data after end. @@ -261,7 +348,7 @@ void dlist_unshift(Dlist *list,void *data) } void dlist_unshift_sorted(Dlist *list, void *data, - int (*sorter)(void *new, void *old)) + int (*sorter)(void *new_elem, void *old_elem)) { if (list->count == 0) dlist_unshift(list, data); @@ -352,3 +439,179 @@ void *dlist_insert_sorted(struct dlist *list, void *new, int (*sorter)(void *, v list->marker!=list->head && !sorter(new,list->marker->data);dlist_next(list)); return(dlist_insert_before(list,new)); } + +/* + * NOTE: internal use only + */ +int _dlist_merge(struct dlist *listsource, struct dlist *listdest, unsigned int passcount, int (*compare)(void *, void *)) +{ + + struct dl_node *l1head; + struct dl_node *l2head; + struct dl_node *target; + unsigned int l1count=0; + unsigned int l2count=0; + unsigned int mergecount=0; + while(listsource->count>0) + { + l1head=listsource->head->next; + l2head=l1head; + while((l1count<passcount)&&(l2head!=listsource->head)) + { + l2head=l2head->next; + l1count++; + } + // so now we have two lists to merge + + if(l2head==listsource->head) + {// l2count + l2count=0; + } + else + { + l2count=passcount; + } + while(l1count>0 || l2count>0) + { + mergecount++; + if((l2count>0)&&(l1count>0)) + { + // we have things to merge + int result=compare(l1head->data,l2head->data); + if(result>0) + { + // move from l2 + target=l2head; + l2head=l2head->next; + dlist_move(listsource,listdest,target,1); + l2count--; + if(l2head==listsource->head) + l2count=0; + } + else + { + // move from l1 + target=l1head; + l1head=l1head->next; + dlist_move(listsource,listdest,target,1); + l1count--; + } + } + else if(l1count>0) + { + // only have l1 to work with + while(l1count>0) + { + target=l1head; + l1head=l1head->next; + dlist_move(listsource,listdest,target,1); + l1count--; + } + } + else if(l2count>0) + { + // only have l2 to work with + while(l2count>0) + { + if(l2head==listsource->head) + { + l2count=0; + } + else + { + target=l2head; + l2head=l2head->next; + dlist_move(listsource,listdest,target,1); + l2count--; + } + } + } + else + { //nothing left and this should be unreachable + } + } + } + return(mergecount); +} + +/** + * mergesort the list based on compare + * compare function in form int sorter(void * a,void * b) + * must return >0 for a after b + * must return <0 for a before b + * else 0 + + * NOTE: mergesort changes the mark pointer + */ +void dlist_sort_custom(struct dlist *list, int (*compare)(void *, void *)) +{ + + dlist_start(list); + struct dlist *listsource, *listdest, *swap; + struct dlist *templist = dlist_new(list->data_size); + unsigned int passcount = 1; + unsigned int mergecount = 1; + // do nothing if there isn't anything to sort + listsource = list; + listdest = templist; + if(listsource->count<2) + { //nothing to do + return; + } + else + { + while(mergecount>0) + { + mergecount=_dlist_merge(listsource, listdest, passcount, compare); + if(mergecount>1) + { + passcount=passcount*2; + //start new pass + swap=listsource; + listsource=listdest; + listdest=swap; + } + } + } + // now put the input list pointers right + // list pointers = newlist pointers + // including the forward and next nodes prev and back pointers + if(list->count==0) + {//copy + list->marker = listdest->marker; + list->count = listdest->count; + list->data_size = listdest->data_size; + list->del_func = listdest->del_func; + list->head->prev = listdest->head->prev; + list->head->next = listdest->head->next; + list->head->data = listdest->head->data; + list->head->next->prev=list->head; + list->head->prev->next=list->head; + templist->head->next=NULL; + templist->head->prev=NULL; + templist->count=0; + } + else + {// no need to copy + + } + + dlist_destroy(templist); +} + + + +/* internal use function + swaps elements a and b + No sense in juggling node pointers when we can just swap the data pointers +*/ + +void _dlist_swap(struct dlist *list, struct dl_node *a, struct dl_node *b) +{ + + void *swap=a->data; + a->data=b->data; + b->data=swap; + +} + diff --git a/libsysfs/dlist.h b/libsysfs/dlist.h index 7fc90e5bf5..9e3a6c96de 100644 --- a/libsysfs/dlist.h +++ b/libsysfs/dlist.h @@ -52,6 +52,7 @@ * to think about it. */ +#include <malloc.h> typedef struct dl_node { struct dl_node *prev; struct dl_node *next; @@ -73,7 +74,7 @@ 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 *)); @@ -91,7 +92,15 @@ 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 *)); @@ -100,6 +109,7 @@ void dlist_transform(struct dlist *list, void (*node_operation)(void *)); * _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) diff --git a/libsysfs/sysfs.h b/libsysfs/sysfs.h index 7ac6efc678..1e58e8abb4 100644 --- a/libsysfs/sysfs.h +++ b/libsysfs/sysfs.h @@ -27,15 +27,18 @@ #include <stdlib.h> #include <unistd.h> #include <string.h> +#include <mntent.h> #include <dirent.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> -#include "dlist.h" + +/* external library functions */ +extern int isascii(int c); /* Debugging */ #ifdef DEBUG -#include "../logging.h" +#include "../logging.h" #define dprintf(format, arg...) dbg(format, ##arg) #else #define dprintf(format, arg...) do { } while (0) diff --git a/libsysfs/sysfs/libsysfs.h b/libsysfs/sysfs/libsysfs.h index 11cffae045..29194f61a6 100644 --- a/libsysfs/sysfs/libsysfs.h +++ b/libsysfs/sysfs/libsysfs.h @@ -25,6 +25,7 @@ #include <sys/types.h> #include <string.h> +#include "dlist.h" /* * Defines to prevent buffer overruns diff --git a/libsysfs/sysfs_bus.c b/libsysfs/sysfs_bus.c index 9ca23c85d8..d47b94ca24 100644 --- a/libsysfs/sysfs_bus.c +++ b/libsysfs/sysfs_bus.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "sysfs/libsysfs.h" +#include "libsysfs.h" #include "sysfs.h" static void sysfs_close_dev(void *dev) diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c index 59ef0be48e..db59aef90f 100644 --- a/libsysfs/sysfs_class.c +++ b/libsysfs/sysfs_class.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "sysfs/libsysfs.h" +#include "libsysfs.h" #include "sysfs.h" static void sysfs_close_cls_dev(void *dev) diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index 290fd9723e..f2f8d2d611 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "sysfs/libsysfs.h" +#include "libsysfs.h" #include "sysfs.h" /** @@ -502,7 +502,7 @@ struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev, * @psize: size of "path" * Returns 0 on success -1 on failure */ -static int get_device_absolute_path(const char *device, const char *bus, +static int get_device_absolute_path(const char *device, const char *bus, char *path, size_t psize) { char bus_path[SYSFS_PATH_MAX]; @@ -547,7 +547,7 @@ static int get_device_absolute_path(const char *device, const char *bus, * 2. Bus the device is on must be supplied * Use sysfs_find_device_bus to get the bus name */ -struct sysfs_device *sysfs_open_device(const char *bus, const char *bus_id) +struct sysfs_device *sysfs_open_device(const char *bus, const char *bus_id) { char sysfs_path[SYSFS_PATH_MAX]; struct sysfs_device *device = NULL; diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c index 8ce8522200..52769916cc 100644 --- a/libsysfs/sysfs_dir.c +++ b/libsysfs/sysfs_dir.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "sysfs/libsysfs.h" +#include "libsysfs.h" #include "sysfs.h" /** @@ -273,7 +273,7 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) errno = EACCES; return -1; } - pgsize = getpagesize(); + pgsize = sysconf(_SC_PAGESIZE); fbuf = (char *)calloc(1, pgsize+1); if (fbuf == NULL) { dprintf("calloc failed\n"); @@ -513,6 +513,7 @@ struct sysfs_link *sysfs_open_link(const char *linkpath) safestrcpy(ln->path, linkpath); if ((sysfs_get_name_from_path(linkpath, ln->name, SYSFS_NAME_LEN)) != 0 || (sysfs_get_link(linkpath, ln->target, SYSFS_PATH_MAX)) != 0) { + sysfs_close_link(ln); errno = EINVAL; dprintf("Invalid link path %s\n", linkpath); return NULL; @@ -884,7 +885,8 @@ struct sysfs_attribute *sysfs_get_directory_attribute attr = (struct sysfs_attribute *)dlist_find_custom (dir->attributes, attrname, dir_attribute_name_equal); if (attr != NULL) { - if ((sysfs_read_attribute(attr)) != 0) { + if ((attr->method & SYSFS_METHOD_SHOW) && + (sysfs_read_attribute(attr)) != 0) { dprintf("Error reading attribute %s\n", attr->name); return NULL; } diff --git a/libsysfs/sysfs_driver.c b/libsysfs/sysfs_driver.c index 2439b7a567..88d26b56dd 100644 --- a/libsysfs/sysfs_driver.c +++ b/libsysfs/sysfs_driver.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "sysfs/libsysfs.h" +#include "libsysfs.h" #include "sysfs.h" static void sysfs_close_driver_device(void *device) diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index f65e5df3aa..8b1f56ed14 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -20,16 +20,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "sysfs/libsysfs.h" +#include "libsysfs.h" #include "sysfs.h" -#ifndef __KLIBC__ -#include <mntent.h> -#endif -static int sort_char(void *new_elem, void *old_elem) +static int sort_char(void *new, void *old) { - return ((strncmp((char *)new_elem, (char *)old_elem, - strlen((char *)new_elem))) < 0 ? 1 : 0); + return ((strncmp((char *)new, (char *)old, + strlen((char *)new))) < 0 ? 1 : 0); } /** @@ -66,10 +63,6 @@ int sysfs_remove_trailing_slash(char *path) static int sysfs_get_fs_mnt_path(const char *fs_type, char *mnt_path, size_t len) { -#ifdef __KLIBC__ - safestrcpymax(mnt_path, "/sys", len); - return 0; -#else FILE *mnt; struct mntent *mntent; int ret = 0; @@ -106,7 +99,6 @@ static int sysfs_get_fs_mnt_path(const char *fs_type, ret = -1; return ret; -#endif } /* @@ -454,7 +446,7 @@ int sysfs_path_is_link(const char *path) return 1; } if ((lstat(path, &astats)) != 0) { - dprintf("stat() failed"); + dprintf("stat() failed\n"); return 1; } if (S_ISLNK(astats.st_mode)) @@ -477,7 +469,7 @@ int sysfs_path_is_file(const char *path) return 1; } if ((lstat(path, &astats)) != 0) { - dprintf("stat() failed"); + dprintf("stat() failed\n"); return 1; } if (S_ISREG(astats.st_mode)) |