@@ -406,15 +406,29 @@ dispatch_io_create_f(dispatch_io_type_t type, dispatch_fd_t fd,
406406^(int  error ){ cleanup_handler (context , error ); });
407407}
408408
409+ #if  defined(_WIN32 )
410+ #define  _is_separator (ch ) ((ch) == '/' || (ch) == '\\')
411+ #else 
412+ #define  _is_separator (ch ) ((ch) == '/')
413+ #endif 
414+ 
409415dispatch_io_t 
410416dispatch_io_create_with_path (dispatch_io_type_t  type , const  char  * path ,
411417int  oflag , mode_t  mode , dispatch_queue_t  queue ,
412418void  (^cleanup_handler )(int  error ))
413419{
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 )) {
416429return  DISPATCH_BAD_INPUT ;
417430}
431+ #endif 
418432size_t  pathlen  =  strlen (path );
419433dispatch_io_path_data_t  path_data  =  malloc (sizeof (* path_data ) +  pathlen + 1 );
420434if  (!path_data ) {
@@ -449,9 +463,15 @@ dispatch_io_create_with_path(dispatch_io_type_t type, const char *path,
449463break ;
450464default :
451465if  ((path_data -> oflag  &  O_CREAT ) && 
452- (* (path_data -> path  +  path_data -> pathlen  -  1 )  !=   '/' )) {
466+ ! _is_separator (* (path_data -> path  +  path_data -> pathlen  -  1 ))) {
453467// 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+ }
455475dispatch_assert (c );
456476* c  =  0 ;
457477int  perr ;
@@ -465,7 +485,11 @@ dispatch_io_create_with_path(dispatch_io_type_t type, const char *path,
465485err  =  0 ;
466486break ;
467487);
488+ #if  defined(_WIN32 )
489+ * c  =  '\\' ;
490+ #else 
468491* c  =  '/' ;
492+ #endif 
469493}
470494break ;
471495);
@@ -1287,18 +1311,31 @@ _dispatch_fd_entry_guarded_open(dispatch_fd_entry_t fd_entry, const char *path,
12871311#if  defined(_WIN32 )
12881312(void )mode ;
12891313DWORD  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+ }
12961325DWORD  dwCreationDisposition  =  OPEN_EXISTING ;
1297- if  (oflag  &  _O_CREAT )
1326+ if  (oflag  &  _O_CREAT ) { 
12981327dwCreationDisposition  =  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 );
13021339#else 
13031340return  open (path , oflag , mode );
13041341#endif 
0 commit comments