@@ -96,32 +96,6 @@ struct SC::FileDescriptor::Internal
96
96
return success == FALSE ;
97
97
}
98
98
};
99
- SC::Result SC::FileDescriptor::setBlocking (bool blocking)
100
- {
101
- // TODO: IMPLEMENT
102
- SC_COMPILER_UNUSED (blocking);
103
- return Result (false );
104
- }
105
-
106
- SC::Result SC::FileDescriptor::setInheritable (bool inheritable)
107
- {
108
- if (::SetHandleInformation (handle, HANDLE_FLAG_INHERIT, inheritable ? TRUE : FALSE ) == FALSE )
109
- {
110
- return Result::Error (" FileDescriptor::setInheritable - ::SetHandleInformation failed" );
111
- }
112
- return Result (true );
113
- }
114
-
115
- SC::Result SC::FileDescriptor::isInheritable (bool & hasValue) const
116
- {
117
- DWORD dwFlags = 0 ;
118
- if (::GetHandleInformation (handle, &dwFlags) == FALSE )
119
- {
120
- return Result::Error (" FileDescriptor::getInheritable = ::GetHandleInformation failed" );
121
- }
122
- hasValue = (dwFlags & HANDLE_FLAG_INHERIT) != 0 ;
123
- return Result (true );
124
- }
125
99
126
100
SC::Result SC::FileDescriptor::seek (SeekMode seekMode, uint64_t offset)
127
101
{
@@ -378,16 +352,6 @@ struct SC::FileDescriptor::Internal
378
352
return Result (true );
379
353
}
380
354
381
- template <int flag>
382
- static Result hasFileDescriptorFlags (int fileDescriptor, bool & hasFlag)
383
- {
384
- static_assert (flag == FD_CLOEXEC, " hasFileDescriptorFlags invalid value" );
385
- int flags = 0 ;
386
- SC_TRY (getFileFlags (F_GETFD, fileDescriptor, flags));
387
- hasFlag = (flags & flag) != 0 ;
388
- return Result (true );
389
- }
390
-
391
355
template <int flag>
392
356
static Result hasFileStatusFlags (int fileDescriptor, bool & hasFlag)
393
357
{
@@ -466,28 +430,11 @@ SC::Result SC::FileDescriptor::open(StringSpan filePath, FileOpen mode)
466
430
SC_TRY (assign (fileDescriptor));
467
431
if (not mode.blocking )
468
432
{
469
- SC_TRY (setBlocking ( false ));
433
+ SC_TRY (Internal::setFileStatusFlags<O_NONBLOCK>(handle, true ));
470
434
}
471
435
return Result (true );
472
436
}
473
437
474
- SC::Result SC::FileDescriptor::setBlocking (bool blocking)
475
- {
476
- return Internal::setFileStatusFlags<O_NONBLOCK>(handle, not blocking);
477
- }
478
-
479
- SC::Result SC::FileDescriptor::setInheritable (bool inheritable)
480
- {
481
- return Internal::setFileDescriptorFlags<FD_CLOEXEC>(handle, not inheritable);
482
- }
483
-
484
- SC::Result SC::FileDescriptor::isInheritable (bool & hasValue) const
485
- {
486
- auto res = Internal::hasFileDescriptorFlags<FD_CLOEXEC>(handle, hasValue);
487
- hasValue = not hasValue;
488
- return res;
489
- }
490
-
491
438
SC::Result SC::FileDescriptor::seek (SeekMode seekMode, uint64_t offset)
492
439
{
493
440
int flags = 0 ;
@@ -625,42 +572,82 @@ SC::Result SC::FileDescriptor::readUntilEOF(IGrowableBuffer&& adapter)
625
572
// PipeDescriptor
626
573
// -------------------------------------------------------------------------------------------------------
627
574
#if SC_PLATFORM_WINDOWS
628
- SC::Result SC::PipeDescriptor::createPipe (InheritableReadFlag readFlag, InheritableWriteFlag writeFlag)
575
+ #include < stdio.h>
576
+ SC::Result SC::PipeDescriptor::createPipe (PipeOptions options)
629
577
{
630
578
// On Windows to inherit flags they must be flagged as inheritable
631
579
// https://devblogs.microsoft.com/oldnewthing/20111216-00/?p=8873
632
580
SECURITY_ATTRIBUTES security;
633
- memset (&security, 0 , sizeof (security));
581
+ :: memset (&security, 0 , sizeof (security));
634
582
security.nLength = sizeof (security);
635
- security.bInheritHandle = readFlag == ReadInheritable or writeFlag == WriteInheritable ? TRUE : FALSE ;
583
+ security.bInheritHandle = options. readInheritable or options. writeInheritable ? TRUE : FALSE ;
636
584
security.lpSecurityDescriptor = nullptr ;
637
585
638
586
HANDLE pipeRead = INVALID_HANDLE_VALUE;
639
587
HANDLE pipeWrite = INVALID_HANDLE_VALUE;
640
588
641
- if (CreatePipe (&pipeRead, &pipeWrite, &security, 0 ) == FALSE )
589
+ if (options. blocking == false )
642
590
{
643
- return Result::Error (" PipeDescriptor::createPipe - ::CreatePipe failed" );
591
+ char pipeName[64 ];
592
+ snprintf (pipeName, sizeof (pipeName), " \\\\ .\\ pipe\\ SC-%lu-%llu" , ::GetCurrentProcessId (), (intptr_t )this );
593
+
594
+ DWORD pipeFlags = PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED;
595
+ DWORD pipeMode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT;
596
+
597
+ pipeRead = ::CreateNamedPipeA (pipeName, pipeFlags, pipeMode, 1 , 65536 , 65536 , 0 , &security);
598
+ if (pipeRead == INVALID_HANDLE_VALUE)
599
+ {
600
+ return Result::Error (" PipeDescriptor::createPipe - CreateNamedPipeW failed" );
601
+ }
602
+ pipeWrite = ::CreateFileA (pipeName, GENERIC_WRITE | FILE_READ_ATTRIBUTES, 0 , &security, OPEN_EXISTING,
603
+ FILE_FLAG_OVERLAPPED, nullptr );
604
+ if (pipeWrite == INVALID_HANDLE_VALUE)
605
+ {
606
+ ::CloseHandle (pipeRead);
607
+ return Result::Error (" PipeDescriptor::createPipe - CreateFileW failed" );
608
+ }
609
+ if (::ConnectNamedPipe (pipeRead, nullptr ) == FALSE ) // Connect the pipe immediately
610
+ {
611
+ if (GetLastError () != ERROR_PIPE_CONNECTED)
612
+ {
613
+ ::CloseHandle (pipeRead);
614
+ ::CloseHandle (pipeWrite);
615
+ return Result::Error (" PipeDescriptor::createPipe - ConnectNamedPipe failed" );
616
+ }
617
+ }
618
+ }
619
+ else
620
+ {
621
+ if (::CreatePipe (&pipeRead, &pipeWrite, &security, 0 ) == FALSE )
622
+ {
623
+ return Result::Error (" PipeDescriptor::createPipe - ::CreatePipe failed" );
624
+ }
644
625
}
645
626
SC_TRY (readPipe.assign (pipeRead));
646
627
SC_TRY (writePipe.assign (pipeWrite));
647
628
648
629
if (security.bInheritHandle )
649
630
{
650
- if (readFlag == ReadNonInheritable )
631
+ if (not options. readInheritable )
651
632
{
652
- SC_TRY_MSG (readPipe.setInheritable (false ), " Cannot set read pipe inheritable" );
633
+ if (::SetHandleInformation (pipeRead, HANDLE_FLAG_INHERIT, FALSE ) == FALSE )
634
+ {
635
+ return Result::Error (" Cannot set read pipe inheritable" );
636
+ }
653
637
}
654
- if (writeFlag == WriteNonInheritable )
638
+ if (not options. writeInheritable )
655
639
{
656
- SC_TRY_MSG (writePipe.setInheritable (false ), " Cannot set write pipe inheritable" );
640
+ if (::SetHandleInformation (pipeWrite, HANDLE_FLAG_INHERIT, FALSE ) == FALSE )
641
+ {
642
+ return Result::Error (" Cannot set write pipe inheritable" );
643
+ }
657
644
}
658
645
}
659
646
return Result (true );
660
647
}
661
648
662
649
#else
663
- SC::Result SC::PipeDescriptor::createPipe (InheritableReadFlag readFlag, InheritableWriteFlag writeFlag )
650
+ SC::Result SC::PipeDescriptor::createPipe (PipeOptions options )
664
651
{
665
652
int pipes[2 ];
666
653
// TODO: Use pipe2 to set cloexec flags immediately
@@ -678,13 +665,22 @@ SC::Result SC::PipeDescriptor::createPipe(InheritableReadFlag readFlag, Inherita
678
665
SC_TRY_MSG (writePipe.assign (pipes[1 ]), " Cannot assign write pipe" );
679
666
// On Posix by default descriptors are inheritable
680
667
// https://devblogs.microsoft.com/oldnewthing/20111216-00/?p=8873
681
- if (readFlag == ReadNonInheritable)
668
+ if (options.readInheritable == false )
669
+ {
670
+ const Result pipeRes1 = FileDescriptor::Internal::setFileDescriptorFlags<FD_CLOEXEC>(pipes[0 ], true );
671
+ SC_TRY_MSG (pipeRes1, " Cannot set close on exec on read pipe" );
672
+ }
673
+ if (options.writeInheritable == false )
682
674
{
683
- SC_TRY_MSG (readPipe.setInheritable (false ), " Cannot set close on exec on read pipe" );
675
+ const Result pipeRes2 = FileDescriptor::Internal::setFileDescriptorFlags<FD_CLOEXEC>(pipes[1 ], true );
676
+ SC_TRY_MSG (pipeRes2, " Cannot set close on exec on write pipe" );
684
677
}
685
- if (writeFlag == WriteNonInheritable )
678
+ if (options. blocking == false )
686
679
{
687
- SC_TRY_MSG (writePipe.setInheritable (false ), " Cannot set close on exec on write pipe" );
680
+ const Result pipeRes1 = FileDescriptor::Internal::setFileStatusFlags<O_NONBLOCK>(pipes[0 ], true );
681
+ SC_TRY_MSG (pipeRes1, " Cannot set non-blocking flag on read" );
682
+ const Result pipeRes2 = FileDescriptor::Internal::setFileStatusFlags<O_NONBLOCK>(pipes[1 ], true );
683
+ SC_TRY_MSG (pipeRes2, " Cannot set non-blocking flag on read" );
688
684
}
689
685
return Result (true );
690
686
}
0 commit comments