"
COPYRIGHT (c) 1989 by Claus Gittinger
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
FileStream subclass:#DirectoryStream
instanceVariableNames:'dirPointer readAhead'
classVariableNames:''
poolDictionaries:''
category:'Streams-External'
!
DirectoryStream comment:'
COPYRIGHT (c) 1989 by Claus Gittinger
All Rights Reserved
$Header: /cvs/stx/stx/libbasic/DirectoryStream.st,v 1.20 1995-08-10 12:27:25 claus Exp $
'!
!DirectoryStream class methodsFor:'documentation'!
copyright
"
COPYRIGHT (c) 1989 by Claus Gittinger
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
!
version
"
$Header: /cvs/stx/stx/libbasic/DirectoryStream.st,v 1.20 1995-08-10 12:27:25 claus Exp $
$Revision: 1.20 $
"
!
documentation
"
Instances of DirectoryStream allow reading a file-directory,
as if it was a stream of filenames.
Basically, its an interface to opendir, readdir and closedir.
"
! !
!DirectoryStream primitiveDefinitions!
%{
#include <stdio.h>
#include <errno.h>
#ifndef transputer
# include <sys/types.h>
# include <sys/stat.h>
# ifdef HAS_OPENDIR
# include <sys/types.h>
# ifdef NEXT
# include <sys/dir.h>
# else
# include <dirent.h>
# endif
# endif
#endif
/*
* on some systems errno is a macro ... check for it here
*/
#ifndef errno
extern errno;
#endif
%}
! !
!DirectoryStream methodsFor:'instance release'!
closeFile
"low level close of a directoryStream"
%{
#ifdef HAS_OPENDIR
OBJ dp;
if ((dp = _INST(dirPointer)) != nil) {
_INST(dirPointer) = nil;
closedir( (DIR *)(MKFD(dp)) );
}
#endif
%}
! !
!DirectoryStream class methodsFor:'instance creation'!
directoryNamed:dirName
"return a DirectoryStream for directory named dirName, aString"
|newStream|
newStream := (self basicNew) pathName:dirName.
newStream openForReading isNil ifTrue:[^nil].
^ newStream
! !
!DirectoryStream methodsFor:'access reading'!
nextLine
"return the next filename as a string"
|prevEntry nextEntry|
%{
#ifdef HAS_OPENDIR
DIR *d;
#ifdef NEXT
struct direct *dp;
#else
struct dirent *dp;
#endif
OBJ dirP;
if ((dirP = _INST(dirPointer)) != nil) {
d = (DIR *)MKFD(dirP);
__BEGIN_INTERRUPTABLE__
errno = 0;
do {
dp = readdir(d);
} while ((dp == NULL) && (errno == EINTR));
__END_INTERRUPTABLE__
if (dp != NULL) {
nextEntry = _MKSTRING((char *)(dp->d_name) COMMA_CON);
} else {
_INST(hitEOF) = true;
if (errno) {
_INST(lastErrorNumber) = _MKSMALLINT(errno);
}
}
}
#endif
%}.
lastErrorNumber notNil ifTrue:[^ self ioError].
prevEntry := readAhead.
readAhead := nextEntry.
^ prevEntry
! !
!DirectoryStream methodsFor:'private'!
openForReading
"open the file for readonly"
|ok|
mode := #readonly.
%{
#ifdef HAS_OPENDIR
DIR *d;
OBJ path;
ok = false;
if (_INST(dirPointer) == nil) {
path = _INST(pathName);
if (__isString(path)) {
__BEGIN_INTERRUPTABLE__
errno = 0;
do {
d = opendir((char *) _stringVal(path));
} while ((d == NULL) && (errno == EINTR));
__END_INTERRUPTABLE__
if (d == NULL) {
_INST(lastErrorNumber) = _MKSMALLINT(errno);
} else {
_INST(dirPointer) = MKOBJ(d);
ok = true;
}
}
}
#endif
%}.
ok isNil ifTrue:[
"
opendir not avalable - use slower pipe
"
^ PipeStream readingFrom:('cd ' , pathName , '; ls -a')
].
(ok == true) ifTrue:[
Lobby register:self.
self nextLine. "read 1st entry into readAhead buffer"
^ self
].
dirPointer notNil ifTrue:[^ self errorOpen].
lastErrorNumber notNil ifTrue:[^ self openError].
^ nil
!
reOpen
"reOpen the stream after image restart"
dirPointer := nil.
super reOpen
! !
!DirectoryStream methodsFor:'testing'!
atEnd
"return true, if position is at end"
^ readAhead == nil
! !
!DirectoryStream methodsFor:'closing'!
close
"close the stream - tell operating system"
dirPointer notNil ifTrue:[
Lobby unregister:self.
self closeFile.
dirPointer := nil
]
! !