Changeset e2ea8d7e in mainline for uspace/app/bdsh/util.c
- Timestamp:
- 2008-08-27T05:36:12Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1b4b7b6
- Parents:
- b510d52
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/util.c
rb510d52 re2ea8d7e 53 53 #include "util.h" 54 54 55 extern volatile int cli_errno; 56 55 57 /* some platforms do not have strdup, implement it here. 56 58 * Returns a pointer to an allocated string or NULL on failure */ … … 60 62 void *ret = malloc(len); 61 63 62 if (ret == NULL) 64 if (ret == NULL) { 65 cli_errno = CL_ENOMEM; 63 66 return (char *) NULL; 64 67 } 68 69 cli_errno = CL_EOK; 65 70 return (char *) memcpy(ret, s1, len); 66 71 } … … 80 85 *s1 = realloc(*s1, len); 81 86 82 if (*s1 == NULL) 83 return -1; 87 if (*s1 == NULL) { 88 cli_errno = CL_ENOMEM; 89 return -1; 90 } 84 91 85 92 memset(*s1, 0, sizeof(*s1)); 86 93 memcpy(*s1, s2, len); 94 cli_errno = CL_EOK; 87 95 return (int) len; 88 96 } 89 97 90 /* An asprintf() for concantenating paths. Allocates the system PATH_MAX value, 91 * expands the formatted string and re-sizes the block s1 points to accordingly. 92 * 93 * Returns the length of the new s1 on success, -1 on failure. On failure, an 94 * attempt is made to return s1 unmodified for sanity, in this case 0 is returned. 95 * to indicate that s1 was not modified. 96 * 97 * FIXME: ugly hack to get around asprintf(), if you use this, CHECK ITS VALUE! */ 98 /* An asprintf() for formatting paths, similar to asprintf() but ensures 99 * the returned allocated string is <= PATH_MAX. On failure, an attempt 100 * is made to return the original string (if not null) unmodified. 101 * 102 * Returns: Length of the new string on success, 0 if the string was handed 103 * back unmodified, -1 on failure. On failure, cli_errno is set. 104 * 105 * We do not use POSIX_PATH_MAX, as it is typically much smaller than the 106 * PATH_MAX defined by the kernel. 107 * 108 * Use this like: 109 * if (1 > cli_psprintf(&char, "%s/%s", foo, bar)) { 110 * cli_error(cli_errno, "Failed to format path"); 111 * stop_what_your_doing_as_your_out_of_memory(); 112 * } 113 */ 114 98 115 int cli_psprintf(char **s1, const char *fmt, ...) 99 116 { 100 117 va_list ap; 101 118 size_t needed, base = PATH_MAX + 1; 119 int skipped = 0; 120 char *orig = NULL; 102 121 char *tmp = (char *) malloc(base); 103 122 104 if (NULL == tmp) 105 return -1; 106 107 char *orig = *s1; 108 123 /* Don't even touch s1, not enough memory */ 124 if (NULL == tmp) { 125 cli_errno = CL_ENOMEM; 126 return -1; 127 } 128 129 /* If re-allocating s1, save a copy in case we fail */ 130 if (NULL != *s1) 131 orig = cli_strdup(*s1); 132 133 /* Print the string to tmp so we can determine the size that 134 * we actually need */ 109 135 memset(tmp, 0, sizeof(tmp)); 110 136 va_start(ap, fmt); 111 vsnprintf(tmp, base, fmt, ap); 137 /* vsnprintf will return the # of bytes not written */ 138 skipped = vsnprintf(tmp, base, fmt, ap); 112 139 va_end(ap); 140 141 /* realloc/alloc s1 to be just the size that we need */ 113 142 needed = strlen(tmp) + 1; 114 143 *s1 = realloc(*s1, needed); 144 115 145 if (NULL == *s1) { 146 /* No string lived here previously, or we failed to 147 * make a copy of it, either way there's nothing we 148 * can do. */ 149 if (NULL == *orig) { 150 cli_errno = CL_ENOMEM; 151 return -1; 152 } 153 /* We can't even allocate enough size to restore the 154 * saved copy, just give up */ 116 155 *s1 = realloc(*s1, strlen(orig) + 1); 117 156 if (NULL == *s1) { 118 157 free(tmp); 158 free(orig); 159 cli_errno = CL_ENOMEM; 119 160 return -1; 120 161 } 162 /* Give the string back as we found it */ 121 163 memset(*s1, 0, sizeof(*s1)); 122 164 memcpy(*s1, orig, strlen(orig) + 1); 123 165 free(tmp); 166 free(orig); 167 cli_errno = CL_ENOMEM; 124 168 return 0; 125 169 } 170 171 /* Ok, great, we have enough room */ 126 172 memset(*s1, 0, sizeof(*s1)); 127 173 memcpy(*s1, tmp, needed); 128 174 free(tmp); 129 175 176 /* Free tmp only if s1 was reallocated instead of allocated */ 177 if (NULL != orig) 178 free(orig); 179 180 if (skipped) { 181 /* s1 was bigger than PATH_MAX when expanded, however part 182 * of the string was printed. Tell the caller not to use it */ 183 cli_errno = CL_ETOOBIG; 184 return -1; 185 } 186 187 /* Success! */ 188 cli_errno = CL_EOK; 130 189 return (int) needed; 131 190 } … … 137 196 int c, sc; 138 197 139 if (s == NULL && (s = *last) == NULL) 198 if (s == NULL && (s = *last) == NULL) { 199 cli_errno = CL_EFAIL; 140 200 return (NULL); 201 } 141 202 142 203 cont:
Note:
See TracChangeset
for help on using the changeset viewer.