DirStr.st
author Claus Gittinger <cg@exept.de>
Wed, 07 Feb 1996 15:11:43 +0100
changeset 939 ffee570b0f09
parent 613 0af19c3594fc
child 1133 961f2b095c22
permissions -rw-r--r--
added #setProject: (does not send change notifications)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
     1
"
5
67342904af11 *** empty log message ***
claus
parents: 3
diff changeset
     2
 COPYRIGHT (c) 1989 by Claus Gittinger
155
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
     3
	      All Rights Reserved
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
     4
a27a279701f8 Initial revision
claus
parents:
diff changeset
     5
 This software is furnished under a license and may be used
a27a279701f8 Initial revision
claus
parents:
diff changeset
     6
 only in accordance with the terms of that license and with the
a27a279701f8 Initial revision
claus
parents:
diff changeset
     7
 inclusion of the above copyright notice.   This software may not
a27a279701f8 Initial revision
claus
parents:
diff changeset
     8
 be provided or otherwise made available to, or used by, any
a27a279701f8 Initial revision
claus
parents:
diff changeset
     9
 other person.  No title to or ownership of the software is
a27a279701f8 Initial revision
claus
parents:
diff changeset
    10
 hereby transferred.
a27a279701f8 Initial revision
claus
parents:
diff changeset
    11
"
a27a279701f8 Initial revision
claus
parents:
diff changeset
    12
a27a279701f8 Initial revision
claus
parents:
diff changeset
    13
FileStream subclass:#DirectoryStream
613
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
    14
	 instanceVariableNames:'dirPointer readAhead'
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
    15
	 classVariableNames:''
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
    16
	 poolDictionaries:''
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
    17
	 category:'Streams-External'
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
    18
!
a27a279701f8 Initial revision
claus
parents:
diff changeset
    19
217
a0400fdbc933 *** empty log message ***
claus
parents: 206
diff changeset
    20
!DirectoryStream primitiveDefinitions!
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
    21
%{
437
claus
parents: 384
diff changeset
    22
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
    23
#include <stdio.h>
437
claus
parents: 384
diff changeset
    24
#define _STDIO_H_INCLUDED_
claus
parents: 384
diff changeset
    25
10
claus
parents: 5
diff changeset
    26
#include <errno.h>
437
claus
parents: 384
diff changeset
    27
#define _ERRNO_H_INCLUDED_
10
claus
parents: 5
diff changeset
    28
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
    29
#ifndef transputer
a27a279701f8 Initial revision
claus
parents:
diff changeset
    30
# include <sys/types.h>
a27a279701f8 Initial revision
claus
parents:
diff changeset
    31
# include <sys/stat.h>
437
claus
parents: 384
diff changeset
    32
77
6c38ca59927f *** empty log message ***
claus
parents: 54
diff changeset
    33
# ifdef HAS_OPENDIR
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
    34
#  include <sys/types.h>
a27a279701f8 Initial revision
claus
parents:
diff changeset
    35
#  ifdef NEXT
a27a279701f8 Initial revision
claus
parents:
diff changeset
    36
#   include <sys/dir.h>
a27a279701f8 Initial revision
claus
parents:
diff changeset
    37
#  else
438
claus
parents: 437
diff changeset
    38
#   ifndef VMS
claus
parents: 437
diff changeset
    39
#    include <dirent.h>
claus
parents: 437
diff changeset
    40
#   endif /* not VMS */
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
    41
#  endif
a27a279701f8 Initial revision
claus
parents:
diff changeset
    42
# endif
a27a279701f8 Initial revision
claus
parents:
diff changeset
    43
#endif
223
3075043790b8 immediateInterr & errno cleanup
claus
parents: 217
diff changeset
    44
3075043790b8 immediateInterr & errno cleanup
claus
parents: 217
diff changeset
    45
/*
3075043790b8 immediateInterr & errno cleanup
claus
parents: 217
diff changeset
    46
 * on some systems errno is a macro ... check for it here
3075043790b8 immediateInterr & errno cleanup
claus
parents: 217
diff changeset
    47
 */
3075043790b8 immediateInterr & errno cleanup
claus
parents: 217
diff changeset
    48
#ifndef errno
3075043790b8 immediateInterr & errno cleanup
claus
parents: 217
diff changeset
    49
 extern errno;
3075043790b8 immediateInterr & errno cleanup
claus
parents: 217
diff changeset
    50
#endif
3075043790b8 immediateInterr & errno cleanup
claus
parents: 217
diff changeset
    51
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
    52
%}
206
5858b2c9d0c6 fixed close
claus
parents: 155
diff changeset
    53
