From 8a633268ef478a31bd649d582ce07e9c26a4a03a Mon Sep 17 00:00:00 2001 From: Mark Whitley Date: Mon, 30 Apr 2001 18:17:00 +0000 Subject: [PATCH] Made new xreadlink function for libbb and changed applets to use it instead of readlink(2). --- Makefile | 4 ++-- applets/busybox.c | 15 ++------------- archival/tar.c | 12 +++--------- busybox.c | 15 ++------------- coreutils/ls.c | 12 ++++++------ include/libbb.h | 1 + libbb/copy_file.c | 13 +++---------- libbb/libbb.h | 1 + libbb/xreadlink.c | 34 ++++++++++++++++++++++++++++++++++ ls.c | 12 ++++++------ miscutils/readlink.c | 16 ++++++---------- readlink.c | 16 ++++++---------- tar.c | 12 +++--------- 13 files changed, 75 insertions(+), 88 deletions(-) create mode 100644 libbb/xreadlink.c diff --git a/Makefile b/Makefile index 5713cdc68..91ed745c6 100644 --- a/Makefile +++ b/Makefile @@ -247,8 +247,8 @@ parse_mode.c parse_number.c perror_msg.c perror_msg_and_die.c print_file.c \ process_escape_sequence.c read_package_field.c read_text_file_to_buffer.c \ recursive_action.c safe_read.c safe_strncpy.c seek_ared_file.c syscalls.c \ syslog_msg_with_name.c time_string.c trim.c untar.c unzip.c vdprintf.c \ -verror_msg.c vperror_msg.c wfopen.c xfuncs.c xgetcwd.c xregcomp.c interface.c \ -remove_file.c last_char_is.c +verror_msg.c vperror_msg.c wfopen.c xfuncs.c xgetcwd.c xreadlink.c\ +xregcomp.c interface.c remove_file.c last_char_is.c LIBBB_OBJS=$(patsubst %.c,$(LIBBB)/%.o, $(LIBBB_CSRC)) LIBBB_CFLAGS = -I$(LIBBB) ifneq ($(strip $(BB_SRC_DIR)),) diff --git a/applets/busybox.c b/applets/busybox.c index b4939e19d..badd53d79 100644 --- a/applets/busybox.c +++ b/applets/busybox.c @@ -37,21 +37,10 @@ typedef int (*__link_f)(const char *, const char *); */ static char *busybox_fullpath() { - pid_t pid; - char path[256]; char proc[256]; - int len; - pid = getpid(); - sprintf(proc, "/proc/%d/exe", pid); - len = readlink(proc, path, 256); - if (len != -1) { - path[len] = 0; - } else { - perror_msg("%s", proc); - return NULL; - } - return strdup(path); + sprintf(proc, "/proc/%d/exe", getpid()); + return xreadlink(proc); } /* create (sym)links for each applet */ diff --git a/archival/tar.c b/archival/tar.c index c168564ca..4bf8004ea 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -921,16 +921,10 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *header_name, header.typeflag = LNKTYPE; strncpy(header.linkname, tbInfo->hlInfo->name, sizeof(header.linkname)); } else if (S_ISLNK(statbuf->st_mode)) { - int link_size=0; - char buffer[BUFSIZ]; + char *lpath = xreadlink(real_name); header.typeflag = SYMTYPE; - link_size = readlink(real_name, buffer, sizeof(buffer) - 1); - if ( link_size < 0) { - perror_msg("Error reading symlink '%s'", header.name); - return ( FALSE); - } - buffer[link_size] = '\0'; - strncpy(header.linkname, buffer, sizeof(header.linkname)); + strncpy(header.linkname, lpath, sizeof(header.linkname)); + free(lpath); } else if (S_ISDIR(statbuf->st_mode)) { header.typeflag = DIRTYPE; strncat(header.name, "/", sizeof(header.name)); diff --git a/busybox.c b/busybox.c index b4939e19d..badd53d79 100644 --- a/busybox.c +++ b/busybox.c @@ -37,21 +37,10 @@ typedef int (*__link_f)(const char *, const char *); */ static char *busybox_fullpath() { - pid_t pid; - char path[256]; char proc[256]; - int len; - pid = getpid(); - sprintf(proc, "/proc/%d/exe", pid); - len = readlink(proc, path, 256); - if (len != -1) { - path[len] = 0; - } else { - perror_msg("%s", proc); - return NULL; - } - return strdup(path); + sprintf(proc, "/proc/%d/exe", getpid()); + return xreadlink(proc); } /* create (sym)links for each applet */ diff --git a/coreutils/ls.c b/coreutils/ls.c index d24ba9866..c13b225fa 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c @@ -577,7 +577,7 @@ static struct dnode **list_dir(char *path) /*----------------------------------------------------------------------*/ static int list_single(struct dnode *dn) { - int i, len; + int i; char scratch[BUFSIZ + 1]; #ifdef BB_FEATURE_LS_TIMESTAMPS char *filetime; @@ -688,16 +688,16 @@ static int list_single(struct dnode *dn) break; case LIST_SYMLINK: if (S_ISLNK(dn->dstat.st_mode)) { - len= readlink(dn->fullname, scratch, (sizeof scratch)-1); - if (len > 0) { - scratch[len]= '\0'; - printf(" -> %s", scratch); + char *lpath = xreadlink(dn->fullname); + if (lpath) { + printf(" -> %s", lpath); #ifdef BB_FEATURE_LS_FILETYPES if (!stat(dn->fullname, &info)) { append = append_char(info.st_mode); } #endif - column += len+4; + column += strlen(lpath) + 4; + free(lpath); } } break; diff --git a/include/libbb.h b/include/libbb.h index a53e647d3..d2f9a9567 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -217,6 +217,7 @@ int ask_confirmation(void); int klogctl(int type, char * b, int len); char *xgetcwd(char *cwd); +char *xreadlink(const char *path); char *concat_path_file(const char *path, const char *filename); int last_char_is(const char *s, const int c); diff --git a/libbb/copy_file.c b/libbb/copy_file.c index 2d18b6087..22684be74 100644 --- a/libbb/copy_file.c +++ b/libbb/copy_file.c @@ -196,19 +196,12 @@ int copy_file(const char *source, const char *dest, int flags) return -1; } } else if (S_ISLNK(source_stat.st_mode)) { - int size; - char buf[BUFSIZ + 1]; - - if ((size = readlink(source, buf, BUFSIZ)) < 0) { - perror_msg("cannot read `%s'", source); - return -1; - } - buf[size] = '\0'; - - if (symlink(buf, dest) < 0) { + char *lpath = xreadlink(source); + if (symlink(lpath, dest) < 0) { perror_msg("cannot create symlink `%s'", dest); return -1; } + free(lpath); #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) if (flags & FILEUTILS_PRESERVE_STATUS) diff --git a/libbb/libbb.h b/libbb/libbb.h index a53e647d3..d2f9a9567 100644 --- a/libbb/libbb.h +++ b/libbb/libbb.h @@ -217,6 +217,7 @@ int ask_confirmation(void); int klogctl(int type, char * b, int len); char *xgetcwd(char *cwd); +char *xreadlink(const char *path); char *concat_path_file(const char *path, const char *filename); int last_char_is(const char *s, const int c); diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c new file mode 100644 index 000000000..66f63b883 --- /dev/null +++ b/libbb/xreadlink.c @@ -0,0 +1,34 @@ +/* + * xreadlink.c - safe implementation of readlink + */ + +#include + +/* + * NOTE: This function returns a malloced char* that you will have to free + * yourself. You have been warned. + */ + +#include +#include "libbb.h" + +extern char *xreadlink(const char *path) +{ + static const int GROWBY = 80; /* how large we will grow strings by */ + + char *buf = NULL; + int bufsize = 0, readsize = 0; + + do { + buf = xrealloc(buf, bufsize += GROWBY); + readsize = readlink(path, buf, bufsize); /* 1st try */ + if (readsize == -1) + perror_msg("%s:%s", applet_name, path); + } + while (bufsize < readsize + 1); + + buf[readsize] = '\0'; + + return buf; +} + diff --git a/ls.c b/ls.c index d24ba9866..c13b225fa 100644 --- a/ls.c +++ b/ls.c @@ -577,7 +577,7 @@ static struct dnode **list_dir(char *path) /*----------------------------------------------------------------------*/ static int list_single(struct dnode *dn) { - int i, len; + int i; char scratch[BUFSIZ + 1]; #ifdef BB_FEATURE_LS_TIMESTAMPS char *filetime; @@ -688,16 +688,16 @@ static int list_single(struct dnode *dn) break; case LIST_SYMLINK: if (S_ISLNK(dn->dstat.st_mode)) { - len= readlink(dn->fullname, scratch, (sizeof scratch)-1); - if (len > 0) { - scratch[len]= '\0'; - printf(" -> %s", scratch); + char *lpath = xreadlink(dn->fullname); + if (lpath) { + printf(" -> %s", lpath); #ifdef BB_FEATURE_LS_FILETYPES if (!stat(dn->fullname, &info)) { append = append_char(info.st_mode); } #endif - column += len+4; + column += strlen(lpath) + 4; + free(lpath); } } break; diff --git a/miscutils/readlink.c b/miscutils/readlink.c index 74196e11d..226649544 100644 --- a/miscutils/readlink.c +++ b/miscutils/readlink.c @@ -30,21 +30,17 @@ int readlink_main(int argc, char **argv) { char *buf = NULL; - int bufsize = 128, size = 128; + + /* no options, no getopt */ if (argc != 2) show_usage(); - while (bufsize < size + 1) { - bufsize *= 2; - buf = xrealloc(buf, bufsize); - size = readlink(argv[1], buf, bufsize); - if (size == -1) - perror_msg_and_die("%s", argv[1]); - } - - buf[size] = '\0'; + buf = xreadlink(argv[1]); puts(buf); +#ifdef BB_FEATURE_CLEAN_UP + free(buf); +#endif return EXIT_SUCCESS; } diff --git a/readlink.c b/readlink.c index 74196e11d..226649544 100644 --- a/readlink.c +++ b/readlink.c @@ -30,21 +30,17 @@ int readlink_main(int argc, char **argv) { char *buf = NULL; - int bufsize = 128, size = 128; + + /* no options, no getopt */ if (argc != 2) show_usage(); - while (bufsize < size + 1) { - bufsize *= 2; - buf = xrealloc(buf, bufsize); - size = readlink(argv[1], buf, bufsize); - if (size == -1) - perror_msg_and_die("%s", argv[1]); - } - - buf[size] = '\0'; + buf = xreadlink(argv[1]); puts(buf); +#ifdef BB_FEATURE_CLEAN_UP + free(buf); +#endif return EXIT_SUCCESS; } diff --git a/tar.c b/tar.c index c168564ca..4bf8004ea 100644 --- a/tar.c +++ b/tar.c @@ -921,16 +921,10 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *header_name, header.typeflag = LNKTYPE; strncpy(header.linkname, tbInfo->hlInfo->name, sizeof(header.linkname)); } else if (S_ISLNK(statbuf->st_mode)) { - int link_size=0; - char buffer[BUFSIZ]; + char *lpath = xreadlink(real_name); header.typeflag = SYMTYPE; - link_size = readlink(real_name, buffer, sizeof(buffer) - 1); - if ( link_size < 0) { - perror_msg("Error reading symlink '%s'", header.name); - return ( FALSE); - } - buffer[link_size] = '\0'; - strncpy(header.linkname, buffer, sizeof(header.linkname)); + strncpy(header.linkname, lpath, sizeof(header.linkname)); + free(lpath); } else if (S_ISDIR(statbuf->st_mode)) { header.typeflag = DIRTYPE; strncat(header.name, "/", sizeof(header.name));