PipeStream.st
author claus
Mon, 04 Oct 1993 11:32:33 +0100
changeset 2 6526dde5f3ac
parent 1 a27a279701f8
child 3 24d81bf47225
permissions -rw-r--r--
2.7.2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
     1
"
a27a279701f8 Initial revision
claus
parents:
diff changeset
     2
 COPYRIGHT (c) 1989-93 by Claus Gittinger
a27a279701f8 Initial revision
claus
parents:
diff changeset
     3
              All Rights Reserved
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
NonPositionableExternalStream subclass:#PipeStream
a27a279701f8 Initial revision
claus
parents:
diff changeset
    14
       instanceVariableNames:''
2
claus
parents: 1
diff changeset
    15
       classVariableNames:'PipeSignal'
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
    16
       poolDictionaries:''
a27a279701f8 Initial revision
claus
parents:
diff changeset
    17
       category:'Streams-External'
a27a279701f8 Initial revision
claus
parents:
diff changeset
    18
!
a27a279701f8 Initial revision
claus
parents:
diff changeset
    19
a27a279701f8 Initial revision
claus
parents:
diff changeset
    20
PipeStream comment:'
a27a279701f8 Initial revision
claus
parents:
diff changeset
    21
a27a279701f8 Initial revision
claus
parents:
diff changeset
    22
COPYRIGHT (c) 1989-93 by Claus Gittinger
a27a279701f8 Initial revision
claus
parents:
diff changeset
    23
              All Rights Reserved
a27a279701f8 Initial revision
claus
parents:
diff changeset
    24
a27a279701f8 Initial revision
claus
parents:
diff changeset
    25
%W% %E%
a27a279701f8 Initial revision
claus
parents:
diff changeset
    26
'!
a27a279701f8 Initial revision
claus
parents:
diff changeset
    27
a27a279701f8 Initial revision
claus
parents:
diff changeset
    28
%{
a27a279701f8 Initial revision
claus
parents:
diff changeset
    29
#include <stdio.h>
a27a279701f8 Initial revision
claus
parents:
diff changeset
    30
#ifndef transputer
a27a279701f8 Initial revision
claus
parents:
diff changeset
    31
# include <sys/types.h>
a27a279701f8 Initial revision
claus
parents:
diff changeset
    32
# include <sys/stat.h>
a27a279701f8 Initial revision
claus
parents:
diff changeset
    33
#endif
a27a279701f8 Initial revision
claus
parents:
diff changeset
    34
%}
a27a279701f8 Initial revision
claus
parents:
diff changeset
    35
2
claus
parents: 1
diff changeset
    36
!PipeStream class methodsFor:'documentation'!
claus
parents: 1
diff changeset
    37
claus
parents: 1
diff changeset
    38
documentation
claus
parents: 1
diff changeset
    39
"
claus
parents: 1
diff changeset
    40
Pipestreams allow reading or writing from/to a unix command.
claus
parents: 1
diff changeset
    41
For example, to get a stream reading the output of an 'ls -l'
claus
parents: 1
diff changeset
    42
command, a PipeStream can be created with:
claus
parents: 1
diff changeset
    43
claus
parents: 1
diff changeset
    44
        PipeStream readingFrom:'ls -l'
claus
parents: 1
diff changeset
    45
claus
parents: 1
diff changeset
    46
the characters of the commands output can be read using the
claus
parents: 1
diff changeset
    47
standard stream messages as next, nextLine etc.
claus
parents: 1
diff changeset
    48
claus
parents: 1
diff changeset
    49
If a writing pipeStream is written to, after the command has finished,
claus
parents: 1
diff changeset
    50
UNIX will generate an error-signal (SIGPIPE), which will raise a
claus
parents: 1
diff changeset
    51
PipeSignal. Thus, to handle this condition correctly, the following
claus
parents: 1
diff changeset
    52
code is suggested:
claus
parents: 1
diff changeset
    53
claus
parents: 1
diff changeset
    54
        p := PipeStream writingTo:' ... '.
claus
parents: 1
diff changeset
    55
        PipeString pipeSignal handle:[:ex |
claus
parents: 1
diff changeset
    56
            ....
claus
parents: 1
diff changeset
    57
            any cleanup action
claus
parents: 1
diff changeset
    58
        ] do:[
claus
parents: 1
diff changeset
    59
            p nextPutLine:' ... '
claus
parents: 1
diff changeset
    60
        ]
claus
parents: 1
diff changeset
    61
"
claus
parents: 1
diff changeset
    62
! !
claus
parents: 1
diff changeset
    63
claus
parents: 1
diff changeset
    64
!PipeStream class methodsFor:'initialization'!
claus
parents: 1
diff changeset
    65
claus
parents: 1
diff changeset
    66
initialize
claus
parents: 1
diff changeset
    67
    "setup the signal"
claus
parents: 1
diff changeset
    68
claus
parents: 1
diff changeset
    69
    PipeSignal := (Signal new) mayProceed:true.