! !
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
    54
438
claus
parents: 437
diff changeset
    55
!DirectoryStream primitiveFunctions!
claus
parents: 437
diff changeset
    56
%{
claus
parents: 437
diff changeset
    57
#ifdef VMS
claus
parents: 437
diff changeset
    58
claus
parents: 437
diff changeset
    59
/*
claus
parents: 437
diff changeset
    60
**  VMS readdir() routines.
claus
parents: 437
diff changeset
    61
**  Written by Rich $alz, <rsalz@bbn.com> in August, 1990.
claus
parents: 437
diff changeset
    62
**  This code has no copyright.
claus
parents: 437
diff changeset
    63
*/
claus
parents: 437
diff changeset
    64
claus
parents: 437
diff changeset
    65
/* 12-NOV-1990 added d_namlen field and special case "." name -GJC@MITECH.COM 
claus
parents: 437
diff changeset
    66
 */
claus
parents: 437
diff changeset
    67
claus
parents: 437
diff changeset
    68
#ifndef _STDIO_H_INCLUDED_
claus
parents: 437
diff changeset
    69
# include <stdio.h>
claus
parents: 437
diff changeset
    70
# define _STDIO_H_INCLUDED_
claus
parents: 437
diff changeset
    71
#endif
claus
parents: 437
diff changeset
    72
claus
parents: 437
diff changeset
    73
#ifndef _CTYPE_H_INCLUDED_
claus
parents: 437
diff changeset
    74
# include <ctype.h>
claus
parents: 437
diff changeset
    75
# define _CTYPE_H_INCLUDED_
claus
parents: 437
diff changeset
    76
#endif
claus
parents: 437
diff changeset
    77
claus
parents: 437
diff changeset
    78
#ifndef _ERRNO_H_INCLUDED_
claus
parents: 437
diff changeset
    79
# include <errno.h>
claus
parents: 437
diff changeset
    80
# define _ERRNO_H_INCLUDED_
claus
parents: 437
diff changeset
    81
#endif
claus
parents: 437
diff changeset
    82
claus
parents: 437
diff changeset
    83
#ifndef _DESCRIP_H_INCLUDED_
claus
parents: 437
diff changeset
    84
# include <descrip.h>
claus
parents: 437
diff changeset
    85
# define _DESCRIP_H_INCLUDED_
claus
parents: 437
diff changeset
    86
#endif
claus
parents: 437
diff changeset
    87
claus
parents: 437
diff changeset
    88
#ifndef _RMSDEF_H_INCLUDED_
claus
parents: 437
diff changeset
    89
# include <rmsdef.h>
claus
parents: 437
diff changeset
    90
# define _RMSDEF_H_INCLUDED_
claus
parents: 437
diff changeset
    91
#endif
claus
parents: 437
diff changeset
    92
claus
parents: 437
diff changeset
    93
/*
claus
parents: 437
diff changeset
    94
 * actually, the following has to go into dirent.h ...
claus
parents: 437
diff changeset
    95
 */
claus
parents: 437
diff changeset
    96
/* BEGIN dirent.h
claus
parents: 437
diff changeset
    97
 *
claus
parents: 437
diff changeset
    98
**  Header file for VMS readdir() routines.
claus
parents: 437
diff changeset
    99
**  Written by Rich $alz, <rsalz@bbn.com> in August, 1990.
claus
parents: 437
diff changeset
   100
**  This code has no copyright.
claus
parents: 437
diff changeset
   101
**
claus
parents: 437
diff changeset
   102
**  You must #include <descrip.h> before this file.
claus
parents: 437
diff changeset
   103
*/
claus
parents: 437
diff changeset
   104
claus
parents: 437
diff changeset
   105
/* 12-NOV-1990 added d_namlen field -GJC@MITECH.COM */
claus
parents: 437
diff changeset
   106
claus
parents: 437
diff changeset
   107
    /* Data structure returned by READDIR(). */
claus
parents: 437
diff changeset
   108
struct dirent {
claus
parents: 437
diff changeset
   109
    char        d_name[100];            /* File name            */
claus
parents: 437
diff changeset
   110
    int         d_namlen;
claus
parents: 437
diff changeset
   111
    int                 vms_verscount;          /* Number of versions   */
claus
parents: 437
diff changeset
   112
    int                 vms_versions[20];       /* Version numbers      */
claus
parents: 437
diff changeset
   113
};
claus
parents: 437
diff changeset
   114
claus
parents: 437
diff changeset
   115
    /* Handle returned by opendir(), used by the other routines.  You
claus
parents: 437
diff changeset
   116
     * are not supposed to care what's inside this structure. */
claus
parents: 437
diff changeset
   117
typedef struct _dirdesc {
claus
parents: 437
diff changeset
   118
    long                        context;
claus
parents: 437
diff changeset
   119
    int                                 vms_wantversions;
claus
parents: 437
diff changeset
   120
    char                        *pattern;
claus
parents: 437
diff changeset
   121
    struct dirent               entry;
claus
parents: 437
diff changeset
   122
    struct dsc$descriptor_s     pat;
claus
parents: 437
diff changeset
   123
} DIR;
claus
parents: 437
diff changeset
   124
claus
parents: 437
diff changeset
   125
claus
parents: 437
diff changeset
   126
#define rewinddir(dirp)                 seekdir((dirp), 0L)
claus
parents: 437
diff changeset
   127
claus
parents: 437
diff changeset
   128
claus
parents: 437
diff changeset
   129
extern DIR              *opendir();
claus
parents: 437
diff changeset
   130
extern struct dirent    *readdir();
claus
parents: 437
diff changeset
   131
extern long             telldir();
claus
parents: 437
diff changeset
   132
extern void             seekdir();
claus
parents: 437
diff changeset
   133
extern void             closedir();
claus
parents: 437
diff changeset
   134
extern void             vmsreaddirversions();
claus
parents: 437
diff changeset
   135
#define _DIRENT_H_INCLUDED_
claus
parents: 437
diff changeset
   136
/*
claus
parents: 437
diff changeset
   137
 * END dirent.h
claus
parents: 437
diff changeset
   138
 */
claus
parents: 437
diff changeset
   139
claus
parents: 437
diff changeset
   140
claus
parents: 437
diff changeset
   141
    /* Number of elements in vms_versions array */
claus
parents: 437
diff changeset
   142
#define VERSIZE(e)      (sizeof e->vms_versions / sizeof e->vms_versions[0])
claus
parents: 437
diff changeset
   143
claus
parents: 437
diff changeset
   144
    /* Linked in later. */
claus
parents: 437
diff changeset
   145
extern char     *strrchr();
claus
parents: 437
diff changeset
   146
extern char     *strcpy();
claus
parents: 437
diff changeset
   147
/*  Don't need this when all these programs are lumped together.    RLD
claus
parents: 437
diff changeset
   148
extern char     *malloc();
claus
parents: 437
diff changeset
   149
*/
claus
parents: 437
diff changeset
   150
claus
parents: 437
diff changeset
   151
/*
claus
parents: 437
diff changeset
   152
**  Open a directory, return a handle for later use.
claus
parents: 437
diff changeset
   153
*/
claus
parents: 437
diff changeset
   154
DIR *
claus
parents: 437
diff changeset
   155
opendir(name)
claus
parents: 437
diff changeset
   156
    char        *name;
claus
parents: 437
diff changeset
   157
{
claus
parents: 437
diff changeset
   158
    DIR                 *dd;
claus
parents: 437
diff changeset
   159
claus
parents: 437
diff changeset
   160
    /* Get memory for the handle, and the pattern. */
claus
parents: 437
diff changeset
   161
    if ((dd = (DIR *)malloc(sizeof *dd)) == NULL) {
claus
parents: 437
diff changeset
   162
	errno = ENOMEM;
claus
parents: 437
diff changeset
   163
	return NULL;
claus
parents: 437
diff changeset
   164
    }
claus
parents: 437
diff changeset
   165
claus
parents: 437
diff changeset
   166
    if (strcmp(".",name) == 0) name = "";
claus
parents: 437
diff changeset
   167
claus
parents: 437
diff changeset
   168
    dd->pattern = malloc((unsigned int)(strlen(name) + sizeof "*.*" + 1));
claus
parents: 437
diff changeset
   169
    if (dd->pattern == NULL) {
claus
parents: 437
diff changeset
   170
	free((char *)dd);
claus
parents: 437
diff changeset
   171
	errno = ENOMEM;
claus
parents: 437
diff changeset
   172
	return NULL;
claus
parents: 437
diff changeset
   173
    }
claus
parents: 437
diff changeset
   174
claus
parents: 437
diff changeset
   175
    /* Fill in the fields; mainly playing with the descriptor. */
claus
parents: 437
diff changeset
   176
    (void)sprintf(dd->pattern, "%s*.*", name);
claus
parents: 437
diff changeset
   177
    dd->context = 0;
claus
parents: 437
diff changeset
   178
    dd->vms_wantversions = 0;
claus
parents: 437
diff changeset
   179
    dd->pat.dsc$a_pointer = dd->pattern;
claus
parents: 437
diff changeset
   180
    dd->pat.dsc$w_length = strlen(dd->pattern);
claus
parents: 437
diff changeset
   181
    dd->pat.dsc$b_dtype = DSC$K_DTYPE_T;
claus
parents: 437
diff changeset
   182
    dd->pat.dsc$b_class = DSC$K_CLASS_S;
claus
parents: 437
diff changeset
   183
claus
parents: 437
diff changeset
   184
    return dd;
claus
parents: 437
diff changeset
   185
}
claus
parents: 437
diff changeset
   186
claus
parents: 437
diff changeset
   187
/*
claus
parents: 437
diff changeset
   188
**  Set the flag to indicate we want versions or not.
claus
parents: 437
diff changeset
   189
*/
claus
parents: 437
diff changeset
   190
void
claus
parents: 437
diff changeset
   191
vmsreaddirversions(dd, flag)
claus
parents: 437
diff changeset
   192
    DIR                 *dd;
claus
parents: 437
diff changeset
   193
    int                 flag;
claus
parents: 437
diff changeset
   194
{
claus
parents: 437
diff changeset
   195
    dd->vms_wantversions = flag;
claus
parents: 437
diff changeset
   196
}
claus
parents: 437
diff changeset
   197
claus
parents: 437
diff changeset
   198
/*
claus
parents: 437
diff changeset
   199
**  Free up an opened directory.
claus
parents: 437
diff changeset
   200
*/
claus
parents: 437
diff changeset
   201
void
claus
parents: 437
diff changeset
   202
closedir(dd)
claus
parents: 437
diff changeset
   203
    DIR                 *dd;
claus
parents: 437
diff changeset
   204
{
claus
parents: 437
diff changeset
   205
    free(dd->pattern);
claus
parents: 437
diff changeset
   206
    free((char *)dd);
claus
parents: 437
diff changeset
   207
}
claus
parents: 437
diff changeset
   208
claus
parents: 437
diff changeset
   209
/*
claus
parents: 437
diff changeset
   210
**  Collect all the version numbers for the current file.
claus
parents: 437
diff changeset
   211
*/
claus
parents: 437
diff changeset
   212
static void
claus
parents: 437
diff changeset
   213
collectversions(dd)
claus
parents: 437
diff changeset
   214
    DIR                                 *dd;
claus
parents: 437
diff changeset
   215
{
claus
parents: 437
diff changeset
   216
    struct dsc$descriptor_s     pat;
claus
parents: 437
diff changeset
   217
    struct dsc$descriptor_s     res;
claus
parents: 437
diff changeset
   218
    struct dirent               *e;
claus
parents: 437
diff changeset
   219
    char                        *p;
claus
parents: 437
diff changeset
   220
    char                        buff[sizeof dd->entry.d_name];
claus
parents: 437
diff changeset
   221
    int                                 i;
claus
parents: 437
diff changeset
   222
    char                        *text;
claus
parents: 437
diff changeset
   223
    long                        context;
claus
parents: 437
diff changeset
   224
claus
parents: 437
diff changeset
   225
    /* Convenient shorthand. */
claus
parents: 437
diff changeset
   226
    e = &dd->entry;
claus
parents: 437
diff changeset
   227
claus
parents: 437
diff changeset
   228
    /* Add the version wildcard, ignoring the "*.*" put on before */
claus
parents: 437
diff changeset
   229
    i = strlen(dd->pattern);
claus
parents: 437
diff changeset
   230
    text = malloc((unsigned int)(i + strlen(e->d_name)+ 2 + 1));
claus
parents: 437
diff changeset
   231
    if (text == NULL)
claus
parents: 437
diff changeset
   232
	return;
claus
parents: 437
diff changeset
   233
    (void)strcpy(text, dd->pattern);
claus
parents: 437
diff changeset
   234
    (void)sprintf(&text[i - 3], "%s;*", e->d_name);
claus
parents: 437
diff changeset
   235
claus
parents: 437
diff changeset
   236
    /* Set up the pattern descriptor. */
claus
parents: 437
diff changeset
   237
    pat.dsc$a_pointer = text;
claus
parents: 437
diff changeset
   238
    pat.dsc$w_length = strlen(text);
claus
parents: 437
diff changeset
   239
    pat.dsc$b_dtype = DSC$K_DTYPE_T;
claus
parents: 437
diff changeset
   240
    pat.dsc$b_class = DSC$K_CLASS_S;
claus
parents: 437
diff changeset
   241
claus
parents: 437
diff changeset
   242
    /* Set up result descriptor. */
claus
parents: 437
diff changeset
   243
    res.dsc$a_pointer = buff;
claus
parents: 437
diff changeset
   244
    res.dsc$w_length = sizeof buff - 2;
claus
parents: 437
diff changeset
   245
    res.dsc$b_dtype = DSC$K_DTYPE_T;
claus
parents: 437
diff changeset
   246
    res.dsc$b_class = DSC$K_CLASS_S;
claus
parents: 437
diff changeset
   247
claus
parents: 437
diff changeset
   248
    /* Read files, collecting versions. */
claus
parents: 437
diff changeset
   249
    for (context = 0; e->vms_verscount < VERSIZE(e); e->vms_verscount++) {
claus
parents: 437
diff changeset
   250
	if (lib$find_file(&pat, &res, &context) == RMS$_NMF || context == 0)
claus
parents: 437
diff changeset
   251
	    break;
claus
parents: 437
diff changeset
   252
	buff[sizeof buff - 1] = '\0';
claus
parents: 437
diff changeset
   253
	if (p = strchr(buff, ';'))
claus
parents: 437
diff changeset
   254
	    e->vms_versions[e->vms_verscount] = atoi(p + 1);
claus
parents: 437
diff changeset
   255
	else
claus
parents: 437
diff changeset
   256
	    e->vms_versions[e->vms_verscount] = -1;
claus
parents: 437
diff changeset
   257
    }
claus
parents: 437
diff changeset
   258
claus
parents: 437
diff changeset
   259
    free(text);
claus
parents: 437
diff changeset
   260
}
claus
parents: 437
diff changeset
   261
claus
parents: 437
diff changeset
   262
/*
claus
parents: 437
diff changeset
   263
**  Read the next entry from the directory.
claus
parents: 437
diff changeset
   264
*/
claus
parents: 437
diff changeset
   265
struct dirent *
claus
parents: 437
diff changeset
   266
readdir(dd)
claus
parents: 437
diff changeset
   267
    DIR                                 *dd;
claus
parents: 437
diff changeset
   268
{
claus
parents: 437
diff changeset
   269
    struct dsc$descriptor_s     res;
claus
parents: 437
diff changeset
   270
    char                        *p;
claus
parents: 437
diff changeset
   271
    char                        buff[sizeof dd->entry.d_name];
claus
parents: 437
diff changeset
   272
    int                                 i;
claus
parents: 437
diff changeset
   273
claus
parents: 437
diff changeset
   274
    /* Set up result descriptor, and get next file. */
claus
parents: 437
diff changeset
   275
    res.dsc$a_pointer = buff;
claus
parents: 437
diff changeset
   276
    res.dsc$w_length = sizeof buff - 2;
claus
parents: 437
diff changeset
   277
    res.dsc$b_dtype = DSC$K_DTYPE_T;
claus
parents: 437
diff changeset
   278
    res.dsc$b_class = DSC$K_CLASS_S;
claus
parents: 437
diff changeset
   279
    if (lib$find_file(&dd->pat, &res, &dd->context) == RMS$_NMF
claus
parents: 437
diff changeset
   280
     || dd->context == 0L)
claus
parents: 437
diff changeset
   281
	/* None left... */
claus
parents: 437
diff changeset
   282
	return NULL;
claus
parents: 437
diff changeset
   283
claus
parents: 437
diff changeset
   284
    /* Force the buffer to end with a NUL. */
claus
parents: 437
diff changeset
   285
    buff[sizeof buff - 1] = '\0';
claus
parents: 437
diff changeset
   286
    for (p = buff; !isspace(*p); p++)
claus
parents: 437
diff changeset
   287
	;
claus
parents: 437
diff changeset
   288
    *p = '\0';
claus
parents: 437
diff changeset
   289
claus
parents: 437
diff changeset
   290
    /* Skip any directory component and just copy the name. */
claus
parents: 437
diff changeset
   291
    if (p = strchr(buff, ']'))
claus
parents: 437
diff changeset
   292
	(void)strcpy(dd->entry.d_name, p + 1);
claus
parents: 437
diff changeset
   293
    else
claus
parents: 437
diff changeset
   294
	(void)strcpy(dd->entry.d_name, buff);
claus
parents: 437
diff changeset
   295
claus
parents: 437
diff changeset
   296
    /* Clobber the version. */
claus
parents: 437
diff changeset
   297
    if (p = strchr(dd->entry.d_name, ';'))
claus
parents: 437
diff changeset
   298
	*p = '\0';
claus
parents: 437
diff changeset
   299
claus
parents: 437
diff changeset
   300
    dd->entry.d_namlen = strlen(dd->entry.d_name);
claus
parents: 437
diff changeset
   301
claus
parents: 437
diff changeset
   302
    dd->entry.vms_verscount = 0;
claus
parents: 437
diff changeset
   303
    if (dd->vms_wantversions)
claus
parents: 437
diff changeset
   304
	collectversions(dd);
claus
parents: 437
diff changeset
   305
    return &dd->entry;
claus
parents: 437
diff changeset
   306
}
claus
parents: 437
diff changeset
   307
claus
parents: 437
diff changeset
   308
/*
claus
parents: 437
diff changeset
   309
**  Return something that can be used in a seekdir later.
claus
parents: 437
diff changeset
   310
*/
claus
parents: 437
diff changeset
   311
long
claus
parents: 437
diff changeset
   312
telldir(dd)
claus
parents: 437
diff changeset
   313
    DIR                 *dd;
claus
parents: 437
diff changeset
   314
{
claus
parents: 437
diff changeset
   315
    return dd->context;
claus
parents: 437
diff changeset
   316
}
claus
parents: 437
diff changeset
   317
claus
parents: 437
diff changeset
   318
/*
claus
parents: 437
diff changeset
   319
**  Return to a spot where we used to be.
claus
parents: 437
diff changeset
   320
*/
claus
parents: 437
diff changeset
   321
void
claus
parents: 437
diff changeset
   322
seekdir(dd, pos)
claus
parents: 437
diff changeset
   323
    DIR                 *dd;
claus
parents: 437
diff changeset
   324
    long        pos;
claus
parents: 437
diff changeset
   325
{
claus
parents: 437
diff changeset
   326
    dd->context = pos;
claus
parents: 437
diff changeset
   327
}
claus
parents: 437
diff changeset
   328
claus
parents: 437
diff changeset
   329
#endif /* VMS */
claus
parents: 437
diff changeset
   330
%}
claus
parents: 437
diff changeset
   331
