DirectoryStream.st
changeset 1631 0d50b800b011
parent 1295 83f594f05c52
child 1664 82793bcf229c
equal deleted inserted replaced
1630:09e6117a1457 1631:0d50b800b011
    18 !
    18 !
    19 
    19 
    20 !DirectoryStream primitiveDefinitions!
    20 !DirectoryStream primitiveDefinitions!
    21 %{
    21 %{
    22 
    22 
    23 #include <stdio.h>
    23 #define UNIX_LIKE
    24 #define _STDIO_H_INCLUDED_
    24 #if defined(WIN32)
    25 
    25 # undef UNIX_LIKE
    26 #include <errno.h>
    26 #endif
    27 #define _ERRNO_H_INCLUDED_
    27 
    28 
    28 #ifdef UNIX_LIKE
    29 #ifndef transputer
    29 
    30 # include <sys/types.h>
    30 # include <stdio.h>
    31 # include <sys/stat.h>
    31 # define _STDIO_H_INCLUDED_
    32 
    32 
    33 # ifdef HAS_OPENDIR
    33 # include <errno.h>
       
    34 # define _ERRNO_H_INCLUDED_
       
    35 
       
    36 # ifndef transputer
    34 #  include <sys/types.h>
    37 #  include <sys/types.h>
    35 #  ifdef NEXT
    38 #  include <sys/stat.h>
    36 #   include <sys/dir.h>
    39 
    37 #  else
    40 #  ifdef HAS_OPENDIR
    38 #   ifndef VMS
    41 #   include <sys/types.h>
    39 #    include <dirent.h>
    42 #   ifdef NEXT
    40 #   endif /* not VMS */
    43 #    include <sys/dir.h>
       
    44 #   else
       
    45 #    ifndef VMS
       
    46 #     include <dirent.h>
       
    47 #    endif /* not VMS */
       
    48 #   endif
    41 #  endif
    49 #  endif
    42 # endif
    50 # endif
    43 #endif
       
    44 
    51 
    45 /*
    52 /*
    46  * on some systems errno is a macro ... check for it here
    53  * on some systems errno is a macro ... check for it here
    47  */
    54  */
    48 #ifndef errno
    55 # ifndef errno
    49  extern errno;
    56   extern errno;
    50 #endif
    57 # endif
       
    58 #endif /* UNIX_LIKE */
       
    59 
       
    60 #ifdef WIN32
       
    61 
       
    62 # ifdef i386
       
    63 #  define _X86_
       
    64 # endif
       
    65 
       
    66 # undef INT
       
    67 # undef Array
       
    68 # undef Number
       
    69 # undef Method
       
    70 # undef Point
       
    71 # undef Context
       
    72 # undef Rectangle
       
    73 
       
    74 # include <h/sys/types.h> /* */
       
    75 # include <h/stdarg.h> /* */
       
    76 # include <h/windef.h> /* */
       
    77 # include <h/winbase.h> /* */
       
    78 # include <h/wingdi.h> /* */
       
    79 # include <h/winuser.h> /* */
       
    80 
       
    81 # ifdef __DEF_Array
       
    82 #  define Array __DEF_Array
       
    83 # endif
       
    84 # ifdef __DEF_Number
       
    85 #  define Number __DEF_Number
       
    86 # endif
       
    87 # ifdef __DEF_Method
       
    88 #  define Method __DEF_Method
       
    89 # endif
       
    90 # ifdef __DEF_Point
       
    91 #  define Point __DEF_Point
       
    92 # endif
       
    93 # ifdef __DEF_Context
       
    94 #  define Context __DEF_Context
       
    95 # endif
       
    96 
       
    97 # define __HANDLEVal(o)  (HANDLE)__MKCP(o)
       
    98 
       
    99 #endif /* WIN32 */
    51 
   100 
    52 %}
   101 %}
    53 ! !
   102 ! !
    54 
   103 
    55 !DirectoryStream primitiveFunctions!
   104 !DirectoryStream primitiveFunctions!
   351     Instances of DirectoryStream allow reading a file-directory,
   400     Instances of DirectoryStream allow reading a file-directory,
   352     as if it was a stream of filenames.
   401     as if it was a stream of filenames.
   353     Basically, its an interface to opendir, readdir and closedir.
   402     Basically, its an interface to opendir, readdir and closedir.
   354 
   403 
   355     [author:]
   404     [author:]
   356         Claus Gittinger
   405 	Claus Gittinger
   357 "
   406 "
   358 ! !
   407 ! !
   359 
   408 
   360 !DirectoryStream class methodsFor:'instance creation'!
   409 !DirectoryStream class methodsFor:'instance creation'!
   361 
   410 
   376 
   425 
   377     |prevEntry nextEntry|
   426     |prevEntry nextEntry|
   378 %{
   427 %{
   379 #ifdef HAS_OPENDIR
   428 #ifdef HAS_OPENDIR
   380     DIR *d;
   429     DIR *d;
   381 #ifdef NEXT
   430 # ifdef NEXT
   382     struct direct *dp;
   431     struct direct *dp;
   383 #else
   432 # else
   384     struct dirent *dp;
   433     struct dirent *dp;
   385 #endif
   434 # endif
   386     OBJ dirP;
   435     OBJ dirP;
   387 
   436 
   388 
       
   389     if (__INST(hitEOF) != true && (dirP = __INST(dirPointer)) != nil) {
   437     if (__INST(hitEOF) != true && (dirP = __INST(dirPointer)) != nil) {
   390         __INST(lastErrorNumber) = nil;
   438 	__INST(lastErrorNumber) = nil;
   391         d = (DIR *)__FILEVal(dirP);
   439 	d = (DIR *)__FILEVal(dirP);
   392 
   440 
   393         __BEGIN_INTERRUPTABLE__
   441 	__BEGIN_INTERRUPTABLE__
   394         do {
   442 	do {
   395             errno = 0;
   443 	    errno = 0;
   396             dp = readdir(d);
   444 	    dp = readdir(d);
   397         } while ((dp == NULL) && (errno == EINTR));
   445 	} while ((dp == NULL) && (errno == EINTR));
   398         __END_INTERRUPTABLE__
   446 	__END_INTERRUPTABLE__
   399 
   447 
   400         if (dp != NULL) {
   448 	if (dp != NULL) {
   401             nextEntry = __MKSTRING((char *)(dp->d_name) COMMA_CON);
   449 	    nextEntry = __MKSTRING((char *)(dp->d_name) COMMA_CON);
   402         } else {
   450 	} else {
   403             if (errno) {
   451 	    if (errno) {
   404                 __INST(lastErrorNumber) = __MKSMALLINT(errno);
   452 		__INST(lastErrorNumber) = __MKSMALLINT(errno);
   405             } else {
   453 	    } else {
   406                __INST(hitEOF) = true;
   454 	       __INST(hitEOF) = true;
   407             }
   455 	    }
   408        }
   456        }
   409     }
   457     }
   410 #endif
   458 #else /* no HAS_OPENDIR */
       
   459 # ifdef WIN32
       
   460     HANDLE d;
       
   461     WIN32_FIND_DATA data;
       
   462     OBJ dirP;
       
   463 
       
   464     if (__INST(hitEOF) != true && (dirP = __INST(dirPointer)) != nil) {
       
   465 	__INST(lastErrorNumber) = nil;
       
   466 	d = __HANDLEVal(dirP);
       
   467 
       
   468 	if (FindNextFile(d, &data)) {
       
   469 	    nextEntry = __MKSTRING( data.cFileName );
       
   470 	} else {
       
   471 	   __INST(hitEOF) = true;
       
   472 	}
       
   473     }
       
   474 # endif /* WIN32 */
       
   475 #endif /* HAS_OPENDIR */
   411 %}.
   476 %}.
   412     lastErrorNumber notNil ifTrue:[^ self ioError].
   477     lastErrorNumber notNil ifTrue:[^ self ioError].
   413     prevEntry := readAhead.
   478     prevEntry := readAhead.
   414     readAhead := nextEntry.
   479     readAhead := nextEntry.
   415     prevEntry isNil ifTrue:[^ self pastEnd].
   480     prevEntry isNil ifTrue:[^ self pastEnd].
   438 
   503 
   439     if ((dp = __INST(dirPointer)) != nil) {
   504     if ((dp = __INST(dirPointer)) != nil) {
   440 	__INST(dirPointer) = nil;
   505 	__INST(dirPointer) = nil;
   441 	closedir( (DIR *)(__FILEVal(dp)) );
   506 	closedir( (DIR *)(__FILEVal(dp)) );
   442     }
   507     }
       
   508 #else
       
   509 # ifdef WIN32
       
   510     OBJ dp;
       
   511 
       
   512     if ((dp = __INST(dirPointer)) != nil) {
       
   513 	__INST(dirPointer) = nil;
       
   514 	FindClose( __HANDLEVal(dp) );
       
   515     }
       
   516 # endif
   443 #endif
   517 #endif
   444 %}
   518 %}
   445 ! !
   519 ! !
   446 
   520 
   447 !DirectoryStream methodsFor:'private'!
   521 !DirectoryStream methodsFor:'private'!
   448 
   522 
   449 openForReading
   523 openForReading
   450     "open the file for readonly"
   524     "open the file for readonly"
   451 
   525 
   452     |ok|
   526     |ok entry|
   453 
   527 
   454     mode := #readonly.
   528     mode := #readonly.
   455 %{
   529 %{
   456 #ifdef HAS_OPENDIR
   530 #ifdef HAS_OPENDIR
   457     DIR *d;
   531     DIR *d;
   474 		__INST(dirPointer) = dp = __MKOBJ(d); __STORE(self, dp);
   548 		__INST(dirPointer) = dp = __MKOBJ(d); __STORE(self, dp);
   475 		ok = true;
   549 		ok = true;
   476 	    }
   550 	    }
   477 	}
   551 	}
   478     }
   552     }
       
   553 #else
       
   554 # ifdef WIN32
       
   555     HANDLE d;
       
   556     OBJ path, dp;
       
   557     char pattern[512];
       
   558     WIN32_FIND_DATA data;
       
   559 
       
   560     ok = false;
       
   561     if (__INST(dirPointer) == nil) {
       
   562 	path = __INST(pathName);
       
   563 	if (__isString(path)) {
       
   564 	    strcpy(pattern, __stringVal(path));
       
   565 	    strcat(pattern, "\\*");
       
   566 	    d = FindFirstFile(pattern, &data);
       
   567 	    if (d == INVALID_HANDLE_VALUE) {
       
   568 		__INST(lastErrorNumber) = __MKSMALLINT(GetLastError());
       
   569 	    } else {
       
   570 		__INST(dirPointer) = dp = __MKOBJ(d); __STORE(self, dp);
       
   571 		entry = __MKSTRING( data.cFileName );
       
   572 		ok = true;
       
   573 	    }
       
   574 	}
       
   575     }
       
   576 # endif
   479 #endif
   577 #endif
   480 %}.
   578 %}.
   481     ok isNil ifTrue:[
   579     ok isNil ifTrue:[
   482 	"
   580 	"
   483 	 opendir not avalable - use slower pipe
   581 	 opendir not avalable - use slower pipe
   485 	^ PipeStream readingFrom:('cd ' , pathName , '; ls -a')
   583 	^ PipeStream readingFrom:('cd ' , pathName , '; ls -a')
   486     ].
   584     ].
   487 
   585 
   488     (ok == true) ifTrue:[
   586     (ok == true) ifTrue:[
   489 	Lobby register:self.
   587 	Lobby register:self.
   490 	self nextLine. "read 1st entry into readAhead buffer"
   588 	entry isNil ifTrue:[
       
   589 	    self nextLine. "read 1st entry into readAhead buffer"
       
   590 	] ifFalse:[
       
   591 	    readAhead := entry.
       
   592 	].
   491 	^ self
   593 	^ self
   492     ].
   594     ].
   493     dirPointer notNil ifTrue:[^ self errorOpen].
   595     dirPointer notNil ifTrue:[^ self errorOpen].
   494     lastErrorNumber notNil ifTrue:[^ self openError].
   596     lastErrorNumber notNil ifTrue:[^ self openError].
   495     ^ nil
   597     ^ nil
   511 ! !
   613 ! !
   512 
   614 
   513 !DirectoryStream class methodsFor:'documentation'!
   615 !DirectoryStream class methodsFor:'documentation'!
   514 
   616 
   515 version
   617 version
   516     ^ '$Header: /cvs/stx/stx/libbasic/DirectoryStream.st,v 1.30 1996-04-25 17:01:37 cg Exp $'
   618     ^ '$Header: /cvs/stx/stx/libbasic/DirectoryStream.st,v 1.31 1996-08-15 12:28:37 cg Exp $'
   517 ! !
   619 ! !