claus
parents: 1
diff changeset
    70
    PipeSignal notifierString:'write on a pipe with no one to read'.
claus
parents: 1
diff changeset
    71
! !
claus
parents: 1
diff changeset
    72
claus
parents: 1
diff changeset
    73
!PipeStream class methodsFor:'signal access'!
claus
parents: 1
diff changeset
    74
claus
parents: 1
diff changeset
    75
pipeSignal
claus
parents: 1
diff changeset
    76
    "return the signal used to handle SIGPIPE unix-signals"
claus
parents: 1
diff changeset
    77
claus
parents: 1
diff changeset
    78
    ^ PipeSignal
claus
parents: 1
diff changeset
    79
! !
claus
parents: 1
diff changeset
    80
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
    81
!PipeStream class methodsFor:'instance creation'!
a27a279701f8 Initial revision
claus
parents:
diff changeset
    82
2
claus
parents: 1
diff changeset
    83
writingTo:commandString
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
    84
    "create and return a new pipeStream which can write to the unix command
a27a279701f8 Initial revision
claus
parents:
diff changeset
    85
     given by command."
a27a279701f8 Initial revision
claus
parents:
diff changeset
    86
2
claus
parents: 1
diff changeset
    87
    ^ (self basicNew) writingTo:commandString
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
    88
a27a279701f8 Initial revision
claus
parents:
diff changeset
    89
    "PipeStream writingTo:'sort'"
a27a279701f8 Initial revision
claus
parents:
diff changeset
    90
!
a27a279701f8 Initial revision
claus
parents:
diff changeset
    91
2
claus
parents: 1
diff changeset
    92
readingFrom:commandString
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
    93
    "create and return a new pipeStream which can read from the unix command
a27a279701f8 Initial revision
claus
parents:
diff changeset
    94
     given by command."
a27a279701f8 Initial revision
claus
parents:
diff changeset
    95
2
claus
parents: 1
diff changeset
    96
    ^ (self basicNew) readingFrom:commandString
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
    97
2
claus
parents: 1
diff changeset
    98
    "PipeStream readingFrom:'ls -l'"
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
    99
! !
a27a279701f8 Initial revision
claus
parents:
diff changeset
   100
a27a279701f8 Initial revision
claus
parents:
diff changeset
   101
!PipeStream methodsFor:'instance release'!
a27a279701f8 Initial revision
claus
parents:
diff changeset
   102
a27a279701f8 Initial revision
claus
parents:
diff changeset
   103
closeFile
a27a279701f8 Initial revision
claus
parents:
diff changeset
   104
    "low level close - redefined since we close a pipe here"
a27a279701f8 Initial revision
claus
parents:
diff changeset
   105
a27a279701f8 Initial revision
claus
parents:
diff changeset
   106
%{  /* NOCONTEXT */
a27a279701f8 Initial revision
claus
parents:
diff changeset
   107
#ifndef transputer
a27a279701f8 Initial revision
claus
parents:
diff changeset
   108
    pclose(MKFD(_INST(filePointer)));
a27a279701f8 Initial revision
claus
parents:
diff changeset
   109
#endif
a27a279701f8 Initial revision
claus
parents:
diff changeset
   110
%}
a27a279701f8 Initial revision
claus
parents:
diff changeset
   111
! !
a27a279701f8 Initial revision
claus
parents:
diff changeset
   112
a27a279701f8 Initial revision
claus
parents:
diff changeset
   113
!PipeStream methodsFor:'private'!
a27a279701f8 Initial revision
claus
parents:
diff changeset
   114
a27a279701f8 Initial revision
claus
parents:
diff changeset
   115
openPipeFor:commandString withMode:mode
a27a279701f8 Initial revision
claus
parents:
diff changeset
   116
    "open a pipe to commandString; mode may be 'r' or 'w'"
a27a279701f8 Initial revision
claus
parents:
diff changeset
   117
a27a279701f8 Initial revision
claus
parents:
diff changeset
   118
    |retVal|
a27a279701f8 Initial revision
claus
parents:
diff changeset
   119
a27a279701f8 Initial revision
claus
parents:
diff changeset
   120
    unBuffered := true.
a27a279701f8 Initial revision
claus
parents:
diff changeset
   121
