~ubuntu-branches/ubuntu/trusty/systemd/trusty

« back to all changes in this revision

Viewing changes to src/libudev/libudev-device.c

Tags: upstream-202
ImportĀ upstreamĀ versionĀ 202

Show diffs side-by-side

added added

removed removed

Lines of Context:
1381
1381
        }
1382
1382
 
1383
1383
        if (S_ISLNK(statbuf.st_mode)) {
1384
 
                struct udev_device *dev;
1385
 
 
1386
1384
                /*
1387
1385
                 * Some core links return only the last element of the target path,
1388
1386
                 * these are just values, the paths should not be exposed.
1398
1396
                        goto out;
1399
1397
                }
1400
1398
 
1401
 
                /* resolve custom link to a device and return its syspath */
1402
 
                if (!streq(sysattr, "device")) {
1403
 
                        strscpyl(path, sizeof(path), udev_device->syspath, "/", sysattr, NULL);
1404
 
                        dev = udev_device_new_from_syspath(udev_device->udev, path);
1405
 
                        if (dev != NULL) {
1406
 
                                list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr,
1407
 
                                                                 udev_device_get_syspath(dev));
1408
 
                                val = udev_list_entry_get_value(list_entry);
1409
 
                                udev_device_unref(dev);
1410
 
                        }
1411
 
                }
1412
1399
                goto out;
1413
1400
        }
1414
1401
 
1440
1427
        return val;
1441
1428
}
1442
1429
 
 
1430
/**
 
1431
 * udev_device_set_sysattr_value:
 
1432
 * @udev_device: udev device
 
1433
 * @sysattr: attribute name
 
1434
 * @value: new value to be set
 
1435
 *
 
1436
 * Update the contents of the sys attribute and the cached value of the device.
 
1437
 *
 
1438
 * Returns: Negative error code on failure or 0 on success.
 
1439
 **/
 
1440
_public_ int udev_device_set_sysattr_value(struct udev_device *udev_device, const char *sysattr, char *value)
 
1441
{
 
1442
        struct udev_device *dev;
 
1443
        char path[UTIL_PATH_SIZE];
 
1444
        struct stat statbuf;
 
1445
        int fd;
 
1446
        ssize_t size, value_len;
 
1447
        int ret = 0;
 
1448
 
 
1449
        if (udev_device == NULL)
 
1450
                return -EINVAL;
 
1451
        dev = udev_device;
 
1452
        if (sysattr == NULL)
 
1453
                return -EINVAL;
 
1454
        if (value == NULL)
 
1455
                value_len = 0;
 
1456
        else
 
1457
                value_len = strlen(value);
 
1458
 
 
1459
        strscpyl(path, sizeof(path), udev_device_get_syspath(dev), "/", sysattr, NULL);
 
1460
        if (lstat(path, &statbuf) != 0) {
 
1461
                udev_list_entry_add(&dev->sysattr_value_list, sysattr, NULL);
 
1462
                ret = -ENXIO;
 
1463
                goto out;
 
1464
        }
 
1465
 
 
1466
        if (S_ISLNK(statbuf.st_mode)) {
 
1467
                ret = -EINVAL;
 
1468
                goto out;
 
1469
        }
 
1470
 
 
1471
        /* skip directories */
 
1472
        if (S_ISDIR(statbuf.st_mode)) {
 
1473
                ret = -EISDIR;
 
1474
                goto out;
 
1475
        }
 
1476
 
 
1477
        /* skip non-readable files */
 
1478
        if ((statbuf.st_mode & S_IRUSR) == 0) {
 
1479
                ret = -EACCES;
 
1480
                goto out;
 
1481
        }
 
1482
 
 
1483
        /* Value is limited to 4k */
 
1484
        if (value_len > 4096) {
 
1485
                ret = -EINVAL;
 
1486
                goto out;
 
1487
        }
 
1488
        util_remove_trailing_chars(value, '\n');
 
1489
 
 
1490
        /* write attribute value */
 
1491
        fd = open(path, O_WRONLY|O_CLOEXEC);
 
1492
        if (fd < 0) {
 
1493
                ret = -errno;
 
1494
                goto out;
 
1495
        }
 
1496
        size = write(fd, value, value_len);
 
1497
        close(fd);
 
1498
        if (size < 0) {
 
1499
                ret = -errno;
 
1500
                goto out;
 
1501
        }
 
1502
        if (size < value_len) {
 
1503
                ret = -EIO;
 
1504
                goto out;
 
1505
        }
 
1506
 
 
1507
        /* wrote a valid value, store it in cache and return it */
 
1508
        udev_list_entry_add(&dev->sysattr_value_list, sysattr, value);
 
1509
out:
 
1510
        if (dev != udev_device)
 
1511
                udev_device_unref(dev);
 
1512
        return ret;
 
1513
}
 
1514
 
1443
1515
static int udev_device_sysattr_list_read(struct udev_device *udev_device)
1444
1516
{
1445
1517
        struct dirent *dent;