581 DIR *d; |
581 DIR *d; |
582 OBJ path, dp; |
582 OBJ path, dp; |
583 |
583 |
584 ok = false; |
584 ok = false; |
585 if (__INST(dirPointer) == nil) { |
585 if (__INST(dirPointer) == nil) { |
586 if (__isStringLike(encodedPathName)) { |
586 if (__isStringLike(encodedPathName)) { |
587 __BEGIN_INTERRUPTABLE__ |
587 __BEGIN_INTERRUPTABLE__ |
588 __threadErrno = 0; |
588 __threadErrno = 0; |
589 do { |
589 do { |
590 d = opendir((char *) __stringVal(encodedPathName)); |
590 d = opendir((char *) __stringVal(encodedPathName)); |
591 } while ((d == NULL) && (__threadErrno == EINTR)); |
591 } while ((d == NULL) && (__threadErrno == EINTR)); |
592 __END_INTERRUPTABLE__ |
592 __END_INTERRUPTABLE__ |
593 |
593 |
594 if (d == NULL) { |
594 if (d == NULL) { |
595 error = __mkSmallInteger(__threadErrno); |
595 error = __mkSmallInteger(__threadErrno); |
596 } else { |
596 } else { |
597 dp = __MKEXTERNALADDRESS(d); __INST(dirPointer) = dp; __STORE(self, dp); |
597 dp = __MKEXTERNALADDRESS(d); __INST(dirPointer) = dp; __STORE(self, dp); |
598 ok = true; |
598 ok = true; |
599 } |
599 } |
600 } |
600 } |
601 } |
601 } |
602 #else |
602 #else |
603 #ifdef WIN32 |
603 #ifdef WIN32 |
604 HANDLE d; |
604 HANDLE d; |
605 OBJ path, dp; |
605 OBJ path, dp; |
606 union { |
606 union { |
607 char pattern[MAXPATHLEN]; |
607 char pattern[MAXPATHLEN]; |
608 wchar_t wpattern[MAXPATHLEN]; |
608 wchar_t wpattern[MAXPATHLEN]; |
609 } uP; |
609 } uP; |
610 union { |
610 union { |
611 WIN32_FIND_DATAA data; |
611 WIN32_FIND_DATAA data; |
612 WIN32_FIND_DATAW wdata; |
612 WIN32_FIND_DATAW wdata; |
613 } uD; |
613 } uD; |
614 |
614 |
615 ok = false; |
615 ok = false; |
616 if (__INST(dirPointer) == nil) { |
616 if (__INST(dirPointer) == nil) { |
617 path = __INST(pathName); |
617 path = __INST(pathName); |
618 if (__isStringLike(path)) { |
618 if (__isStringLike(path)) { |
619 int l = __stringSize(path); |
619 int l = __stringSize(path); |
620 |
620 |
621 if (l < (MAXPATHLEN-4)) { |
621 if (l < (MAXPATHLEN-4)) { |
622 strncpy(uP.pattern, __stringVal(path), l); |
622 strncpy(uP.pattern, __stringVal(path), l); |
623 strcpy(uP.pattern+l, "\\*"); |
623 strcpy(uP.pattern+l, "\\*"); |
624 |
624 |
625 do { |
625 do { |
626 __threadErrno = 0; |
626 __threadErrno = 0; |
627 d = STX_API_NOINT_CALL2( "FindFirstFileA", FindFirstFileA, uP.pattern, &uD.data ); |
627 d = STX_API_NOINT_CALL2( "FindFirstFileA", FindFirstFileA, uP.pattern, &uD.data ); |
628 } while ((d < 0) && (__threadErrno == EINTR)); |
628 } while ((d < 0) && (__threadErrno == EINTR)); |
629 |
629 |
630 if (d == INVALID_HANDLE_VALUE) { |
630 if (d == INVALID_HANDLE_VALUE) { |
631 error = __mkSmallInteger(GetLastError()); |
631 error = __mkSmallInteger(GetLastError()); |
632 } else { |
632 } else { |
633 dp = __MKEXTERNALADDRESS(d); __INST(dirPointer) = dp; __STORE(self, dp); |
633 dp = __MKEXTERNALADDRESS(d); __INST(dirPointer) = dp; __STORE(self, dp); |
634 |
634 |
635 fileSize = __MKLARGEINT64(1, uD.data.nFileSizeLow, uD.data.nFileSizeHigh ); |
635 fileSize = __MKLARGEINT64(1, uD.data.nFileSizeLow, uD.data.nFileSizeHigh ); |
636 osPathname = __MKSTRING( uD.data.cFileName ); |
636 osPathname = __MKSTRING( uD.data.cFileName ); |
637 osFileAttributes = __mkSmallInteger( uD.data.dwFileAttributes ); |
637 osFileAttributes = __mkSmallInteger( uD.data.dwFileAttributes ); |
638 |
638 |
639 osCrtTime = FileTimeToOsTime(&uD.data.ftCreationTime); |
639 osCrtTime = FileTimeToOsTime(&uD.data.ftCreationTime); |
640 osAccTime = FileTimeToOsTime(&uD.data.ftLastAccessTime); |
640 osAccTime = FileTimeToOsTime(&uD.data.ftLastAccessTime); |
641 osModTime = FileTimeToOsTime(&uD.data.ftLastWriteTime); |
641 osModTime = FileTimeToOsTime(&uD.data.ftLastWriteTime); |
642 ok = true; |
642 ok = true; |
643 } |
643 } |
644 } |
644 } |
645 } |
645 } |
646 else if (__isUnicode16String(path)) { |
646 else if (__isUnicode16String(path)) { |
647 int l = __unicode16StringSize(path); |
647 int l = __unicode16StringSize(path); |
648 int i; |
648 int i; |
649 |
649 |
650 if (l < (MAXPATHLEN-4)) { |
650 if (l < (MAXPATHLEN-4)) { |
651 for (i=0; i<l; i++) { |
651 for (i=0; i<l; i++) { |
652 uP.wpattern[i] = __unicode16StringVal(path)[i]; |
652 uP.wpattern[i] = __unicode16StringVal(path)[i]; |
653 } |
653 } |
654 uP.wpattern[i++] = '\\'; |
654 uP.wpattern[i++] = '\\'; |
655 uP.wpattern[i++] = '*'; |
655 uP.wpattern[i++] = '*'; |
656 uP.wpattern[i] = 0; |
656 uP.wpattern[i] = 0; |
657 |
657 |
658 do { |
658 do { |
659 __threadErrno = 0; |
659 __threadErrno = 0; |
660 d = STX_API_NOINT_CALL2( "FindFirstFileW", FindFirstFileW, uP.wpattern, &uD.wdata ); |
660 d = STX_API_NOINT_CALL2( "FindFirstFileW", FindFirstFileW, uP.wpattern, &uD.wdata ); |
661 } while ((d < 0) && (__threadErrno == EINTR)); |
661 } while ((d < 0) && (__threadErrno == EINTR)); |
662 |
662 |
663 if (d == INVALID_HANDLE_VALUE) { |
663 if (d == INVALID_HANDLE_VALUE) { |
664 error = __mkSmallInteger(GetLastError()); |
664 error = __mkSmallInteger(GetLastError()); |
665 } else { |
665 } else { |
666 dp = __MKEXTERNALADDRESS(d); __INST(dirPointer) = dp; __STORE(self, dp); |
666 dp = __MKEXTERNALADDRESS(d); __INST(dirPointer) = dp; __STORE(self, dp); |
667 |
667 |
668 fileSize = __MKLARGEINT64(1, uD.wdata.nFileSizeLow, uD.wdata.nFileSizeHigh ); |
668 fileSize = __MKLARGEINT64(1, uD.wdata.nFileSizeLow, uD.wdata.nFileSizeHigh ); |
669 osPathname = __MKU16STRING( uD.wdata.cFileName ); |
669 osPathname = __MKU16STRING( uD.wdata.cFileName ); |
670 osFileAttributes = __mkSmallInteger( uD.data.dwFileAttributes ); |
670 osFileAttributes = __mkSmallInteger( uD.data.dwFileAttributes ); |
671 |
671 |
672 osCrtTime = FileTimeToOsTime(&uD.wdata.ftCreationTime); |
672 osCrtTime = FileTimeToOsTime(&uD.wdata.ftCreationTime); |
673 osAccTime = FileTimeToOsTime(&uD.wdata.ftLastAccessTime); |
673 osAccTime = FileTimeToOsTime(&uD.wdata.ftLastAccessTime); |
674 osModTime = FileTimeToOsTime(&uD.wdata.ftLastWriteTime); |
674 osModTime = FileTimeToOsTime(&uD.wdata.ftLastWriteTime); |
675 ok = true; |
675 ok = true; |
676 } |
676 } |
677 } |
677 } |
678 } |
678 } |
679 } |
679 } |
680 #endif |
680 #endif |
681 #endif |
681 #endif |
682 %}. |
682 %}. |
683 |
683 |
684 ok == true ifTrue:[ |
684 ok == true ifTrue:[ |
685 Lobby register:self. |
685 self registerForFinalization. |
686 osPathname isNil ifTrue:[ |
686 osPathname isNil ifTrue:[ |
687 "UNIX: does not automatically provide the first entry" |
687 "UNIX: does not automatically provide the first entry" |
688 |
688 |
689 StreamError handle:[:ex | |
689 StreamError handle:[:ex | |
690 self close. |
690 self close. |
691 ex reject. |
691 ex reject. |
692 ] do:[ |
692 ] do:[ |
693 readAheadEntry := OperatingSystem nextLinkInfoFrom:self dirPointer:dirPointer. |
693 readAheadEntry := OperatingSystem nextLinkInfoFrom:self dirPointer:dirPointer. |
694 ]. |
694 ]. |
695 ] ifFalse:[ |
695 ] ifFalse:[ |
696 "Windows already provides the first entry's info" |
696 "Windows already provides the first entry's info" |
697 |
697 |
698 readAheadEntry := OperatingSystem |
698 readAheadEntry := OperatingSystem |
699 linkInfoFor:osPathname |
699 linkInfoFor:osPathname |
700 fileSize:fileSize |
700 fileSize:fileSize |
701 fileAttributes:osFileAttributes |
701 fileAttributes:osFileAttributes |
702 osCrtTime:osCrtTime |
702 osCrtTime:osCrtTime |
703 osAccTime:osAccTime |
703 osAccTime:osAccTime |
704 osModTime:osModTime |
704 osModTime:osModTime |
705 ]. |
705 ]. |
706 |
706 |
707 ^ self |
707 ^ self |
708 ]. |
708 ]. |
709 |
709 |
710 ok notNil ifTrue:[ |
710 ok notNil ifTrue:[ |
711 dirPointer notNil ifTrue:[^ self errorAlreadyOpen]. |
711 dirPointer notNil ifTrue:[^ self errorAlreadyOpen]. |
712 ]. |
712 ]. |
713 error notNil ifTrue:[ |
713 error notNil ifTrue:[ |
714 ^ self openError:(lastErrorNumber := error). |
714 ^ self openError:(lastErrorNumber := error). |
715 ]. |
715 ]. |
716 ^ nil |
716 ^ nil |
717 ! |
717 ! |
718 |
718 |
719 reOpen |
719 reOpen |