示例#1
0
void udev_node_add(struct udev_device *dev, bool apply,
                   mode_t mode, uid_t uid, gid_t gid,
                   struct udev_list *seclabel_list) {
        char filename[UTIL_PATH_SIZE];
        struct udev_list_entry *list_entry;

        log_debug("handling device node '%s', devnum=%s, mode=%#o, uid="UID_FMT", gid="GID_FMT,
                  udev_device_get_devnode(dev), udev_device_get_id_filename(dev), mode, uid, gid);

        if (node_permissions_apply(dev, apply, mode, uid, gid, seclabel_list) < 0)
                return;

        /* always add /dev/{block,char}/$major:$minor */
        snprintf(filename, sizeof(filename), "/dev/%s/%u:%u",
                 streq(udev_device_get_subsystem(dev), "block") ? "block" : "char",
                 major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)));
        node_symlink(dev, udev_device_get_devnode(dev), filename);

        /* create/update symlinks, add symlinks to name index */
        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev))
                        link_update(dev, udev_list_entry_get_name(list_entry), true);
}
示例#2
0
UdevEventContextRef UdevEventPublisher::createEventContextFrom(
    struct udev_device* device) {
  auto ec = createEventContext();
  ec->device = device;
  // Map the action string to the eventing enum.
  ec->action = UDEV_EVENT_ACTION_UNKNOWN;
  ec->action_string = std::string(udev_device_get_action(device));
  if (ec->action_string == "add") {
    ec->action = UDEV_EVENT_ACTION_ADD;
  } else if (ec->action_string == "remove") {
    ec->action = UDEV_EVENT_ACTION_REMOVE;
  } else if (ec->action_string == "change") {
    ec->action = UDEV_EVENT_ACTION_CHANGE;
  }

  // Set the subscription-aware variables for the event.
  auto value = udev_device_get_subsystem(device);
  if (value != nullptr) {
    ec->subsystem = std::string(value);
  }

  value = udev_device_get_devnode(device);
  if (value != nullptr) {
    ec->devnode = std::string(value);
  }

  value = udev_device_get_devtype(device);
  if (value != nullptr) {
    ec->devtype = std::string(value);
  }

  value = udev_device_get_driver(device);
  if (value != nullptr) {
    ec->driver = std::string(value);
  }

  return ec;
}
示例#3
0
static int names_ccw(struct  udev_device *dev, struct netnames *names) {
        struct udev_device *cdev;
        const char *bus_id;
        size_t bus_id_len;
        int rc;

        /* Retrieve the associated CCW device */
        cdev = udev_device_get_parent(dev);
        if (!cdev)
                return -ENOENT;

        /* Network devices are always grouped CCW devices */
        if (!streq_ptr("ccwgroup", udev_device_get_subsystem(cdev)))
                return -ENOENT;

        /* Retrieve bus-ID of the grouped CCW device.  The bus-ID uniquely
         * identifies the network device on the Linux on System z channel
         * subsystem.  Note that the bus-ID contains lowercase characters.
         */
        bus_id = udev_device_get_sysname(cdev);
        if (!bus_id)
                return -ENOENT;

        /* Check the length of the bus-ID.  Rely on that the kernel provides
         * a correct bus-ID; alternatively, improve this check and parse and
         * verify each bus-ID part...
         */
        bus_id_len = strlen(bus_id);
        if (!bus_id_len || bus_id_len < 8 || bus_id_len > 9)
                return -EINVAL;

        /* Store the CCW bus-ID for use as network device name */
        rc = snprintf(names->ccw_group, sizeof(names->ccw_group), "ccw%s", bus_id);
        if (rc >= 0 && rc < (int)sizeof(names->ccw_group))
                names->type = NET_CCWGROUP;
        return 0;
}
示例#4
0
static int udev_builtin_hwdb_search(struct udev_device *dev, struct udev_device *srcdev,
                                    const char *subsystem, const char *prefix,
                                    const char *filter, bool test) {
        struct udev_device *d;
        char s[16];
        int n = 0;

        for (d = srcdev; d; d = udev_device_get_parent(d)) {
                const char *dsubsys;
                const char *modalias = NULL;

                dsubsys = udev_device_get_subsystem(d);
                if (!dsubsys)
                        continue;

                /* look only at devices of a specific subsystem */
                if (subsystem && !streq(dsubsys, subsystem))
                        continue;

                /* the usb_device does not have a modalias, compose one */
                if (streq(dsubsys, "usb"))
                        modalias = modalias_usb(d, s, sizeof(s));

                if (!modalias)
                        modalias = udev_device_get_property_value(d, "MODALIAS");

                if (!modalias)
                        continue;

                n = udev_builtin_hwdb_lookup(dev, prefix, modalias, filter, test);
                if (n > 0)
                        break;
        }

        return n;
}
示例#5
0
static int usb_dongle_probe_print_list(struct udev_enumerate *enumerate)
{
	struct udev_list_entry *list_entry;
	unsigned int vid, pid;
	int ret = -1;

	udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
		struct udev_device *device;

		device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
				udev_list_entry_get_name(list_entry));
		if (device != NULL) {
			mylog_info("device: '%s' (%s)\n",
					udev_device_get_syspath(device),
					udev_device_get_subsystem(device));
			get_vid_pid(device, &vid, &pid);
			ret = wlan_driver_match(vid, pid, wlan_driver_add_callback);
			udev_device_unref(device);
			if (!ret)
				break;
		}
	}
	return ret;
}
示例#6
0
文件: path_id.c 项目: Lingvorn/udev
int main(int argc, char **argv)
{
	static const struct option options[] = {
		{ "debug", no_argument, NULL, 'd' },
		{ "help", no_argument, NULL, 'h' },
		{}
	};
	struct udev *udev;
	struct udev_device *dev;
	struct udev_device *parent;
	char syspath[UTIL_PATH_SIZE];
	const char *devpath;
	char *path;
	char *path_suffix;
	int rc = 1;

	udev = udev_new();
	if (udev == NULL)
		goto exit;

	udev_log_init("path_id");
	udev_set_log_fn(udev, log_fn);

	while (1) {
		int option;

		option = getopt_long(argc, argv, "dh", options, NULL);
		if (option == -1)
			break;

		switch (option) {
		case 'd':
			debug = 1;
			if (udev_get_log_priority(udev) < LOG_INFO)
				udev_set_log_priority(udev, LOG_INFO);
			break;
		case 'h':
			printf("Usage: path_id [--debug] [--help] <devpath>\n"
			       "  --debug    print debug information\n"
			       "  --help      print this help text\n\n");
		default:
			rc = 1;
			goto exit;
		}
	}

	devpath = argv[optind];
	if (devpath == NULL) {
		fprintf(stderr, "No device specified\n");
		rc = 2;
		goto exit;
	}

	util_strscpyl(syspath, sizeof(syspath), udev_get_sys_path(udev), devpath, NULL);
	dev = udev_device_new_from_syspath(udev, syspath);
	if (dev == NULL) {
		fprintf(stderr, "unable to access '%s'\n", devpath);
		rc = 3;
		goto exit;
	}

	path = NULL;
	path_suffix = NULL;

	/* S390 ccw bus */
	parent = udev_device_get_parent_with_subsystem_devtype(dev, "ccw", NULL);
	if (parent != NULL) {
		handle_ccw(parent, dev, &path);
		goto out;
	}

	/* walk up the chain of devices and compose path */
	parent = dev;
	while (parent != NULL) {
		const char *subsys;

		subsys = udev_device_get_subsystem(parent);

		if (subsys == NULL) {
			;
		} else if (strcmp(subsys, "scsi_tape") == 0) {
			handle_scsi_tape(parent, &path_suffix);
		} else if (strcmp(subsys, "scsi") == 0) {
			parent = handle_scsi(parent, &path);
		} else if (strcmp(subsys, "cciss") == 0) {
			handle_cciss(parent, &path);
		} else if (strcmp(subsys, "usb") == 0) {
			parent = handle_usb(parent, &path);
		} else if (strcmp(subsys, "serio") == 0) {
			path_prepend(&path, "serio-%s", udev_device_get_sysnum(parent));
			parent = skip_subsystem(parent, "serio");
		} else if (strcmp(subsys, "pci") == 0) {
			path_prepend(&path, "pci-%s", udev_device_get_sysname(parent));
			parent = skip_subsystem(parent, "pci");
		} else if (strcmp(subsys, "platform") == 0) {
			path_prepend(&path, "platform-%s", udev_device_get_sysname(parent));
			parent = skip_subsystem(parent, "platform");
		} else if (strcmp(subsys, "xen") == 0) {
			path_prepend(&path, "xen-%s", udev_device_get_sysname(parent));
			parent = skip_subsystem(parent, "xen");
		} else if (strcmp(subsys, "virtio") == 0) {
			path_prepend(&path, "virtio-pci-%s", udev_device_get_sysname(parent));
			parent = skip_subsystem(parent, "virtio");
		}

		parent = udev_device_get_parent(parent);
	}
out:
	if (path != NULL) {
		if (path_suffix != NULL) {
			printf("ID_PATH=%s%s\n", path, path_suffix);
			free(path_suffix);
		} else {
			printf("ID_PATH=%s\n", path);
		}
		free(path);
		rc = 0;
	}

	udev_device_unref(dev);
exit:
	udev_unref(udev);
	udev_log_close();
	return rc;
}
示例#7
0
const char* UdevDevice::getSubsystem(void)
	{
	return udev_device_get_subsystem(device);
	}
