Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
6.5 KiB

  1. /***
  2. *pipe.c - create a pipe
  3. *
  4. * Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * defines _pipe() - creates a pipe (i.e., an I/O channel for interprocess
  8. * communication)
  9. *
  10. *Revision History:
  11. * 06-20-89 PHG Module created, based on asm version
  12. * 03-13-90 GJF Made calling type _CALLTYPE2 (for now), added #include
  13. * <cruntime.h> and fixed copyright. Also, cleaned up the
  14. * formatting a bit.
  15. * 04-03-90 GJF Now _CALLTYPE1.
  16. * 07-24-90 SBM Removed '32' from API names
  17. * 08-14-90 SBM Compiles cleanly with -W3
  18. * 10-01-90 GJF New-style function declarator.
  19. * 12-04-90 SRW Changed to include <oscalls.h> instead of <doscalls.h>
  20. * 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals.
  21. * 01-18-91 GJF ANSI naming.
  22. * 02-18-91 SRW Added _WIN32_ implementation [_WIN32_]
  23. * 02-25-91 SRW Renamed _get_free_osfhnd to be _alloc_osfhnd [_WIN32_]
  24. * 03-13-91 SRW Fixed _pipe so it works [_WIN32_]
  25. * 03-18-91 SRW Fixed _pipe NtCreatePipe handles are inherited [_WIN32_]
  26. * 04-06-92 SRW Pay attention to _O_NOINHERIT flag in oflag parameter
  27. * 01-10-93 GJF Fixed bug in checking for _O_BINARY (inadvertently
  28. * introduced by SRW's change above).
  29. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  30. * 09-06-94 CFW Remove Cruiser support.
  31. * 12-03-94 SKS Clean up OS/2 references
  32. * 06-12-95 GJF Replaced _osfile[] with _osfile() (macro referencing
  33. * field in ioinfo struct).
  34. * 05-16-96 GJF Set the FNOINHERIT bit (new) if appropriate. Also,
  35. * detab-ed and cleaned up the formatting a bit.
  36. * 05-31-96 SKS Fix expression error in GJF's most recent check-in
  37. * 12-29-97 GJF Exception-safe locking.
  38. * 02-07-98 GJF Changes for Win64: arg type of _set_osfhnd is now
  39. * intptr_t.
  40. * 10-16-00 PML Avoid deadlock in _alloc_osfhnd (vs7#173087).
  41. *
  42. *******************************************************************************/
  43. #include <cruntime.h>
  44. #include <oscalls.h>
  45. #include <mtdll.h>
  46. #include <io.h>
  47. #include <internal.h>
  48. #include <stdlib.h>
  49. #include <errno.h>
  50. #include <msdos.h>
  51. #include <fcntl.h>
  52. /***
  53. *int _pipe(phandles, psize, textmode) - open a pipe
  54. *
  55. *Purpose:
  56. * Checks if the given handle is associated with a character device
  57. * (terminal, console, printer, serial port)
  58. *
  59. * Multi-thread notes: No locking is performed or deemed necessary. The
  60. * handles returned by DOSCREATEPIPE are newly opened and, therefore,
  61. * should not be referenced by any thread until after the _pipe call is
  62. * complete. The function is not protected from some thread of the caller
  63. * doing, say, output to a previously invalid handle that becomes one of
  64. * the pipe handles. However, any such program is doomed anyway and
  65. * protecting the _pipe function such a case would be of little value.
  66. *
  67. *Entry:
  68. * int phandle[2] - array to hold returned read (phandle[0]) and write
  69. * (phandle[1]) handles
  70. *
  71. * unsigned psize - amount of memory, in bytes, to ask o.s. to reserve
  72. * for the pipe
  73. *
  74. * int textmode - _O_TEXT, _O_BINARY, _O_NOINHERIT, or 0 (use default)
  75. *
  76. *Exit:
  77. * returns 0 if successful
  78. * returns -1 if an error occurs in which case, errno is set to:
  79. *
  80. *Exceptions:
  81. *
  82. *******************************************************************************/
  83. int __cdecl _pipe (
  84. int phandles[2],
  85. unsigned psize,
  86. int textmode
  87. )
  88. {
  89. ULONG dosretval; /* o.s. return value */
  90. int handle0, handle1;
  91. HANDLE ReadHandle, WriteHandle;
  92. SECURITY_ATTRIBUTES SecurityAttributes;
  93. phandles[0] = phandles[1] = -1;
  94. SecurityAttributes.nLength = sizeof(SecurityAttributes);
  95. SecurityAttributes.lpSecurityDescriptor = NULL;
  96. if (textmode & _O_NOINHERIT) {
  97. SecurityAttributes.bInheritHandle = FALSE;
  98. }
  99. else {
  100. SecurityAttributes.bInheritHandle = TRUE;
  101. }
  102. if (!CreatePipe(&ReadHandle, &WriteHandle, &SecurityAttributes, psize)) {
  103. /* o.s. error */
  104. dosretval = GetLastError();
  105. _dosmaperr(dosretval);
  106. return -1;
  107. }
  108. /* now we must allocate C Runtime handles for Read and Write handles */
  109. if ((handle0 = _alloc_osfhnd()) != -1) {
  110. #ifdef _MT
  111. __try {
  112. #endif /* _MT */
  113. _osfile(handle0) = (char)(FOPEN | FPIPE | FTEXT);
  114. #ifdef _MT
  115. }
  116. __finally {
  117. _unlock_fh( handle0 );
  118. }
  119. #endif /* _MT */
  120. if ((handle1 = _alloc_osfhnd()) != -1) {
  121. #ifdef _MT
  122. __try {
  123. #endif /* _MT */
  124. _osfile(handle1) = (char)(FOPEN | FPIPE | FTEXT);
  125. #ifdef _MT
  126. }
  127. __finally {
  128. if ( handle1 != -1 )
  129. _unlock_fh( handle1 );
  130. }
  131. #endif /* _MT */
  132. if ( (textmode & _O_BINARY) ||
  133. (((textmode & _O_TEXT) == 0) &&
  134. (_fmode == _O_BINARY)) ) {
  135. /* binary mode */
  136. _osfile(handle0) &= ~FTEXT;
  137. _osfile(handle1) &= ~FTEXT;
  138. }
  139. if ( textmode & _O_NOINHERIT ) {
  140. _osfile(handle0) |= FNOINHERIT;
  141. _osfile(handle1) |= FNOINHERIT;
  142. }
  143. _set_osfhnd(handle0, (intptr_t)ReadHandle);
  144. _set_osfhnd(handle1, (intptr_t)WriteHandle);
  145. errno = 0;
  146. }
  147. else {
  148. _osfile(handle0) = 0;
  149. errno = EMFILE; /* too many files */
  150. }
  151. }
  152. else {
  153. errno = EMFILE; /* too many files */
  154. }
  155. /* If error occurred, close Win32 handles and return -1 */
  156. if (errno != 0) {
  157. CloseHandle(ReadHandle);
  158. CloseHandle(WriteHandle);
  159. _doserrno = 0; /* not an o.s. error */
  160. return -1;
  161. }
  162. phandles[0] = handle0;
  163. phandles[1] = handle1;
  164. return 0;
  165. }