static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], bool test) {
        struct udev_list_entry *entry;
        unsigned release[1024];
        unsigned release_count = 0;
        _cleanup_close_ int fd = -1;
        const char *node;
        int has_abs = -1;

        node = udev_device_get_devnode(dev);
        if (!node) {
                log_error("No device node for \"%s\"", udev_device_get_syspath(dev));
                return EXIT_FAILURE;
        }

        udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev)) {
                const char *key;
                char *endptr;

                key = udev_list_entry_get_name(entry);
                if (startswith(key, "KEYBOARD_KEY_")) {
                        const char *keycode;
                        unsigned scancode;

                        /* KEYBOARD_KEY_<hex scan code>=<key identifier string> */
                        scancode = strtoul(key + 13, &endptr, 16);
                        if (endptr[0] != '\0') {
                                log_warning("Unable to parse scan code from \"%s\"", key);
                                continue;
                        }

                        keycode = udev_list_entry_get_value(entry);

                        /* a leading '!' needs a force-release entry */
                        if (keycode[0] == '!') {
                                keycode++;

                                release[release_count] = scancode;
                                if (release_count <  ELEMENTSOF(release)-1)
                                        release_count++;

                                if (keycode[0] == '\0')
                                        continue;
                        }

                        if (fd == -1) {
                                fd = open_device(node);
                                if (fd < 0)
                                        return EXIT_FAILURE;
                        }

                        map_keycode(fd, node, scancode, keycode);
                } else if (startswith(key, "EVDEV_ABS_")) {
                        unsigned evcode;

                        /* EVDEV_ABS_<EV_ABS code>=<min>:<max>:<res>:<fuzz>:<flat> */
                        evcode = strtoul(key + 10, &endptr, 16);
                        if (endptr[0] != '\0') {
                                log_warning("Unable to parse EV_ABS code from \"%s\"", key);
                                continue;
                        }

                        if (fd == -1) {
                                fd = open_device(node);
                                if (fd < 0)
                                        return EXIT_FAILURE;
                        }

                        if (has_abs == -1) {
                                unsigned long bits;
                                int rc;

                                rc = ioctl(fd, EVIOCGBIT(0, sizeof(bits)), &bits);
                                if (rc < 0) {
                                        log_error_errno(errno, "Unable to EVIOCGBIT device \"%s\"", node);
                                        return EXIT_FAILURE;
                                }

                                has_abs = !!(bits & (1 << EV_ABS));
                                if (!has_abs)
                                        log_warning("EVDEV_ABS override set but no EV_ABS present on device \"%s\"", node);
                        }

                        if (!has_abs)
                                continue;

                        override_abs(fd, node, evcode, udev_list_entry_get_value(entry));
                } else if (streq(key, "POINTINGSTICK_SENSITIVITY"))
                        set_trackpoint_sensitivity(dev, udev_list_entry_get_value(entry));
        }

        /* install list of force-release codes */
        if (release_count > 0)
                install_force_release(dev, release, release_count);

        return EXIT_SUCCESS;
}
示例#2
0
static void
device_added(struct udev_device *udev_device)
{
    const char *path, *name = NULL;
    char *config_info = NULL;
    const char *syspath;
    const char *tags_prop;
    const char *key, *value, *tmp;
    InputOption *input_options;
    InputAttributes attrs = { };
    DeviceIntPtr dev = NULL;
    struct udev_list_entry *set, *entry;
    struct udev_device *parent;
    int rc;
    const char *dev_seat;

    path = udev_device_get_devnode(udev_device);

    syspath = udev_device_get_syspath(udev_device);

    if (!path || !syspath)
        return;

    dev_seat = udev_device_get_property_value(udev_device, "ID_SEAT");
    if (!dev_seat)
        dev_seat = "seat0";

    if (SeatId && strcmp(dev_seat, SeatId))
        return;

    if (!SeatId && strcmp(dev_seat, "seat0"))
        return;

#ifdef CONFIG_UDEV_KMS
    if (!strcmp(udev_device_get_subsystem(udev_device), "drm")) {
        const char *sysname = udev_device_get_sysname(udev_device);

        if (strncmp(sysname, "card", 4) != 0)
            return;

        LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n", path);

        config_udev_odev_setup_attribs(path, syspath, NewGPUDeviceRequest);
        return;
    }
#endif

    if (!udev_device_get_property_value(udev_device, "ID_INPUT")) {
        LogMessageVerb(X_INFO, 10,
                       "config/udev: ignoring device %s without "
                       "property ID_INPUT set\n", path);
        return;
    }

    input_options = input_option_new(NULL, "_source", "server/udev");
    if (!input_options)
        return;

    parent = udev_device_get_parent(udev_device);
    if (parent) {
        const char *ppath = udev_device_get_devnode(parent);
        const char *product = udev_device_get_property_value(parent, "PRODUCT");
        const char *pnp_id = udev_device_get_sysattr_value(parent, "id");
        unsigned int usb_vendor, usb_model;

        name = udev_device_get_sysattr_value(parent, "name");
        LOG_SYSATTR(ppath, "name", name);
        if (!name) {
            name = udev_device_get_property_value(parent, "NAME");
            LOG_PROPERTY(ppath, "NAME", name);
        }

        /* construct USB ID in lowercase hex - "0000:ffff" */
        if (product &&
            sscanf(product, "%*x/%4x/%4x/%*x", &usb_vendor, &usb_model) == 2) {
            if (asprintf(&attrs.usb_id, "%04x:%04x", usb_vendor, usb_model)
                == -1)
                attrs.usb_id = NULL;
            else
                LOG_PROPERTY(ppath, "PRODUCT", product);
        }

        while (!pnp_id && (parent = udev_device_get_parent(parent))) {
            pnp_id = udev_device_get_sysattr_value(parent, "id");
            if (!pnp_id)
                continue;

            attrs.pnp_id = strdup(pnp_id);
            ppath = udev_device_get_devnode(parent);
            LOG_SYSATTR(ppath, "id", pnp_id);
        }

    }
    if (!name)
        name = "(unnamed)";
    else
        attrs.product = strdup(name);
    input_options = input_option_new(input_options, "name", name);
    input_options = input_option_new(input_options, "path", path);
    input_options = input_option_new(input_options, "device", path);
    if (path)
        attrs.device = strdup(path);

    tags_prop = udev_device_get_property_value(udev_device, "ID_INPUT.tags");
    LOG_PROPERTY(path, "ID_INPUT.tags", tags_prop);
    attrs.tags = xstrtokenize(tags_prop, ",");

    if (asprintf(&config_info, "udev:%s", syspath) == -1) {
        config_info = NULL;
        goto unwind;
    }

    if (device_is_duplicate(config_info)) {
        LogMessage(X_WARNING, "config/udev: device %s already added. "
                   "Ignoring.\n", name);
        goto unwind;
    }

    set = udev_device_get_properties_list_entry(udev_device);
    udev_list_entry_foreach(entry, set) {
        key = udev_list_entry_get_name(entry);
        if (!key)
            continue;
        value = udev_list_entry_get_value(entry);
        if (!strncasecmp(key, UDEV_XKB_PROP_KEY, sizeof(UDEV_XKB_PROP_KEY) - 1)) {
            LOG_PROPERTY(path, key, value);
            tmp = key + sizeof(UDEV_XKB_PROP_KEY) - 1;
            if (!strcasecmp(tmp, "rules"))
                input_options =
                    input_option_new(input_options, "xkb_rules", value);
            else if (!strcasecmp(tmp, "layout"))
                input_options =
                    input_option_new(input_options, "xkb_layout", value);
            else if (!strcasecmp(tmp, "variant"))
                input_options =
                    input_option_new(input_options, "xkb_variant", value);
            else if (!strcasecmp(tmp, "model"))
                input_options =
                    input_option_new(input_options, "xkb_model", value);
            else if (!strcasecmp(tmp, "options"))
                input_options =
                    input_option_new(input_options, "xkb_options", value);
        }
        else if (!strcmp(key, "ID_VENDOR")) {
            LOG_PROPERTY(path, key, value);
            attrs.vendor = strdup(value);
        }
        else if (!strcmp(key, "ID_INPUT_KEY")) {
            LOG_PROPERTY(path, key, value);
            attrs.flags |= ATTR_KEYBOARD;
        }
        else if (!strcmp(key, "ID_INPUT_MOUSE")) {
            LOG_PROPERTY(path, key, value);
            attrs.flags |= ATTR_POINTER;
        }
        else if (!strcmp(key, "ID_INPUT_JOYSTICK")) {
            LOG_PROPERTY(path, key, value);
            attrs.flags |= ATTR_JOYSTICK;
        }
        else if (!strcmp(key, "ID_INPUT_TABLET")) {
            LOG_PROPERTY(path, key, value);
            attrs.flags |= ATTR_TABLET;
        }
        else if (!strcmp(key, "ID_INPUT_TOUCHPAD")) {
            LOG_PROPERTY(path, key, value);
            attrs.flags |= ATTR_TOUCHPAD;
        }
        else if (!strcmp(key, "ID_INPUT_TOUCHSCREEN")) {
            LOG_PROPERTY(path, key, value);
            attrs.flags |= ATTR_TOUCHSCREEN;
        }
    }
static void get_video_devices (ofGstCamData & cam_data)
{
#ifdef TARGET_LINUX
	int fd, ok;

	struct udev * my_udev;
	struct udev_enumerate * enumerate;
	struct udev_list_entry * list;
	struct udev_list_entry * entry;

	my_udev = udev_new();
	enumerate = udev_enumerate_new(my_udev);
	udev_enumerate_scan_devices(enumerate);
	list = udev_enumerate_get_list_entry(enumerate);

	/*udev_list_entry_foreach(entry,list){
		const char * name = udev_list_entry_get_name(entry);
		struct udev_device * device = udev_device_new_from_syspath(my_udev, name);
		const char * subsystem = udev_device_get_subsystem(device);
		if(strcmp(subsystem,"video4linux")==0){
			num_devices++;
		}
	}*/

	ofLog (OF_LOG_NOTICE, "Probing devices with udev...");

	/* Initialize webcam structures */
	udev_list_entry_foreach(entry,list){
		const char * name = udev_list_entry_get_name(entry);
		struct udev_device * device = udev_device_new_from_syspath(my_udev, name);
		string subsystem = udev_device_get_subsystem(device);

		if(subsystem != "video4linux") continue;
		const char  *gstreamer_src, *product_name;
		struct v4l2_capability  v2cap;
		struct video_capability v1cap;
		string vendor_id;
		string product_id;

		const char * dev_node = udev_device_get_devnode(device);
		struct udev_list_entry * properties = udev_device_get_properties_list_entry(device);
		struct udev_list_entry * property;
		udev_list_entry_foreach(property,properties){
			const char * name = udev_list_entry_get_name(property);

			if(strcmp(name,"ID_VENDOR_ID")==0){
				vendor_id = udev_list_entry_get_value(property);
			}

			if(strcmp(name,"ID_MODEL_ID")==0){
				product_id = udev_list_entry_get_value(property);
			}

		}


		ofLog (OF_LOG_NOTICE, "Found device " + vendor_id + ":" + product_id + ", getting capabilities...");

		/* vbi devices support capture capability too, but cannot be used,
		 * so detect them by device name */
		if (strstr (dev_node, "vbi"))
		{
			ofLog (OF_LOG_WARNING, "Skipping vbi device: %s", dev_node);
			continue;
		}


		if ((fd = open (dev_node, O_RDONLY | O_NONBLOCK)) < 0)
		{
			ofLog (OF_LOG_WARNING, "Failed to open %s: %s", dev_node, strerror (errno));
			continue;
		}

		ok = ioctl (fd, VIDIOC_QUERYCAP, &v2cap);
		if (ok < 0)
		{
			ok = ioctl (fd, VIDIOCGCAP, &v1cap);
			if (ok < 0)
			{
				ofLog (OF_LOG_WARNING, "Error while probing v4l capabilities for %s: %s",
						dev_node, strerror (errno));
				close (fd);
				continue;
			}
			ofLog (OF_LOG_NOTICE,"Detected v4l device: %s", v1cap.name);
			ofLog (OF_LOG_NOTICE,"Device type: %d", v1cap.type);
			gstreamer_src = "v4lsrc";
			product_name  = v1cap.name;
		}
		else
		{
			guint cap = v2cap.capabilities;
			ofLog (OF_LOG_NOTICE,"Detected v4l2 device: %s", v2cap.card);
			ofLog (OF_LOG_NOTICE,"Driver: %s, version: %d", v2cap.driver, v2cap.version);
			/* g_print ("Bus info: %s\n", v2cap.bus_info); */ /* Doesn't seem anything useful */
			ofLog (OF_LOG_NOTICE,"Capabilities: 0x%08X", v2cap.capabilities);
			if (!(cap & V4L2_CAP_VIDEO_CAPTURE))
			{
			  ofLog (OF_LOG_NOTICE,"Device %s seems to not have the capture capability, (radio tuner?)\n"
					 "Removing it from device list.", dev_node);
			close (fd);
			continue;
			}
			gstreamer_src = "v4l2src";
			product_name  = (char *) v2cap.card;
		}


		ofGstDevice gst_device;
		gst_device.video_device = dev_node;
		gst_device.gstreamer_src = gstreamer_src;
		gst_device.product_name = product_name;
		cam_data.webcam_devices.push_back(gst_device);
		/*cam_data.webcam_devices[cam_data.num_webcam_devices].video_device      = dev_node;
		cam_data.webcam_devices[cam_data.num_webcam_devices].gstreamer_src     = gstreamer_src;
		cam_data.webcam_devices[cam_data.num_webcam_devices].product_name      = product_name;
		cam_data.webcam_devices[cam_data.num_webcam_devices].num_video_formats = 0;
		cam_data.webcam_devices[cam_data.num_webcam_devices].supported_resolutions =
		  g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
		cam_data.num_webcam_devices++;*/

		close (fd);
	}

	cam_data.bInited=true;
#endif
}
示例#4
0
static void
udev_monitor_watcher (struct udev_monitor *udev_monitor,
		      NihIoWatch *         watch,
		      NihIoEvents          events)
{
	struct udev_device *    udev_device;
	nih_local char *        subsystem = NULL;
	nih_local char *        action = NULL;
	nih_local char *        kernel = NULL;
	nih_local char *        devpath = NULL;
	nih_local char *        devname = NULL;
	nih_local char *        name = NULL;
	nih_local char **       env = NULL;
	const char *            value = NULL;
	size_t                  env_len = 0;
	DBusPendingCall *       pending_call;
	char                 *(*copy_string)(const void *, const char *) = NULL;


	udev_device = udev_monitor_receive_device (udev_monitor);
	if (! udev_device)
		return;

	copy_string = no_strip_udev_data ? nih_strdup : make_safe_string;

	value = udev_device_get_subsystem (udev_device);
	subsystem = value ? copy_string (NULL, value) : NULL;

	value = udev_device_get_action (udev_device);
	action = value ? copy_string (NULL, value) : NULL;

	value = udev_device_get_sysname (udev_device);
	kernel = value ? copy_string (NULL, value) : NULL;

	value = udev_device_get_devpath (udev_device);
	devpath = value ? copy_string (NULL, value) : NULL;

	value = udev_device_get_devnode (udev_device);
	devname = value ? copy_string (NULL, value) : NULL;

	/* Protect against the "impossible" */
	if (! action)
		goto out;

	if (! strcmp (action, "add")) {
		name = NIH_MUST (nih_sprintf (NULL, "%s-device-added",
					      subsystem));
	} else if (! strcmp (action, "change")) {
		name = NIH_MUST (nih_sprintf (NULL, "%s-device-changed",
					      subsystem));
	} else if (! strcmp (action, "remove")) {
		name = NIH_MUST (nih_sprintf (NULL, "%s-device-removed",
					      subsystem));
	} else {
		name = NIH_MUST (nih_sprintf (NULL, "%s-device-%s",
					      subsystem, action));
	}

	env = NIH_MUST (nih_str_array_new (NULL));

	if (kernel) {
		nih_local char *var = NULL;

		var = NIH_MUST (nih_sprintf (NULL, "KERNEL=%s", kernel));
		NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var));
	}

	if (devpath) {
		nih_local char *var = NULL;

		var = NIH_MUST (nih_sprintf (NULL, "DEVPATH=%s", devpath));
		NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var));
	}

	if (devname) {
		nih_local char *var = NULL;

		var = NIH_MUST (nih_sprintf (NULL, "DEVNAME=%s", devname));
		NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var));
	}

	if (subsystem) {
		nih_local char *var = NULL;

		var = NIH_MUST (nih_sprintf (NULL, "SUBSYSTEM=%s", subsystem));
		NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var));
	}

	if (action) {
		nih_local char *var = NULL;

		var = NIH_MUST (nih_sprintf (NULL, "ACTION=%s", action));
		NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var));
	}

	for (struct udev_list_entry *list_entry = udev_device_get_properties_list_entry (udev_device);
	     list_entry != NULL;
	     list_entry = udev_list_entry_get_next (list_entry)) {
		nih_local char *udev_name = NULL;
		nih_local char *udev_value = NULL;
		nih_local char *var = NULL;

		udev_name = copy_string (NULL, udev_list_entry_get_name (list_entry));

		if (! strcmp (udev_name, "DEVPATH"))
			continue;
		if (! strcmp (udev_name, "DEVNAME"))
			continue;
		if (! strcmp (udev_name, "SUBSYSTEM"))
			continue;
		if (! strcmp (udev_name, "ACTION"))
			continue;

		udev_value = copy_string (NULL, udev_list_entry_get_value (list_entry));

		var = NIH_MUST (nih_sprintf (NULL, "%s=%s", udev_name, udev_value));
		NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var));
	}

	nih_debug ("%s %s", name, devname ? devname : "");

	pending_call = upstart_emit_event (upstart,
			name, env, FALSE,
			NULL, emit_event_error, NULL,
			NIH_DBUS_TIMEOUT_NEVER);

	if (! pending_call) {
		NihError *err;
		int saved = errno;

		err = nih_error_get ();
		nih_warn ("%s", err->message);

		if (saved != ENOMEM && subsystem)
			nih_warn ("Likely that udev '%s' event contains binary garbage", subsystem);

		nih_free (err);
	}

	dbus_pending_call_unref (pending_call);

