aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2016-06-15 15:47:01 -0500
committerRob Landley <rob@landley.net>2016-06-15 15:47:01 -0500
commit46409d50e5632b28b88cfa4991fffef9adaa490d (patch)
tree4c3347b37664b580996e4551bde023346567728b /lib
parent97ddc600c95623bf803eac4f2a4deda2a2db02d4 (diff)
downloadtoybox-46409d50e5632b28b88cfa4991fffef9adaa490d.tar.gz
Add readlink0() and readlinkat0() which null terminate the data.
Diffstat (limited to 'lib')
-rw-r--r--lib/lib.c20
-rw-r--r--lib/lib.h2
2 files changed, 21 insertions, 1 deletions
diff --git a/lib/lib.c b/lib/lib.c
index 66814a45..b742bd17 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -444,7 +444,8 @@ off_t fdlength(int fd)
// Read contents of file as a single nul-terminated string.
// measure file size if !len, allocate buffer if !buf
-// note: for existing buffers use len = size-1, will set buf[len] = 0
+// Existing buffers need len in *plen
+// Returns amount of data read in *plen
char *readfileat(int dirfd, char *name, char *ibuf, off_t *plen)
{
off_t len, rlen;
@@ -1130,3 +1131,20 @@ struct group *bufgetgrgid(gid_t gid)
return &list->gr;
}
+
+// Always null terminates, returns 0 for failure, len for success
+int readlinkat0(int dirfd, char *path, char *buf, int len)
+{
+ if (!len) return 0;
+
+ len = readlinkat(dirfd, path, buf, len-1);
+ if (len<1) return 0;
+ buf[len] = 0;
+
+ return len;
+}
+
+int readlink0(char *path, char *buf, int len)
+{
+ return readlinkat0(AT_FDCWD, path, buf, len);
+}
diff --git a/lib/lib.h b/lib/lib.h
index f545a794..3088f252 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -207,6 +207,8 @@ int dev_major(int dev);
int dev_makedev(int major, int minor);
struct passwd *bufgetpwuid(uid_t uid);
struct group *bufgetgrgid(gid_t gid);
+int readlinkat0(int dirfd, char *path, char *buf, int len);
+int readlink0(char *path, char *buf, int len);
#define HR_SPACE 1 // Space between number and units
#define HR_B 2 // Use "B" for single byte units