summaryrefslogtreecommitdiffstats
path: root/lib/sysfs.c
diff options
context:
space:
mode:
authorKarel Zak2014-08-01 12:08:44 +0200
committerKarel Zak2014-08-01 12:08:44 +0200
commit6c987ca9d7ce31544e55541c680d11ac9b47b22f (patch)
tree1edb9b11141f28b4688428b06d1721b93f36abaa /lib/sysfs.c
parentMerge branch 'travis' of git://github.com/kerolasa/lelux-utiliteetit (diff)
downloadkernel-qcow2-util-linux-6c987ca9d7ce31544e55541c680d11ac9b47b22f.tar.gz
kernel-qcow2-util-linux-6c987ca9d7ce31544e55541c680d11ac9b47b22f.tar.xz
kernel-qcow2-util-linux-6c987ca9d7ce31544e55541c680d11ac9b47b22f.zip
lib/sysfs: allow to write to sysfs attributes
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'lib/sysfs.c')
-rw-r--r--lib/sysfs.c48
1 files changed, 42 insertions, 6 deletions
diff --git a/lib/sysfs.c b/lib/sysfs.c
index bbe238b7c..e2baf7fcd 100644
--- a/lib/sysfs.c
+++ b/lib/sysfs.c
@@ -11,6 +11,7 @@
#include "pathnames.h"
#include "sysfs.h"
#include "fileutils.h"
+#include "all-io.h"
char *sysfs_devno_attribute_path(dev_t devno, char *buf,
size_t bufsiz, const char *attr)
@@ -204,9 +205,9 @@ int sysfs_has_attribute(struct sysfs_cxt *cxt, const char *attr)
return sysfs_stat(cxt, attr, &st) == 0;
}
-static int sysfs_open(struct sysfs_cxt *cxt, const char *attr)
+static int sysfs_open(struct sysfs_cxt *cxt, const char *attr, int flags)
{
- int fd = open_at(cxt->dir_fd, cxt->dir_path, attr, O_RDONLY|O_CLOEXEC);
+ int fd = open_at(cxt->dir_fd, cxt->dir_path, attr, flags);
if (fd == -1 && errno == ENOENT &&
strncmp(attr, "queue/", 6) == 0 && cxt->parent) {
@@ -214,8 +215,7 @@ static int sysfs_open(struct sysfs_cxt *cxt, const char *attr)
/* Exception for "queue/<attr>". These attributes are available
* for parental devices only
*/
- fd = open_at(cxt->parent->dir_fd, cxt->dir_path, attr,
- O_RDONLY|O_CLOEXEC);
+ fd = open_at(cxt->parent->dir_fd, cxt->dir_path, attr, flags);
}
return fd;
}
@@ -239,7 +239,7 @@ DIR *sysfs_opendir(struct sysfs_cxt *cxt, const char *attr)
int fd = -1;
if (attr)
- fd = sysfs_open(cxt, attr);
+ fd = sysfs_open(cxt, attr, O_RDONLY|O_CLOEXEC);
else if (cxt->dir_fd >= 0)
/* request to open root of device in sysfs (/sys/block/<dev>)
@@ -264,7 +264,7 @@ DIR *sysfs_opendir(struct sysfs_cxt *cxt, const char *attr)
static FILE *sysfs_fopen(struct sysfs_cxt *cxt, const char *attr)
{
- int fd = sysfs_open(cxt, attr);
+ int fd = sysfs_open(cxt, attr, O_RDONLY|O_CLOEXEC);
return fd < 0 ? NULL : fdopen(fd, "r" UL_CLOEXECSTR);
}
@@ -419,6 +419,42 @@ int sysfs_read_int(struct sysfs_cxt *cxt, const char *attr, int *res)
return -1;
}
+int sysfs_write_string(struct sysfs_cxt *cxt, const char *attr, const char *str)
+{
+ int fd = sysfs_open(cxt, attr, O_WRONLY|O_CLOEXEC);
+ int rc, errsv;
+
+ if (fd < 0)
+ return -errno;
+ rc = write_all(fd, str, strlen(str));
+
+ errsv = errno;
+ close(fd);
+ errno = errsv;
+ return rc;
+}
+
+int sysfs_write_u64(struct sysfs_cxt *cxt, const char *attr, uint64_t num)
+{
+ char buf[sizeof(stringify_value(ULLONG_MAX))];
+ int fd, rc = 0, len, errsv;
+
+ fd = sysfs_open(cxt, attr, O_WRONLY|O_CLOEXEC);
+ if (fd < 0)
+ return -errno;
+
+ len = snprintf(buf, sizeof(buf), "%ju", num);
+ if (len < 0 || (size_t) len + 1 > sizeof(buf))
+ rc = -errno;
+ else
+ rc = write_all(fd, buf, len);
+
+ errsv = errno;
+ close(fd);
+ errno = errsv;
+ return rc;
+}
+
char *sysfs_strdup(struct sysfs_cxt *cxt, const char *attr)
{
char buf[1024];