Made new xreadlink function for libbb and changed applets to use it instead of
authorMark Whitley <markw@lineo.com>
Mon, 30 Apr 2001 18:17:00 +0000 (18:17 -0000)
committerMark Whitley <markw@lineo.com>
Mon, 30 Apr 2001 18:17:00 +0000 (18:17 -0000)
readlink(2).

13 files changed:
Makefile
applets/busybox.c
archival/tar.c
busybox.c
coreutils/ls.c
include/libbb.h
libbb/copy_file.c
libbb/libbb.h
libbb/xreadlink.c [new file with mode: 0644]
ls.c
miscutils/readlink.c
readlink.c
tar.c

index 5713cdc688bb32065a791cd464f216ef002f7266..91ed745c619af21aac71262b222dce3b4a8e014a 100644 (file)
--- 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)),)
index b4939e19d319a5dea4a3fbea596e7317921ec70f..badd53d79de9a7c28dc34fbf1c46903d1f96e8b1 100644 (file)
@@ -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 */
index c168564ca8b3751d9599e32ef0fc1962989576e5..4bf8004eafad45f56f9fd5b79e951646ac32ac4f 100644 (file)
@@ -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)); 
index b4939e19d319a5dea4a3fbea596e7317921ec70f..badd53d79de9a7c28dc34fbf1c46903d1f96e8b1 100644 (file)
--- 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 */
index d24ba98663f12e2227d6ef4f0c6604a0a7f7b668..c13b225fafb5363d2dfb5acc296d9fc037e478f2 100644 (file)
@@ -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;
index a53e647d326cb53194d2c7687b26993ae8dc8d33..d2f9a95675bf1133e9a617a4c2a465620b671987 100644 (file)
@@ -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);
 
index 2d18b6087afd1ddb3f8194dd442523f62252c9fe..22684be74283c1bf0996637979a91c48ded60f9a 100644 (file)
@@ -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)
index a53e647d326cb53194d2c7687b26993ae8dc8d33..d2f9a95675bf1133e9a617a4c2a465620b671987 100644 (file)
@@ -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 (file)
index 0000000..66f63b8
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ *  xreadlink.c - safe implementation of readlink
+ */
+
+#include <stdio.h>
+
+/*
+ * NOTE: This function returns a malloced char* that you will have to free
+ * yourself. You have been warned.
+ */
+
+#include <unistd.h>
+#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 d24ba98663f12e2227d6ef4f0c6604a0a7f7b668..c13b225fafb5363d2dfb5acc296d9fc037e478f2 100644 (file)
--- 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;
index 74196e11d93a8aa64b7def8abeab76dd46bbbb8b..226649544c1e6b0fe28a0c7e46b5fe3d56043567 100644 (file)
 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;
 }
index 74196e11d93a8aa64b7def8abeab76dd46bbbb8b..226649544c1e6b0fe28a0c7e46b5fe3d56043567 100644 (file)
 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 c168564ca8b3751d9599e32ef0fc1962989576e5..4bf8004eafad45f56f9fd5b79e951646ac32ac4f 100644 (file)
--- 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));