diff options
| -rw-r--r-- | doc/api-channels.texi | 10 | ||||
| -rw-r--r-- | libguile-ssh/channel-func.c | 3 | ||||
| -rw-r--r-- | libguile-ssh/channel-type.c | 39 | ||||
| -rw-r--r-- | libguile-ssh/channel-type.h | 5 | ||||
| -rw-r--r-- | libguile-ssh/message-func.c | 3 | ||||
| -rw-r--r-- | modules/ssh/channel.scm | 11 |
6 files changed, 56 insertions, 15 deletions
diff --git a/doc/api-channels.texi b/doc/api-channels.texi index 6123027..03c5b7b 100644 --- a/doc/api-channels.texi +++ b/doc/api-channels.texi @@ -33,9 +33,13 @@ Return @code{#t} if @var{x} is a Guile-SSH channel, @code{#f} otherwise. @end deffn -@deffn {Scheme Procedure} make-channel session -Allocate a new Guile-SSH channel for the @var{session} -(@pxref{Sessions}). +@deffn {Scheme Procedure} make-channel session [flags] +Allocate a new Guile-SSH channel for the @var{session} (@pxref{Sessions}). + +@var{flags} are determine what kind of a channel should be created. Possible +flags are: @code{O_RDONLY}, @code{O_WRONLY}, @code{O_RDWR}. They play similar +role to @code{open} procedure flags, and allow to create an ihput channel, +output channel or input/output channel respectively. @end deffn @deffn {Scheme Procedure} channel-open-session channel diff --git a/libguile-ssh/channel-func.c b/libguile-ssh/channel-func.c index eb2ca62..152b5cd 100644 --- a/libguile-ssh/channel-func.c +++ b/libguile-ssh/channel-func.c @@ -316,7 +316,8 @@ SCM_GSSH_DEFINE (guile_ssh_channel_accept_forward, &port); if (c_channel) { - channel = _scm_from_channel_data (c_channel, session); + channel = _scm_from_channel_data (c_channel, session, + SCM_RDNG | SCM_WRTNG); SCM_SET_CELL_TYPE (channel, SCM_CELL_TYPE (channel) | SCM_OPN); } diff --git a/libguile-ssh/channel-type.c b/libguile-ssh/channel-type.c index cd11b36..8e992ab 100644 --- a/libguile-ssh/channel-type.c +++ b/libguile-ssh/channel-type.c @@ -182,7 +182,14 @@ static int print_channel (SCM channel, SCM port, scm_print_state *pstate) { struct channel_data *ch = _scm_to_channel_data (channel); - scm_puts ("#<channel ", port); + + if (SCM_INPUT_PORT_P (port) && SCM_OUTPUT_PORT_P (port)) + scm_puts ("#<channel ", port); + else if (SCM_INPUT_PORT_P (port)) + scm_puts ("#<input channel ", port); + else if (SCM_OUTPUT_PORT_P (port)) + scm_puts ("#<output channel ", port); + if (! ch) { scm_puts ("(freed) ", port); @@ -202,20 +209,26 @@ print_channel (SCM channel, SCM port, scm_print_state *pstate) } /* Allocate a new SSH channel. */ -SCM_DEFINE (guile_ssh_make_channel, "make-channel", 1, 0, 0, - (SCM arg1), +SCM_DEFINE (guile_ssh_make_channel, "%make-channel", 2, 0, 0, + (SCM arg1, SCM flags), "\ Allocate a new SSH channel.\ ") +#define FUNC_NAME s_guile_ssh_make_channel { struct session_data *session_data = _scm_to_session_data (arg1); - ssh_channel ch = ssh_channel_new (session_data->ssh_session); + ssh_channel ch; + + SCM_ASSERT (scm_is_integer (flags), flags, SCM_ARG2, FUNC_NAME); + + ch = ssh_channel_new (session_data->ssh_session); if (! ch) return SCM_BOOL_F; - return _scm_from_channel_data (ch, arg1); + return _scm_from_channel_data (ch, arg1, scm_to_long (flags)); } +#undef FUNC_NAME /* Predicates */ @@ -247,9 +260,13 @@ equalp_channel (SCM x1, SCM x2) /* Helper procedures */ /* Pack the SSH channel CH to a Scheme port and return newly created - port. */ + port. + + Asserts: + - mode has only SCM_RDNG and SCM_WRTNG bits set. + */ SCM -_scm_from_channel_data (ssh_channel ch, SCM session) +_scm_from_channel_data (ssh_channel ch, SCM session, long flags) { struct channel_data *channel_data; SCM ptob; @@ -278,7 +295,10 @@ _scm_from_channel_data (ssh_channel ch, SCM session) pt->read_pos = pt->read_buf; pt->read_end = pt->read_buf; - SCM_SET_CELL_TYPE (ptob, channel_tag | SCM_RDNG | SCM_WRTNG); + assert ((flags ^ (SCM_RDNG | SCM_WRTNG)) == 0); + + SCM_SET_CELL_TYPE (ptob, channel_tag | flags); + SCM_SETSTREAM (ptob, channel_data); return ptob; @@ -311,6 +331,9 @@ init_channel_type (void) scm_set_port_print (channel_tag, print_channel); scm_set_port_equalp (channel_tag, equalp_channel); + scm_c_define ("RDNG", scm_from_int (SCM_RDNG)); + scm_c_define ("WRTNG", scm_from_int (SCM_WRTNG)); + #include "channel-type.x" } diff --git a/libguile-ssh/channel-type.h b/libguile-ssh/channel-type.h index 1ac8a28..8810248 100644 --- a/libguile-ssh/channel-type.h +++ b/libguile-ssh/channel-type.h @@ -52,7 +52,7 @@ struct channel_data { /* API */ -extern SCM guile_ssh_make_channel (SCM arg1); +extern SCM guile_ssh_make_channel (SCM arg1, SCM flags); extern SCM guile_ssh_is_channel_p (SCM arg1); extern SCM guile_ssh_channel_get_session (SCM arg1); @@ -61,6 +61,7 @@ extern void init_channel_type (void); /* Helper procedures */ extern struct channel_data *_scm_to_channel_data (SCM x); -extern SCM _scm_from_channel_data (ssh_channel ch, SCM session); +extern SCM _scm_from_channel_data (ssh_channel ch, SCM session, + long flags); #endif /* ifndef __CHANNEL_TYPE_H__ */ diff --git a/libguile-ssh/message-func.c b/libguile-ssh/message-func.c index 428af34..aa7a8e2 100644 --- a/libguile-ssh/message-func.c +++ b/libguile-ssh/message-func.c @@ -138,7 +138,8 @@ Return a new SSH channel.\ if (! ch) return SCM_BOOL_F; - SCM channel = _scm_from_channel_data (ch, msg_data->session); + SCM channel = _scm_from_channel_data (ch, msg_data->session, + SCM_RDNG | SCM_WRTNG); SCM_SET_CELL_TYPE (channel, SCM_CELL_TYPE (channel) | SCM_OPN); diff --git a/modules/ssh/channel.scm b/modules/ssh/channel.scm index eddb91b..7b3629e 100644 --- a/modules/ssh/channel.scm +++ b/modules/ssh/channel.scm @@ -72,6 +72,17 @@ open-remote-pipe open-remote-pipe*)) +(define* (make-channel session #:optional (flags O_RDWR)) + (cond + ((= flags O_RDWR) + (%make-channel session (logior RDNG WRTNG))) + ((= flags O_RDONLY) + (%make-channel session RDNG)) + ((= flags O_WRONLY) + (%make-channel session WRTNG)) + (else + (throw 'guile-ssh-error "Wrong flags" flags)))) + (define* (channel-open-forward channel #:key (source-host "localhost") local-port |
