@@ -406,15 +406,29 @@ dispatch_io_create_f(dispatch_io_type_t type, dispatch_fd_t fd,
406
406
^(int error ){ cleanup_handler (context , error ); });
407
407
}
408
408
409
+ #if defined(_WIN32 )
410
+ #define _is_separator (ch ) ((ch) == '/' || (ch) == '\\')
411
+ #else
412
+ #define _is_separator (ch ) ((ch) == '/')
413
+ #endif
414
+
409
415
dispatch_io_t
410
416
dispatch_io_create_with_path (dispatch_io_type_t type , const char * path ,
411
417
int oflag , mode_t mode , dispatch_queue_t queue ,
412
418
void (^cleanup_handler )(int error ))
413
419
{
414
- if ((type != DISPATCH_IO_STREAM && type != DISPATCH_IO_RANDOM ) ||
415
- !(* path == '/' )) {
420
+ if (type != DISPATCH_IO_STREAM && type != DISPATCH_IO_RANDOM ) {
421
+ return DISPATCH_BAD_INPUT ;
422
+ }
423
+ #if defined(_WIN32 )
424
+ if (PathIsRelativeA (path )) {
425
+ return DISPATCH_BAD_INPUT ;
426
+ }
427
+ #else
428
+ if (!_is_separator (* path )) {
416
429
return DISPATCH_BAD_INPUT ;
417
430
}
431
+ #endif
418
432
size_t pathlen = strlen (path );
419
433
dispatch_io_path_data_t path_data = malloc (sizeof (* path_data ) + pathlen + 1 );
420
434
if (!path_data ) {
@@ -449,9 +463,15 @@ dispatch_io_create_with_path(dispatch_io_type_t type, const char *path,
449
463
break ;
450
464
default :
451
465
if ((path_data -> oflag & O_CREAT ) &&
452
- (* (path_data -> path + path_data -> pathlen - 1 ) != '/' )) {
466
+ ! _is_separator (* (path_data -> path + path_data -> pathlen - 1 ))) {
453
467
// Check parent directory
454
- char * c = strrchr (path_data -> path , '/' );
468
+ char * c = NULL ;
469
+ for (ssize_t i = (ssize_t )path_data -> pathlen - 1 ; i >= 0 ; i -- ) {
470
+ if (_is_separator (path_data -> path [i ])) {
471
+ c = & path_data -> path [i ];
472
+ break ;
473
+ }
474
+ }
455
475
dispatch_assert (c );
456
476
* c = 0 ;
457
477
int perr ;
@@ -465,7 +485,11 @@ dispatch_io_create_with_path(dispatch_io_type_t type, const char *path,
465
485
err = 0 ;
466
486
break ;
467
487
);
488
+ #if defined(_WIN32 )
489
+ * c = '\\' ;
490
+ #else
468
491
* c = '/' ;
492
+ #endif
469
493
}
470
494
break ;
471
495
);
@@ -1287,18 +1311,31 @@ _dispatch_fd_entry_guarded_open(dispatch_fd_entry_t fd_entry, const char *path,
1287
1311
#if defined(_WIN32 )
1288
1312
(void )mode ;
1289
1313
DWORD dwDesiredAccess = 0 ;
1290
- if (oflag & _O_RDWR )
1291
- dwDesiredAccess = GENERIC_READ | GENERIC_WRITE ;
1292
- else if (oflag & _O_RDONLY )
1293
- dwDesiredAccess = GENERIC_READ ;
1294
- else if (oflag & _O_WRONLY )
1295
- dwDesiredAccess = GENERIC_WRITE ;
1314
+ switch (oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR )) {
1315
+ case _O_RDONLY :
1316
+ dwDesiredAccess = GENERIC_READ ;
1317
+ break ;
1318
+ case _O_WRONLY :
1319
+ dwDesiredAccess = GENERIC_WRITE ;
1320
+ break ;
1321
+ case _O_RDWR :
1322
+ dwDesiredAccess = GENERIC_READ | GENERIC_WRITE ;
1323
+ break ;
1324
+ }
1296
1325
DWORD dwCreationDisposition = OPEN_EXISTING ;
1297
- if (oflag & _O_CREAT )
1326
+ if (oflag & _O_CREAT ) {
1298
1327
dwCreationDisposition = OPEN_ALWAYS ;
1299
- if (oflag & _O_TRUNC )
1300
- dwCreationDisposition = CREATE_ALWAYS ;
1301
- return (dispatch_fd_t )CreateFile (path , dwDesiredAccess , 0 , NULL , dwCreationDisposition , 0 , NULL );
1328
+ if (oflag & _O_EXCL ) {
1329
+ dwCreationDisposition = CREATE_NEW ;
1330
+ } else if (oflag & _O_TRUNC ) {
1331
+ dwCreationDisposition = CREATE_ALWAYS ;
1332
+ }
1333
+ } else if (oflag & _O_TRUNC ) {
1334
+ dwCreationDisposition = TRUNCATE_EXISTING ;
1335
+ }
1336
+ return (dispatch_fd_t )CreateFile (path , dwDesiredAccess ,
1337
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE , NULL ,
1338
+ dwCreationDisposition , 0 , NULL );
1302
1339
#else
1303
1340
return open (path , oflag , mode );
1304
1341
#endif
0 commit comments