示例#8
0
/* private function to further filter watch results based on Eeze_Udev_Type
 * specified; helpful for new udev versions, but absolutely required for
 * old udev, which does not implement filtering in device monitors.
 */
static Eina_Bool
_get_syspath_from_watch(void             *data,
                        Ecore_Fd_Handler *fd_handler)
{
   struct _store_data *store = data;
   _udev_device *device = NULL, *parent, *tmpdev;
   const char *ret, *test;
   Eeze_Udev_Watch_Cb func = store->func;
   void *sdata = store->data;
   Eeze_Udev_Watch *watch = store->watch;
   int event = 0;

   if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
     return EINA_TRUE;

   device = udev_monitor_receive_device(store->mon);

   if (!device)
     return EINA_TRUE;

   if ((!(test = udev_device_get_action(device)))
       || (!(ret = udev_device_get_syspath(device))))
     goto error;

   if (store->event)
     {
        if (!strcmp(test, "add"))
          {
             if ((store->event != EEZE_UDEV_EVENT_NONE) &&
                 ((store->event & EEZE_UDEV_EVENT_ADD) != EEZE_UDEV_EVENT_ADD))
               goto error;

             event |= EEZE_UDEV_EVENT_ADD;
          }
        else if (!strcmp(test, "remove"))
          {
             if ((store->event != EEZE_UDEV_EVENT_NONE) &&
                 ((store->event & EEZE_UDEV_EVENT_REMOVE) != EEZE_UDEV_EVENT_REMOVE))
               goto error;

             event |= EEZE_UDEV_EVENT_REMOVE;
          }
        else if (!strcmp(test, "change"))
          {
             if ((store->event != EEZE_UDEV_EVENT_NONE) &&
                 ((store->event & EEZE_UDEV_EVENT_CHANGE) != EEZE_UDEV_EVENT_CHANGE))
               goto error;

             event |= EEZE_UDEV_EVENT_CHANGE;
          }
        else if (!strcmp(test, "online"))
          {
             if ((store->event != EEZE_UDEV_EVENT_NONE) &&
                 ((store->event & EEZE_UDEV_EVENT_ONLINE) != EEZE_UDEV_EVENT_ONLINE))
               goto error;

             event |= EEZE_UDEV_EVENT_ONLINE;
          }
        else
          {
             if ((store->event != EEZE_UDEV_EVENT_NONE) &&
                 ((store->event & EEZE_UDEV_EVENT_OFFLINE) != EEZE_UDEV_EVENT_OFFLINE))
               goto error;

             event |= EEZE_UDEV_EVENT_OFFLINE;
          }
     }

   if ((event & EEZE_UDEV_EVENT_OFFLINE) || (event & EEZE_UDEV_EVENT_REMOVE))
     goto out;
   switch (store->type)
     {
      case EEZE_UDEV_TYPE_KEYBOARD:
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
        if ((!(test = udev_device_get_subsystem(device)))
            || (strcmp(test, "input")))
          goto error;

        test = udev_device_get_property_value(device, "ID_CLASS");

        if ((_walk_parents_test_attr(device, "bInterfaceProtocol", "01"))
            || ((test) && (!strcmp(test, "kbd"))))
          break;

        goto error;
#endif
        if ((!udev_device_get_property_value(device, "ID_INPUT_KEYBOARD")) &&
            (!udev_device_get_property_value(device, "ID_INPUT_KEY")))
          goto error;

        break;

      case EEZE_UDEV_TYPE_MOUSE:
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
        if ((!(test = udev_device_get_subsystem(device)))
            || (strcmp(test, "input")))
          goto error;

        test = udev_device_get_property_value(device, "ID_CLASS");

        if ((_walk_parents_test_attr(device, "bInterfaceProtocol", "02"))
            || ((test) && (!strcmp(test, "mouse"))))
          break;

        goto error;
#endif

        if (!udev_device_get_property_value(device, "ID_INPUT_MOUSE"))
          goto error;

        break;

      case EEZE_UDEV_TYPE_TOUCHPAD:
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
        if ((!(test = udev_device_get_subsystem(device)))
            || (strcmp(test, "input")))
          goto error;

        if (_walk_parents_test_attr(device, "resolution", NULL))
          break;

        goto error;
#endif
        if (!udev_device_get_property_value(device, "ID_INPUT_TOUCHPAD"))
          goto error;

        break;

      case EEZE_UDEV_TYPE_DRIVE_MOUNTABLE:
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
        if ((!(test = udev_device_get_subsystem(device)))
            || (strcmp(test, "block")))
          goto error;
#endif
        if (!(test = (udev_device_get_property_value(device, "ID_FS_USAGE"))) ||
            (strcmp("filesystem", test)))
          goto error;
        {
           int devcheck;

           devcheck = open(udev_device_get_devnode(device), O_RDONLY);
           if (devcheck < 0) goto error;
           close(devcheck);
        }

        break;

      case EEZE_UDEV_TYPE_DRIVE_INTERNAL:
        if (udev_device_get_property_value(device, "ID_FS_USAGE")) goto error;
        test = udev_device_get_sysattr_value(device, "removable");
        if (test && test[0] == '1') goto error;
        test = udev_device_get_property_value(device, "ID_BUS");
        if ((!test) || strcmp(test, "ata")) goto error;
        test = udev_device_get_property_value(device, "ID_TYPE");
        if ((!test) || strcmp(test, "disk")) goto error;
        break;

      case EEZE_UDEV_TYPE_DRIVE_REMOVABLE:
        if (udev_device_get_sysattr_value(device, "partition")) goto error;
        test = udev_device_get_sysattr_value(device, "removable");
        if ((!test) || (test[0] == '0')) goto error;
        test = udev_device_get_property_value(device, "ID_TYPE");
        if ((!test) || strcmp(test, "disk")) goto error;

        break;

      case EEZE_UDEV_TYPE_DRIVE_CDROM:
        if (!udev_device_get_property_value(device, "ID_CDROM"))
          goto error;

        break;

      case EEZE_UDEV_TYPE_POWER_AC:
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
        if ((!(test = udev_device_get_subsystem(device)))
            || (strcmp(test, "power_supply")))
          goto error;
#endif
        test = udev_device_get_property_value(device, "POWER_SUPPLY_ONLINE");
        if (!test) goto error;
        break;

      case EEZE_UDEV_TYPE_POWER_BAT:
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
        if ((!(test = udev_device_get_subsystem(device)))
            || (strcmp(test, "power_supply")))
          goto error;
#endif
        test = udev_device_get_property_value(device, "POWER_SUPPLY_PRESENT");
        if (!test) goto error;
        break;

      case EEZE_UDEV_TYPE_IS_IT_HOT_OR_IS_IT_COLD_SENSOR:
#ifdef OLD_UDEV_RRRRRRRRRRRRRR
        if ((!(test = udev_device_get_subsystem(device)))
            || (strcmp(test, "hwmon")))
          goto error;
#endif /* have to do stuff up here since we need info from the parent */
        if (!_walk_parents_test_attr(device, "temp1_input", NULL))
          goto error;

        /* if device is not the one which has the temp input, we must go up the chain */
        if (!udev_device_get_sysattr_value(device, "temp1_input"))
          {
             for (parent = udev_device_get_parent(device); parent; parent = udev_device_get_parent(parent)) /*check for parent */
               if (udev_device_get_sysattr_value(parent, "temp1_input"))
                 {
                    tmpdev = device;

                    if (!(device = _copy_device(parent)))
                      goto error;

                    udev_device_unref(tmpdev);
                    break;
                 }
          }

        break;

      default:
        break;
     }
out:
   (*func)(eina_stringshare_add(ret), event, sdata, watch);
error:
   if (device)
     udev_device_unref(device);
   return EINA_TRUE;
}
示例#9
0
文件: sysfs-show.c 项目: cee1/systemd
static int show_sysfs_one(
                struct udev *udev,
                const char *seat,
                struct udev_list_entry **item,
                const char *sub,
                const char *prefix,
                unsigned n_columns) {

        assert(udev);
        assert(seat);
        assert(item);
        assert(prefix);

        while (*item) {
                struct udev_list_entry *next, *lookahead;
                struct udev_device *d;
                const char *sn, *name, *sysfs, *subsystem, *sysname;
                char *l, *k;
                bool is_master;

                sysfs = udev_list_entry_get_name(*item);
                if (!path_startswith(sysfs, sub))
                        return 0;

                d = udev_device_new_from_syspath(udev, sysfs);
                if (!d) {
                        *item = udev_list_entry_get_next(*item);
                        continue;
                }

                sn = udev_device_get_property_value(d, "ID_SEAT");
                if (isempty(sn))
                        sn = "seat0";

                /* Explicitly also check for tag 'seat' here */
                if (!streq(seat, sn) || !udev_device_has_tag(d, "seat")) {
                        udev_device_unref(d);
                        *item = udev_list_entry_get_next(*item);
                        continue;
                }

                is_master = udev_device_has_tag(d, "seat-master");

                name = udev_device_get_sysattr_value(d, "name");
                if (!name)
                        name = udev_device_get_sysattr_value(d, "id");
                subsystem = udev_device_get_subsystem(d);
                sysname = udev_device_get_sysname(d);

                /* Look if there's more coming after this */
                lookahead = next = udev_list_entry_get_next(*item);
                while (lookahead) {
                        const char *lookahead_sysfs;

                        lookahead_sysfs = udev_list_entry_get_name(lookahead);

                        if (path_startswith(lookahead_sysfs, sub) &&
                            !path_startswith(lookahead_sysfs, sysfs)) {
                                struct udev_device *lookahead_d;

                                lookahead_d = udev_device_new_from_syspath(udev, lookahead_sysfs);
                                if (lookahead_d) {
                                        const char *lookahead_sn;
                                        bool found;

                                        lookahead_sn = udev_device_get_property_value(d, "ID_SEAT");
                                        if (isempty(lookahead_sn))
                                                lookahead_sn = "seat0";

                                        found = streq(seat, lookahead_sn) && udev_device_has_tag(lookahead_d, "seat");
                                        udev_device_unref(lookahead_d);

                                        if (found)
                                                break;
                                }
                        }

                        lookahead = udev_list_entry_get_next(lookahead);
                }

                k = ellipsize(sysfs, n_columns, 20);
                printf("%s%s%s\n", prefix, draw_special_char(lookahead ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT),
                                   k ? k : sysfs);
                free(k);

                if (asprintf(&l,
                             "%s%s:%s%s%s%s",
                             is_master ? "[MASTER] " : "",
                             subsystem, sysname,
                             name ? " \"" : "", name ? name : "", name ? "\"" : "") < 0) {
                        udev_device_unref(d);
                        return -ENOMEM;
                }

                k = ellipsize(l, n_columns, 70);
                printf("%s%s%s\n", prefix, lookahead ? draw_special_char(DRAW_TREE_VERT) : "  ",
                                   k ? k : l);
                free(k);
                free(l);

                *item = next;
                if (*item) {
                        char *p;

                        p = strappend(prefix, lookahead ? draw_special_char(DRAW_TREE_VERT) : "  ");
                        show_sysfs_one(udev, seat, item, sysfs, p ? p : prefix, n_columns - 2);
                        free(p);
                }

                udev_device_unref(d);
        }

        return 0;
}
示例#10
0
   static void *Listener(void *parm)
   {
      DeviceChangeListener *This = (DeviceChangeListener *) parm;

      // Instantiate the udev object
      struct udev *udev = udev_new();
      if (!udev)
      {
         pthread_exit(NULL);
      }
   
      // Instantiate the monitor object
      struct udev_monitor *mon = udev_monitor_new_from_netlink(udev, "udev");

      // Start receiving notifications
      udev_monitor_enable_receiving(mon);

      // Get the file descriptor we'll wait on
      int fd = udev_monitor_get_fd(mon);

      while (true)
      {
         fd_set set;
         
         FD_ZERO(&set);
         FD_SET(fd, &set);

         if (select(fd + 1, &set, NULL, NULL, NULL) < 0)
         {
            break;
         }
         
         if (FD_ISSET(fd, &set))
         {
            struct udev_device *dev = udev_monitor_receive_device(mon);
            if (dev)
            {
#if 0
               printf("Got Device\n");
               printf("   Node: %s\n", udev_device_get_devnode(dev));
               printf("   Subsystem: %s\n", udev_device_get_subsystem(dev));
               printf("   Devtype: %s\n", udev_device_get_devtype(dev));
               printf("   Action: %s\n", udev_device_get_action(dev));
#endif
               if (This->mEnabled)
               {
                  This->mEnabled = false;
                  wxMutexGuiEnter();
                  wxCommandEvent e(EVT_DEVICE_CHANGE);
                  This->mHandler->AddPendingEvent(e);
                  wxMutexGuiLeave();
               }
         
               udev_device_unref(dev);
            }
         }
      }
   
      udev_unref(udev);

      pthread_exit(NULL);
   }