! !
claus
parents: 437
diff changeset
   332
613
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   333
!DirectoryStream class methodsFor:'documentation'!
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   334
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   335
copyright
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   336
"
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   337
 COPYRIGHT (c) 1989 by Claus Gittinger
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   338
	      All Rights Reserved
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   339
613
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   340
 This software is furnished under a license and may be used
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   341
 only in accordance with the terms of that license and with the
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   342
 inclusion of the above copyright notice.   This software may not
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   343
 be provided or otherwise made available to, or used by, any
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   344
 other person.  No title to or ownership of the software is
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   345
 hereby transferred.
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   346
"
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   347
!
360
claus
parents: 249
diff changeset
   348
613
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   349
documentation
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   350
"
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   351
    Instances of DirectoryStream allow reading a file-directory,
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   352
    as if it was a stream of filenames.
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   353
    Basically, its an interface to opendir, readdir and closedir.
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   354
"
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   355
!
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   356
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   357
version
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   358
    ^ '$Header: /cvs/stx/stx/libbasic/Attic/DirStr.st,v 1.27 1995-11-23 01:49:57 cg Exp $'
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   359
! !
a27a279701f8 Initial revision
claus
parents:
diff changeset
   360
a27a279701f8 Initial revision
claus
parents:
diff changeset
   361
