Source code of Windows XP (NT5)
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.

502 lines
10 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. conio.c
  5. Abstract:
  6. This module implements server performed console io
  7. Author:
  8. Matthew Bradburn (mattbr) 18-Dec-1992
  9. Revision History:
  10. --*/
  11. #include <sys/stat.h>
  12. #include "psxsrv.h"
  13. #define NTPSX_ONLY
  14. #include "sesport.h"
  15. BOOLEAN
  16. ConOpen(
  17. IN PPSX_PROCESS p,
  18. IN PFILEDESCRIPTOR Fd,
  19. IN OUT PPSX_API_MSG m
  20. );
  21. BOOLEAN
  22. ConRead(
  23. IN PPSX_PROCESS p,
  24. IN OUT PPSX_API_MSG m,
  25. IN PFILEDESCRIPTOR Fd
  26. );
  27. BOOLEAN
  28. ConWrite (
  29. IN PPSX_PROCESS p,
  30. IN OUT PPSX_API_MSG m,
  31. IN PFILEDESCRIPTOR Fd
  32. );
  33. BOOLEAN
  34. ConDup (
  35. IN PPSX_PROCESS p,
  36. IN OUT PPSX_API_MSG m,
  37. IN PFILEDESCRIPTOR Fd,
  38. IN PFILEDESCRIPTOR FdDup
  39. );
  40. BOOLEAN
  41. ConLseek (
  42. IN PPSX_PROCESS p,
  43. IN OUT PPSX_API_MSG m,
  44. IN PFILEDESCRIPTOR Fd
  45. );
  46. BOOLEAN
  47. ConStat (
  48. IN PIONODE IoNode,
  49. IN HANDLE FileHandle,
  50. OUT struct stat *StatBuf,
  51. OUT NTSTATUS *Status
  52. );
  53. VOID
  54. ConLastClose (
  55. IN PPSX_PROCESS p,
  56. IN PSYSTEMOPENFILE SystemOpenFile
  57. )
  58. {
  59. NTSTATUS st;
  60. SCREQUESTMSG Request;
  61. #if 0
  62. //
  63. // We don't do this anymore, because if the session manager has
  64. // died, we'll never get a reply, and we'll hang while holding some
  65. // lock or another.
  66. //
  67. Request.Request = ConRequest;
  68. Request.d.Con.Request = ScCloseFile;
  69. Request.d.Con.d.IoBuf.Handle = SystemOpenFile->NtIoHandle;
  70. PORT_MSG_TOTAL_LENGTH(Request) = sizeof(SCREQUESTMSG);
  71. PORT_MSG_DATA_LENGTH(Request) = sizeof(SCREQUESTMSG) -
  72. sizeof(PORT_MESSAGE);
  73. PORT_MSG_ZERO_INIT(Request) = 0;
  74. RtlEnterCriticalSection(&SystemOpenFile->Terminal->Lock);
  75. st = NtRequestWaitReplyPort(
  76. SystemOpenFile->Terminal->ConsolePort,
  77. (PPORT_MESSAGE)&Request, (PPORT_MESSAGE)&Request);
  78. // ASSERT(NT_SUCCESS(st));
  79. RtlLeaveCriticalSection(&SystemOpenFile->Terminal->Lock);
  80. #endif
  81. SystemOpenFile->NtIoHandle = NULL;
  82. }
  83. PSXIO_VECTORS ConVectors = {
  84. ConOpen,
  85. NULL,
  86. NULL,
  87. ConLastClose,
  88. NULL,
  89. ConRead,
  90. ConWrite,
  91. ConDup,
  92. ConLseek,
  93. ConStat
  94. };
  95. BOOLEAN
  96. ConOpen(
  97. IN PPSX_PROCESS p,
  98. IN PFILEDESCRIPTOR Fd,
  99. IN OUT PPSX_API_MSG m
  100. )
  101. /*++
  102. Routine Description:
  103. This routine is called when the path /dev/tty is opened. Its
  104. function is to set up the stuff for stat that doesn't exist because
  105. there isn't really such a file.
  106. Arguments:
  107. p - Supplies the address of the process making the call.
  108. m - Supplies the address of the message associated with the request.
  109. Fd - supplies the address of the file descriptor being written.
  110. Return Value:
  111. FALSE - Failure.
  112. TRUE - Success.
  113. --*/
  114. {
  115. PPSX_OPEN_MSG args;
  116. LARGE_INTEGER time;
  117. ULONG posix_time;
  118. args = &m->u.Open;
  119. NtQuerySystemTime(&time);
  120. if (!RtlTimeToSecondsSince1970(&time, &posix_time)) {
  121. posix_time = 0;
  122. }
  123. RtlEnterCriticalSection(&Fd->SystemOpenFileDesc->IoNode->IoNodeLock);
  124. Fd->SystemOpenFileDesc->IoNode->ModifyDataTime = posix_time;
  125. Fd->SystemOpenFileDesc->IoNode->ModifyIoNodeTime = posix_time;
  126. Fd->SystemOpenFileDesc->IoNode->AccessDataTime = posix_time;
  127. RtlLeaveCriticalSection(&Fd->SystemOpenFileDesc->IoNode->IoNodeLock);
  128. return TRUE;
  129. }
  130. BOOLEAN
  131. ConWrite (
  132. IN PPSX_PROCESS p,
  133. IN OUT PPSX_API_MSG m,
  134. IN PFILEDESCRIPTOR Fd
  135. )
  136. /*++
  137. Routine Description:
  138. This procedure implements write when the device being written
  139. is a file.
  140. Arguments:
  141. p - Supplies the address of the process making the call.
  142. m - Supplies the address of the message associated with the request.
  143. Fd - supplies the address of the file descriptor being written.
  144. Return Value:
  145. --*/
  146. {
  147. PPSX_WRITE_MSG args;
  148. NTSTATUS st;
  149. IO_STATUS_BLOCK Iosb;
  150. LARGE_INTEGER ByteOffset;
  151. ULONG IoBufferSize;
  152. FILE_FS_SIZE_INFORMATION SizeInfo;
  153. ULONG Avail;
  154. PVOID IoBuffer = NULL;
  155. LARGE_INTEGER Time;
  156. ULONG PosixTime;
  157. SCREQUESTMSG Request;
  158. args = &m->u.Write;
  159. args->Command = IO_COMMAND_DO_CONSIO;
  160. //
  161. // We need to tell the dll whether to do non-blocking io
  162. // or not.
  163. //
  164. if (Fd->SystemOpenFileDesc->Flags & PSX_FD_NOBLOCK) {
  165. args->Scratch1 = O_NONBLOCK;
  166. } else {
  167. args->Scratch1 = 0;
  168. }
  169. //
  170. // Replace the given file descriptor with the one that should
  171. // really be used to do the io to posix.exe. They might be
  172. // different if the one passed in was created by duping 0, 1,
  173. // or 2.
  174. //
  175. args->FileDes = HandleToUlong(Fd->SystemOpenFileDesc->NtIoHandle);
  176. //
  177. // Update st_mtime and st_ctime.
  178. //
  179. NtQuerySystemTime(&Time);
  180. if (!RtlTimeToSecondsSince1970(&Time, &PosixTime)) {
  181. PosixTime = 0;
  182. }
  183. RtlEnterCriticalSection(&Fd->SystemOpenFileDesc->IoNode->IoNodeLock);
  184. Fd->SystemOpenFileDesc->IoNode->ModifyDataTime = PosixTime;
  185. Fd->SystemOpenFileDesc->IoNode->ModifyIoNodeTime = PosixTime;
  186. RtlLeaveCriticalSection(&Fd->SystemOpenFileDesc->IoNode->IoNodeLock);
  187. return TRUE;
  188. }
  189. BOOLEAN
  190. ConRead (
  191. IN PPSX_PROCESS p,
  192. IN OUT PPSX_API_MSG m,
  193. IN PFILEDESCRIPTOR Fd
  194. )
  195. /*++
  196. Routine Description:
  197. This procedure implements read when the device being read
  198. is a file.
  199. Arguments:
  200. p - Supplies the address of the process making the call.
  201. m - Supplies the address of the message associated with the request.
  202. Fd - supplies the address of the file descriptor being read.
  203. Return Value:
  204. --*/
  205. {
  206. PPSX_READ_MSG args;
  207. NTSTATUS st;
  208. IO_STATUS_BLOCK Iosb;
  209. LARGE_INTEGER ByteOffset;
  210. ULONG IoBufferSize;
  211. PVOID IoBuffer = NULL;
  212. LARGE_INTEGER Time;
  213. ULONG PosixTime;
  214. PSIGDB SigDb;
  215. SCREQUESTMSG Request;
  216. args = &m->u.Read;
  217. //
  218. // 1003.1-90 (6.4.1.4): EIO ... The implementation supports job
  219. // control, the process is in a background process group and is
  220. // attempting to read from its controlling terminal, and either
  221. // the process is ignoring or blocking the SIGTTIN signal or
  222. // the process group of the process is orphaned.
  223. //
  224. SigDb = &p->SignalDataBase;
  225. if (NULL != p->PsxSession->Terminal &&
  226. p->PsxSession->Terminal->ForegroundProcessGroup !=
  227. p->ProcessGroupId &&
  228. p->PsxSession->Terminal == Fd->SystemOpenFileDesc->Terminal &&
  229. ((SigDb->SignalDisposition[SIGTTIN-1].sa_handler == SIG_IGN ||
  230. SIGISMEMBER(&SigDb->BlockedSignalMask, SIGTTIN)) ||
  231. IsGroupOrphaned(p->ProcessGroupId))) {
  232. m->Error = EIO;
  233. return TRUE;
  234. }
  235. args->Command = IO_COMMAND_DO_CONSIO;
  236. //
  237. // We need to tell the dll whether to do non-blocking io
  238. // or not.
  239. //
  240. if (Fd->SystemOpenFileDesc->Flags & PSX_FD_NOBLOCK) {
  241. args->Scratch1 = O_NONBLOCK;
  242. } else {
  243. args->Scratch1 = 0;
  244. }
  245. //
  246. // Replace the given file descriptor with the one that should
  247. // really be used to do the io to posix.exe. They might be
  248. // different if the one passed in was created by duping 0, 1,
  249. // or 2.
  250. //
  251. args->FileDes = HandleToUlong(Fd->SystemOpenFileDesc->NtIoHandle);
  252. NtQuerySystemTime(&Time);
  253. if (!RtlTimeToSecondsSince1970(&Time, &PosixTime)) {
  254. PosixTime = 0;
  255. }
  256. //
  257. // Update st_atime.
  258. //
  259. RtlEnterCriticalSection(&Fd->SystemOpenFileDesc->IoNode->IoNodeLock);
  260. Fd->SystemOpenFileDesc->IoNode->AccessDataTime = PosixTime;
  261. RtlLeaveCriticalSection(&Fd->SystemOpenFileDesc->IoNode->IoNodeLock);
  262. return TRUE;
  263. }
  264. BOOLEAN
  265. ConDup (
  266. IN PPSX_PROCESS p,
  267. IN OUT PPSX_API_MSG m,
  268. IN PFILEDESCRIPTOR Fd,
  269. IN PFILEDESCRIPTOR FdDup
  270. )
  271. /*++
  272. Routine Description:
  273. This procedure implements dup and dup2
  274. Arguments:
  275. p - Supplies the address of the process making the call.
  276. m - Supplies the address of the message associated with the request.
  277. Fd - supplies the address of the file descriptor being duplicated.
  278. FdDup - supplies the address of the duplicate file descriptor.
  279. Return Value:
  280. ???
  281. --*/
  282. {
  283. PPSX_DUP_MSG args;
  284. args = &m->u.Dup;
  285. //
  286. // Copy contents of source file descriptor slot into new descriptor
  287. // Note that FD_CLOEXEC must be CLEAR on FdDup.
  288. //
  289. *FdDup = *Fd;
  290. FdDup->Flags &= ~PSX_FD_CLOSE_ON_EXEC;
  291. //
  292. // Increment reference count associated with the SystemOpenFile
  293. // descriptor for this file.
  294. //
  295. RtlEnterCriticalSection(&SystemOpenFileLock);
  296. Fd->SystemOpenFileDesc->HandleCount++;
  297. RtlLeaveCriticalSection(&SystemOpenFileLock);
  298. return TRUE;
  299. }
  300. BOOLEAN
  301. ConLseek (
  302. IN PPSX_PROCESS p,
  303. IN OUT PPSX_API_MSG m,
  304. IN PFILEDESCRIPTOR Fd
  305. )
  306. /*++
  307. Routine Description:
  308. This procedure implements lseek when the device being seeked on
  309. is a file.
  310. Arguments:
  311. p - Supplies the address of the process making the call.
  312. m - Supplies the address of the message associated with the request.
  313. Fd - supplies the address of the file descriptor being seekd
  314. Return Value:
  315. ???
  316. --*/
  317. {
  318. //
  319. // Can't seek on a console.
  320. //
  321. m->Error = ESPIPE;
  322. return TRUE;
  323. }
  324. BOOLEAN
  325. ConStat (
  326. IN PIONODE IoNode,
  327. IN HANDLE FileHandle,
  328. OUT struct stat *StatBuf,
  329. OUT NTSTATUS *pStatus
  330. )
  331. /*++
  332. Routine Description:
  333. This procedure implements stat when the device being read
  334. is a file.
  335. Arguments:
  336. IoNode - supplies a pointer to the ionode of the file for which stat is
  337. requested. NULL if no active Ionode entry.
  338. FileHandle - supplies the Nt file handle of the file .
  339. StatBuf - Supplies the address of the statbuf portion of the message
  340. associated with the request.
  341. Return Value:
  342. TRUE
  343. --*/
  344. {
  345. ULONG PosixTime;
  346. StatBuf->st_mode = IoNode->Mode;
  347. StatBuf->st_ino = (ino_t)IoNode->FileSerialNumber;
  348. StatBuf->st_dev = IoNode->DeviceSerialNumber;
  349. StatBuf->st_uid = IoNode->OwnerId;
  350. StatBuf->st_gid = IoNode->GroupId;
  351. StatBuf->st_size = 0;
  352. StatBuf->st_atime = IoNode->AccessDataTime;
  353. StatBuf->st_mtime = IoNode->ModifyDataTime;
  354. StatBuf->st_ctime = IoNode->ModifyIoNodeTime;
  355. StatBuf->st_nlink = 1;
  356. return TRUE;
  357. }