示例#11
0
void
UdevSubsystem::print_info(udev_device* device)
{
  log_debug("/---------------------------------------------");
  log_debug("devpath: " << udev_device_get_devpath(device));

  if (udev_device_get_action(device))
    log_debug("action: " << udev_device_get_action(device));
  //log_debug("init: " << udev_device_get_is_initialized(device));

  if (udev_device_get_subsystem(device))
    log_debug("subsystem: " << udev_device_get_subsystem(device));

  if (udev_device_get_devtype(device))
    log_debug("devtype:   " << udev_device_get_devtype(device));

  if (udev_device_get_syspath(device))
    log_debug("syspath:   " << udev_device_get_syspath(device));

  if (udev_device_get_sysname(device))
    log_debug("sysname:   " << udev_device_get_sysname(device));

  if (udev_device_get_sysnum(device))
    log_debug("sysnum:    " << udev_device_get_sysnum(device));

  if (udev_device_get_devnode(device))
    log_debug("devnode:   " << udev_device_get_devnode(device));

  if (udev_device_get_driver(device))
    log_debug("driver:    " << udev_device_get_driver(device));

  if (udev_device_get_action(device))
    log_debug("action:    " << udev_device_get_action(device));

  //udev_device_get_sysattr_value(device, "busnum");
  //udev_device_get_sysattr_value(device, "devnum");

#if 0
  // FIXME: only works with newer versions of libudev
  {
    log_debug("list: ");
    struct udev_list_entry* it = udev_device_get_tags_list_entry(device);
    while((it = udev_list_entry_get_next(it)) != 0)
    {
      log_debug("  "
                << udev_list_entry_get_name(it) << " = "
                << udev_list_entry_get_value(it)
        );
    }
  }

  {
    log_debug("properties: ");
    struct udev_list_entry* it = udev_device_get_properties_list_entry(device);
    while((it = udev_list_entry_get_next(it)) != 0)
    {
      log_debug("  "
                << udev_list_entry_get_name(it) << " = "
                << udev_list_entry_get_value(it)
        );
    }
  }

  {
    log_debug("devlist: ");
    struct udev_list_entry* it = udev_device_get_tags_list_entry(device);
    while((it = udev_list_entry_get_next(it)) != 0)
    {
      log_debug("  "
                << udev_list_entry_get_name(it) << " = "
                << udev_list_entry_get_value(it)
        );
    }
  }
#endif

  log_debug("\\----------------------------------------------");
}
示例#12
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;
        }
    }