!DirectoryStream class methodsFor:'instance creation'!
a27a279701f8 Initial revision
claus
parents:
diff changeset
   362
a27a279701f8 Initial revision
claus
parents:
diff changeset
   363
directoryNamed:dirName
a27a279701f8 Initial revision
claus
parents:
diff changeset
   364
    "return a DirectoryStream for directory named dirName, aString"
a27a279701f8 Initial revision
claus
parents:
diff changeset
   365
a27a279701f8 Initial revision
claus
parents:
diff changeset
   366
    |newStream|
a27a279701f8 Initial revision
claus
parents:
diff changeset
   367
a27a279701f8 Initial revision
claus
parents:
diff changeset
   368
    newStream := (self basicNew) pathName:dirName.
a27a279701f8 Initial revision
claus
parents:
diff changeset
   369
    newStream openForReading isNil ifTrue:[^nil].
a27a279701f8 Initial revision
claus
parents:
diff changeset
   370
    ^ newStream
a27a279701f8 Initial revision
claus
parents:
diff changeset
   371
! !
a27a279701f8 Initial revision
claus
parents:
diff changeset
   372
a27a279701f8 Initial revision
claus
parents:
diff changeset
   373
!DirectoryStream methodsFor:'access reading'!
a27a279701f8 Initial revision
claus
parents:
diff changeset
   374
