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);
#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)
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) {
/* 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;
}
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>)
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);
}
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];