示例#13
0
static int node_permissions_apply(struct udev_device *dev, bool apply,
                                  mode_t mode, uid_t uid, gid_t gid,
                                  struct udev_list *seclabel_list) {
        const char *devnode = udev_device_get_devnode(dev);
        dev_t devnum = udev_device_get_devnum(dev);
        struct stat stats;
        struct udev_list_entry *entry;
        int err = 0;

        if (streq(udev_device_get_subsystem(dev), "block"))
                mode |= S_IFBLK;
        else
                mode |= S_IFCHR;

        if (lstat(devnode, &stats) != 0) {
                err = -errno;
                log_debug_errno(errno, "can not stat() node '%s' (%m)", devnode);
                goto out;
        }

        if (((stats.st_mode & S_IFMT) != (mode & S_IFMT)) || (stats.st_rdev != devnum)) {
                err = -EEXIST;
                log_debug("found node '%s' with non-matching devnum %s, skip handling",
                          udev_device_get_devnode(dev), udev_device_get_id_filename(dev));
                goto out;
        }

        if (apply) {
                bool selinux = false;
                bool smack = false;

                if ((stats.st_mode & 0777) != (mode & 0777) || stats.st_uid != uid || stats.st_gid != gid) {
                        log_debug("set permissions %s, %#o, uid=%u, gid=%u", devnode, mode, uid, gid);
                        err = chmod(devnode, mode);
                        if (err < 0)
                                log_warning_errno(errno, "setting mode of %s to %#o failed: %m", devnode, mode);
                        err = chown(devnode, uid, gid);
                        if (err < 0)
                                log_warning_errno(errno, "setting owner of %s to uid=%u, gid=%u failed: %m", devnode, uid, gid);
                } else {
                        log_debug("preserve permissions %s, %#o, uid=%u, gid=%u", devnode, mode, uid, gid);
                }

                /* apply SECLABEL{$module}=$label */
                udev_list_entry_foreach(entry, udev_list_get_entry(seclabel_list)) {
                        const char *name, *label;
                        int r;

                        name = udev_list_entry_get_name(entry);
                        label = udev_list_entry_get_value(entry);

                        if (streq(name, "selinux")) {
                                selinux = true;

                                r = mac_selinux_apply(devnode, label);
                                if (r < 0)
                                        log_error_errno(r, "SECLABEL: failed to set SELinux label '%s': %m", label);
                                else
                                        log_debug("SECLABEL: set SELinux label '%s'", label);

                        } else if (streq(name, "smack")) {
                                smack = true;

                                r = mac_smack_apply(devnode, label);
                                if (r < 0)
                                        log_error_errno(r, "SECLABEL: failed to set SMACK label '%s': %m", label);
                                else
                                        log_debug("SECLABEL: set SMACK label '%s'", label);

                        } else
                                log_error("SECLABEL: unknown subsystem, ignoring '%s'='%s'", name, label);
                }

                /* set the defaults */
                if (!selinux)
                        mac_selinux_fix(devnode, true, false);
                if (!smack)
                        mac_smack_apply(devnode, NULL);
        }

        /* always update timestamp when we re-use the node, like on media change events */
        utimensat(AT_FDCWD, devnode, NULL, 0);
out:
        return err;
}
示例#14
0
文件: udev-node.c 项目: OPSF/uClinux
int udev_node_mknod(struct udev_device *dev, const char *file, dev_t devnum, mode_t mode, uid_t uid, gid_t gid)
{
	struct udev *udev = udev_device_get_udev(dev);
	char file_tmp[UTIL_PATH_SIZE + sizeof(TMP_FILE_EXT)];
	struct stat stats;
	int preserve = 0;
	int err = 0;

	if (major(devnum) == 0)
		devnum = udev_device_get_devnum(dev);

	if (strcmp(udev_device_get_subsystem(dev), "block") == 0)
		mode |= S_IFBLK;
	else
		mode |= S_IFCHR;

	if (file == NULL)
		file = udev_device_get_devnode(dev);

	if (lstat(file, &stats) == 0) {
		if (((stats.st_mode & S_IFMT) == (mode & S_IFMT)) && (stats.st_rdev == devnum)) {
			info(udev, "preserve file '%s', because it has correct dev_t\n", file);
			preserve = 1;
			udev_selinux_lsetfilecon(udev, file, mode);
		} else {
			info(udev, "atomically replace existing file '%s'\n", file);
			util_strlcpy(file_tmp, file, sizeof(file_tmp));
			util_strlcat(file_tmp, TMP_FILE_EXT, sizeof(file_tmp));
			unlink(file_tmp);
			udev_selinux_setfscreatecon(udev, file_tmp, mode);
			err = mknod(file_tmp, mode, devnum);
			udev_selinux_resetfscreatecon(udev);
			if (err != 0) {
				err(udev, "mknod(%s, %#o, %u, %u) failed: %m\n",
				    file_tmp, mode, major(devnum), minor(devnum));
				goto exit;
			}
			err = rename(file_tmp, file);
			if (err != 0) {
				err(udev, "rename(%s, %s) failed: %m\n", file_tmp, file);
				unlink(file_tmp);
			}
		}
	} else {
		info(udev, "mknod(%s, %#o, (%u,%u))\n", file, mode, major(devnum), minor(devnum));
		udev_selinux_setfscreatecon(udev, file, mode);
		err = mknod(file, mode, devnum);
		udev_selinux_resetfscreatecon(udev);
		if (err != 0) {
			err(udev, "mknod(%s, %#o, (%u,%u) failed: %m\n", file, mode, major(devnum), minor(devnum));
			goto exit;
		}
	}

	if (!preserve || stats.st_mode != mode) {
		info(udev, "chmod(%s, %#o)\n", file, mode);
		err = chmod(file, mode);
		if (err != 0) {
			err(udev, "chmod(%s, %#o) failed: %m\n", file, mode);
			goto exit;
		}
	}

	if (!preserve || stats.st_uid != uid || stats.st_gid != gid) {
		info(udev, "chown(%s, %u, %u)\n", file, uid, gid);
		err = chown(file, uid, gid);
		if (err != 0) {
			err(udev, "chown(%s, %u, %u) failed: %m\n", file, uid, gid);
			goto exit;
		}
	}
exit:
	return err;
}
示例#15
0
int main(int argc, char *argv[]) {
        _cleanup_udev_unref_ struct udev *udev = NULL;
        _cleanup_udev_event_unref_ struct udev_event *event = NULL;
        _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
        _cleanup_udev_rules_unref_ struct udev_rules *rules = NULL;
        char syspath[UTIL_PATH_SIZE];
        const char *devpath;
        const char *action;
        int err;

        err = fake_filesystems();
        if (err < 0)
                return EXIT_FAILURE;

        udev = udev_new();
        if (udev == NULL)
                return EXIT_FAILURE;

        log_debug("version %s", VERSION);
        mac_selinux_init("/dev");

        action = argv[1];
        if (action == NULL) {
                log_error("action missing");
                goto out;
        }

        devpath = argv[2];
        if (devpath == NULL) {
                log_error("devpath missing");
                goto out;
        }

        rules = udev_rules_new(udev, 1);

        strscpyl(syspath, sizeof(syspath), "/sys", devpath, NULL);
        dev = udev_device_new_from_synthetic_event(udev, syspath, action);
        if (dev == NULL) {
                log_debug("unknown device '%s'", devpath);
                goto out;
        }

        event = udev_event_new(dev);

        assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, SIGHUP, SIGCHLD, -1) >= 0);

        /* do what devtmpfs usually provides us */
        if (udev_device_get_devnode(dev) != NULL) {
                mode_t mode = 0600;

                if (streq(udev_device_get_subsystem(dev), "block"))
                        mode |= S_IFBLK;
                else
                        mode |= S_IFCHR;

                if (!streq(action, "remove")) {
                        mkdir_parents_label(udev_device_get_devnode(dev), 0755);
                        mknod(udev_device_get_devnode(dev), mode, udev_device_get_devnum(dev));
                } else {
                        unlink(udev_device_get_devnode(dev));
                        rmdir_parents(udev_device_get_devnode(dev), "/");
                }
        }

        udev_event_execute_rules(event,
                                 3 * USEC_PER_SEC, USEC_PER_SEC,
                                 NULL,
                                 rules);
        udev_event_execute_run(event,
                               3 * USEC_PER_SEC, USEC_PER_SEC);