a27a279701f8 Initial revision
claus
parents:
diff changeset
   375
nextLine
a27a279701f8 Initial revision
claus
parents:
diff changeset
   376
    "return the next filename as a string"
a27a279701f8 Initial revision
claus
parents:
diff changeset
   377
a27a279701f8 Initial revision
claus
parents:
diff changeset
   378
    |prevEntry nextEntry|
a27a279701f8 Initial revision
claus
parents:
diff changeset
   379
%{
77
6c38ca59927f *** empty log message ***
claus
parents: 54
diff changeset
   380
#ifdef HAS_OPENDIR
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   381
    DIR *d;
a27a279701f8 Initial revision
claus
parents:
diff changeset
   382
#ifdef NEXT
a27a279701f8 Initial revision
claus
parents:
diff changeset
   383
    struct direct *dp;
a27a279701f8 Initial revision
claus
parents:
diff changeset
   384
#else
a27a279701f8 Initial revision
claus
parents:
diff changeset
   385
    struct dirent *dp;
a27a279701f8 Initial revision
claus
parents:
diff changeset
   386
#endif
92
0c73b48551ac *** empty log message ***
claus
parents: 88
diff changeset
   387
    OBJ dirP;
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   388
92
0c73b48551ac *** empty log message ***
claus
parents: 88
diff changeset
   389
    if ((dirP = _INST(dirPointer)) != nil) {
475
b57530aa1b0a use new FILE* wrapper macros (based on externalAddress)
Claus Gittinger <cg@exept.de>
parents: 438
diff changeset
   390
	d = (DIR *)__FILEVal(dirP);
92
0c73b48551ac *** empty log message ***
claus
parents: 88
diff changeset
   391
362
claus
parents: 360
diff changeset
   392
	__BEGIN_INTERRUPTABLE__
92
0c73b48551ac *** empty log message ***
claus
parents: 88
diff changeset
   393
	errno = 0;
155
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   394
	do {
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   395
	    dp = readdir(d);
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   396
	} while ((dp == NULL) && (errno == EINTR));
362
claus
parents: 360
diff changeset
   397
	__END_INTERRUPTABLE__
92
0c73b48551ac *** empty log message ***
claus
parents: 88
diff changeset
   398
155
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   399
	if (dp != NULL) {
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   400
	    nextEntry = _MKSTRING((char *)(dp->d_name) COMMA_CON);
92
0c73b48551ac *** empty log message ***
claus
parents: 88
diff changeset
   401
	} else {
0c73b48551ac *** empty log message ***
claus
parents: 88
diff changeset
   402
	    _INST(hitEOF) = true;
0c73b48551ac *** empty log message ***
claus
parents: 88
diff changeset
   403
	    if (errno) {
155
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   404
		_INST(lastErrorNumber) = _MKSMALLINT(errno);
92
0c73b48551ac *** empty log message ***
claus
parents: 88
diff changeset
   405
	    }
155
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   406
	}
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   407
    }
a27a279701f8 Initial revision
claus
parents:
diff changeset
   408
#endif
155
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   409
%}.
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   410
    lastErrorNumber notNil ifTrue:[^ self ioError].
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   411
    prevEntry := readAhead.
