Changeset 2416 in kBuild for trunk/src/kash
- Timestamp:
- Sep 14, 2010 12:30:30 AM (15 years ago)
- Location:
- trunk/src/kash
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kash/miscbltin.c
r2290 r2416 108 108 } 109 109 110 if (prompt && isatty(0)) {110 if (prompt && shfile_isatty(&psh->fdtab, 0)) { 111 111 out2str(psh, prompt); 112 112 output_flushall(psh); -
trunk/src/kash/shfile.c
r2413 r2416 39 39 # define PIPE_BUF 512 40 40 # endif 41 # include <ntstatus.h> 42 # define WIN32_NO_STATUS 41 43 # include <Windows.h> 44 # if !defined(_WIN32_WINNT) 45 # define _WIN32_WINNT 0x0502 /* Windows Server 2003 */ 46 # endif 47 # include <winternl.h> //NTSTATUS 42 48 #else 43 49 # include <unistd.h> … … 86 92 87 93 # define MY_ObjectBasicInformation 0 88 typedef LONG (NTAPI * PFN_NtQueryObject)(HANDLE, int, void *, size_t, size_t *); 89 90 typedef struct MY_OBJECT_BASIC_INFORMATION94 # define MY_FileNamesInformation 12 95 96 typedef struct 91 97 { 92 98 ULONG Attributes; … … 103 109 } MY_OBJECT_BASIC_INFORMATION; 104 110 111 #if 0 112 typedef struct 113 { 114 union 115 { 116 LONG Status; 117 PVOID Pointer; 118 }; 119 ULONG_PTR Information; 120 } MY_IO_STATUS_BLOCK; 121 #else 122 typedef IO_STATUS_BLOCK MY_IO_STATUS_BLOCK; 123 #endif 124 typedef MY_IO_STATUS_BLOCK *PMY_IO_STATUS_BLOCK; 125 126 typedef struct 127 { 128 ULONG NextEntryOffset; 129 ULONG FileIndex; 130 ULONG FileNameLength; 131 WCHAR FileName[1]; 132 } MY_FILE_NAMES_INFORMATION, *PMY_FILE_NAMES_INFORMATION; 133 134 typedef NTSTATUS (NTAPI * PFN_NtQueryObject)(HANDLE, int, void *, size_t, size_t *); 135 typedef NTSTATUS (NTAPI * PFN_NtQueryDirectoryFile)(HANDLE, HANDLE, void *, void *, PMY_IO_STATUS_BLOCK, void *, 136 ULONG, int, int, PUNICODE_STRING, int); 137 typedef NTSTATUS (NTAPI * PFN_RtlUnicodeStringToAnsiString)(PANSI_STRING, PCUNICODE_STRING, int); 138 139 140 #endif /* K_OS_WINDOWS */ 141 142 143 /******************************************************************************* 144 * Global Variables * 145 *******************************************************************************/ 146 #if K_OS == K_OS_WINDOWS 147 static int g_shfile_globals_initialized = 0; 148 static PFN_NtQueryObject g_pfnNtQueryObject = NULL; 149 static PFN_NtQueryDirectoryFile g_pfnNtQueryDirectoryFile = NULL; 150 static PFN_RtlUnicodeStringToAnsiString g_pfnRtlUnicodeStringToAnsiString = NULL; 105 151 #endif /* K_OS_WINDOWS */ 106 152 … … 387 433 } 388 434 435 /** 436 * Converts an NT status code to errno, 437 * assigning it to errno. 438 * 439 * @returns -1 440 * @param rcNt The NT status code. 441 */ 442 static int shfile_nt2errno(NTSTATUS rcNt) 443 { 444 switch (rcNt) 445 { 446 default: errno = EINVAL; break; 447 } 448 return -1; 449 } 450 389 451 DWORD shfile_query_handle_access_mask(HANDLE h, PACCESS_MASK pMask) 390 452 { 391 static PFN_NtQueryObject s_pfnNtQueryObject = NULL;392 453 MY_OBJECT_BASIC_INFORMATION BasicInfo; 393 LONG Status; 394 395 if (!s_pfnNtQueryObject) 396 { 397 s_pfnNtQueryObject = (PFN_NtQueryObject)GetProcAddress(GetModuleHandle("NTDLL"), "NtQueryObject"); 398 if (!s_pfnNtQueryObject) 399 return ERROR_NOT_SUPPORTED; 400 } 401 402 Status = s_pfnNtQueryObject(h, MY_ObjectBasicInformation, &BasicInfo, sizeof(BasicInfo), NULL); 403 if (Status >= 0) 454 NTSTATUS rcNt; 455 456 if (!g_pfnNtQueryObject) 457 return ERROR_NOT_SUPPORTED; 458 459 rcNt = g_pfnNtQueryObject(h, MY_ObjectBasicInformation, &BasicInfo, sizeof(BasicInfo), NULL); 460 if (rcNt >= 0) 404 461 { 405 462 *pMask = BasicInfo.GrantedAccess; 406 463 return NO_ERROR; 407 464 } 408 if ( Status!= STATUS_INVALID_HANDLE)465 if (rcNt != STATUS_INVALID_HANDLE) 409 466 return ERROR_GEN_FAILURE; 410 467 return ERROR_INVALID_HANDLE; … … 414 471 415 472 #endif /* SHFILE_IN_USE */ 473 474 /** 475 * Initializes the global variables in this file. 476 */ 477 static void shfile_init_globals(void) 478 { 479 #if K_OS == K_OS_WINDOWS 480 if (!g_shfile_globals_initialized) 481 { 482 HMODULE hNtDll = GetModuleHandle("NTDLL"); 483 g_pfnNtQueryObject = (PFN_NtQueryObject) GetProcAddress(hNtDll, "NtQueryObject"); 484 g_pfnNtQueryDirectoryFile = (PFN_NtQueryDirectoryFile)GetProcAddress(hNtDll, "NtQueryDirectoryFile"); 485 g_pfnRtlUnicodeStringToAnsiString = (PFN_RtlUnicodeStringToAnsiString)GetProcAddress(hNtDll, "RtlUnicodeStringToAnsiString"); 486 if ( !g_pfnRtlUnicodeStringToAnsiString 487 || !g_pfnNtQueryDirectoryFile) 488 { 489 /* fatal error */ 490 } 491 g_shfile_globals_initialized = 1; 492 } 493 #endif 494 } 416 495 417 496 /** … … 426 505 { 427 506 int rc; 507 508 shfile_init_globals(); 428 509 429 510 pfdtab->cwd = NULL; … … 1417 1498 1418 1499 1500 1419 1501 shdir *shfile_opendir(shfdtab *pfdtab, const char *dir) 1420 1502 { 1421 1503 #ifdef SHFILE_IN_USE 1422 errno = ENOSYS; 1423 return NULL; 1504 shdir *pdir = NULL; 1505 1506 if (g_pfnNtQueryDirectoryFile) 1507 { 1508 char abspath[SHFILE_MAX_PATH]; 1509 if (shfile_make_path(pfdtab, dir, &abspath[0]) == 0) 1510 { 1511 HANDLE hFile; 1512 SECURITY_ATTRIBUTES SecurityAttributes; 1513 1514 SecurityAttributes.nLength = sizeof(SecurityAttributes); 1515 SecurityAttributes.lpSecurityDescriptor = NULL; 1516 SecurityAttributes.bInheritHandle = FALSE; 1517 1518 hFile = CreateFileA(abspath, 1519 GENERIC_READ, 1520 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 1521 &SecurityAttributes, 1522 OPEN_ALWAYS, 1523 FILE_ATTRIBUTE_DIRECTORY | FILE_FLAG_BACKUP_SEMANTICS, 1524 NULL /* hTemplateFile */); 1525 if (hFile != INVALID_HANDLE_VALUE) 1526 { 1527 pdir = (shdir *)sh_malloc(shthread_get_shell(), sizeof(*pdir)); 1528 if (pdir) 1529 { 1530 pdir->pfdtab = pfdtab; 1531 pdir->native = hFile; 1532 pdir->off = ~(size_t)0; 1533 } 1534 else 1535 CloseHandle(hFile); 1536 } 1537 else 1538 shfile_dos2errno(GetLastError()); 1539 } 1540 } 1541 else 1542 errno = ENOSYS; 1543 return pdir; 1424 1544 #else 1425 1545 return (shdir *)opendir(dir); … … 1430 1550 { 1431 1551 #ifdef SHFILE_IN_USE 1432 errno = ENOSYS; 1552 if (pdir) 1553 { 1554 NTSTATUS rcNt; 1555 1556 if ( pdir->off == ~(size_t)0 1557 || pdir->off + sizeof(MY_FILE_NAMES_INFORMATION) >= pdir->cb) 1558 { 1559 MY_IO_STATUS_BLOCK Ios; 1560 1561 memset(&Ios, 0, sizeof(Ios)); 1562 rcNt = g_pfnNtQueryDirectoryFile(pdir->native, 1563 NULL /*Event*/, 1564 NULL /*ApcRoutine*/, 1565 NULL /*ApcContext*/, 1566 &Ios, 1567 &pdir->buf[0], 1568 sizeof(pdir->buf), 1569 MY_FileNamesInformation, 1570 FALSE /*ReturnSingleEntry*/, 1571 NULL /*FileName*/, 1572 pdir->off == ~(size_t)0 /*RestartScan*/); 1573 if (rcNt >= 0 && rcNt != STATUS_PENDING) 1574 { 1575 pdir->cb = Ios.Information; 1576 pdir->off = 0; 1577 } 1578 else if (rcNt == STATUS_NO_MORE_FILES) 1579 errno = 0; /* wrong? */ 1580 else 1581 shfile_nt2errno(rcNt); 1582 } 1583 1584 if ( pdir->off != ~(size_t)0 1585 && pdir->off + sizeof(MY_FILE_NAMES_INFORMATION) <= pdir->cb) 1586 { 1587 PMY_FILE_NAMES_INFORMATION pcur = (PMY_FILE_NAMES_INFORMATION)&pdir->buf[pdir->off]; 1588 ANSI_STRING astr; 1589 UNICODE_STRING ustr; 1590 1591 astr.Length = astr.MaximumLength = sizeof(pdir->ent.name); 1592 astr.Buffer = &pdir->ent.name[0]; 1593 1594 ustr.Length = ustr.MaximumLength = pcur->FileNameLength < ~(USHORT)0 ? (USHORT)pcur->FileNameLength : ~(USHORT)0; 1595 ustr.Buffer = &pcur->FileName[0]; 1596 1597 rcNt = g_pfnRtlUnicodeStringToAnsiString(&astr, &ustr, 0/*AllocateDestinationString*/); 1598 if (rcNt < 0) 1599 sprintf(pdir->ent.name, "conversion-failed-%08x-rcNt=%08x-len=%u", 1600 pcur->FileIndex, rcNt, pcur->FileNameLength); 1601 if (pcur->NextEntryOffset) 1602 pdir->off += pcur->NextEntryOffset; 1603 else 1604 pdir->off = pdir->cb; 1605 return &pdir->ent; 1606 } 1607 } 1608 else 1609 errno = EINVAL; 1433 1610 return NULL; 1434 1611 #else … … 1441 1618 { 1442 1619 #ifdef SHFILE_IN_USE 1443 errno = ENOSYS; 1620 if (pdir) 1621 { 1622 CloseHandle(pdir->native); 1623 pdir->pfdtab = NULL; 1624 pdir->native = INVALID_HANDLE_VALUE; 1625 sh_free(shthread_get_shell(), pdir); 1626 } 1627 else 1628 errno = EINVAL; 1444 1629 #else 1445 1630 closedir((DIR *)pdir); -
trunk/src/kash/shfile.h
r2415 r2416 173 173 typedef struct shdir 174 174 { 175 shfdtab *p shfdtab;175 shfdtab *pfdtab; 176 176 void *native; 177 177 shdirent ent; 178 #if K_OS == K_OS_WINDOWS 179 size_t off; 180 size_t cb; 181 char buf[32768 - sizeof(void *) * 2 - sizeof(shdirent) * 2]; 182 #endif 178 183 } shdir; 179 184 -
trunk/src/kash/shfork-win.c
r2377 r2416 6 6 #include <string.h> 7 7 #include <locale.h> 8 #include <assert.h> 8 9 #include "shinstance.h" 9 10 #include <Windows.h> … … 29 30 30 31 /* in shforkA-win.asm: */ 32 extern pid_t shfork_do_it(shinstance *psh); 31 33 extern void shfork_resume(void *cur, void *base, void *limit); 32 34 … … 34 36 void *shfork_maybe_forked(int argc, char **argv, char **envp); 35 37 extern int shfork_body(shinstance *psh, void *stack_ptr); 36 37 38 /*** 38 extern void init_syntax(void); 39 40 41 /** 39 42 * Called by shforkA-win.asm to check whether we're a forked child 40 43 * process or not. … … 64 67 { 65 68 char *stack; 66 shheap_init(); 67 stack = (char *)sh_malloc(NULL, SHFORK_STACK_SIZE) + SHFORK_STACK_SIZE; 68 g_stack_base = stack + SHFORK_STACK_SIZE; 69 g_stack_limit = stack; 69 shheap_init(NULL); 70 g_stack_limit = stack = (char *)sh_malloc(NULL, SHFORK_STACK_SIZE); 71 g_stack_base = stack += SHFORK_STACK_SIZE; 70 72 return stack; 71 73 } … … 83 85 g_stack_base = shfork_string_to_ptr(argv[5], argv[0], "--stack-base"); 84 86 g_stack_limit = shfork_string_to_ptr(argv[7], argv[0], "--stack-limit"); 87 assert((uintptr_t)stack_ptr < (uintptr_t)g_stack_base); 88 assert((uintptr_t)stack_ptr > (uintptr_t)g_stack_limit); 85 89 86 90 /* … … 137 141 } 138 142 139 /*** 143 /** 144 * Do the fork. 145 * @returns same as fork(). 146 * @param psh The shell that's forking. 147 */ 148 int shfork_do(shinstance *psh) 149 { 150 /* save globals */ 151 void *pheap_head = shheap_get_head(); 152 pid_t pid = shfork_do_it(psh); 153 if (pid == 0) 154 { 155 /* reinit stuff, only the heap is copied! */ 156 shthread_set_shell(psh); 157 shheap_init(pheap_head); 158 setlocale(LC_ALL, ""); 159 init_syntax(); 160 } 161 return pid; 162 } 163 164 /** 140 165 * Create the child process making sure it inherits all our handles, 141 166 * copy of the forkable heap and kick it off. … … 156 181 DWORD cch; 157 182 int rc = 0; 183 184 assert((uintptr_t)stack_ptr < (uintptr_t)g_stack_base); 185 assert((uintptr_t)stack_ptr > (uintptr_t)g_stack_limit); 158 186 159 187 /* … … 178 206 stack_ptr, g_stack_base, g_stack_limit); 179 207 szCmdLine[cch+1] = '\0'; 208 TRACE2((NULL, "shfork_body: szCmdLine=%s\n", szCmdLine)); 180 209 181 210 memset(&StrtInfo, '\0', sizeof(StrtInfo)); /* just in case. */ -
trunk/src/kash/shforkA-win.asm
r2413 r2416 121 121 mov r8, [rbp - 18h] ; envp 122 122 123 lea rsp, [ eax - 40h] ; Switch!123 lea rsp, [rax - 40h] ; Switch! 124 124 %else 125 125 mov [esp + 18h], eax -
trunk/src/kash/shheap.c
r2413 r2416 123 123 124 124 125 int shheap_init(void )125 int shheap_init(void *phead) 126 126 { 127 127 int rc; … … 129 129 SHHEAP_ASSERT(SHHEAP_ALIGN(sizeof(shmemhdr)) == sizeof(shmemhdr)); 130 130 rc = shmtx_init(&g_sh_heap_mtx); 131 g_sh_heap = (shmemchunk *)phead; /* non-zero on fork() */ 131 132 #else 132 133 rc = 0; … … 138 139 139 140 # if K_OS == K_OS_WINDOWS 141 142 /** 143 * Get the head so the child can pass it to shheap_init() after fork(). 144 * 145 * @returns g_sh_heap. 146 */ 147 void *shheap_get_head(void) 148 { 149 return g_sh_heap; 150 } 151 140 152 /** 141 153 * Copies the heap into the child process. … … 180 192 return -1; 181 193 } 182 # endif 183 194 195 # endif /* K_OS == K_OS_WINDOWS */ 184 196 185 197 /** -
trunk/src/kash/shheap.h
r2413 r2416 32 32 33 33 /* heap */ 34 int shheap_init(void); 34 int shheap_init(void *phead); 35 void *shheap_get_head(void); 35 36 int shheap_fork_copy_to_child(void *); 36 37 -
trunk/src/kash/shinstance.c
r2413 r2416 42 42 #if K_OS == K_OS_WINDOWS 43 43 # include <Windows.h> 44 extern pid_t shfork_do _it(shinstance *psh); /* shforkA-win.asm */44 extern pid_t shfork_do(shinstance *psh); /* shforkA-win.asm */ 45 45 #endif 46 46 … … 898 898 899 899 #if K_OS == K_OS_WINDOWS //&& defined(SH_FORKED_MODE) 900 pid = shfork_do_it(psh); 901 if (pid == 0) 902 shthread_set_shell(psh); 900 pid = shfork_do(psh); 903 901 904 902 #elif defined(SH_FORKED_MODE)
Note:
See TracChangeset
for help on using the changeset viewer.