out:
        mac_selinux_finish();

        return err ? EXIT_FAILURE : EXIT_SUCCESS;
}
示例#16
0
int main (void) {
	struct udev *udev;
	struct udev_enumerate *enumerate;
	struct udev_list_entry *devices, *dev_list_entry;
	struct udev_device *dev;
	struct udev_device *dev2;
   	struct udev_monitor *mon;
	int fd;
	udev = udev_new();
	if (!udev) {
		printf("Can't create udev\n");
		exit(1);
	}
	mon = udev_monitor_new_from_netlink(udev, "udev");
	udev_monitor_filter_add_match_subsystem_devtype(mon, "tty", NULL);
	udev_monitor_enable_receiving(mon);
	fd = udev_monitor_get_fd(mon);
	enumerate = udev_enumerate_new(udev);
	udev_enumerate_add_match_subsystem(enumerate, "tty");
	udev_enumerate_scan_devices(enumerate);
	devices = udev_enumerate_get_list_entry(enumerate);
	udev_list_entry_foreach(dev_list_entry, devices) {
		const char *path;
		path = udev_list_entry_get_name(dev_list_entry);
		dev = udev_device_new_from_syspath(udev, path);
		dev2 = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device");
		if (dev2) {
			printf("Device Node Path: %s\n", udev_device_get_devnode(dev));
			printf("  VID/PID: %s %s\n", udev_device_get_sysattr_value(dev2,"idVendor"), udev_device_get_sysattr_value(dev, "idProduct"));
			printf("  %s\n  %s\n", udev_device_get_sysattr_value(dev2,"manufacturer"), udev_device_get_sysattr_value(dev2,"product"));
			printf("  serial: %s\n", udev_device_get_sysattr_value(dev2, "serial"));
			udev_device_unref(dev2);
		}
	}
	udev_enumerate_unref(enumerate);
	

	while (1) {
		fd_set fds;
		struct timeval tv;
		int ret;
		
		FD_ZERO(&fds);
		FD_SET(fd, &fds);
		tv.tv_sec = 0;
		tv.tv_usec = 0;
		
		ret = select(fd+1, &fds, NULL, NULL, &tv);
		
		/* Check if our file descriptor has received data. */
		if (ret > 0 && FD_ISSET(fd, &fds)) {
			printf("\nselect() says there should be data\n");
			
			/* Make the call to receive the device.
			   select() ensured that this will not block. */
			dev = udev_monitor_receive_device(mon);
			if (dev) {
				printf("Got Device\n");
				printf("   Node: %s\n", udev_device_get_devnode(dev));
				printf("   Subsystem: %s\n", udev_device_get_subsystem(dev));
				printf("   Devtype: %s\n", udev_device_get_devtype(dev));

				printf("   Action: %s\n", udev_device_get_action(dev));
				udev_device_unref(dev);
			}
			else {
				printf("No Device from receive_device(). An error occured.\n");
			}					
		}
		usleep(250*1000);
		printf(".");
		fflush(stdout);
	}


	udev_unref(udev);

	return 0;       
}
示例#17
0
int main(int argc, char *argv[]) {
        struct udev *udev = NULL;
        struct udev_device *device = NULL;
        _cleanup_free_ char *saved = NULL;
        int r;

        if (argc != 3) {
                log_error("This program requires two arguments.");
                return EXIT_FAILURE;
        }

        log_set_target(LOG_TARGET_AUTO);
        log_parse_environment();
        log_open();

        umask(0022);

        r = mkdir_p("/var/lib/backlight", 0755);
        if (r < 0) {
                log_error("Failed to create backlight directory: %s", strerror(-r));
                goto finish;
        }

        udev = udev_new();
        if (!udev) {
                r = log_oom();
                goto finish;
        }

        errno = 0;
        device = udev_device_new_from_subsystem_sysname(udev, "backlight", argv[2]);
        if (!device) {
                if (errno != 0) {
                        log_error("Failed to get backlight device: %m");
                        r = -errno;
                } else
                        r = log_oom();

                goto finish;
        }

        if (!streq_ptr(udev_device_get_subsystem(device), "backlight")) {
                log_error("Not a backlight device: %s", argv[2]);
                r = -ENODEV;
                goto finish;
        }

        saved = strappend("/var/lib/backlight/", udev_device_get_sysname(device));
        if (!saved) {
                r = log_oom();
                goto finish;
        }

        if (streq(argv[1], "load")) {
                _cleanup_free_ char *value = NULL;

                r = read_one_line_file(saved, &value);
                if (r < 0) {

                        if (r == -ENOENT) {
                                r = 0;
                                goto finish;
                        }

                        log_error("Failed to read %s: %s", saved, strerror(-r));
                        goto finish;
                }

                r = udev_device_set_sysattr_value(device, "brightness", value);
                if (r < 0) {
                        log_error("Failed to write system attribute: %s", strerror(-r));
                        goto finish;
                }

        } else if (streq(argv[1], "save")) {
                const char *value;

                value = udev_device_get_sysattr_value(device, "brightness");
                if (!value) {
                        log_error("Failed to read system attribute: %s", strerror(-r));
                        goto finish;
                }

                r = write_string_file(saved, value);
                if (r < 0) {
                        log_error("Failed to write %s: %s", saved, strerror(-r));
                        goto finish;
                }

        } else {
                log_error("Unknown verb %s.", argv[1]);
                r = -EINVAL;
                goto finish;
        }

finish:
        if (device)
                udev_device_unref(device);

        if (udev)
                udev_unref(udev);

        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;

}
示例#18
0
int main (void)
{
	struct udev *udev;
	struct udev_enumerate *enumerate;
	struct udev_list_entry *devices, *dev_list_entry;
	struct udev_device *dev;
	struct udev_device *parent_dev;
	
	/* Create the udev object */
	udev = udev_new();
	if (!udev) {
		printf("Can't create udev\n");
		exit(1);
	}
	
	/* Create a list of the devices in the 'hidraw' subsystem. */
	enumerate = udev_enumerate_new(udev);
	udev_enumerate_add_match_subsystem(enumerate, "block");
	udev_enumerate_scan_devices(enumerate);
	devices = udev_enumerate_get_list_entry(enumerate);
	/* For each item enumerated, print out its information.
	   udev_list_entry_foreach is a macro which expands to
	   a loop. The loop will be executed for each member in
	   devices, setting dev_list_entry to a list entry
	   which contains the device's path in /sys. */
	udev_list_entry_foreach(dev_list_entry, devices) {
		const char *path;
		
		/* Get the filename of the /sys entry for the device
		   and create a udev_device object (dev) representing it */
		path = udev_list_entry_get_name(dev_list_entry);
		dev = udev_device_new_from_syspath(udev, path);
		
		parent_dev = udev_device_get_parent_with_subsystem_devtype(
		       dev,
		       "usb",
		       "usb_device");
		if (parent_dev) {
		/* usb_device_get_devnode() returns the path to the device node
		   itself in /dev. */
		printf("   Node: %s\n", udev_device_get_devnode(dev));
		printf("   Subsystem: %s\n", udev_device_get_subsystem(dev));
		printf("   Devtype: %s\n", udev_device_get_devtype(dev));
		/* The device pointed to by dev contains information about
		   the hidraw device. In order to get information about the
		   USB device, get the parent device with the
		   subsystem/devtype pair of "usb"/"usb_device". This will
		   be several levels up the tree, but the function will find
		   it.*/
		dev = udev_device_get_parent_with_subsystem_devtype(
		       dev,
		       "usb",
		       "usb_device");
	
		/* From here, we can call get_sysattr_value() for each file
		   in the device's /sys entry. The strings passed into these
		   functions (idProduct, idVendor, serial, etc.) correspond
		   directly to the files in the directory which represents
		   the USB device. Note that USB strings are Unicode, UCS2
		   encoded, but the strings returned from
		   udev_device_get_sysattr_value() are UTF-8 encoded. */
		printf("  VID/PID: %s %s\n",
		        udev_device_get_sysattr_value(dev,"idVendor"),
		        udev_device_get_sysattr_value(dev, "idProduct"));
		printf("  %s\n  %s\n",
		        udev_device_get_sysattr_value(dev,"manufacturer"),
		        udev_device_get_sysattr_value(dev,"product"));
		printf("  serial: %s\n",
		         udev_device_get_sysattr_value(dev, "serial"));
		udev_device_unref(dev);
		udev_device_unref(parent_dev);
	}}
	/* Free the enumerator object */
	udev_enumerate_unref(enumerate);

	udev_unref(udev);

	return 0;       
}
示例#19
0
int main(int argc, char *argv[]) {
        _cleanup_udev_unref_ struct udev *udev = NULL;
        _cleanup_udev_event_unref_ struct udev_event *event = NULL;
        _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
        _cleanup_udev_rules_unref_ struct udev_rules *rules = NULL;
        char syspath[UTIL_PATH_SIZE];
        const char *devpath;
        const char *action;
        sigset_t mask, sigmask_orig;
        int err;

        err = fake_filesystems();
        if (err < 0)
                return EXIT_FAILURE;

        udev = udev_new();
        if (udev == NULL)
                return EXIT_FAILURE;

        log_debug("version %s", VERSION);
        mac_selinux_init("/dev");

        sigprocmask(SIG_SETMASK, NULL, &sigmask_orig);

        action = argv[1];
        if (action == NULL) {
                log_error("action missing");
                goto out;
        }

        devpath = argv[2];
        if (devpath == NULL) {
                log_error("devpath missing");
                goto out;
        }

        rules = udev_rules_new(udev, 1);

        strscpyl(syspath, sizeof(syspath), "/sys", devpath, NULL);
        dev = udev_device_new_from_synthetic_event(udev, syspath, action);
        if (dev == NULL) {
                log_debug("unknown device '%s'", devpath);
                goto out;
        }

        event = udev_event_new(dev);

        sigfillset(&mask);
        sigprocmask(SIG_SETMASK, &mask, &sigmask_orig);
        event->fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
        if (event->fd_signal < 0) {
                fprintf(stderr, "error creating signalfd\n");
                goto out;
        }

        /* do what devtmpfs usually provides us */
        if (udev_device_get_devnode(dev) != NULL) {
                mode_t mode = 0600;

                if (streq(udev_device_get_subsystem(dev), "block"))
                        mode |= S_IFBLK;
                else
                        mode |= S_IFCHR;

                if (!streq(action, "remove")) {
                        mkdir_parents_label(udev_device_get_devnode(dev), 0755);
                        mknod(udev_device_get_devnode(dev), mode, udev_device_get_devnum(dev));
                } else {
                        unlink(udev_device_get_devnode(dev));
                        rmdir_parents(udev_device_get_devnode(dev), "/");
                }
        }

        udev_event_execute_rules(event,
                                 3 * USEC_PER_SEC, USEC_PER_SEC,
                                 NULL,
                                 rules,
                                 &sigmask_orig);
        udev_event_execute_run(event,
                               3 * USEC_PER_SEC, USEC_PER_SEC,
                               NULL);
out:
        if (event != NULL && event->fd_signal >= 0)
                close(event->fd_signal);
        mac_selinux_finish();

        return err ? EXIT_FAILURE : EXIT_SUCCESS;
}
示例#20
0
/* check for udev events for v4l2 devices*/
gboolean 
check_v4l2_udev_events(gpointer data)
{
    struct ALL_DATA * all_data = (struct ALL_DATA *) data;
    struct vdIn *videoIn = all_data->videoIn;
    struct GLOBAL *global = all_data->global;
    struct GWIDGET *gwidget = all_data->gwidget;
    
    fd_set fds;
    struct timeval tv;
    int ret;
    
    FD_ZERO(&fds);
    FD_SET(videoIn->udev_fd, &fds);
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    
    ret = select(videoIn->udev_fd+1, &fds, NULL, NULL, &tv);
    
    /* Check if our file descriptor has received data. */
    if (ret > 0 && FD_ISSET(videoIn->udev_fd, &fds)) 
    {
        /* Make the call to receive the device.
            select() ensured that this will not block. */
        struct udev_device *dev = udev_monitor_receive_device(videoIn->udev_mon);
        if (dev) 
        {
            if (global->debug)
            {
                g_print("Got Device event\n");
                g_print("   Node: %s\n", udev_device_get_devnode(dev));
                g_print("   Subsystem: %s\n", udev_device_get_subsystem(dev));
                g_print("   Devtype: %s\n", udev_device_get_devtype(dev));

                g_print("   Action: %s\n",udev_device_get_action(dev));
            }
            
            /*update device list*/
            g_signal_handlers_block_by_func(GTK_COMBO_BOX_TEXT(gwidget->Devices), 
                G_CALLBACK (Devices_changed), all_data);
                
            /* clear out the old device list... */
            if(videoIn->listDevices != NULL) freeDevices(videoIn->listDevices);
            
            GtkListStore *store = GTK_LIST_STORE(gtk_combo_box_get_model (GTK_COMBO_BOX(gwidget->Devices)));
            gtk_list_store_clear(store);
            
            /*create new device list*/
            videoIn->listDevices = enum_devices( videoIn->videodevice, videoIn->udev, global->debug );
            
            if (videoIn->listDevices->num_devices < 1)
            {
                //use current
                gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gwidget->Devices),
                    videoIn->videodevice);
                gtk_combo_box_set_active(GTK_COMBO_BOX(gwidget->Devices),0);
            }
            else
            {
                int i=0;
                for(i=0;i<(videoIn->listDevices->num_devices);i++)
                {
                    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gwidget->Devices),
                        videoIn->listDevices->listVidDevices[i].name);
                    if(videoIn->listDevices->listVidDevices[i].current)
                        gtk_combo_box_set_active(GTK_COMBO_BOX(gwidget->Devices),i);
                }
            }
            g_signal_handlers_unblock_by_func(GTK_COMBO_BOX_TEXT(gwidget->Devices), 
                G_CALLBACK (Devices_changed), all_data);
            
            udev_device_unref(dev);
        }
        else 
            g_printerr("No Device from receive_device(). An error occured.\n");

    }

    return(TRUE);
}
示例#21
0
static int udev_fill_info(struct device_info *info, struct stat *stat)
{
    struct udev *ctx;
    struct udev_device *dev, *parent;
    struct udev_enumerate *uenum;
    const char *attr;
    char holders_path[PATH_MAX + 1];
    DIR *holders_dir;
    struct dirent *dir_entry;
    unsigned long number;
    char *endptr;

    if (device_info_verbose >= 3)
	printf("udev_fill_info()\n");

    ctx = udev_new();
    if (!ctx) {
	if (device_info_verbose)
	    printf("no udev library context\n");
	return -1;
    }

    dev = udev_device_new_from_devnum(ctx, 'b', stat->st_rdev);
    if (!dev) {
	if (device_info_verbose)
	    printf("no udev context\n");
	udev_unref(ctx);
	return -1;
    }

    /*
     * first, look for for dependent devices (partitions or virtual mappings on
     * this device)
     */
    if (device_info_verbose >= 3)
	printf("looking for dependent devices\n");

    uenum = udev_enumerate_new(ctx);
    if (uenum) {
	struct udev_list_entry *entry;
	if (udev_enumerate_add_match_parent(uenum, dev) >= 0 &&
		udev_enumerate_scan_devices(uenum) >= 0) {
	    entry = udev_enumerate_get_list_entry(uenum);
	    if (entry) {
		/*
		 * the list of children includes the parent device, so make
		 * sure that has_children is -1 to end up with the correct
		 * count
		 */
		info->has_children = -1;

		while (entry) {
		    if (device_info_verbose >= 2)
			printf("child-or-self: %s\n", udev_list_entry_get_name(entry));
		    entry = udev_list_entry_get_next(entry);
		    info->has_children++;
		}
	    } else
		info->has_children = 0;
	}
	udev_enumerate_unref(uenum);
    }

    /* see if the holders directory in sysfs exists and has entries */
    if (device_info_verbose >= 2)
	printf("syspath: %s\n", udev_device_get_syspath(dev));
    if (info->has_children < 1 || device_info_verbose >= 3) {
	snprintf(holders_path, PATH_MAX, "%s/holders",
		udev_device_get_syspath(dev));
	holders_path[PATH_MAX] = 0;

	if (info->has_children < 0)
	    info->has_children = 0;

	holders_dir = opendir(holders_path);
	if (holders_dir) {
	    dir_entry = readdir(holders_dir);
	    while (dir_entry) {
		if (dir_entry->d_reclen && dir_entry->d_name[0] != '.') {
		    if (device_info_verbose >= 2)
			printf("holder: %s\n", dir_entry->d_name);

		    info->has_children++;

		    /* look up and print every holder when very verbose */
		    if (device_info_verbose < 3)
			break;
		}
		dir_entry = readdir(holders_dir);
	    }

	    closedir(holders_dir);
	}
    }

    /*
     * block devices on real hardware have either other block devices
     * (in the case of partitions) or the actual hardware as parent
     */
    parent = udev_device_get_parent(dev);

    if (!parent) {
	if (device_info_verbose >= 3)
	    printf("no parent found, therefore virtual device\n");
	info->type = TYPE_VIRTUAL;
	info->partition = 0;
	udev_device_unref(dev);
	return 0;
    }

    attr = udev_device_get_sysattr_value(dev, "removable");
    if (device_info_verbose >= 3) {
	if (attr)
	    printf("attribute \"removable\" is \"%s\"\n", attr);
	else
	    printf("attribute \"removable\" not found\n");
    }
    if (attr && !strcmp(attr, "1"))
	info->type = TYPE_REMOVABLE;
    else
	info->type = TYPE_FIXED;

    attr = udev_device_get_sysattr_value(dev, "partition");
    if (attr) {
	if (device_info_verbose >= 3)
	    printf("attribute \"partition\" is \"%s\"\n", attr);

	number = strtoul(attr, &endptr, 10);
	if (!*endptr)
	    info->partition = number;
    } else {
	printf("attribute \"partition\" not found\n");
	if (info->type != TYPE_VIRTUAL && parent) {
	    /* partitions have other block devices as parent */
	    attr = udev_device_get_subsystem(parent);
	    if (attr) {
		if (device_info_verbose >= 3)
		    printf("parent subsystem is \"%s\"\n", attr);

		if (!strcmp(attr, "block"))
		    /* we don't know the partition number, use 1 */
		    info->partition = 1;
		else
		    info->partition = 0;
	    }
	}
    }

    udev_device_unref(dev);
    udev_unref(ctx);
    return 0;
}
示例#22
0
文件: udevng.c 项目: endocode/ofono
	modem = g_hash_table_lookup(modem_list, syspath);
	if (modem == NULL) {
		modem = g_try_new0(struct modem_info, 1);
		if (modem == NULL)
			return;

		modem->type = MODEM_TYPE_SERIAL;
		modem->syspath = g_strdup(syspath);
		modem->devname = g_strdup(devname);
		modem->driver = g_strdup("legacy");

		g_hash_table_replace(modem_list, modem->syspath, modem);
	}

	subsystem = udev_device_get_subsystem(dev);

	DBG("%s", syspath);
	DBG("%s", devpath);
	DBG("%s (%s)", devnode, driver);

	info = g_try_new0(struct serial_device_info, 1);
	if (info == NULL)
		return;

	info->devpath = g_strdup(devpath);
	info->devnode = g_strdup(devnode);
	info->subsystem = g_strdup(subsystem);
	info->dev = udev_device_ref(dev);

	modem->devices = g_slist_append(modem->devices, info);