a27a279701f8 Initial revision
claus
parents:
diff changeset
   412
    readAhead := nextEntry.
a27a279701f8 Initial revision
claus
parents:
diff changeset
   413
    ^ prevEntry
a27a279701f8 Initial revision
claus
parents:
diff changeset
   414
! !
a27a279701f8 Initial revision
claus
parents:
diff changeset
   415
613
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   416
!DirectoryStream methodsFor:'closing'!
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   417
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   418
close
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   419
    "close the stream - tell operating system"
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   420
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   421
    dirPointer notNil ifTrue:[
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   422
	Lobby unregister:self.
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   423
	self closeFile.
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   424
	dirPointer := nil
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   425
    ]
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   426
! !
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   427
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   428
!DirectoryStream methodsFor:'instance release'!
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   429
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   430
closeFile
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   431
    "low level close of a directoryStream"
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   432
%{
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   433
#ifdef HAS_OPENDIR
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   434
    OBJ dp;
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   435
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   436
    if ((dp = _INST(dirPointer)) != nil) {
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   437
	_INST(dirPointer) = nil;
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   438
	closedir( (DIR *)(__FILEVal(dp)) );
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   439
    }
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   440
#endif
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   441
%}
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   442
! !
0af19c3594fc checkin from browser
Claus Gittinger <cg@exept.de>
parents: 528
diff changeset
   443
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   444
!DirectoryStream methodsFor:'private'!
a27a279701f8 Initial revision
claus
parents:
diff changeset
   445