out:
	udev_device_unref (udev_device);
}
static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], bool test) {
        struct udev_list_entry *entry;
        struct {
                unsigned int scan;
                unsigned int key;
        } map[1024];
        unsigned int map_count = 0;
        unsigned int release[1024];
        unsigned int release_count = 0;

        udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev)) {
                const char *key;
                unsigned int scancode;
                char *endptr;
                const char *keycode;
                const struct key *k;

                key = udev_list_entry_get_name(entry);
                if (!startswith(key, "KEYBOARD_KEY_"))
                        continue;

                /* KEYBOARD_KEY_<hex scan code>=<key identifier string> */
                scancode = strtoul(key + 13, &endptr, 16);
                if (endptr[0] != '\0') {
                        log_error("Error, unable to parse scan code from '%s'\n", key);
                        continue;
                }

                keycode = udev_list_entry_get_value(entry);

                /* a leading '!' needs a force-release entry */
                if (keycode[0] == '!') {
                        keycode++;

                        release[release_count] = scancode;
                        if (release_count <  ELEMENTSOF(release)-1)
                                release_count++;

                        if (keycode[0] == '\0')
                                continue;
                }

                /* translate identifier to key code */
                k = keyboard_lookup_key(keycode, strlen(keycode));
                if (!k) {
                        log_error("Error, unknown key identifier '%s'\n", keycode);
                        continue;
                }

                map[map_count].scan = scancode;
                map[map_count].key = k->id;
                if (map_count < ELEMENTSOF(map)-1)
                        map_count++;
        }

        if (map_count > 0 || release_count > 0) {
                const char *node;
                int fd;
                unsigned int i;

                node = udev_device_get_devnode(dev);
                if (!node) {
                        log_error("Error, no device node for '%s'\n", udev_device_get_syspath(dev));
                        return EXIT_FAILURE;
                }

                fd = open(udev_device_get_devnode(dev), O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
                if (fd < 0) {
                        log_error("Error, opening device '%s': %m\n", node);
                        return EXIT_FAILURE;
                }

                /* install list of map codes */
                for (i = 0; i < map_count; i++) {
                        log_debug("keyboard: mapping scan code %d (0x%x) to key code %d (0x%x)\n",
                                  map[i].scan, map[i].scan, map[i].key, map[i].key);
                        if (ioctl(fd, EVIOCSKEYCODE, &map[i]) < 0)
                                log_error("Error calling EVIOCSKEYCODE (scan code 0x%x, key code %d): %m\n", map[i].scan, map[i].key);
                }

                /* install list of force-release codes */
                if (release_count > 0)
                        install_force_release(dev, release, release_count);

                close(fd);
        }

        return EXIT_SUCCESS;
}
示例#6
0
	pPartition createPartition( struct udev_device* device )
	{
		struct udev_list_entry* entries = udev_device_get_properties_list_entry( device );
		struct udev_list_entry* entry = 0;
		pPartition partition;
		QVariantMap properties;
		
		udev_list_entry_foreach( entry, entries ) {
			const QString name = udev_list_entry_get_name( entry );
			const QString value = QString::fromLocal8Bit( udev_device_get_property_value( device, name.toLocal8Bit().constData() ) );

			properties[ name ] = value;
		}
		
		if ( properties.contains( "UDISKS_PARTITION_TYPE" ) ) {
			properties[ "UDISKS_PARTITION_TYPE" ] = properties[ "UDISKS_PARTITION_TYPE" ].toString().toLongLong( 0, 16 );
		}
		
		const QString devName = QFileInfo( properties[ "DEVNAME" ].toString() ).fileName();
		QDBusMessage question = QDBusMessage::createMethodCall( "org.freedesktop.UDisks", QString( "/org/freedesktop/UDisks/devices/%1" ).arg( devName ), "org.freedesktop.DBus.Properties", "Get" );
		question << "org.freedesktop.UDisks.Device" << "DeviceMountPaths";
		QDBusMessage answer = QDBusConnection::systemBus().call( question, QDBus::Block, 1 );
		QStringList mountPoints;
		
		foreach ( const QVariant& variant, answer.arguments() ) {
			const QStringList values = variant.value<QDBusVariant>().variant().toStringList();
			
			if ( !values.isEmpty() ) {
				mountPoints << values;
			}
		}
		
		if ( pPartition::isWBFSPartition( properties[ "DEVNAME" ].toString() ) ) {
			properties[ "UDISKS_PARTITION_TYPE" ] = 0x25;
			properties[ "ID_FS_TYPE" ] = pPartition::fileSystemIdToString( 0x25 );
		}
		
		qint64 total = properties.value( "UDISKS_PARTITION_SIZE", -1 ).toLongLong();
		qint64 free = -1;
		
		if ( !mountPoints.isEmpty() ) {
			struct statfs stats;
			
			if ( statfs( qPrintable( mountPoints.first() ), &stats ) == 0 ) {
				/*const qint64 total = stats.f_blocks *stats.f_bsize;
				partition.used = total -( stats.f_bfree *stats.f_bsize );
				partition.free = partition.total -partition.used;*/
				
				total = stats.f_blocks *stats.f_bsize;
				free = stats.f_bfree *stats.f_bsize;
			}
			
			properties[ "UDISKS_PARTITION_MOUNT_POINTS" ] = mountPoints;
		}
		
		properties[ "REMOVABLE" ] = "0";

		// Check removable attr
		struct udev_device* parent = 0;
		
		if ( properties[ "DEVTYPE" ] == "partition" ) {
			parent = udev_device_get_parent( device );
		}
		else if ( properties[ "DEVTYPE" ] == "disk" ) {
			parent = device; // disk without partitions
		}

		if ( parent != 0 ) {
			const char* value = udev_device_get_sysattr_value( parent, "removable" );

			if ( value ) {
				properties[ "REMOVABLE" ] = QString::fromLocal8Bit( value );
			}
		}
		
		partition.setProperties( properties );
		partition.updateSizes( total, free );
		
		return partition;
	}
