From: Rob Landley Date: Wed, 15 Jun 2016 20:47:01 +0000 (-0500) Subject: Add readlink0() and readlinkat0() which null terminate the data. X-Git-Tag: android-x86-7.1-r1~6^2~4^2~74 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=46409d50e5632b28b88cfa4991fffef9adaa490d;p=android-x86%2Fexternal-toybox.git Add readlink0() and readlinkat0() which null terminate the data. --- 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 diff --git a/toys/other/lspci.c b/toys/other/lspci.c index 077ce757..a0671791 100644 --- a/toys/other/lspci.c +++ b/toys/other/lspci.c @@ -50,10 +50,9 @@ static int do_lspci(struct dirtree *new) if (-1 == (dirfd = openat(dirtree_parentfd(new), new->name, O_RDONLY))) return 0; - // it's ok for the driver link not to be there, whatever fortify says *driver = 0; if (toys.optflags & FLAG_k) - if (readlinkat(dirfd, "driver", driver, sizeof(driver))) {}; + readlinkat0(dirfd, "driver", driver, sizeof(driver)); for (fields = (char*[]){"class", "vendor", "device", 0}; *fields; fields++) { int fd, size = 6 + 2*((toys.optflags & FLAG_e) && p == toybuf); @@ -122,8 +121,7 @@ void lspci_main(void) { if (CFG_LSPCI_TEXT && TT.numeric != 1) { if (!TT.ids) TT.ids = "/usr/share/misc/pci.ids"; - if (!(TT.db = fopen(TT.ids, "r"))) - perror_msg("could not open PCI ID db"); + if (!(TT.db = fopen(TT.ids, "r"))) perror_msg("%s", TT.ids); } dirtree_read("/sys/bus/pci/devices", do_lspci); diff --git a/toys/other/pwdx.c b/toys/other/pwdx.c index bde16e79..2a72dba3 100644 --- a/toys/other/pwdx.c +++ b/toys/other/pwdx.c @@ -20,20 +20,14 @@ void pwdx_main(void) char **optargs; for (optargs = toys.optargs; *optargs; optargs++) { - char *path; - int num_bytes; + char *path = toybuf; - path = xmprintf("/proc/%s/cwd", *optargs); - num_bytes = readlink(path, toybuf, sizeof(toybuf)-1); - free(path); - - if (num_bytes==-1) { + sprintf(toybuf, "/proc/%d/cwd", atoi(*optargs)); + if (!readlink0(path, toybuf, sizeof(toybuf))) { path = strerror(errno); toys.exitval = 1; - } else { - path = toybuf; - toybuf[num_bytes] = 0; } + xprintf("%s: %s\n", *optargs, path); } } diff --git a/toys/other/stat.c b/toys/other/stat.c index 9f77a600..7a6b38d7 100644 --- a/toys/other/stat.c +++ b/toys/other/stat.c @@ -110,7 +110,7 @@ static void print_stat(char type) } else if (type == 'N') { xprintf("`%s'", TT.file); if (S_ISLNK(stat->st_mode)) - if (0 `%s'", toybuf); } else if (type == 'o') out('u', stat->st_blksize); else if (type == 's') out('u', stat->st_size); diff --git a/toys/posix/cp.c b/toys/posix/cp.c index 77e7f132..eafabcd1 100644 --- a/toys/posix/cp.c +++ b/toys/posix/cp.c @@ -251,8 +251,7 @@ int cp_node(struct dirtree *try) // make symlink, or make block/char/fifo/socket if (S_ISLNK(try->st.st_mode) - ? (0 < (i = readlinkat(tfd, try->name, toybuf, sizeof(toybuf))) && - sizeof(toybuf) > i && !(toybuf[i] = '\0') && + ? ((i = readlinkat0(tfd, try->name, toybuf, sizeof(toybuf))) && !symlinkat(toybuf, cfd, catch)) : !mknodat(cfd, catch, try->st.st_mode, try->st.st_rdev)) { diff --git a/toys/posix/ps.c b/toys/posix/ps.c index 8ac6eef7..773f40c4 100644 --- a/toys/posix/ps.c +++ b/toys/posix/ps.c @@ -751,9 +751,8 @@ static int get_ps(struct dirtree *new) if (TT.threadparent && TT.threadparent->extra) ptb = (void *)TT.threadparent->extra; - if (j==3 && !ptb) { - if ((len = readlinkat(fd, buf, buf, len))<1) len = 0; - } else { + if (j==3 && !ptb) len = readlinkat0(fd, buf, buf, len); + else { if (j==3) i = strlen(s = ptb->str+ptb->offset[3]); else { if (!ptb || tb->slot[SLOT_argv0len]) ptb = tb; @@ -766,8 +765,8 @@ static int get_ps(struct dirtree *new) } if (i