2004-03-24 20:46:58 -08:00
/*
2004-03-27 01:21:46 -08:00
* dev_d . c - dev . d / multiplexer
2004-03-24 20:46:58 -08:00
*
* Copyright ( C ) 2004 Greg Kroah - Hartman < greg @ kroah . 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 version 2 of the License .
*/
2004-03-27 01:21:46 -08:00
/*
2004-03-24 20:46:58 -08:00
* This essentially emulates the following shell script logic in C :
2004-03-27 01:21:46 -08:00
* DIR = " /etc/dev.d "
2004-04-08 18:48:56 -07:00
* export DEVNAME = " whatever_dev_name_udev_just_gave "
* for I in " ${DIR}/$DEVNAME/ " * . dev " ${DIR}/$1/ " * . dev " ${DIR}/default/ " * . dev ; do
2004-03-27 01:21:46 -08:00
* if [ - f $ I ] ; then $ I $ 1 ; fi
* done
* exit 1 ;
2004-03-24 20:46:58 -08:00
*/
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <sys/types.h>
# include <sys/wait.h>
2004-10-06 00:54:08 -07:00
# include <sys/stat.h>
2004-03-24 20:46:58 -08:00
# include <unistd.h>
2004-10-06 00:54:08 -07:00
# include <fcntl.h>
2004-03-24 20:46:58 -08:00
# include "udev.h"
# include "udev_lib.h"
# include "logging.h"
2004-11-12 06:20:22 +01:00
static int run_program ( const char * filename , void * data )
2004-03-24 20:46:58 -08:00
{
pid_t pid ;
2004-10-06 00:54:08 -07:00
int fd ;
2004-11-12 06:20:22 +01:00
struct udevice * udev = data ;
2004-03-24 20:46:58 -08:00
2004-11-12 06:20:22 +01:00
dbg ( " running %s " , filename ) ;
2004-03-24 20:46:58 -08:00
pid = fork ( ) ;
2004-03-27 01:21:46 -08:00
switch ( pid ) {
case 0 :
/* child */
2004-10-06 00:54:08 -07:00
fd = open ( " /dev/null " , O_RDWR ) ;
if ( fd > = 0 ) {
dup2 ( fd , STDOUT_FILENO ) ;
dup2 ( fd , STDIN_FILENO ) ;
dup2 ( fd , STDERR_FILENO ) ;
}
close ( fd ) ;
2004-10-07 00:17:11 -07:00
2004-11-12 06:20:22 +01:00
execl ( filename , filename , udev - > subsystem , NULL ) ;
2004-03-27 01:21:46 -08:00
dbg ( " exec of child failed " ) ;
2004-10-18 19:28:39 -07:00
_exit ( 1 ) ;
2004-03-27 01:21:46 -08:00
case - 1 :
dbg ( " fork of child failed " ) ;
break ;
return - 1 ;
default :
2004-11-05 13:16:56 +01:00
waitpid ( pid , NULL , 0 ) ;
2004-03-24 20:46:58 -08:00
}
2004-03-27 01:21:46 -08:00
return 0 ;
2004-03-24 20:46:58 -08:00
}
2004-03-27 01:21:46 -08:00
/*
* runs files in these directories in order :
* < node name given by udev > /
* subsystem /
* default /
2004-03-24 20:46:58 -08:00
*/
2004-11-12 06:21:16 +01:00
void dev_d_execute ( struct udevice * udev , const char * basedir , const char * suffix )
2004-03-24 20:46:58 -08:00
{
2004-10-18 19:28:39 -07:00
char dirname [ PATH_MAX ] ;
char devname [ NAME_SIZE ] ;
2004-04-21 20:24:51 -07:00
char * temp ;
2004-03-24 20:46:58 -08:00
2004-10-18 19:28:39 -07:00
/* skip if UDEV_NO_DEVD is set */
[PATCH] netdev - udevdb+dev.d changes
Here is a patch to change the netdev handling in the database and for
the dev.d/ calls. I applies on top of the udevd.patch, cause klibc has
no sysinfo().
o netdev's are also put into our database now. I want this for the
udevruler gui to get a list of all handled devices.
All devices in the db are stamped with the system uptime value at
the creation time. 'udevinfo -d' prints it.
o the DEVPATH value is the key for udevdb, but if we rename
a netdev, the name is replaced in the kernel, so we add
the changed name to the db to match with the remove event.
NOTE: The dev.d/ scripts still get the original name from the
hotplug call. Should we replace DEVPATH with the new name too?
o We now only add a device to the db, if we have successfully created
the main node or successfully renamed a netdev. This is the main part
of the patch, cause I needed to clean the retval passing trough all
the functions used for node creation.
o DEVNODE sounds a bit ugly for netdev's so I exported DEVNAME too.
Can we change the name?
o I've added a UDEV_NO_DEVD to possibly skip the script execution
and used it in udev-test.pl.
udevstart is the same horror now, if you have scripts with logging
statements in dev.d/ it takes minutes to finish, can we skip the
scripts here too?
o The get_device_type() function is changed to be more strict, cause
'udevinfo -a -p /block/' gets a class device for it and tries to
print the major/minor values.
o bugfix, the RESULT value has now a working newline removal and a test
for this case.
2004-03-31 23:12:57 -08:00
if ( udev_dev_d = = 0 )
return ;
2004-10-18 19:28:39 -07:00
strfieldcpy ( devname , udev - > name ) ;
2004-04-21 20:24:51 -07:00
2004-11-12 06:21:16 +01:00
/* chop the device name up into pieces based on '/' */
2004-04-21 20:24:51 -07:00
temp = strchr ( devname , ' / ' ) ;
while ( temp ! = NULL ) {
2004-10-18 19:28:39 -07:00
temp [ 0 ] = ' \0 ' ;
2004-11-12 06:21:16 +01:00
snprintf ( dirname , PATH_MAX , " %s/%s " , basedir , devname ) ;
dirname [ PATH_MAX - 1 ] = ' \0 ' ;
call_foreach_file ( run_program , dirname , suffix , udev ) ;
2004-04-21 20:24:51 -07:00
2004-10-18 19:28:39 -07:00
temp [ 0 ] = ' / ' ;
2004-04-21 20:24:51 -07:00
+ + temp ;
temp = strchr ( temp , ' / ' ) ;
}
2004-03-24 20:46:58 -08:00
2004-11-23 06:22:26 +01:00
if ( udev - > name [ 0 ] ! = ' \0 ' ) {
snprintf ( dirname , PATH_MAX , " %s/%s " , basedir , udev - > name ) ;
dirname [ PATH_MAX - 1 ] = ' \0 ' ;
call_foreach_file ( run_program , dirname , suffix , udev ) ;
}
2004-03-24 20:46:58 -08:00
2004-11-23 06:22:26 +01:00
if ( udev - > subsystem [ 0 ] ! = ' \0 ' ) {
snprintf ( dirname , PATH_MAX , " %s/%s " , basedir , udev - > subsystem ) ;
dirname [ PATH_MAX - 1 ] = ' \0 ' ;
call_foreach_file ( run_program , dirname , suffix , udev ) ;
}
2004-03-24 20:46:58 -08:00
2004-11-12 06:21:16 +01:00
snprintf ( dirname , PATH_MAX , " %s/default " , basedir ) ;
dirname [ PATH_MAX - 1 ] = ' \0 ' ;
call_foreach_file ( run_program , dirname , suffix , udev ) ;
2004-03-24 20:46:58 -08:00
}