/////////////////////////////////////////////////////////////////////////////
/// main looop
void DeviceMonitor::Main( ) {
	assert( dev_monitor_ );
	
	const int fd_mon = udev_monitor_get_fd( dev_monitor_ );
	const int nfds = fd_mon + 1;
        int queue_tok = 8;
	
	sigset_t sigempty;
	sigemptyset( &sigempty );

        struct timespec timeout;

        if( activity )
        {
            timeout.tv_sec = 0;
            //timeout.tv_sec = 1;
            timeout.tv_nsec = 100000000;
            //timeout.tv_nsec = 0;
        }
        else
        {
            timeout.tv_sec = 999;
            timeout.tv_nsec = 0;
        }

	while ( true ) {
		fd_set fds_read;
		FD_ZERO( &fds_read );
		FD_SET( fd_mon, &fds_read );
		
		// block for something interesting to happen
		int res = pselect( nfds, &fds_read, 0, 0, &timeout, &sigempty );
		if ( res < 0 ) {
			if ( EINTR != errno ) throw ErrnoException( "select" );
			std::cout << "Exiting on signal\n";
			return; // signalled
		}
		
		// udev monitor notification?
		if ( FD_ISSET( fd_mon, &fds_read ) ) {
			std::tr1::shared_ptr< udev_device > device( udev_monitor_receive_device( dev_monitor_ ), &udev_device_unref );
                        // make sure this is a device we want to monitor
			if (!acceptDevice_(device.get())) continue;
	
			const char* str = udev_device_get_action( device.get() );
			if ( !str ) {
			} else if ( 0 == strcasecmp( str, "add" ) ) {
				deviceAdded_( device.get() );
			} else if ( 0 == strcasecmp( str, "remove" ) ) {
				deviceRemove_( device.get() );
			} else {
				if ( debug ) {
					std::cout << "action: " << str << '\n';
					std::cout << ' ' << udev_device_get_syspath(device.get()) << "' (" << udev_device_get_subsystem(device.get()) << ")\n";
				}
			}
		}

                if( activity )
                {
                    for( int i = 0; i < num_disks_; ++i )
                    {
                        std::ifstream stats;
                        stats.open( statsFile(i).c_str() );

                        char buf[256];
                        stats.getline( &(buf[0]), 255 );
                        std::string s(&(buf[0]));

                        // tokenize the string
                        std::string::size_type last = s.find_first_not_of( " ", 0 );
                        std::string::size_type pos = s.find_first_of( " ", last );

                        int tok = 0;
                        int queue_length = 0;
                        while( std::string::npos != pos || std::string::npos != last )
                        {
                            last = s.find_first_not_of(" ", pos );
                            pos = s.find_first_of( " ", last );
                            ++tok;

                            if( tok == queue_tok )
                            {
                                queue_length = atoi(s.substr( last, pos - last ).c_str());
                                if( debug )
                                    std::cout << " " << i << " " << queue_length;
                                break;
                            }
                        }

                        int led_idx = ledIndex(i);

                        if( led_enabled_[led_idx] && leds_ )
                        {
                            if( queue_length > 0 )
                            {
                                leds_->Set( LED_BLUE, led_idx, true );
                                leds_->Set( LED_RED, led_idx, true );
                            }
                            else
                            {
                                leds_->Set( LED_BLUE, led_idx, true );
                                leds_->Set( LED_RED, led_idx, false );
                            }
                        }
                    }
                }
                if( debug )
                    std::cout << "\n";
	}
}
/////////////////////////////////////////////////////////////////////////////
/// device removed
void DeviceMonitor::deviceRemove_( udev_device* device ) {
	std::cout << "REMOVED: '" << udev_device_get_syspath(device) << "' (" << udev_device_get_subsystem(device) << ")\n";
	deviceChanged_( device, false );
}
示例#25
0
int main(int argc, char *argv[])
{
        struct udev *udev;
        struct udev_event *event = NULL;
        struct udev_device *dev = NULL;
        struct udev_rules *rules = NULL;
        char syspath[UTIL_PATH_SIZE];
        const char *devpath;
        const char *action;
        sigset_t mask, sigmask_orig;
        int err = -EINVAL;

        udev = udev_new();
        if (udev == NULL)
                exit(1);
        info(udev, "version %s\n", VERSION);
        udev_selinux_init(udev);

        sigprocmask(SIG_SETMASK, NULL, &sigmask_orig);

        action = argv[1];
        if (action == NULL) {
                err(udev, "action missing\n");
                goto out;
        }

        devpath = argv[2];
        if (devpath == NULL) {
                err(udev, "devpath missing\n");
                goto out;
        }

        rules = udev_rules_new(udev, 1);

        util_strscpyl(syspath, sizeof(syspath), udev_get_sys_path(udev), devpath, NULL);
        dev = udev_device_new_from_syspath(udev, syspath);
        if (dev == NULL) {
                info(udev, "unknown device '%s'\n", devpath);
                goto out;
        }

        udev_device_set_action(dev, action);
        event = udev_event_new(dev);

        sigfillset(&mask);
        sigprocmask(SIG_SETMASK, &mask, &sigmask_orig);
        event->fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
        if (event->fd_signal < 0) {
                fprintf(stderr, "error creating signalfd\n");
                goto out;
        }

        /* do what devtmpfs usually provides us */
        if (udev_device_get_devnode(dev) != NULL) {
                mode_t mode;

                if (strcmp(udev_device_get_subsystem(dev), "block") == 0)
                        mode |= S_IFBLK;
                else
                        mode |= S_IFCHR;

                if (strcmp(action, "remove") != 0) {
                        util_create_path(udev, udev_device_get_devnode(dev));
                        mknod(udev_device_get_devnode(dev), mode, udev_device_get_devnum(dev));
                } else {
                        unlink(udev_device_get_devnode(dev));
                        util_delete_path(udev, udev_device_get_devnode(dev));
                }
        }

        err = udev_event_execute_rules(event, rules, &sigmask_orig);
        if (err == 0)
                udev_event_execute_run(event, NULL);
out:
        if (event != NULL && event->fd_signal >= 0)
                close(event->fd_signal);
        udev_event_unref(event);
        udev_device_unref(dev);
        udev_rules_unref(rules);
        udev_selinux_exit(udev);
        udev_unref(udev);
        if (err != 0)
                return 1;
        return 0;
}
示例#26
0
int main (void)
{
	struct udev *udev;
	struct udev_device *dev;
	udev = udev_new();
	struct udev_monitor *mon;
	int fd;
	if (!udev) {
		printf("Can't create udev\n");
		exit(1);
	}
	
/* Set up a monitor to monitor hidraw devices */
	mon = udev_monitor_new_from_netlink(udev, "udev");
	udev_monitor_filter_add_match_subsystem_devtype(mon, "block", "disk");
	udev_monitor_enable_receiving(mon);
	/* Get the file descriptor (fd) for the monitor.
	   This fd will get passed to select() */
	fd = udev_monitor_get_fd(mon);
	
	/* This section will run continuously, calling usleep() at
	   the end of each pass. This is to demonstrate how to use
	   a udev_monitor in a non-blocking way. */
	while (1) {
		/* Set up the call to select(). In this case, select() will
		   only operate on a single file descriptor, the one
		   associated with our udev_monitor. Note that the timeval
		   object is set to 0, which will cause select() to not
		   block. */
		fd_set fds;
		struct timeval tv;
		int ret;
		
		FD_ZERO(&fds);
		FD_SET(fd, &fds);
		tv.tv_sec = 0;
		tv.tv_usec = 0;
		
		ret = select(fd+1, &fds, NULL, NULL, &tv);
		
		/* Check if our file descriptor has received data. */
		if (ret > 0 && FD_ISSET(fd, &fds)) {
			
			/* Make the call to receive the device.
			   select() ensured that this will not block. */
			dev = udev_monitor_receive_device(mon);
			if (dev) {
				if(strcmp(udev_device_get_action(dev),"remove") != 0){
					printf("Got Device\n");
					printf("   Node: %s\n", udev_device_get_devnode(dev));
					printf("   Subsystem: %s\n", udev_device_get_subsystem(dev));
					printf("   Devtype: %s\n", udev_device_get_devtype(dev));
					printf("   Action: %s\n",udev_device_get_action(dev));
					
					dev = udev_device_get_parent_with_subsystem_devtype(dev,
			       			"usb",
			       			"usb_device");
					printf("  VID/PID: %s %s\n",
			        	udev_device_get_sysattr_value(dev,"idVendor"),
			        	udev_device_get_sysattr_value(dev, "idProduct"));
					printf("  %s\n  %s\n",
			        		udev_device_get_sysattr_value(dev,"manufacturer"),
			        		udev_device_get_sysattr_value(dev,"product"));
					printf("  serial: %s\n",
			         		udev_device_get_sysattr_value(dev, "serial"));
					}
				udev_device_unref(dev);
			}
			else {
				printf("No Device from receive_device(). An error occured.\n");
			}					
		}
		usleep(250*1000);
		printf(".");
		fflush(stdout);
	}
	udev_monitor_unref (mon);
	udev_unref(udev);
}
示例#27
0
int main (void)
{
	struct udev *udev;
	struct udev_enumerate *enumerate;
	struct udev_list_entry *devices, *dev_list_entry;
	struct udev_device *dev;

	struct udev_monitor *mon;
	int fd;

	/* Create the udev object */
	udev = udev_new();
	if (!udev) {
		printf("Can't create udev\n");
		exit(1);
	}

	/* This section sets up a monitor which will report events when
	   devices attached to the system change.  Events include "add",
	   "remove", "change", "online", and "offline".

	   This section sets up and starts the monitoring. Events are
	   polled for (and delivered) later in the file.

	   It is important that the monitor be set up before the call to
	   udev_enumerate_scan_devices() so that events (and devices) are
	   not missed.  For example, if enumeration happened first, there
	   would be no event generated for a device which was attached after
	   enumeration but before monitoring began.

	   Note that a filter is added so that we only get events for
	   "hidraw" devices. */

	/* Set up a monitor to monitor hidraw devices */
	mon = udev_monitor_new_from_netlink(udev, "udev");
//	udev_monitor_filter_add_match_subsystem_devtype(mon, "hidraw", NULL);
	udev_monitor_filter_add_match_subsystem_devtype(mon, "block", NULL);
	udev_monitor_enable_receiving(mon);
	/* Get the file descriptor (fd) for the monitor.
	   This fd will get passed to select() */
	fd = udev_monitor_get_fd(mon);


	/* Create a list of the devices in the 'hidraw' subsystem. */
	enumerate = udev_enumerate_new(udev);
//	udev_enumerate_add_match_subsystem(enumerate, "hidraw");
	udev_enumerate_add_match_subsystem(enumerate, "block");
	udev_enumerate_scan_devices(enumerate);
	devices = udev_enumerate_get_list_entry(enumerate);
	/* For each item enumerated, print out its information.
	   udev_list_entry_foreach is a macro which expands to
	   a loop. The loop will be executed for each member in
	   devices, setting dev_list_entry to a list entry
	   which contains the device's path in /sys. */
	udev_list_entry_foreach(dev_list_entry, devices) {
		const char *path;

		/* Get the filename of the /sys entry for the device
		   and create a udev_device object (dev) representing it */
		path = udev_list_entry_get_name(dev_list_entry);
		dev = udev_device_new_from_syspath(udev, path);

		/* usb_device_get_devnode() returns the path to the device node
		   itself in /dev. */
		printf("Device Node Path: %s\n", udev_device_get_devnode(dev));

#if 0
		/* The device pointed to by dev contains information about
		   the hidraw device. In order to get information about the
		   USB device, get the parent device with the
		   subsystem/devtype pair of "usb"/"usb_device". This will
		   be several levels up the tree, but the function will find
		   it.*/
		dev = udev_device_get_parent_with_subsystem_devtype(
		       dev,
		       "usb",
		       "usb_device");
		if (!dev) {
			printf("Unable to find parent usb device.");
			exit(1);
		}
#endif
		/* From here, we can call get_sysattr_value() for each file
		   in the device's /sys entry. The strings passed into these
		   functions (idProduct, idVendor, serial, etc.) correspond
		   directly to the files in the /sys directory which
		   represents the USB device. Note that USB strings are
		   Unicode, UCS2 encoded, but the strings returned from
		   udev_device_get_sysattr_value() are UTF-8 encoded. */
		printf("  VID/PID: %s %s\n",
		        udev_device_get_sysattr_value(dev,"idVendor"),
		        udev_device_get_sysattr_value(dev, "idProduct"));
		printf("  %s\n  %s\n",
		        udev_device_get_sysattr_value(dev,"manufacturer"),
		        udev_device_get_sysattr_value(dev,"product"));
		printf("  serial: %s\n",
		         udev_device_get_sysattr_value(dev, "serial"));
		udev_device_unref(dev);
	}
	/* Free the enumerator object */
	udev_enumerate_unref(enumerate);

	/* Begin polling for udev events. Events occur when devices
	   attached to the system are added, removed, or change state.
	   udev_monitor_receive_device() will return a device
	   object representing the device which changed and what type of
	   change occured.

	   The select() system call is used to ensure that the call to
	   udev_monitor_receive_device() will not block.

	   The monitor was set up earler in this file, and monitoring is
	   already underway.

	   This section will run continuously, calling usleep() at the end
	   of each pass. This is to demonstrate how to use a udev_monitor
	   in a non-blocking way. */
	while (1) {
		/* Set up the call to select(). In this case, select() will
		   only operate on a single file descriptor, the one
		   associated with our udev_monitor. Note that the timeval
		   object is set to 0, which will cause select() to not
		   block. */
		fd_set fds;
		struct timeval tv;
		int ret;

		FD_ZERO(&fds);
		FD_SET(fd, &fds);
		tv.tv_sec = 0;
		tv.tv_usec = 0;

		ret = select(fd+1, &fds, NULL, NULL, &tv);

		/* Check if our file descriptor has received data. */
		if (ret > 0 && FD_ISSET(fd, &fds)) {
			printf("\nselect() says there should be data\n");

			/* Make the call to receive the device.
			   select() ensured that this will not block. */
			dev = udev_monitor_receive_device(mon);
			if (dev) {
				printf("Got Device\n");
				printf("   Node: %s\n", udev_device_get_devnode(dev));
				printf("   Subsystem: %s\n", udev_device_get_subsystem(dev));
				printf("   Devtype: %s\n", udev_device_get_devtype(dev));

				printf("   Action: %s\n", udev_device_get_action(dev));
				udev_device_unref(dev);
			}
			else {
				printf("No Device from receive_device(). An error occured.\n");
			}
		}
		usleep(250*1000);
		printf(".");
		fflush(stdout);
	}


	udev_unref(udev);

	return 0;
}
示例#28
0
static void get_video_devices (ofGstCamData & cam_data)
{

	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;

}
示例#29
0
int dev_create(struct wiimote_dev *dev) {
	int ret = 0;
	struct udev *udev;
	struct udev_device *d, *p;
	struct stat st;
	const char *root, *snum, *driver, *subs;
	int num;

	if (!dev->device) {
		ret = EINVAL;
		goto exit;
	}

	if (stat(dev->device, &st)) {
		ret = errno;
		goto exit;
	}

	udev = udev_new();
	if (!udev) {
		fputs("could not connect to udev\n", stderr);
		ret = errno;
		goto exit;
	}

	d = udev_device_new_from_devnum(udev, 'c', st.st_rdev);
	if (!d) {
		fputs("could not find udev device\n", stderr);
		ret = errno;
		goto exit_udev;
	}

	p = udev_device_get_parent_with_subsystem_devtype(d, "hid", NULL);
	if (!p) {
		fputs("could not find parent HID device\n", stderr);
		ret = errno;
		goto exit_dev;
	}

	driver = udev_device_get_driver(p);
	subs = udev_device_get_subsystem(p);
	if (!driver || strcmp(driver, "wiimote") || !subs || strcmp(subs, "hid")) {
		fputs("parent is not a HID Wiimote\n", stderr);
		ret = errno;
		goto exit_dev;
	}

	root = udev_device_get_syspath(p);
	snum = udev_device_get_sysname(p);
	snum = snum ? strchr(snum, '.') : NULL;
	if (!root || !snum) {
		fputs("Could not get root path\n", stderr);
		ret = errno;
		goto exit_dev;
	}

	num = strtol(&snum[1], NULL, 16);
	if (num < 0) {
		fputs("Negative device number!\n", stderr);
		ret = errno;
		goto exit_dev;
	}
	dev->dev_id = num;

	dev->root = strdup(root);
	if (!dev->root) {
		fputs("Could not set device root\n", stderr);
		ret = errno;
		goto exit_dev;
	}

	printf("using device %d from root %s for %s\n",
		dev->dev_id, dev->root, dev->device);

	dev->ifs = XWII_IFACE_CORE | XWII_IFACE_ACCEL;
	ret = xwii_iface_new(&dev->iface, dev->root);
	if (ret) {
		fputs("Could not create xwiimote interface\n", stderr);
		ret = errno;
		goto exit_wii;
	}

	ret = xwii_iface_open(dev->iface, dev->ifs);
	if (ret) {
		fputs("Could not open xwiimote interface\n", stderr);
		ret = errno;
		goto exit_wii;
	}
	if (xwii_iface_opened(dev->iface) != dev->ifs) {
		fputs("Some interfaces failed to open\n", stderr);
		ret = errno;
		goto exit_wii;
	}

	dev->fd = xwii_iface_get_fd(dev->iface);

	goto exit_dev;

exit_wii:
	free(dev->root);
	dev->root = NULL;

exit_dev:
	udev_device_unref(d);
exit_udev:
	udev_unref(udev);
exit:
	return ret;
}
/////////////////////////////////////////////////////////////////////////////
/// device added
void DeviceMonitor::deviceAdded_( udev_device* device ) {
	std::cout << "ADDED: '" << udev_device_get_syspath(device) << "' (" << udev_device_get_subsystem(device) << ")\n";
	deviceChanged_( device, true );
}