示例#7
0
文件: libudev-fs.c 项目: bjb/vdev
int main( int argc, char** argv ) {
   
   int rc = 0;
   char pathbuf[PATH_MAX+1];
   struct udev* udev_client = NULL;
   struct udev_monitor* monitor = NULL;
   int monitor_fd = 0;
   struct udev_device* dev = NULL;
   struct pollfd pfd[1];
   int num_events = INT_MAX;
   int num_forks = 0;
   
   // usage: $0 [num events to process [num times to fork]]
   if( argc > 1 ) {
      char* tmp = NULL;
      num_events = (int)strtol( argv[1], &tmp, 10 );
      if( tmp == argv[1] || *tmp != '\0' ) {
         fprintf(stderr, "Usage: %s [number of events to process [number of times to fork]]\n", argv[0] );
         exit(1);
      }
      
      if( argc > 2 ) {
         
         num_forks = (int)strtol( argv[2], &tmp, 10 );
         if( tmp == argv[2] || *tmp != '\0' ) {
            fprintf(stderr, "Usage: %s [number of events to process [number of times to fork]]\n", argv[0] );
            exit(1);
         }
      }
   }
   
   // make sure events dir exists 
   log_trace("events directory '%s'", UDEV_FS_EVENTS_DIR);
   
   rc = mkdir( UDEV_FS_EVENTS_DIR, 0700 );
   if( rc != 0 ) {
      
      rc = -errno;
      if( rc != -EEXIST ) {
         log_error("mkdir('%s') rc = %d", UDEV_FS_EVENTS_DIR, rc );
         exit(1);
      }
   }
   
   udev_monitor_fs_events_path( "", pathbuf, 0 );
   
   printf("Watching '%s'\n", pathbuf );
   
   udev_client = udev_new();
   if( udev_client == NULL ) {
      
      // OOM
      exit(2);
   }
   
   monitor = udev_monitor_new_from_netlink( udev_client, "udev" );
   if( monitor == NULL ) {
      
      // OOM or error
      udev_unref( udev_client );
      exit(2);
   }
   
   printf("Press Ctrl-C to quit\n");
   
   monitor_fd = udev_monitor_get_fd( monitor );
   if( monitor_fd < 0 ) {
      
      rc = -errno;
      log_error("udev_monitor_get_fd rc = %d\n", rc );
      exit(3);
   }
   
   pfd[0].fd = monitor_fd;
   pfd[0].events = POLLIN;
   
   while( num_events > 0 ) {
      
      // wait for the next device 
      rc = poll( pfd, 1, -1 );
      if( rc < 0 ) {
      
         log_error("poll(%d) rc = %d\n", monitor_fd, rc );
         break;
      }
      
      // get devices 
      while( num_events > 0 ) {
         
         dev = udev_monitor_receive_device( monitor );
         if( dev == NULL ) {
            break;
         }
         
         int pid = getpid();
         struct udev_list_entry *list_entry = NULL;
         
         printf("[%d] [%d] ACTION:     '%s'\n", pid, num_events, udev_device_get_action( dev ) );
         printf("[%d] [%d] SEQNUM:      %llu\n", pid, num_events, udev_device_get_seqnum( dev ) );
         printf("[%d] [%d] USEC:        %llu\n", pid, num_events, udev_device_get_usec_since_initialized( dev ) );
         printf("[%d] [%d] DEVNODE:    '%s'\n", pid, num_events, udev_device_get_devnode( dev ) );
         printf("[%d] [%d] DEVPATH:    '%s'\n", pid, num_events, udev_device_get_devpath( dev ) );
         printf("[%d] [%d] SYSNAME:    '%s'\n", pid, num_events, udev_device_get_sysname( dev ) );
         printf("[%d] [%d] SYSPATH:    '%s'\n", pid, num_events, udev_device_get_syspath( dev ) );
         printf("[%d] [%d] SUBSYSTEM:  '%s'\n", pid, num_events, udev_device_get_subsystem( dev ) );
         printf("[%d] [%d] DEVTYPE:    '%s'\n", pid, num_events, udev_device_get_devtype( dev ) );
         printf("[%d] [%d] SYSNUM:     '%s'\n", pid, num_events, udev_device_get_sysnum( dev ) );
         printf("[%d] [%d] DRIVER:     '%s'\n", pid, num_events, udev_device_get_driver( dev ) );
         printf("[%d] [%d] DEVNUM:      %d:%d\n", pid, num_events, major( udev_device_get_devnum( dev ) ), minor( udev_device_get_devnum( dev ) ) );
         printf("[%d] [%d] IFINDEX:    '%s'\n", pid, num_events, udev_device_get_property_value( dev, "IFINDEX" ) );
         printf("[%d] [%d] DEVMODE:    '%s'\n", pid, num_events, udev_device_get_property_value( dev, "DEVMODE" ) );
         printf("[%d] [%d] DEVUID:     '%s'\n", pid, num_events, udev_device_get_property_value( dev, "DEVUID" ) );
         printf("[%d] [%d] DEVGID:     '%s'\n", pid, num_events, udev_device_get_property_value( dev, "DEVGID" ) );         
         
         list_entry = udev_device_get_devlinks_list_entry( dev );
         udev_list_entry_foreach( list_entry, udev_list_entry_get_next( list_entry )) {
          
            printf("[%d] [%d] devlink:    '%s'\n", pid, num_events, udev_list_entry_get_name( list_entry ) );
         }
         
         list_entry = udev_device_get_properties_list_entry( dev );
         udev_list_entry_foreach( list_entry, udev_list_entry_get_next( list_entry )) {
            
            printf("[%d] [%d] property:   '%s' = '%s'\n", pid, num_events, udev_list_entry_get_name( list_entry ), udev_list_entry_get_value( list_entry ) );
         }
         
         list_entry = udev_device_get_tags_list_entry( dev );
         udev_list_entry_foreach( list_entry, udev_list_entry_get_next( list_entry )) {
            
            printf("[%d] [%d] tag:        '%s'\n", pid, num_events, udev_list_entry_get_name( list_entry ) );
         }