Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How can you check if a channel supports read or write ?

45 views
Skip to first unread message

aldo.www...@gmail.com

unread,
Mar 20, 2019, 11:25:03 AM3/20/19
to
Is there a way to check if given channelId supports "puts" (i.e. it's not a readonly channel), supports read/gets (i.e. it's not a write-only channel) ?


Andreas Leitgeb

unread,
Mar 20, 2019, 12:37:53 PM3/20/19
to
Not very elegant, as it relies on thrown errors:

proc isReadable {chan} {
if {[catch {fileevent $chan readable}]} {
return 0; # fileevent complained, so it's not
} else {
return 1; # fileevent queried the handler: harmless
}
}
isReadable stdin
isReadable stdout

For isWritable copy the body for isReadable and replace
readable by writable (note: *not* writ_e_able)


aldo.www...@gmail.com

unread,
Mar 20, 2019, 4:06:29 PM3/20/19
to
@Andreas : very clever !

Let me add another related question: how can you check if a channel is a "random-access" channel ?

Below you can se my solution, but I fear it's rather limited since (maybe) it does not work with channel with "limited seeking" (see refchan man-page: "...A channel may provide only limited seeking. For example sockets can seek forward, but not backward."
Let me tell you that I was not able to 'seek forward a socket' ...


What do you think ?

# returns 1 if $chan support the [chan seek ..] command
proc isSeekable {chan} {
expr {[chan tell $chan] >= 0}
}

Andreas Leitgeb

unread,
Mar 22, 2019, 4:32:58 AM3/22/19
to
That is just as much as I'd have suggested, although obviously it
rather "returns 1 if $chan supports the [chan tell ...] command"
To what degree the correlation between "supports tell" and "supports
seek" is strong enough, depends on what you really need the classi-
fication for.

Aldo Buratti

unread,
Mar 22, 2019, 7:43:57 AM3/22/19
to
@Andreas
After checking if a channel isReadable, I need to know if it supports random-access, i.e jumping to the end, jumping to the beginning, .. jumping to the n-th byte.
( NOTE: I need to know it in advance, without performing a test like ... catch {[seek $ch 0 end]} because this test may change the state of the channel )


I noted that if [chan tell $fd] returns -1, then the channel does not support random-accees, and it can be scanned only sequentially.
E.g: chan tell stdin == -1 ==> stdin does not support random-access.

This test is of course only partial; the inverse is not necessarily true.
There may be non-random-access channels (sequential access channesl) still able to [tell] their current position.
Unfortunately for me, I never find this kind of channels; sockets only support sequential-access, but they also return [tell $sock] == -1.

Therefore, up to now, for my (limited) experience
[chan tell $f] == -1 is equivalent to "$f is NOT a random-access channel"

Any counterexample ?

Ashok

unread,
Mar 22, 2019, 8:31:12 AM3/22/19
to
On 3/22/2019 5:13 PM, Aldo Buratti wrote:
> @Andreas
> ( NOTE: I need to know it in advance, without performing a test like ... catch {[seek $ch 0 end]} because this test may change the state of the channel )

set seekable [seek $ch 0 current]

I think using "current" instead of "end" will not change the state. But
not tested.

/Ashok

Ashok

unread,
Mar 22, 2019, 8:34:16 AM3/22/19
to
On 3/20/2019 8:55 PM, aldo.www...@gmail.com wrote:
> Is there a way to check if given channelId supports "puts" (i.e. it's not a readonly channel), supports read/gets (i.e. it's not a write-only channel) ?
>
>

0-length reads and writes might tell you.

% set fd [open xxx.xxx w]
file2c5fcf2a550
% read $fd 0
channel "file2c5fcf2a550" wasn't opened for reading
% close $fd
% set fd [open xxx.xxx r]
file2c5fcf26e80
% puts -nonewline $fd ""
channel "file2c5fcf26e80" wasn't opened for writing

Not sure if there might be any side-effects!

/Ashok
0 new messages