2003-07-19 07:08:00 +04:00
/*
2003-12-20 05:29:10 +03:00
* sysfs_dir . c
2003-07-19 07:08:00 +04:00
*
* Directory utility functions for libsysfs
*
2005-02-23 14:21:39 +03:00
* Copyright ( C ) IBM Corp . 2003 - 2005
2003-07-19 07:08:00 +04:00
*
* 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
*
*/
2004-10-20 15:15:26 +04:00
# include "libsysfs.h"
2003-07-19 07:08:00 +04:00
# include "sysfs.h"
2005-02-23 14:21:39 +03:00
static int sort_char ( void * new , void * old )
2003-10-21 12:19:14 +04:00
{
2005-02-23 14:21:39 +03:00
return ( ( strncmp ( ( char * ) new , ( char * ) old ,
strlen ( ( char * ) new ) ) ) < 0 ? 1 : 0 ) ;
2003-10-21 12:19:14 +04:00
}
/**
2005-02-23 14:21:39 +03:00
* sysfs_del_name : free function for sysfs_open_subsystem_list
* @ name : memory area to be freed
2003-10-21 12:19:14 +04:00
*/
2005-02-23 14:21:39 +03:00
static void sysfs_del_name ( void * name )
2003-10-21 12:19:14 +04:00
{
2005-02-23 14:21:39 +03:00
free ( name ) ;
2003-10-21 12:19:14 +04:00
}
/**
2005-02-23 14:21:39 +03:00
* sysfs_del_attribute : routine for dlist integration
2003-10-21 12:19:14 +04:00
*/
2005-02-23 14:21:39 +03:00
static void sysfs_del_attribute ( void * attr )
2003-10-21 12:19:14 +04:00
{
2005-02-23 14:21:39 +03:00
sysfs_close_attribute ( ( struct sysfs_attribute * ) attr ) ;
2003-10-21 12:19:14 +04:00
}
/**
2005-02-23 14:21:39 +03:00
* attr_name_equal : compares attributes by name
2003-10-21 12:19:14 +04:00
* @ a : attribute name for comparison
* @ b : sysfs_attribute to be compared .
* returns 1 if a = = b - > name or 0 if not equal
*/
2005-02-23 14:21:39 +03:00
static int attr_name_equal ( void * a , void * b )
2003-10-21 12:19:14 +04:00
{
2005-02-23 14:21:39 +03:00
if ( ! a | | ! b )
2003-10-21 12:19:14 +04:00
return 0 ;
2004-03-12 11:57:30 +03:00
if ( strcmp ( ( ( char * ) a ) , ( ( struct sysfs_attribute * ) b ) - > name ) = = 0 )
2003-10-21 12:19:14 +04:00
return 1 ;
2004-03-12 11:57:30 +03:00
2003-10-21 12:19:14 +04:00
return 0 ;
}
2003-07-19 07:08:00 +04:00
/**
* sysfs_close_attribute : closes and cleans up attribute
* @ sysattr : attribute to close .
*/
void sysfs_close_attribute ( struct sysfs_attribute * sysattr )
{
2005-02-23 14:21:39 +03:00
if ( sysattr ) {
if ( sysattr - > value )
2003-07-19 07:08:00 +04:00
free ( sysattr - > value ) ;
free ( sysattr ) ;
}
}
/**
* alloc_attribute : allocates and initializes attribute structure
* returns struct sysfs_attribute with success and NULL with error .
*/
static struct sysfs_attribute * alloc_attribute ( void )
{
return ( struct sysfs_attribute * )
calloc ( 1 , sizeof ( struct sysfs_attribute ) ) ;
}
/**
* sysfs_open_attribute : creates sysfs_attribute structure
* @ path : path to attribute .
* returns sysfs_attribute struct with success and NULL with error .
*/
2004-03-12 11:57:30 +03:00
struct sysfs_attribute * sysfs_open_attribute ( const char * path )
2003-07-19 07:08:00 +04:00
{
struct sysfs_attribute * sysattr = NULL ;
struct stat fileinfo ;
2005-02-23 14:21:39 +03:00
if ( ! path ) {
2003-07-19 07:08:00 +04:00
errno = EINVAL ;
return NULL ;
}
sysattr = alloc_attribute ( ) ;
2005-02-23 14:21:39 +03:00
if ( ! sysattr ) {
2003-10-21 12:19:14 +04:00
dprintf ( " Error allocating attribute at %s \n " , path ) ;
return NULL ;
}
2004-03-12 11:57:30 +03:00
if ( sysfs_get_name_from_path ( path , sysattr - > name ,
SYSFS_NAME_LEN ) ! = 0 ) {
dprintf ( " Error retrieving attrib name from path: %s \n " , path ) ;
2003-10-21 12:19:14 +04:00
sysfs_close_attribute ( sysattr ) ;
2003-07-19 07:08:00 +04:00
return NULL ;
}
2004-03-12 11:57:30 +03:00
safestrcpy ( sysattr - > path , path ) ;
2003-07-19 07:08:00 +04:00
if ( ( stat ( sysattr - > path , & fileinfo ) ) ! = 0 ) {
2003-10-21 12:19:14 +04:00
dprintf ( " Stat failed: No such attribute? \n " ) ;
2003-07-19 07:08:00 +04:00
sysattr - > method = 0 ;
2003-10-21 12:19:14 +04:00
free ( sysattr ) ;
sysattr = NULL ;
2003-07-19 07:08:00 +04:00
} else {
if ( fileinfo . st_mode & S_IRUSR )
sysattr - > method | = SYSFS_METHOD_SHOW ;
if ( fileinfo . st_mode & S_IWUSR )
sysattr - > method | = SYSFS_METHOD_STORE ;
}
return sysattr ;
}
/**
* sysfs_read_attribute : reads value from attribute
* @ sysattr : attribute to read
* returns 0 with success and - 1 with error .
*/
int sysfs_read_attribute ( struct sysfs_attribute * sysattr )
{
2004-03-12 11:57:30 +03:00
char * fbuf = NULL ;
char * vbuf = NULL ;
2003-12-20 05:29:10 +03:00
ssize_t length = 0 ;
2003-12-16 08:53:28 +03:00
long pgsize = 0 ;
2003-07-19 07:08:00 +04:00
int fd ;
2005-02-23 14:21:39 +03:00
if ( ! sysattr ) {
2003-07-19 07:08:00 +04:00
errno = EINVAL ;
return - 1 ;
}
if ( ! ( sysattr - > method & SYSFS_METHOD_SHOW ) ) {
2003-10-21 12:19:14 +04:00
dprintf ( " Show method not supported for attribute %s \n " ,
2003-07-19 07:08:00 +04:00
sysattr - > path ) ;
2004-03-12 11:57:30 +03:00
errno = EACCES ;
2003-07-19 07:08:00 +04:00
return - 1 ;
}
2005-03-06 04:09:30 +03:00
pgsize = getpagesize ( ) ;
2004-03-12 11:57:30 +03:00
fbuf = ( char * ) calloc ( 1 , pgsize + 1 ) ;
2005-02-23 14:21:39 +03:00
if ( ! fbuf ) {
2003-10-21 12:19:14 +04:00
dprintf ( " calloc failed \n " ) ;
2003-07-19 07:08:00 +04:00
return - 1 ;
}
if ( ( fd = open ( sysattr - > path , O_RDONLY ) ) < 0 ) {
2003-10-21 12:19:14 +04:00
dprintf ( " Error reading attribute %s \n " , sysattr - > path ) ;
2003-07-19 07:08:00 +04:00
free ( fbuf ) ;
return - 1 ;
}
length = read ( fd , fbuf , pgsize ) ;
if ( length < 0 ) {
2003-10-21 12:19:14 +04:00
dprintf ( " Error reading from attribute %s \n " , sysattr - > path ) ;
2003-07-19 07:08:00 +04:00
close ( fd ) ;
free ( fbuf ) ;
return - 1 ;
}
2003-12-16 08:53:28 +03:00
if ( sysattr - > len > 0 ) {
if ( ( sysattr - > len = = length ) & &
( ! ( strncmp ( sysattr - > value , fbuf , length ) ) ) ) {
close ( fd ) ;
2004-03-12 11:57:30 +03:00
free ( fbuf ) ;
2003-12-16 08:53:28 +03:00
return 0 ;
}
free ( sysattr - > value ) ;
}
2003-07-19 07:08:00 +04:00
sysattr - > len = length ;
close ( fd ) ;
2004-03-12 11:57:30 +03:00
vbuf = ( char * ) realloc ( fbuf , length + 1 ) ;
2005-02-23 14:21:39 +03:00
if ( ! vbuf ) {
2003-10-21 12:19:14 +04:00
dprintf ( " realloc failed \n " ) ;
2003-07-19 07:08:00 +04:00
free ( fbuf ) ;
return - 1 ;
}
sysattr - > value = vbuf ;
return 0 ;
}
/**
2005-02-23 14:21:39 +03:00
* sysfs_write_attribute : write value to the attribute
* @ sysattr : attribute to write
* @ new_value : value to write
* @ len : length of " new_value "
2003-07-19 07:08:00 +04:00
* returns 0 with success and - 1 with error .
*/
2005-02-23 14:21:39 +03:00
int sysfs_write_attribute ( struct sysfs_attribute * sysattr ,
const char * new_value , size_t len )
2003-07-19 07:08:00 +04:00
{
2005-02-23 14:21:39 +03:00
int fd ;
int length ;
2003-07-19 07:08:00 +04:00
2005-02-23 14:21:39 +03:00
if ( ! sysattr | | ! new_value | | len = = 0 ) {
2003-07-19 07:08:00 +04:00
errno = EINVAL ;
return - 1 ;
}
2005-02-23 14:21:39 +03:00
if ( ! ( sysattr - > method & SYSFS_METHOD_STORE ) ) {
dprintf ( " Store method not supported for attribute %s \n " ,
sysattr - > path ) ;
errno = EACCES ;
2003-07-19 07:08:00 +04:00
return - 1 ;
}
2005-02-23 14:21:39 +03:00
if ( sysattr - > method & SYSFS_METHOD_SHOW ) {
/*
* read attribute again to see if we can get an updated value
*/
if ( ( sysfs_read_attribute ( sysattr ) ) ) {
dprintf ( " Error reading attribute \n " ) ;
return - 1 ;
}
if ( ( strncmp ( sysattr - > value , new_value , sysattr - > len ) ) = = 0 ) {
dprintf ( " Attr %s already has the requested value %s \n " ,
sysattr - > name , new_value ) ;
return 0 ;
}
2003-07-19 07:08:00 +04:00
}
2005-02-23 14:21:39 +03:00
/*
* open O_WRONLY since some attributes have no " read " but only
* " write " permission
*/
if ( ( fd = open ( sysattr - > path , O_WRONLY ) ) < 0 ) {
dprintf ( " Error reading attribute %s \n " , sysattr - > path ) ;
return - 1 ;
2003-07-19 07:08:00 +04:00
}
2003-10-21 12:19:14 +04:00
2005-02-23 14:21:39 +03:00
length = write ( fd , new_value , len ) ;
if ( length < 0 ) {
dprintf ( " Error writing to the attribute %s - invalid value? \n " ,
sysattr - > name ) ;
close ( fd ) ;
2003-10-21 12:19:14 +04:00
return - 1 ;
2005-02-23 14:21:39 +03:00
} else if ( ( unsigned int ) length ! = len ) {
2005-03-10 02:58:01 +03:00
dprintf ( " Could not write %zd bytes to attribute %s \n " ,
2005-02-23 14:21:39 +03:00
len , sysattr - > name ) ;
/*
* since we could not write user supplied number of bytes ,
* restore the old value if one available
*/
if ( sysattr - > method & SYSFS_METHOD_SHOW ) {
length = write ( fd , sysattr - > value , sysattr - > len ) ;
close ( fd ) ;
return - 1 ;
2003-12-20 05:29:10 +03:00
}
2003-10-21 12:19:14 +04:00
}
2003-07-19 07:08:00 +04:00
2005-02-23 14:21:39 +03:00
/*
* Validate length that has been copied . Alloc appropriate area
* in sysfs_attribute . Verify first if the attribute supports reading
* ( show method ) . If it does not , do not bother
*/
if ( sysattr - > method & SYSFS_METHOD_SHOW ) {
if ( length ! = sysattr - > len ) {
sysattr - > value = ( char * ) realloc
( sysattr - > value , length ) ;
sysattr - > len = length ;
safestrcpymax ( sysattr - > value , new_value , length ) ;
} else {
/*"length" of the new value is same as old one */
safestrcpymax ( sysattr - > value , new_value , length ) ;
}
2003-07-19 07:08:00 +04:00
}
2005-02-23 14:21:39 +03:00
close ( fd ) ;
return 0 ;
2003-07-19 07:08:00 +04:00
}
2003-12-16 08:53:28 +03:00
/**
* add_attribute : open and add attribute at path to given directory
2005-02-23 14:21:39 +03:00
* @ dev : device whose attribute is to be added
2003-12-16 08:53:28 +03:00
* @ path : path to attribute
2005-02-23 14:21:39 +03:00
* returns pointer to attr added with success and NULL with error .
2003-12-16 08:53:28 +03:00
*/
2005-02-23 14:21:39 +03:00
static struct sysfs_attribute * add_attribute ( void * dev , const char * path )
2003-12-16 08:53:28 +03:00
{
2005-02-23 14:21:39 +03:00
struct sysfs_attribute * attr ;
2003-12-16 08:53:28 +03:00
attr = sysfs_open_attribute ( path ) ;
2005-02-23 14:21:39 +03:00
if ( ! attr ) {
2003-12-16 08:53:28 +03:00
dprintf ( " Error opening attribute %s \n " , path ) ;
2005-02-23 14:21:39 +03:00
return NULL ;
2003-12-16 08:53:28 +03:00
}
if ( attr - > method & SYSFS_METHOD_SHOW ) {
2005-02-23 14:21:39 +03:00
if ( sysfs_read_attribute ( attr ) ) {
2003-12-16 08:53:28 +03:00
dprintf ( " Error reading attribute %s \n " , path ) ;
sysfs_close_attribute ( attr ) ;
2005-02-23 14:21:39 +03:00
return NULL ;
2003-12-16 08:53:28 +03:00
}
}
2005-02-23 14:21:39 +03:00
if ( ! ( ( struct sysfs_device * ) dev ) - > attrlist ) {
( ( struct sysfs_device * ) dev ) - > attrlist = dlist_new_with_delete
( sizeof ( struct sysfs_attribute ) , sysfs_del_attribute ) ;
2003-12-16 08:53:28 +03:00
}
2005-02-23 14:21:39 +03:00
dlist_unshift_sorted ( ( ( struct sysfs_device * ) dev ) - > attrlist ,
attr , sort_list ) ;
2003-12-16 08:53:28 +03:00
2005-02-23 14:21:39 +03:00
return attr ;
2003-12-16 08:53:28 +03:00
}
2005-02-23 14:21:39 +03:00
/*
* get_attribute - given a sysfs_ * struct and a name , return the
* sysfs_attribute corresponding to " name "
* returns sysfs_attribute on success and NULL on error
2003-07-19 07:08:00 +04:00
*/
2005-02-23 14:21:39 +03:00
struct sysfs_attribute * get_attribute ( void * dev , const char * name )
2003-07-19 07:08:00 +04:00
{
2005-02-23 14:21:39 +03:00
struct sysfs_attribute * cur = NULL ;
char path [ SYSFS_PATH_MAX ] ;
2003-07-19 07:08:00 +04:00
2005-02-23 14:21:39 +03:00
if ( ! dev | | ! name ) {
2003-07-19 07:08:00 +04:00
errno = EINVAL ;
2005-02-23 14:21:39 +03:00
return NULL ;
2003-07-19 07:08:00 +04:00
}
2005-02-23 14:21:39 +03:00
if ( ( ( struct sysfs_device * ) dev ) - > attrlist ) {
/* check if attr is already in the list */
cur = ( struct sysfs_attribute * ) dlist_find_custom
( ( ( ( struct sysfs_device * ) dev ) - > attrlist ) ,
( void * ) name , attr_name_equal ) ;
if ( cur )
return cur ;
2003-12-16 08:53:28 +03:00
}
2005-02-23 14:21:39 +03:00
safestrcpymax ( path , ( ( struct sysfs_device * ) dev ) - > path ,
SYSFS_PATH_MAX ) ;
safestrcatmax ( path , " / " , SYSFS_PATH_MAX ) ;
safestrcatmax ( path , name , SYSFS_PATH_MAX ) ;
2005-04-15 18:28:56 +04:00
if ( ! sysfs_path_is_file ( path ) )
2005-02-23 14:21:39 +03:00
cur = add_attribute ( ( void * ) dev , path ) ;
return cur ;
2003-12-16 08:53:28 +03:00
}
/**
2005-02-23 14:21:39 +03:00
* read_dir_links : grabs links in a specific directory
* @ sysdir : sysfs directory to read
* returns list of link names with success and NULL with error .
2003-12-16 08:53:28 +03:00
*/
2005-02-23 14:21:39 +03:00
struct dlist * read_dir_links ( const char * path )
2003-12-16 08:53:28 +03:00
{
DIR * dir = NULL ;
struct dirent * dirent = NULL ;
2005-02-23 14:21:39 +03:00
char file_path [ SYSFS_PATH_MAX ] , * linkname ;
struct dlist * linklist = NULL ;
2003-12-16 08:53:28 +03:00
2005-02-23 14:21:39 +03:00
if ( ! path ) {
2003-12-16 08:53:28 +03:00
errno = EINVAL ;
2005-02-23 14:21:39 +03:00
return NULL ;
2003-12-16 08:53:28 +03:00
}
2005-02-23 14:21:39 +03:00
dir = opendir ( path ) ;
if ( ! dir ) {
dprintf ( " Error opening directory %s \n " , path ) ;
return NULL ;
2003-12-16 08:53:28 +03:00
}
2005-02-23 14:21:39 +03:00
while ( ( dirent = readdir ( dir ) ) ! = NULL ) {
2003-12-16 08:53:28 +03:00
if ( 0 = = strcmp ( dirent - > d_name , " . " ) )
continue ;
if ( 0 = = strcmp ( dirent - > d_name , " .. " ) )
continue ;
memset ( file_path , 0 , SYSFS_PATH_MAX ) ;
2005-02-23 14:21:39 +03:00
safestrcpy ( file_path , path ) ;
2004-03-12 11:57:30 +03:00
safestrcat ( file_path , " / " ) ;
safestrcat ( file_path , dirent - > d_name ) ;
2005-04-15 18:28:56 +04:00
if ( ! sysfs_path_is_link ( file_path ) ) {
2005-02-23 14:21:39 +03:00
if ( ! linklist ) {
linklist = dlist_new_with_delete
( SYSFS_NAME_LEN , sysfs_del_name ) ;
if ( ! linklist ) {
dprintf ( " Error creating list \n " ) ;
return NULL ;
}
}
linkname = ( char * ) calloc ( 1 , SYSFS_NAME_LEN ) ;
safestrcpymax ( linkname , dirent - > d_name , SYSFS_NAME_LEN ) ;
dlist_unshift_sorted ( linklist , linkname , sort_char ) ;
2003-07-19 07:08:00 +04:00
}
}
closedir ( dir ) ;
2005-02-23 14:21:39 +03:00
return linklist ;
2003-07-19 07:08:00 +04:00
}
/**
2005-02-23 14:21:39 +03:00
* read_dir_subdirs : grabs subdirs in a specific directory
* @ sysdir : sysfs directory to read
* returns list of directory names with success and NULL with error .
2003-12-16 08:53:28 +03:00
*/
2005-02-23 14:21:39 +03:00
struct dlist * read_dir_subdirs ( const char * path )
2003-12-16 08:53:28 +03:00
{
DIR * dir = NULL ;
struct dirent * dirent = NULL ;
2005-02-23 14:21:39 +03:00
char file_path [ SYSFS_PATH_MAX ] , * dir_name ;
struct dlist * dirlist = NULL ;
2003-12-16 08:53:28 +03:00
2005-02-23 14:21:39 +03:00
if ( ! path ) {
2003-12-16 08:53:28 +03:00
errno = EINVAL ;
2005-02-23 14:21:39 +03:00
return NULL ;
2003-12-16 08:53:28 +03:00
}
2005-02-23 14:21:39 +03:00
dir = opendir ( path ) ;
if ( ! dir ) {
dprintf ( " Error opening directory %s \n " , path ) ;
return NULL ;
2003-12-16 08:53:28 +03:00
}
2005-02-23 14:21:39 +03:00
while ( ( dirent = readdir ( dir ) ) ! = NULL ) {
2003-12-16 08:53:28 +03:00
if ( 0 = = strcmp ( dirent - > d_name , " . " ) )
continue ;
if ( 0 = = strcmp ( dirent - > d_name , " .. " ) )
continue ;
memset ( file_path , 0 , SYSFS_PATH_MAX ) ;
2005-02-23 14:21:39 +03:00
safestrcpy ( file_path , path ) ;
2004-03-12 11:57:30 +03:00
safestrcat ( file_path , " / " ) ;
safestrcat ( file_path , dirent - > d_name ) ;
2005-04-15 18:28:56 +04:00
if ( ! sysfs_path_is_dir ( file_path ) ) {
2005-02-23 14:21:39 +03:00
if ( ! dirlist ) {
dirlist = dlist_new_with_delete
( SYSFS_NAME_LEN , sysfs_del_name ) ;
if ( ! dirlist ) {
dprintf ( " Error creating list \n " ) ;
return NULL ;
}
}
dir_name = ( char * ) calloc ( 1 , SYSFS_NAME_LEN ) ;
safestrcpymax ( dir_name , dirent - > d_name , SYSFS_NAME_LEN ) ;
dlist_unshift_sorted ( dirlist , dir_name , sort_char ) ;
}
2003-12-16 08:53:28 +03:00
}
closedir ( dir ) ;
2005-02-23 14:21:39 +03:00
return dirlist ;
2003-12-16 08:53:28 +03:00
}
/**
2005-02-23 14:21:39 +03:00
* get_attributes_list : build a list of attributes for the given device
* @ dev : devices whose attributes list is required
* returns dlist of attributes on success and NULL on failure
2003-12-16 08:53:28 +03:00
*/
2005-02-23 14:21:39 +03:00
struct dlist * get_attributes_list ( void * dev )
2003-12-16 08:53:28 +03:00
{
DIR * dir = NULL ;
struct dirent * dirent = NULL ;
2005-02-23 14:21:39 +03:00
struct sysfs_attribute * attr = NULL ;
char file_path [ SYSFS_PATH_MAX ] , path [ SYSFS_PATH_MAX ] ;
2003-12-16 08:53:28 +03:00
2005-02-23 14:21:39 +03:00
if ( ! dev ) {
2003-12-16 08:53:28 +03:00
errno = EINVAL ;
2005-02-23 14:21:39 +03:00
return NULL ;
2003-12-16 08:53:28 +03:00
}
2005-02-23 14:21:39 +03:00
memset ( path , 0 , SYSFS_PATH_MAX ) ;
safestrcpy ( path , ( ( struct sysfs_device * ) dev ) - > path ) ;
dir = opendir ( path ) ;
if ( ! dir ) {
dprintf ( " Error opening directory %s \n " , path ) ;
return NULL ;
2003-12-16 08:53:28 +03:00
}
2005-02-23 14:21:39 +03:00
while ( ( dirent = readdir ( dir ) ) ! = NULL ) {
2003-12-16 08:53:28 +03:00
if ( 0 = = strcmp ( dirent - > d_name , " . " ) )
continue ;
if ( 0 = = strcmp ( dirent - > d_name , " .. " ) )
continue ;
memset ( file_path , 0 , SYSFS_PATH_MAX ) ;
2005-02-23 14:21:39 +03:00
safestrcpy ( file_path , path ) ;
2004-03-12 11:57:30 +03:00
safestrcat ( file_path , " / " ) ;
safestrcat ( file_path , dirent - > d_name ) ;
2005-04-15 18:28:56 +04:00
if ( ! sysfs_path_is_file ( file_path ) ) {
2005-02-23 14:21:39 +03:00
if ( ( ( struct sysfs_device * ) dev ) - > attrlist ) {
/* check if attr is already in the list */
2003-12-20 05:29:10 +03:00
attr = ( struct sysfs_attribute * )
2005-02-23 14:21:39 +03:00
dlist_find_custom
( ( ( ( struct sysfs_device * ) dev ) - > attrlist ) ,
( void * ) dirent - > d_name , attr_name_equal ) ;
if ( attr )
2003-12-16 08:53:28 +03:00
continue ;
2005-02-23 14:21:39 +03:00
else
add_attribute ( dev , file_path ) ;
} else
attr = add_attribute ( dev , file_path ) ;
2003-10-21 12:19:14 +04:00
}
}
2005-02-23 14:21:39 +03:00
closedir ( dir ) ;
return ( ( struct sysfs_device * ) dev ) - > attrlist ;
2004-01-15 09:21:38 +03:00
}