Magellan Linux

Diff of /tags/mkinitrd-6_2_0/libbb/xreadlink.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 532 by niro, Sat Sep 1 22:45:15 2007 UTC revision 816 by niro, Fri Apr 24 18:33:46 2009 UTC
# Line 8  Line 8 
8    
9  /*  /*
10   * NOTE: This function returns a malloced char* that you will have to free   * NOTE: This function returns a malloced char* that you will have to free
11   * yourself. You have been warned.   * yourself.
12   */   */
13    char* FAST_FUNC xmalloc_readlink(const char *path)
 char *xreadlink(const char *path)  
14  {  {
15   enum { GROWBY = 80 }; /* how large we will grow strings by */   enum { GROWBY = 80 }; /* how large we will grow strings by */
16    
# Line 19  char *xreadlink(const char *path) Line 18  char *xreadlink(const char *path)
18   int bufsize = 0, readsize = 0;   int bufsize = 0, readsize = 0;
19    
20   do {   do {
21   buf = xrealloc(buf, bufsize += GROWBY);   bufsize += GROWBY;
22   readsize = readlink(path, buf, bufsize); /* 1st try */   buf = xrealloc(buf, bufsize);
23     readsize = readlink(path, buf, bufsize);
24   if (readsize == -1) {   if (readsize == -1) {
  bb_perror_msg("%s", path);  
25   free(buf);   free(buf);
26   return NULL;   return NULL;
27   }   }
28   }   } while (bufsize < readsize + 1);
  while (bufsize < readsize + 1);  
29    
30   buf[readsize] = '\0';   buf[readsize] = '\0';
31    
32   return buf;   return buf;
33  }  }
34    
35  char *xmalloc_realpath(const char *path)  /*
36     * This routine is not the same as realpath(), which
37     * canonicalizes the given path completely. This routine only
38     * follows trailing symlinks until a real file is reached and
39     * returns its name. If the path ends in a dangling link or if
40     * the target doesn't exist, the path is returned in any case.
41     * Intermediate symlinks in the path are not expanded -- only
42     * those at the tail.
43     * A malloced char* is returned, which must be freed by the caller.
44     */
45    char* FAST_FUNC xmalloc_follow_symlinks(const char *path)
46    {
47     char *buf;
48     char *lpc;
49     char *linkpath;
50     int bufsize;
51     int looping = MAXSYMLINKS + 1;
52    
53     buf = xstrdup(path);
54     goto jump_in;
55    
56     while (1) {
57     linkpath = xmalloc_readlink(buf);
58     if (!linkpath) {
59     /* not a symlink, or doesn't exist */
60     if (errno == EINVAL || errno == ENOENT)
61     return buf;
62     goto free_buf_ret_null;
63     }
64    
65     if (!--looping) {
66     free(linkpath);
67     free_buf_ret_null:
68     free(buf);
69     return NULL;
70     }
71    
72     if (*linkpath != '/') {
73     bufsize += strlen(linkpath);
74     buf = xrealloc(buf, bufsize);
75     lpc = bb_get_last_path_component_strip(buf);
76     strcpy(lpc, linkpath);
77     free(linkpath);
78     } else {
79     free(buf);
80     buf = linkpath;
81     jump_in:
82     bufsize = strlen(buf) + 1;
83     }
84     }
85    }
86    
87    char* FAST_FUNC xmalloc_readlink_or_warn(const char *path)
88    {
89     char *buf = xmalloc_readlink(path);
90     if (!buf) {
91     /* EINVAL => "file: Invalid argument" => puzzled user */
92     bb_error_msg("%s: cannot read link (not a symlink?)", path);
93     }
94     return buf;
95    }
96    
97    /* UNUSED */
98    #if 0
99    char* FAST_FUNC xmalloc_realpath(const char *path)
100  {  {
101  #if defined(__GLIBC__) && !defined(__UCLIBC__)  #if defined(__GLIBC__) && !defined(__UCLIBC__)
102   /* glibc provides a non-standard extension */   /* glibc provides a non-standard extension */
# Line 46  char *xmalloc_realpath(const char *path) Line 108  char *xmalloc_realpath(const char *path)
108   return xstrdup(realpath(path, buf));   return xstrdup(realpath(path, buf));
109  #endif  #endif
110  }  }
111    #endif

Legend:
Removed from v.532  
changed lines
  Added in v.816