@@ -1467,14 +1467,44 @@ rb_w32_cmdvector(const char *cmd, char ***vec)
1467
1467
#define BitOfIsRep(n) ((n) * 2 + 1)
1468
1468
#define DIRENT_PER_CHAR (CHAR_BIT / 2)
1469
1469
1470
+ static HANDLE
1471
+ open_dir_handle(const char *filename, WIN32_FIND_DATA *fd)
1472
+ {
1473
+ HANDLE fh;
1474
+ static const char wildcard[] = "/*";
1475
+ long len = strlen(filename);
1476
+ char *scanname = malloc(len + sizeof(wildcard));
1477
+
1478
+ //
1479
+ // Create the search pattern
1480
+ //
1481
+ if (!scanname) {
1482
+ return INVALID_HANDLE_VALUE;
1483
+ }
1484
+ memcpy(scanname, filename, len + 1);
1485
+
1486
+ if (index("/\\:", *CharPrev(scanname, scanname + len)) == NULL)
1487
+ memcpy(scanname + len, wildcard, sizeof(wildcard));
1488
+ else
1489
+ memcpy(scanname + len, wildcard + 1, sizeof(wildcard) - 1);
1490
+
1491
+ //
1492
+ // do the FindFirstFile call
1493
+ //
1494
+ fh = FindFirstFile(scanname, fd);
1495
+ free(scanname);
1496
+ if (fh == INVALID_HANDLE_VALUE) {
1497
+ errno = map_errno(GetLastError());
1498
+ }
1499
+ return fh;
1500
+ }
1501
+
1470
1502
DIR *
1471
1503
rb_w32_opendir(const char *filename)
1472
1504
{
1473
1505
DIR *p;
1474
1506
long len;
1475
1507
long idx;
1476
- char scannamespc[PATHLEN];
1477
- char *scanname = scannamespc;
1478
1508
struct stat sbuf;
1479
1509
WIN32_FIND_DATA fd;
1480
1510
HANDLE fh;
@@ -1492,35 +1522,17 @@ rb_w32_opendir(const char *filename)
1492
1522
return NULL;
1493
1523
}
1494
1524
1495
- //
1496
- // Get us a DIR structure
1497
- //
1498
-
1499
- p = xcalloc(sizeof(DIR), 1);
1500
- if (p == NULL)
1525
+ fh = open_dir_handle(filename, &fd);
1526
+ if (fh == INVALID_HANDLE_VALUE) {
1501
1527
return NULL;
1502
-
1503
- //
1504
- // Create the search pattern
1505
- //
1506
-
1507
- strcpy(scanname, filename);
1508
-
1509
- if (index("/\\:", *CharPrev(scanname, scanname + strlen(scanname))) == NULL)
1510
- strcat(scanname, "/*");
1511
- else
1512
- strcat(scanname, "*");
1528
+ }
1513
1529
1514
1530
//
1515
- // do the FindFirstFile call
1531
+ // Get us a DIR structure
1516
1532
//
1517
-
1518
- fh = FindFirstFile(scanname, &fd);
1519
- if (fh == INVALID_HANDLE_VALUE) {
1520
- errno = map_errno(GetLastError());
1521
- free(p);
1533
+ p = calloc(sizeof(DIR), 1);
1534
+ if (p == NULL)
1522
1535
return NULL;
1523
- }
1524
1536
1525
1537
//
1526
1538
// now allocate the first part of the string table for the
@@ -3173,6 +3185,17 @@ fileattr_to_unixmode(DWORD attr, const char *path)
3173
3185
return mode;
3174
3186
}
3175
3187
3188
+ static int
3189
+ check_valid_dir(const char *path)
3190
+ {
3191
+ WIN32_FIND_DATA fd;
3192
+ HANDLE fh = open_dir_handle(path, &fd);
3193
+ if (fh == INVALID_HANDLE_VALUE)
3194
+ return -1;
3195
+ FindClose(fh);
3196
+ return 0;
3197
+ }
3198
+
3176
3199
static int
3177
3200
winnt_stat(const char *path, struct stat *st)
3178
3201
{
@@ -3203,6 +3226,9 @@ winnt_stat(const char *path, struct stat *st)
3203
3226
errno = map_errno(GetLastError());
3204
3227
return -1;
3205
3228
}
3229
+ if (attr & FILE_ATTRIBUTE_DIRECTORY) {
3230
+ if (check_valid_dir(path)) return -1;
3231
+ }
3206
3232
st->st_mode = fileattr_to_unixmode(attr, path);
3207
3233
}
3208
3234
@@ -3212,6 +3238,21 @@ winnt_stat(const char *path, struct stat *st)
3212
3238
return 0;
3213
3239
}
3214
3240
3241
+ #ifdef WIN95
3242
+ static int
3243
+ win95_stat(const char *path, struct stat *st)
3244
+ {
3245
+ int ret = stat(path, st);
3246
+ if (ret) return ret;
3247
+ if (st->st_mode & S_IFDIR) {
3248
+ return check_valid_dir(path);
3249
+ }
3250
+ return 0;
3251
+ }
3252
+ #else
3253
+ #define win95_stat(path, st) -1
3254
+ #endif
3255
+
3215
3256
int
3216
3257
rb_w32_stat(const char *path, struct stat *st)
3217
3258
{
@@ -3247,7 +3288,7 @@ rb_w32_stat(const char *path, struct stat *st)
3247
3288
} else if (*end == '\\' || (buf1 + 1 == end && *end == ':'))
3248
3289
strcat(buf1, ".");
3249
3290
3250
- ret = IsWinNT() ? winnt_stat(buf1, st) : stat (buf1, st);
3291
+ ret = IsWinNT() ? winnt_stat(buf1, st) : win95_stat (buf1, st);
3251
3292
if (ret == 0) {
3252
3293
st->st_mode &= ~(S_IWGRP | S_IWOTH);
3253
3294
}
0 commit comments