1 // 2 // pipe.cpp 3 // 4 // Copyright (c) Microsoft Corporation. All rights reserved. 5 // 6 // Defines _pipe(), which creates a pipe. 7 // 8 #include <corecrt_internal_lowio.h> 9 #include <stdlib.h> 10 11 12 13 // Creates a pipe. The phandles pointer must be a pointer to an array of two 14 // int objects. Upon successful return, phandles[0] is the read handle, and 15 // phandles[1] is the write handle for the pipe. On success, 0 is returned; on 16 // failure, -1 is returned and errno is set. 17 // 18 // The psize is the amount of memory, in bytes, to ask the OS to reserve for the 19 // pipe. The textmode is the text mode that will be given to the pipe. 20 extern "C" int __cdecl _pipe(int* const phandles, unsigned const psize, int const textmode) 21 { 22 _VALIDATE_CLEAR_OSSERR_RETURN(phandles != nullptr, EINVAL, -1); 23 phandles[0] = phandles[1] = -1; 24 25 _VALIDATE_CLEAR_OSSERR_RETURN((textmode & ~(_O_NOINHERIT | _O_BINARY | _O_TEXT)) == 0, EINVAL, -1); 26 _VALIDATE_CLEAR_OSSERR_RETURN((textmode & (_O_BINARY | _O_TEXT)) != (_O_BINARY | _O_TEXT), EINVAL, -1); 27 28 29 SECURITY_ATTRIBUTES security_attributes; 30 security_attributes.nLength = sizeof(security_attributes); 31 security_attributes.lpSecurityDescriptor = nullptr; 32 security_attributes.bInheritHandle = (textmode & _O_NOINHERIT) == 0; 33 34 35 // Create the pipe: 36 HANDLE read_handle, write_handle; 37 if (!CreatePipe(&read_handle, &write_handle, &security_attributes, psize)) 38 { 39 __acrt_errno_map_os_error(GetLastError()); 40 return -1; 41 } 42 43 // Create the CRT read handle for the pipe: 44 int const crt_read_handle = _alloc_osfhnd(); 45 if (crt_read_handle == -1) 46 { 47 errno = EMFILE; 48 _doserrno = 0; 49 CloseHandle(read_handle); 50 CloseHandle(write_handle); 51 return -1; 52 } 53 54 __try 55 { 56 _osfile(crt_read_handle) = FOPEN | FPIPE | FTEXT; 57 _textmode(crt_read_handle) = __crt_lowio_text_mode::ansi; 58 _tm_unicode(crt_read_handle) = false; 59 } 60 __finally 61 { 62 __acrt_lowio_unlock_fh(crt_read_handle); 63 } 64 __endtry 65 66 // Create the CRT write handle for the pipe: 67 int const crt_write_handle = _alloc_osfhnd(); 68 if (crt_write_handle == -1) 69 { 70 _osfile(crt_read_handle) = 0; 71 errno = EMFILE; 72 _doserrno = 0; 73 CloseHandle(read_handle); 74 CloseHandle(write_handle); 75 return -1; 76 } 77 78 __try 79 { 80 _osfile(crt_write_handle) = FOPEN | FPIPE | FTEXT; 81 _textmode(crt_write_handle) = __crt_lowio_text_mode::ansi; 82 _tm_unicode(crt_write_handle) = false; 83 } 84 __finally 85 { 86 __acrt_lowio_unlock_fh(crt_write_handle); 87 } 88 __endtry 89 90 // Figure out which textmode the file gets: 91 int fmode = 0; 92 _ERRCHECK(_get_fmode(&fmode)); 93 94 // The pipe gets binary mode if (a) binary was requested or (b) the 95 // global default fmode was changed to binary. 96 if ((textmode & _O_BINARY) || ((textmode & _O_TEXT) == 0 && fmode == _O_BINARY)) 97 { 98 _osfile(crt_read_handle) &= ~FTEXT; 99 _osfile(crt_write_handle) &= ~FTEXT; 100 } 101 102 if (textmode & _O_NOINHERIT) 103 { 104 _osfile(crt_read_handle) |= FNOINHERIT; 105 _osfile(crt_write_handle) |= FNOINHERIT; 106 } 107 108 __acrt_lowio_set_os_handle(crt_read_handle, reinterpret_cast<intptr_t>(read_handle)); 109 __acrt_lowio_set_os_handle(crt_write_handle, reinterpret_cast<intptr_t>(write_handle)); 110 111 phandles[0] = crt_read_handle; 112 phandles[1] = crt_write_handle; 113 114 return 0; 115 } 116