a27a279701f8 Initial revision
claus
parents:
diff changeset
   446
openForReading
a27a279701f8 Initial revision
claus
parents:
diff changeset
   447
    "open the file for readonly"
a27a279701f8 Initial revision
claus
parents:
diff changeset
   448
155
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   449
    |ok|
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   450
a27a279701f8 Initial revision
claus
parents:
diff changeset
   451
    mode := #readonly.
a27a279701f8 Initial revision
claus
parents:
diff changeset
   452
%{
77
6c38ca59927f *** empty log message ***
claus
parents: 54
diff changeset
   453
#ifdef HAS_OPENDIR
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   454
    DIR *d;
477
8710aba7876b oops - making id's real objects requires a store macro
Claus Gittinger <cg@exept.de>
parents: 475
diff changeset
   455
    OBJ path, dp;
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   456
155
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   457
    ok = false;
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   458
    if (_INST(dirPointer) == nil) {
155
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   459
	path = _INST(pathName);
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   460
	if (__isString(path)) {
362
claus
parents: 360
diff changeset
   461
	    __BEGIN_INTERRUPTABLE__
92
0c73b48551ac *** empty log message ***
claus
parents: 88
diff changeset
   462
	    errno = 0;
155
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   463
	    do {
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   464
		d = opendir((char *) _stringVal(path));
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   465
	    } while ((d == NULL) && (errno == EINTR));
362
claus
parents: 360
diff changeset
   466
	    __END_INTERRUPTABLE__
92
0c73b48551ac *** empty log message ***
claus
parents: 88
diff changeset
   467
155
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   468
	    if (d == NULL) {
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   469
		_INST(lastErrorNumber) = _MKSMALLINT(errno);
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   470
	    } else {
477
8710aba7876b oops - making id's real objects requires a store macro
Claus Gittinger <cg@exept.de>
parents: 475
diff changeset
   471
		_INST(dirPointer) = dp = __MKOBJ(d); __STORE(self, dp);
155
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   472
		ok = true;
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   473
	    }
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   474
	}
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   475
    }
a27a279701f8 Initial revision
claus
parents:
diff changeset
   476
#endif
155
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   477
%}.
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   478
    ok isNil ifTrue:[
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   479
	"
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   480
	 opendir not avalable - use slower pipe
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   481
	"
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   482
	^ PipeStream readingFrom:('cd ' , pathName , '; ls -a')
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   483
    ].
