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); }
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; }
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; }
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; }
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; }
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; }
const char* UdevDevice::getSubsystem(void) { return udev_device_get_subsystem(device); }
/* 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; }
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; }
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); }
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("\\----------------------------------------------"); }
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 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; }
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; }
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; }
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; }
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; }
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; }
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; }
/* 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); }
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; }
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 ); }
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; }
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); }
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; }
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; }
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 ); }