Hello Manuel, I've seen your recent changes to socket_shutdown. Maybe you could go one step further and support a common use case (SHUT_WR) directly?
Attached to this email you can find a little
client/server example application:
1) client writes characters, server reads them
2) client shuts down connection for writing
3) server reads eof-object,
writes response (here: received byte count),
performs socket shutdown and close
4) client reads response until eof-object,
prints response and closes socket
The attached ./make-and-test.bash should print:
Response string = '11'
(This is the byte count of "hello world".)
>From my exposure to other languages (mozart/oz),
shutdown and close are two separate issues, and
can be implemented independently of each other.
While low-level close() for all practical purposes
implies a shutdown, the partial shutdown() for one
direction does have its use.
In essence, I guess that the close_socket arg
can be removed from socket_shutdown entirely;
at least it is unclear to me why the call to
shutdown() depends on it.
Maybe you can think of a better way to expose the
three shutdown variants (SHUT_RD, SHUT_WR, SHUT_RDWR)?
Cheers & thanks a lot for bigloo development,
Andreas
============== Diff Summary ============
--- csocket.c
+++ csocket_extra.c
@@ ... @@
+#if( !defined( SHUT_RD ) )
+# define SHUT_RD 0
+#endif
+#if( !defined( SHUT_WR ) )
+# define SHUT_WR 1
+#endif
#if( !defined( SHUT_RDWR ) )
# define SHUT_RDWR 2
#endif
@@ ... @@
/*---------------------------------------------------------------------*/
/* imports ... */
/*---------------------------------------------------------------------*/
extern obj_t bgl_close_input_port( obj_t );
+extern obj_t bgl_close_output_port( obj_t );
@@ ... @@
/*---------------------------------------------------------------------*/
/* obj_t */
-/* socket_shutdown ... */
+/* socket_shutdown and friends (.._read, .._write, .._read_write) */
/*---------------------------------------------------------------------*/
BGL_RUNTIME_DEF obj_t
-socket_shutdown( obj_t sock, int close_socket ) {
+socket_shutdown( obj_t sock, int how ) {
int fd = SOCKET( sock ).fd;
if( fd > 0 ) {
- if( close_socket ) {
- if( shutdown( fd, SHUT_RDWR ) ) {
+ if( shutdown( fd, how ) ) {
char *buffer = alloca( 1024 );
-
- /* force closing the socket anyhow */
- socket_close( sock );
-
BGL_MUTEX_LOCK( socket_mutex );
- sprintf( buffer, "cannot shutdown socket, %s %d", strerror( errno
), fd );
+ sprintf( buffer, "cannot shutdown socket (how = %d), %s %d",
+ how, strerror( errno ), fd );
BGL_MUTEX_UNLOCK( socket_mutex );
socket_error( "socket-shutdown", buffer, sock );
}
}
- socket_close( sock );
+
+ if( ( how == SHUT_RD ) || ( how == SHUT_RDWR ) ) {
+ if( INPUT_PORTP( SOCKET( sock ).input ) ) {
+ bgl_close_input_port( SOCKET( sock ).input );
+ }
+ }
+
+ if( ( how == SHUT_WR ) || ( how == SHUT_RDWR ) ) {
+ if( OUTPUT_PORTP( SOCKET( sock ).output ) ) {
+ bgl_close_output_port( SOCKET( sock ).output );
+ }
}
return BUNSPEC;
}
+
+BGL_RUNTIME_DEF obj_t
+socket_shutdown_read( obj_t sock ) {
+ return socket_shutdown( sock, SHUT_RD );
+}
+BGL_RUNTIME_DEF obj_t
+socket_shutdown_write( obj_t sock ) {
+ return socket_shutdown( sock , SHUT_WR );
+}
+BGL_RUNTIME_DEF obj_t
+socket_shutdown_read_write( obj_t sock ) {
+ return socket_shutdown( sock, SHUT_RDWR );
+}
bigloo_socket_shutdown.tgz
Description: application/compressed-tar
