int main () { udev = udev_new(); if(!udev) { fprintf(stderr, "Can't create udev.\n"); exit(EXIT_FAILURE); } mon = udev_monitor_new_from_netlink(udev, "udev"); udev_monitor_filter_add_match_subsystem_devtype(mon, "block", NULL); udev_monitor_enable_receiving(mon); while(1) { if (mon != NULL) FD_SET(udev_monitor_get_fd(mon), &readfds); select(udev_monitor_get_fd(mon) + 1, &readfds, NULL, NULL, NULL); if ((mon != NULL) && FD_ISSET(udev_monitor_get_fd(mon), &readfds)) { dev = udev_monitor_receive_device(mon); if(dev) { device = (char *) udev_device_get_sysname(dev); } } devnum = udev_device_get_devnum(dev); major = major(devnum); minor = minor(devnum); action = udev_device_get_action(dev); printf("Processing device %s %d:%d\n", action, major, minor); struct udev_list_entry * props = udev_device_get_properties_list_entry(dev); while(props != NULL) { printf("%s = %s\n", udev_list_entry_get_name(props), udev_list_entry_get_value(props)); props = udev_list_entry_get_next (props); } props = udev_device_get_sysattr_list_entry(dev); while(props != NULL) { printf("%s = %s\n", udev_list_entry_get_name(props), udev_device_get_sysattr_value(dev, udev_list_entry_get_name(props))); props = udev_list_entry_get_next (props); } } return 0; }
int scan_connected_devices(detector_state_t *state) { struct udev_list_entry *cursor; struct udev_enumerate *ue; struct udev_device *ud; const char *devnode = NULL; if( !(ue = udev_enumerate_new(state->u)) ) return 1; udev_enumerate_add_match_subsystem(ue, "tty"); udev_enumerate_add_match_property(ue, "ID_BUS", "usb"); udev_enumerate_scan_devices(ue); cursor = udev_enumerate_get_list_entry(ue); do { ud = udev_device_new_from_syspath( state->u, udev_list_entry_get_name(cursor)); if( (devnode = udev_device_get_devnode(ud)) ) spawn_server(state->exec_path, devnode); udev_device_unref(ud); } while( (cursor = udev_list_entry_get_next(cursor)) ); udev_enumerate_unref(ue); return 0; }
static virInterfacePtr udevInterfaceLookupByMACString(virConnectPtr conn, const char *macstr) { struct udev_iface_driver *driverState = conn->interfacePrivateData; struct udev *udev = udev_ref(driverState->udev); struct udev_enumerate *enumerate = NULL; struct udev_list_entry *dev_entry; struct udev_device *dev; const char *name; virInterfacePtr ret = NULL; enumerate = udevGetDevices(udev, VIR_UDEV_IFACE_ALL); if (!enumerate) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to lookup interface with MAC address '%s'"), macstr); goto err; } /* Match on MAC */ udev_enumerate_add_match_sysattr(enumerate, "address", macstr); /* Do the scan to load up the enumeration */ udev_enumerate_scan_devices(enumerate); /* Get a list we can walk */ dev_entry = udev_enumerate_get_list_entry(enumerate); /* Check that we got something back */ if (!dev_entry) { virReportError(VIR_ERR_NO_INTERFACE, _("couldn't find interface with MAC address '%s'"), macstr); goto err; } /* Check that we didn't get multiple items back */ if (udev_list_entry_get_next(dev_entry)) { virReportError(VIR_ERR_MULTIPLE_INTERFACES, _("the MAC address '%s' matches multiple interfaces"), macstr); goto err; } dev = udev_device_new_from_syspath(udev, udev_list_entry_get_name(dev_entry)); name = udev_device_get_sysname(dev); ret = virGetInterface(conn, name, macstr); udev_device_unref(dev); err: if (enumerate) udev_enumerate_unref(enumerate); udev_unref(udev); return ret; }
io_object_t io_device_iterator::next() { if (!m_next) return nullptr; else { udev_device* dev = udev_device_new_from_syspath(m_udev, udev_list_entry_get_name(m_next)); m_next = udev_list_entry_get_next(m_next); return new io_device(dev); } }
int find_and_open_p6s() { int result = -1; char buf[300]; memset(buf, 0, sizeof(buf)); get_usb_device_syspath(ID_VENDOR_YEALINK,ID_PRODUCT_VOIPUSBPHONE, buf); int len = strlen(buf); if (len==0) { return result; } printf("Found Skypemate P6S USB at %s \n", buf); struct udev* udev; struct udev_enumerate* enumerate; struct udev_list_entry* dev_list_entry; struct udev_device* dev; udev = udev_new(); if (udev<0) { perror("error creating udev object"); return result; } // enumerating all hidraw devices enumerate = udev_enumerate_new(udev); udev_enumerate_add_match_subsystem(enumerate, "hidraw"); udev_enumerate_scan_devices(enumerate); dev_list_entry = udev_enumerate_get_list_entry(enumerate); while ((dev_list_entry!=0) && (result==-1)) { const char* syspath = udev_list_entry_get_name(dev_list_entry); dev = udev_device_new_from_syspath(udev, syspath); // get hidraw USB parent struct udev_device* parent = udev_device_get_parent_with_subsystem_devtype(dev, "usb","usb_device"); if (parent != 0) { const char* parent_syspath = udev_device_get_syspath(parent); if ( strcmp(buf, parent_syspath) == 0) { // found it const char* devnode = udev_device_get_devnode(dev); printf("Found corresponding hidraw device: %s \n", devnode); result = open(devnode, O_RDONLY); } } udev_device_unref(dev); dev_list_entry = udev_list_entry_get_next(dev_list_entry); } udev_enumerate_unref(enumerate); udev_unref(udev); return result; }
///////////////////////////////////////////////////////////////////////////// /// enumerate existing devices void DeviceMonitor::enumDevices_( ) { assert( dev_context_ ); // create udev enumeration interface std::tr1::shared_ptr< udev_enumerate > dev_enum( udev_enumerate_new( dev_context_ ), &udev_enumerate_unref ); // only interested in scsi_device's udev_enumerate_add_match_subsystem( dev_enum.get(), "block" ); udev_enumerate_add_match_property( dev_enum.get(), "ID_BUS", "ata" ); udev_enumerate_scan_devices( dev_enum.get() ); // start //- enumerate list udev_list_entry* list_entry = udev_enumerate_get_list_entry( dev_enum.get() ); for ( ; list_entry; list_entry = udev_list_entry_get_next( list_entry ) ) { // retrieve device std::tr1::shared_ptr< udev_device > device( udev_device_new_from_syspath( udev_enumerate_get_udev( dev_enum.get() ), udev_list_entry_get_name( list_entry ) ), &udev_device_unref ); if ( !device ) continue; if (!acceptDevice_(device.get())) continue; int led_idx = scsiHostIndex_(device.get()); if (led_idx < 0) continue; if (debug || verbose > 1) std::cout << " device: " << udev_device_get_syspath(device.get()) << "\n led: " << led_idx << "\n"; leds_idx_[num_disks_] = led_idx; stats_files_[num_disks_] = std::string( udev_device_get_syspath(device.get()) ); stats_files_[num_disks_].append( "/stat" ); // make sure it's there and we can open it std::ifstream stats; stats.open( stats_files_[num_disks_].c_str() ); if( !stats ) { std::cout << " Couldn't open stats " << stats_files_[num_disks_] << "\n"; continue; } else stats.close(); ++num_disks_; deviceAdded_( device.get() ); } }
static int udev_device_get_devid(struct udev_device *dev, char *bufptr, size_t buflen) { struct udev_list_entry *entry; const char *bus; char devbyid[MAXPATHLEN]; /* The bus based by-id path is preferred */ bus = udev_device_get_property_value(dev, "ID_BUS"); if (bus == NULL) { const char *dm_uuid; /* * For multipath nodes use the persistent uuid based identifier * * Example: 'dm-uuid-mpath-35000c5006304de3f' */ dm_uuid = udev_device_get_property_value(dev, "DM_UUID"); if (dm_uuid != NULL) { (void) snprintf(bufptr, buflen, "dm-uuid-%s", dm_uuid); return (0); } return (ENODATA); } /* * locate the bus specific by-id link * * Example: 'scsi-MG03SCA300_350000494a8cb3d67-part1' */ (void) snprintf(devbyid, sizeof (devbyid), "%s%s-", DEV_BYID_PATH, bus); entry = udev_device_get_devlinks_list_entry(dev); while (entry != NULL) { const char *name; name = udev_list_entry_get_name(entry); if (strncmp(name, devbyid, strlen(devbyid)) == 0) { name += strlen(DEV_BYID_PATH); (void) stpncpy(bufptr, name, buflen); return (0); } entry = udev_list_entry_get_next(entry); } return (ENODATA); }
int read_fpga_status() { struct udev *udev; struct udev_enumerate *enumerate; struct udev_list_entry *device; struct udev_device *dev; const char *path; long prog_done = 0; udev = udev_new(); if (!udev) { fprintf(stderr, "ERROR: udev_new() failed\n"); return -1; } // Enumerate devcfg enumerate = udev_enumerate_new(udev); udev_enumerate_add_match_sysname(enumerate, XDEV_CFG_NAME); udev_enumerate_scan_devices(enumerate); device = udev_enumerate_get_list_entry(enumerate); // Did not find a device, lets try a different name if (!device) { fprintf(stderr, "ERROR: Could not find FPGA configuration device!\n"); return -1; } // List should have only one entry if (udev_list_entry_get_next(device) != 0) { fprintf(stderr, "ERROR: Found more than one FPGA configuration device!\n"); return -1; } // Create udev device path = udev_list_entry_get_name(device); dev = udev_device_new_from_syspath(udev, path); prog_done = (int)atol(udev_device_get_sysattr_value(dev, "prog_done")); udev_enumerate_unref(enumerate); udev_unref(udev); return(prog_done); }
static bool open_devices(udev_input_t *udev, const char *type, device_handle_cb cb) { struct udev_list_entry *devs = NULL; struct udev_list_entry *item = NULL; struct udev_enumerate *enumerate = udev_enumerate_new(udev->udev); if (!enumerate) return false; udev_enumerate_add_match_property(enumerate, type, "1"); udev_enumerate_scan_devices(enumerate); devs = udev_enumerate_get_list_entry(enumerate); for (item = devs; item; item = udev_list_entry_get_next(item)) { const char *name = udev_list_entry_get_name(item); /* Get the filename of the /sys entry for the device * and create a udev_device object (dev) representing it. */ struct udev_device *dev = udev_device_new_from_syspath(udev->udev, name); const char *devnode = udev_device_get_devnode(dev); if (devnode) { int fd = open(devnode, O_RDONLY | O_NONBLOCK); (void)fd; RARCH_LOG("[udev] Adding device %s as type %s.\n", devnode, type); if (!add_device(udev, devnode, cb)) RARCH_ERR("[udev] Failed to open device: %s (%s).\n", devnode, strerror(errno)); } udev_device_unref(dev); } udev_enumerate_unref(enumerate); return true; }
static GSList *hw_scan(GSList *options) { int i; GSList *devices = NULL; const char *conn = NULL; const char *serialcomm = NULL; GSList *l; struct sr_config *src; struct udev *udev; (void)options; for (l = options; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_CONN: conn = src->value; break; case SR_CONF_SERIALCOMM: serialcomm = src->value; break; } } if (!conn) conn = SERIALCONN; if (serialcomm == NULL) serialcomm = SERIALCOMM; udev = udev_new(); if (!udev) { sr_err("Failed to initialize udev."); } struct udev_enumerate *enumerate = udev_enumerate_new(udev); udev_enumerate_add_match_subsystem(enumerate, "usb-serial"); udev_enumerate_scan_devices(enumerate); struct udev_list_entry *devs = udev_enumerate_get_list_entry(enumerate); struct udev_list_entry *dev_list_entry; for (dev_list_entry = devs; dev_list_entry != NULL; dev_list_entry = udev_list_entry_get_next(dev_list_entry)) { const char *syspath = udev_list_entry_get_name(dev_list_entry); struct udev_device *dev = udev_device_new_from_syspath(udev, syspath); const char *sysname = udev_device_get_sysname(dev); struct udev_device *parent = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device"); if (!parent) { sr_err("Unable to find parent usb device for %s", sysname); continue; } const char *idVendor = udev_device_get_sysattr_value(parent, "idVendor"); const char *idProduct = udev_device_get_sysattr_value(parent, "idProduct"); if (strcmp(USB_VENDOR, idVendor) || strcmp(USB_PRODUCT, idProduct)) continue; const char *iSerial = udev_device_get_sysattr_value(parent, "serial"); const char *iProduct = udev_device_get_sysattr_value(parent, "product"); char path[32]; snprintf(path, sizeof(path), "/dev/%s", sysname); conn = path; size_t s = strcspn(iProduct, " "); char product[32]; char manufacturer[32]; if (s > sizeof(product) || strlen(iProduct) - s > sizeof(manufacturer)) { sr_err("Could not parse iProduct: %s.", iProduct); continue; } strncpy(product, iProduct, s); product[s] = 0; strcpy(manufacturer, iProduct + s + 1); //Create the device context and set its params struct dev_context *devc; if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) { sr_err("Device context malloc failed."); return devices; } if (mso_parse_serial(iSerial, iProduct, devc) != SR_OK) { sr_err("Invalid iSerial: %s.", iSerial); g_free(devc); return devices; } char hwrev[32]; sprintf(hwrev, "r%d", devc->hwrev); devc->ctlbase1 = 0; devc->protocol_trigger.spimode = 0; for (i = 0; i < 4; i++) { devc->protocol_trigger.word[i] = 0; devc->protocol_trigger.mask[i] = 0xff; } if (!(devc->serial = sr_serial_dev_inst_new(conn, serialcomm))) { g_free(devc); return devices; } struct sr_dev_inst *sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, manufacturer, product, hwrev); if (!sdi) { sr_err("Unable to create device instance for %s", sysname); sr_dev_inst_free(sdi); g_free(devc); return devices; } sdi->driver = di; sdi->priv = devc; for (i = 0; i < NUM_PROBES; i++) { struct sr_probe *probe; if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, mso19_probe_names[i]))) return 0; sdi->probes = g_slist_append(sdi->probes, probe); } //Add the driver struct drv_context *drvc = di->priv; drvc->instances = g_slist_append(drvc->instances, sdi); devices = g_slist_append(devices, sdi); } return devices; }
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; }
bool connmgr_add_scanned_avr_connections(struct conn_manager* self, struct console* console) { // Remove old connections. size_t i; for (i = 0; i < connmgr_size(self); i ++) { if (conn_is_of_type(self->conns[i], ConnectionHost2Avr)) { __connmgr_remove_connection_at(self, i); } } struct udev* udev_ctx = udev_new(); if (!udev_ctx) { console_log(console, ConsoleLogSevere, "udev context is invalid. Failed to scan connections."); return false; } // Enumerate devices that are in the hidraw subsystem. struct udev_enumerate* enumerate = udev_enumerate_new(udev_ctx); udev_enumerate_add_match_subsystem(enumerate, "hidraw"); udev_enumerate_scan_devices(enumerate); struct udev_list_entry* first_devent = udev_enumerate_get_list_entry(enumerate); // Scan all the devices. struct udev_list_entry* devent; for (devent = first_devent; devent != nullptr; devent = udev_list_entry_get_next(devent)) { // Get device path. const char* path = udev_list_entry_get_name(devent); struct udev_device* dev = udev_device_new_from_syspath(udev_ctx, path); // Get device node path. const char* node_path = udev_device_get_devnode(dev); console_log(console, ConsoleLogNormal, "Device node path: %s.", node_path); // Get parent usb device. dev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device"); if (!dev) { console_log(console, ConsoleLogNormal, "Unable to find parent usb device. This device will be skipped."); continue; } // Extract device infos. const char* vender_id = udev_device_get_sysattr_value(dev, "idVendor"); const char* product_id = udev_device_get_sysattr_value(dev, "idProduct"); const char* manufacturer = udev_device_get_sysattr_value(dev,"manufacturer"); const char* product_name = udev_device_get_sysattr_value(dev,"product"); console_log(console, ConsoleLogNormal, "\tVender ID & Product ID: %s %s", vender_id, product_id); console_log(console, ConsoleLogNormal, "\tManufacturer: %s", manufacturer); console_log(console, ConsoleLogNormal, "\tProduct Name: %s", product_name); udev_device_unref(dev); // Add new connection. char combined_id[64]; sprintf(combined_id, "vid=%s pid=%s", vender_id, product_id); __connmgr_add_connection(self, &conn_h2a_create(console, combined_id, product_name, manufacturer, node_path)->__parent); } udev_enumerate_unref(enumerate); udev_unref(udev_ctx); return true; }
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 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; }
static void udev_monitor_watcher (struct udev_monitor *udev_monitor, NihIoWatch * watch, NihIoEvents events) { struct udev_device * udev_device; nih_local char * subsystem = NULL; nih_local char * action = NULL; nih_local char * kernel = NULL; nih_local char * devpath = NULL; nih_local char * devname = NULL; nih_local char * name = NULL; nih_local char ** env = NULL; const char * value = NULL; size_t env_len = 0; DBusPendingCall * pending_call; char *(*copy_string)(const void *, const char *) = NULL; udev_device = udev_monitor_receive_device (udev_monitor); if (! udev_device) return; copy_string = no_strip_udev_data ? nih_strdup : make_safe_string; value = udev_device_get_subsystem (udev_device); subsystem = value ? copy_string (NULL, value) : NULL; value = udev_device_get_action (udev_device); action = value ? copy_string (NULL, value) : NULL; value = udev_device_get_sysname (udev_device); kernel = value ? copy_string (NULL, value) : NULL; value = udev_device_get_devpath (udev_device); devpath = value ? copy_string (NULL, value) : NULL; value = udev_device_get_devnode (udev_device); devname = value ? copy_string (NULL, value) : NULL; /* Protect against the "impossible" */ if (! action) goto out; if (! strcmp (action, "add")) { name = NIH_MUST (nih_sprintf (NULL, "%s-device-added", subsystem)); } else if (! strcmp (action, "change")) { name = NIH_MUST (nih_sprintf (NULL, "%s-device-changed", subsystem)); } else if (! strcmp (action, "remove")) { name = NIH_MUST (nih_sprintf (NULL, "%s-device-removed", subsystem)); } else { name = NIH_MUST (nih_sprintf (NULL, "%s-device-%s", subsystem, action)); } env = NIH_MUST (nih_str_array_new (NULL)); if (kernel) { nih_local char *var = NULL; var = NIH_MUST (nih_sprintf (NULL, "KERNEL=%s", kernel)); NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); } if (devpath) { nih_local char *var = NULL; var = NIH_MUST (nih_sprintf (NULL, "DEVPATH=%s", devpath)); NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); } if (devname) { nih_local char *var = NULL; var = NIH_MUST (nih_sprintf (NULL, "DEVNAME=%s", devname)); NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); } if (subsystem) { nih_local char *var = NULL; var = NIH_MUST (nih_sprintf (NULL, "SUBSYSTEM=%s", subsystem)); NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); } if (action) { nih_local char *var = NULL; var = NIH_MUST (nih_sprintf (NULL, "ACTION=%s", action)); NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); } for (struct udev_list_entry *list_entry = udev_device_get_properties_list_entry (udev_device); list_entry != NULL; list_entry = udev_list_entry_get_next (list_entry)) { nih_local char *udev_name = NULL; nih_local char *udev_value = NULL; nih_local char *var = NULL; udev_name = copy_string (NULL, udev_list_entry_get_name (list_entry)); if (! strcmp (udev_name, "DEVPATH")) continue; if (! strcmp (udev_name, "DEVNAME")) continue; if (! strcmp (udev_name, "SUBSYSTEM")) continue; if (! strcmp (udev_name, "ACTION")) continue; udev_value = copy_string (NULL, udev_list_entry_get_value (list_entry)); var = NIH_MUST (nih_sprintf (NULL, "%s=%s", udev_name, udev_value)); NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var)); } nih_debug ("%s %s", name, devname ? devname : ""); pending_call = upstart_emit_event (upstart, name, env, FALSE, NULL, emit_event_error, NULL, NIH_DBUS_TIMEOUT_NEVER); if (! pending_call) { NihError *err; int saved = errno; err = nih_error_get (); nih_warn ("%s", err->message); if (saved != ENOMEM && subsystem) nih_warn ("Likely that udev '%s' event contains binary garbage", subsystem); nih_free (err); } dbus_pending_call_unref (pending_call); out: udev_device_unref (udev_device); }
int main( int argc, char** argv ) { int rc = 0; char pathbuf[PATH_MAX+1]; struct udev* udev_client = NULL; struct udev_monitor* monitor = NULL; int monitor_fd = 0; struct udev_device* dev = NULL; struct pollfd pfd[1]; int num_events = INT_MAX; int num_forks = 0; // usage: $0 [num events to process [num times to fork]] if( argc > 1 ) { char* tmp = NULL; num_events = (int)strtol( argv[1], &tmp, 10 ); if( tmp == argv[1] || *tmp != '\0' ) { fprintf(stderr, "Usage: %s [number of events to process [number of times to fork]]\n", argv[0] ); exit(1); } if( argc > 2 ) { num_forks = (int)strtol( argv[2], &tmp, 10 ); if( tmp == argv[2] || *tmp != '\0' ) { fprintf(stderr, "Usage: %s [number of events to process [number of times to fork]]\n", argv[0] ); exit(1); } } } // make sure events dir exists log_trace("events directory '%s'", UDEV_FS_EVENTS_DIR); rc = mkdir( UDEV_FS_EVENTS_DIR, 0700 ); if( rc != 0 ) { rc = -errno; if( rc != -EEXIST ) { log_error("mkdir('%s') rc = %d", UDEV_FS_EVENTS_DIR, rc ); exit(1); } } udev_monitor_fs_events_path( "", pathbuf, 0 ); printf("Watching '%s'\n", pathbuf ); udev_client = udev_new(); if( udev_client == NULL ) { // OOM exit(2); } monitor = udev_monitor_new_from_netlink( udev_client, "udev" ); if( monitor == NULL ) { // OOM or error udev_unref( udev_client ); exit(2); } printf("Press Ctrl-C to quit\n"); monitor_fd = udev_monitor_get_fd( monitor ); if( monitor_fd < 0 ) { rc = -errno; log_error("udev_monitor_get_fd rc = %d\n", rc ); exit(3); } pfd[0].fd = monitor_fd; pfd[0].events = POLLIN; while( num_events > 0 ) { // wait for the next device rc = poll( pfd, 1, -1 ); if( rc < 0 ) { log_error("poll(%d) rc = %d\n", monitor_fd, rc ); break; } // get devices while( num_events > 0 ) { dev = udev_monitor_receive_device( monitor ); if( dev == NULL ) { break; } int pid = getpid(); struct udev_list_entry *list_entry = NULL; printf("[%d] [%d] ACTION: '%s'\n", pid, num_events, udev_device_get_action( dev ) ); printf("[%d] [%d] SEQNUM: %llu\n", pid, num_events, udev_device_get_seqnum( dev ) ); printf("[%d] [%d] USEC: %llu\n", pid, num_events, udev_device_get_usec_since_initialized( dev ) ); printf("[%d] [%d] DEVNODE: '%s'\n", pid, num_events, udev_device_get_devnode( dev ) ); printf("[%d] [%d] DEVPATH: '%s'\n", pid, num_events, udev_device_get_devpath( dev ) ); printf("[%d] [%d] SYSNAME: '%s'\n", pid, num_events, udev_device_get_sysname( dev ) ); printf("[%d] [%d] SYSPATH: '%s'\n", pid, num_events, udev_device_get_syspath( dev ) ); printf("[%d] [%d] SUBSYSTEM: '%s'\n", pid, num_events, udev_device_get_subsystem( dev ) ); printf("[%d] [%d] DEVTYPE: '%s'\n", pid, num_events, udev_device_get_devtype( dev ) ); printf("[%d] [%d] SYSNUM: '%s'\n", pid, num_events, udev_device_get_sysnum( dev ) ); printf("[%d] [%d] DRIVER: '%s'\n", pid, num_events, udev_device_get_driver( dev ) ); printf("[%d] [%d] DEVNUM: %d:%d\n", pid, num_events, major( udev_device_get_devnum( dev ) ), minor( udev_device_get_devnum( dev ) ) ); printf("[%d] [%d] IFINDEX: '%s'\n", pid, num_events, udev_device_get_property_value( dev, "IFINDEX" ) ); printf("[%d] [%d] DEVMODE: '%s'\n", pid, num_events, udev_device_get_property_value( dev, "DEVMODE" ) ); printf("[%d] [%d] DEVUID: '%s'\n", pid, num_events, udev_device_get_property_value( dev, "DEVUID" ) ); printf("[%d] [%d] DEVGID: '%s'\n", pid, num_events, udev_device_get_property_value( dev, "DEVGID" ) ); list_entry = udev_device_get_devlinks_list_entry( dev ); udev_list_entry_foreach( list_entry, udev_list_entry_get_next( list_entry )) { printf("[%d] [%d] devlink: '%s'\n", pid, num_events, udev_list_entry_get_name( list_entry ) ); } list_entry = udev_device_get_properties_list_entry( dev ); udev_list_entry_foreach( list_entry, udev_list_entry_get_next( list_entry )) { printf("[%d] [%d] property: '%s' = '%s'\n", pid, num_events, udev_list_entry_get_name( list_entry ), udev_list_entry_get_value( list_entry ) ); } list_entry = udev_device_get_tags_list_entry( dev ); udev_list_entry_foreach( list_entry, udev_list_entry_get_next( list_entry )) { printf("[%d] [%d] tag: '%s'\n", pid, num_events, udev_list_entry_get_name( list_entry ) ); }