lib/sysfs: allow to write to sysfs attributes

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2014-08-01 12:08:44 +02:00
parent f9afb37d1a
commit 6c987ca9d7
2 changed files with 45 additions and 6 deletions

View File

@ -58,6 +58,9 @@ extern int sysfs_read_s64(struct sysfs_cxt *cxt, const char *attr, int64_t *res)
extern int sysfs_read_u64(struct sysfs_cxt *cxt, const char *attr, uint64_t *res);
extern int sysfs_read_int(struct sysfs_cxt *cxt, const char *attr, int *res);
extern int sysfs_write_string(struct sysfs_cxt *cxt, const char *attr, const char *str);
extern int sysfs_write_u64(struct sysfs_cxt *cxt, const char *attr, uint64_t num);
extern char *sysfs_get_devname(struct sysfs_cxt *cxt, char *buf, size_t bufsiz);
extern char *sysfs_strdup(struct sysfs_cxt *cxt, const char *attr);

View File

@ -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];