Skip to content

Commit 7434a18

Browse files
authored
Merge pull request #880 from uyjulian/cwd_handling_cleanup
Simplification of cwd handling
2 parents fde25e3 + cdc7d28 commit 7434a18

2 files changed

Lines changed: 52 additions & 61 deletions

File tree

ee/libcglue/src/cwd.c

Lines changed: 39 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <sys/param.h>
1616
#include <dirent.h>
1717
#include <errno.h>
18+
#include <stdlib.h>
1819

1920
#ifdef F___cwd
2021
/* the present working directory variable. */
@@ -33,43 +34,36 @@ extern size_t __cwd_len;
3334
#define defaultCWD "host:"
3435

3536
enum SeparatorType {
37+
SeparatorTypeNotFound,
3638
SeparatorTypeNone,
3739
SeparatorTypePOSIX,
38-
SeparatorTypeWindows
40+
SeparatorTypeWindows,
3941
};
4042

4143
#define isnum(c) ((c) >= '0' && (c) <= '9')
4244

4345
#ifdef F___get_drive
4446
/* Return the number of bytes taken up by the "drive:" prefix,
4547
or -1 if it's not found */
46-
int __get_drive(const char *dev, enum SeparatorType *usePOSIXSeparator)
48+
int __get_drive(const char *dev, enum SeparatorType *usePOSIXSeparator, int maxLen)
4749
{
48-
const char *tail;
50+
const char *t;
4951
const char *d;
5052
int devname_len;
5153

5254
/* Skip leading spaces */
53-
d = dev;
54-
while (*d == ' ')
55-
{
56-
d += 1;
57-
}
55+
for (d = dev; ((int)(d - dev) < maxLen) && *d == ' '; d += 1);
5856

5957
/* Get colon position */
60-
tail = strchr(d, ':');
61-
if (tail == NULL)
58+
for (t = d; ((int)(t - dev) < maxLen) && *t && *t != ':'; t += 1);
59+
if (*t != ':')
6260
{
63-
return -1;
61+
*usePOSIXSeparator = SeparatorTypeNotFound;
62+
return 0;
6463
}
6564

66-
devname_len = (int)(tail - d);
67-
6865
/* Reduce length to not include index */
69-
while (isnum(d[devname_len - 1]))
70-
{
71-
devname_len -= 1;
72-
}
66+
for (devname_len = (int)(t - d); isnum(d[devname_len - 1]); devname_len -= 1);
7367

7468
*usePOSIXSeparator = SeparatorTypePOSIX;
7569
switch (devname_len)
@@ -99,27 +93,37 @@ int __get_drive(const char *dev, enum SeparatorType *usePOSIXSeparator)
9993
* - device index
10094
* - colon
10195
*/
102-
return (tail - dev) + 1;
96+
return (t - dev) + 1;
10397
}
10498
#else
105-
int __get_drive(const char *dev, enum SeparatorType *usePOSIXSeparator);
99+
int __get_drive(const char *dev, enum SeparatorType *usePOSIXSeparator, int maxLen);
106100
#endif
107101