%{
a27a279701f8 Initial revision
claus
parents:
diff changeset
   122
#ifndef transputer
a27a279701f8 Initial revision
claus
parents:
diff changeset
   123
    {
a27a279701f8 Initial revision
claus
parents:
diff changeset
   124
        FILE *f;
a27a279701f8 Initial revision
claus
parents:
diff changeset
   125
        extern OBJ ErrorNumber;
a27a279701f8 Initial revision
claus
parents:
diff changeset
   126
        extern errno;
2
claus
parents: 1
diff changeset
   127
        extern int _immediateInterrupt;
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   128
a27a279701f8 Initial revision
claus
parents:
diff changeset
   129
        if (_isString(commandString) && _isString(mode)) {
2
claus
parents: 1
diff changeset
   130
            _immediateInterrupt = 1;
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   131
            f = (FILE *)popen((char *) _stringVal(commandString),
2
claus
parents: 1
diff changeset
   132
                              (char *) _stringVal(mode));
claus
parents: 1
diff changeset
   133
            _immediateInterrupt = 0;
1
a27a279701f8 Initial revision
claus
parents:
diff changeset
   134
            if (f == NULL) {
a27a279701f8 Initial revision
claus
parents:
diff changeset
   135
                ErrorNumber = _MKSMALLINT(errno);
a27a279701f8 Initial revision
claus
parents:
diff changeset
   136
            } else {
a27a279701f8 Initial revision
claus
parents:
diff changeset
   137
                _INST(filePointer) = MKOBJ(f);
a27a279701f8 Initial revision
claus
parents:
diff changeset
   138
                retVal = self;
a27a279701f8 Initial revision
claus
parents:
diff changeset
   139
            }
a27a279701f8 Initial revision
claus
parents:
diff changeset
   140
        }
a27a279701f8 Initial revision
claus
parents:
diff changeset
   141
    }
a27a279701f8 Initial revision
claus
parents:
diff changeset
   142
#endif
a27a279701f8 Initial revision
claus
parents:
diff changeset
   143
%}
a27a279701f8 Initial revision
claus
parents:
diff changeset
   144
.
a27a279701f8 Initial revision
claus
parents:
diff changeset
   145
    retVal notNil ifTrue:[
a27a279701f8 Initial revision
claus
parents:
diff changeset
   146
        lobby register:self
a27a279701f8 Initial revision
claus
parents:
diff changeset
   147
    ].
a27a279701f8 Initial revision
claus
parents:
diff changeset
   148
    ^ retVal
a27a279701f8 Initial revision
claus
parents:
diff changeset
   149
!
a27a279701f8 Initial revision
claus
parents:
diff changeset
   150
a27a279701f8 Initial revision
claus
parents:
diff changeset
   151
readingFrom:command
a27a279701f8 Initial revision
claus
parents:
diff changeset
   152
    "setup the receiver to read from command"
a27a279701f8 Initial revision
claus
parents:
diff changeset
   153
a27a279701f8 Initial revision
claus
parents:
diff changeset
   154
    self readonly.
a27a279701f8 Initial revision
claus
parents:
diff changeset
   155
    ^ self openPipeFor:command withMode:'r'
a27a279701f8 Initial revision
claus
parents:
diff changeset
   156
!
a27a279701f8 Initial revision
claus
parents:
diff changeset
   157
a27a279701f8 Initial revision
claus
parents:
diff changeset
   158
writingTo:command
a27a279701f8 Initial revision
claus
parents:
diff changeset
   159
    "setup the receiver to write to command"
a27a279701f8 Initial revision
claus
parents:
diff changeset
   160
a27a279701f8 Initial revision
claus
parents:
diff changeset
   161
    self writeonly.
a27a279701f8 Initial revision
claus
parents:
diff changeset
   162
    ^ self openPipeFor:command withMode:'w'
a27a279701f8 Initial revision
claus
parents:
diff changeset
   163
! !
a27a279701f8 Initial revision
claus
parents:
diff changeset
   164
a27a279701f8 Initial revision
claus
parents:
diff changeset
   165
!PipeStream methodsFor:'redefined basic'!
a27a279701f8 Initial revision
claus
parents:
diff changeset
   166
a27a279701f8 Initial revision
claus
parents:
diff changeset
   167
size
a27a279701f8 Initial revision
claus
parents:
diff changeset
   168
    "redefined since pipes have no size"
a27a279701f8 Initial revision
claus
parents:
diff changeset
   169
a27a279701f8 Initial revision
claus
parents:
diff changeset
   170
    ^ self shouldNotImplement
a27a279701f8 Initial revision
claus
parents:
diff changeset
   171
!
a27a279701f8 Initial revision
claus
parents:
diff changeset
   172
a27a279701f8 Initial revision
claus
parents:
diff changeset
   173
position:newpos
a27a279701f8 Initial revision
claus
parents:
diff changeset
   174
    "redefined since pipes cannot be positioned"
a27a279701f8 Initial revision
claus
parents:
diff changeset
   175
a27a279701f8 Initial revision
claus
parents:
diff changeset
   176
    ^ self shouldNotImplement
a27a279701f8 Initial revision
claus
parents:
diff changeset
   177
!
a27a279701f8 Initial revision
claus
parents:
diff changeset
   178
a27a279701f8 Initial revision
claus
parents:
diff changeset
   179
position
a27a279701f8 Initial revision
claus
parents:
diff changeset
   180
    "redefined since pipes have no position"
a27a279701f8 Initial revision
claus
parents:
diff changeset
   181
a27a279701f8 Initial revision
claus
parents:
diff changeset
   182
    ^ self shouldNotImplement
a27a279701f8 Initial revision
claus
parents:
diff changeset
   183
! !