155
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   484
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   485
    (ok == true) ifTrue:[
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   486
	Lobby register:self.
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   487
	self nextLine. "read 1st entry into readAhead buffer"
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   488
	^ self
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   489
    ].
155
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   490
    dirPointer notNil ifTrue:[^ self errorOpen].
edd7fc34e104 *** empty log message ***
claus
parents: 92
diff changeset
   491
    lastErrorNumber notNil ifTrue:[^ self openError].
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   492
    ^ nil
a27a279701f8 Initial revision
claus
parents:
diff changeset
   493
!
a27a279701f8 Initial revision
claus
parents:
diff changeset
   494
a27a279701f8 Initial revision
claus
parents:
diff changeset
   495
reOpen
38
454b1b94a48e *** empty log message ***
claus
parents: 31
diff changeset
   496
    "reOpen the stream after image restart"
454b1b94a48e *** empty log message ***
claus
parents: 31
diff changeset
   497
2
claus
parents: 1
diff changeset
   498
    dirPointer := nil.
claus
parents: 1
diff changeset
   499
    super reOpen
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   500
! !
a27a279701f8 Initial revision
claus
parents:
diff changeset
   501
a27a279701f8 Initial revision
claus
parents:
diff changeset
   502
!DirectoryStream methodsFor:'testing'!
a27a279701f8 Initial revision
claus
parents:
diff changeset
   503
a27a279701f8 Initial revision
claus
parents:
diff changeset
   504
atEnd
a27a279701f8 Initial revision
claus
parents:
diff changeset
   505
    "return true, if position is at end"
a27a279701f8 Initial revision
claus
parents:
diff changeset
   506
a27a279701f8 Initial revision
claus
parents:
diff changeset
   507
    ^ readAhead == nil
a27a279701f8 Initial revision
claus
parents:
diff changeset
   508
! !
a27a279701f8 Initial revision
claus
parents:
diff changeset
   509