108102
#ifdef F_getcwd
109103
char *getcwd(char *buf, size_t size)
110104
{
111-
if(!buf) {
105+
if (!buf)
106+
{
107+
size = __cwd_len + 1;
108+
buf = malloc(size);
109+
if (!buf)
110+
{
111+
errno = ENOMEM;
112+
return NULL;
113+
}
114+
}
115+
else if (!size)
116+
{
112117
errno = EINVAL;
113118
return NULL;
114-
}
115-
116-
if(__cwd_len >= size) {
119+
}
120+
else if (size < (__cwd_len + 1))
121+
{
117122
errno = ERANGE;
118123
return NULL;
119124
}
120125

121-
memcpy(buf, __cwd, __cwd_len);
122-
buf[__cwd_len] = '\x00';
126+
snprintf(buf, size, "%*s", __cwd_len, __cwd);
123127
return buf;
124128
}
125129
#endif
@@ -202,43 +206,30 @@ int __path_absolute(const char *in, char *out, int len)
202206
int dr;
203207
enum SeparatorType separatorType;
204208
size_t in_len;
209+
size_t out_len;
205210

206211
in_len = strlen(in);
207212
/* See what the relative URL starts with */
208-
dr = __get_drive(in, &separatorType);
213+
dr = __get_drive(in, &separatorType, in_len);
209214
char separator = separatorType == SeparatorTypePOSIX ? '/' : '\\';
210215

211-
if(dr > 0 && (separatorType == SeparatorTypeNone || in[dr] == separator)) {
216+
if((separatorType != SeparatorTypeNotFound) && (separatorType == SeparatorTypeNone || in[dr] == separator)) {
212217
/* It starts with "drive:" and has no separator or "drive:/", so it's already absolute */
213-
if (in_len >= len) return -1;
214-
strncpy(out, in, len);
215-
} else if(dr > 0 && in[dr - 1] == ':') {
218+
out_len = snprintf(out, len, "%*s", in_len, in);
219+
} else if((separatorType != SeparatorTypeNotFound) && in[dr - 1] == ':') {
216220
/* It starts with "drive:", so it's already absoulte, however it misses the "/" after unit */
217-
if (in_len + 1 >= len) return -2;
218-
strncpy(out, in, dr);
219-
out[dr] = separator;
220-
strncpy(out + dr + 1, in + dr, len - dr - 1);
221+
out_len = snprintf(out, len, "%*s%c%*s", dr, in, separator, in_len - dr, in + dr);
221222
} else if(in[0] == '\\' || in[0] == '/') {
222223
/* It's absolute, but missing the drive, so use cwd's drive */
223-
if(__cwd_len + in_len >= len) return -3;
224-
memcpy(out, __cwd, __cwd_len);
225-
out[__cwd_len] = '\x00';
226-
dr = __get_drive(out, &separatorType);
227-
if(dr < 0) dr = 0;
228-
out[dr] = 0;
229-
strncat(out, in, len);
224+
out_len = snprintf(out, len, "%*s%*s", __get_drive(__cwd, &separatorType, __cwd_len), __cwd, in_len, in);
230225
} else {
231226
/* It's not absolute, so append it to the current cwd */
232-
if(__cwd_len + 1 + in_len >= len) return -5;
233-
memcpy(out, __cwd, __cwd_len);
234-
out[__cwd_len] = separator;
235-
out[__cwd_len + 1] = '\x00';
236-
strncat(out, in, len);
227+
out_len = snprintf(out, len, "%*s%c%*s", __cwd_len, __cwd, separator, in_len, in);
237228
}
229+
if (out_len >= len) return -1;
238230

239231
/* Now normalize the pathname portion */
240-
dr = __get_drive(out, &separatorType);
241-
if(dr < 0) dr = 0;
232+
dr = __get_drive(out, &separatorType, out_len);
242233
return __path_normalize(out + dr, len - dr, separatorType == SeparatorTypePOSIX);
243234
}
244235
#endif

ee/libcglue/src/glue.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ int _open(const char *buf, int flags, ...) {
170170
mode = va_arg(alist, int); // Retrieve the mode argument, regardless of whether it is expected or not.
171171
va_end(alist);
172172

173-
if(__path_absolute(buf, t_fname, MAXNAMLEN) < 0) {
173+
if(__path_absolute(buf, t_fname, sizeof(t_fname)) < 0) {
174174
errno = ENAMETOOLONG;
175175
return -1;
176176
}
@@ -279,7 +279,7 @@ int _write(int fd, const void *buf, size_t nbytes) {
279279
int _stat(const char *path, struct stat *buf) {
280280
char dest[MAXNAMLEN + 1];
281281

282-
if(__path_absolute(path, dest, MAXNAMLEN) < 0) {
282+
if(__path_absolute(path, dest, sizeof(dest)) < 0) {
283283
errno = ENAMETOOLONG;
284284
return -1;
285285
}
@@ -518,13 +518,13 @@ off64_t lseek64(int fd, off64_t offset, int whence)
518518
int chdir(const char *path) {
519519
char dest[MAXNAMLEN + 1];
520520

521-
if(__path_absolute(path, dest, MAXNAMLEN) < 0) {
521+
if(__path_absolute(path, dest, sizeof(dest)) < 0) {
522522
errno = ENAMETOOLONG;
523523
return -1;
524524
}
525525

526-
strncpy(__cwd, dest, sizeof(__cwd));
527-
__cwd_len = strnlen(__cwd, sizeof(__cwd));
526+
__cwd_len = snprintf(__cwd, sizeof(__cwd), "%*s", sizeof(dest) - 1, dest);
527+
__cwd_len = (__cwd_len > (sizeof(__cwd) - 1)) ? (sizeof(__cwd) - 1) : __cwd_len;
528528
return 0;
529529
}
530530
#endif
@@ -543,7 +543,7 @@ int _mkdir(const char *path, mode_t mode)
543543
{
544544
char dest[MAXNAMLEN + 1];
545545

546-
if(__path_absolute(path, dest, MAXNAMLEN) < 0) {
546+
if(__path_absolute(path, dest, sizeof(dest)) < 0) {
547547
errno = ENAMETOOLONG;
548548
return -1;
549549
}
@@ -573,7 +573,7 @@ int mkdir(const char *path, mode_t mode);
573573
int rmdir(const char *path) {
574574
char dest[MAXNAMLEN + 1];
575575

576-
if(__path_absolute(path, dest, MAXNAMLEN) < 0) {
576+
if(__path_absolute(path, dest, sizeof(dest)) < 0) {
577577
errno = ENAMETOOLONG;
578578
return -1;
579579
}
@@ -600,7 +600,7 @@ int _link(const char *old, const char *new_) {
600600
// Called from newlib unlinkr.c
601601
int _unlink(const char *path) {
602602
char dest[MAXNAMLEN + 1];
603-
if(__path_absolute(path, dest, MAXNAMLEN) < 0) {
603+
if(__path_absolute(path, dest, sizeof(dest)) < 0) {
604604
errno = ENAMETOOLONG;
605605
return -1;
606606
}
@@ -621,12 +621,12 @@ int _rename(const char *old, const char *new_) {
621621
char oldname[MAXNAMLEN + 1];
622622
char newname[MAXNAMLEN + 1];
623623

624-
if(__path_absolute(old, oldname, MAXNAMLEN) < 0) {
624+
if(__path_absolute(old, oldname, sizeof(oldname)) < 0) {
625625
errno = ENAMETOOLONG;
626626
return -1;
627627
}
628628

629-
if(__path_absolute(new_, newname, MAXNAMLEN) < 0) {
629+
if(__path_absolute(new_, newname, sizeof(newname)) < 0) {
630630
errno = ENAMETOOLONG;
631631
return -1;
632632
}
@@ -993,12 +993,12 @@ int _symlink(const char *target, const char *linkpath)
993993
char dest_target[MAXNAMLEN + 1];
994994
char dest_linkpath[MAXNAMLEN + 1];
995995

996-
if(__path_absolute(target, dest_target, MAXNAMLEN) < 0) {
996+
if(__path_absolute(target, dest_target, sizeof(dest_target)) < 0) {
997997
errno = ENAMETOOLONG;
998998
return -1;
999999
}
10001000

1001-
if(__path_absolute(linkpath, dest_linkpath, MAXNAMLEN) < 0) {
1001+
if(__path_absolute(linkpath, dest_linkpath, sizeof(dest_linkpath)) < 0) {
10021002
errno = ENAMETOOLONG;
10031003
return -1;
10041004
}
@@ -1027,7 +1027,7 @@ ssize_t _readlink(const char *path, char *buf, size_t bufsiz)
10271027
{
10281028
char dest[MAXNAMLEN + 1];
10291029

1030-
if(__path_absolute(path, dest, MAXNAMLEN) < 0) {
1030+
if(__path_absolute(path, dest, sizeof(dest)) < 0) {
10311031
errno = ENAMETOOLONG;
10321032
return -1;
10331033
}

0 commit comments

Comments
 (0)