From 7e56a0e32cb399151013dfddc187c31aa9ef077e Mon Sep 17 00:00:00 2001 From: Martin Peach Date: Wed, 20 Feb 2013 20:58:37 +0000 Subject: fopen and fclose -> sys_fopen and sys_fclose for recent pd svn path=/trunk/externals/mrpeach/; revision=17045 --- net/tcpserver.c | 476 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 241 insertions(+), 235 deletions(-) diff --git a/net/tcpserver.c b/net/tcpserver.c index b7cc254..72f9b95 100644 --- a/net/tcpserver.c +++ b/net/tcpserver.c @@ -52,6 +52,12 @@ #include #endif +/* support older Pd versions without sys_open(), sys_fopen(), sys_fclose() */ +#if PD_MAJOR_VERSION == 0 && PD_MINOR_VERSION < 44 +#define sys_open open +#define sys_fopen fopen +#define sys_fclose fclose +#endif #ifdef _MSC_VER #define snprintf sprintf_s @@ -112,12 +118,12 @@ typedef struct _tcpserver char x_msginbuf[MAX_UDP_RECEIVE]; } t_tcpserver; -typedef struct _tcpserver_broadcast_params -{ - t_tcpserver *x; - t_int argc; - t_atom argv[MAX_UDP_RECEIVE]; -} t_tcpserver_broadcast_params; +typedef struct _tcpserver_broadcast_params +{ + t_tcpserver *x; + t_int argc; + t_atom argv[MAX_UDP_RECEIVE]; +} t_tcpserver_broadcast_params; static t_tcpserver_socketreceiver *tcpserver_socketreceiver_new(void *owner, t_tcpserver_socketnotifier notifier, t_tcpserver_socketreceivefn socketreceivefn); @@ -130,7 +136,7 @@ static void tcpserver_send_bytes(int sockfd, t_tcpserver *x, int argc, t_atom *a static int tcpserver_send_buffer_avaliable_for_client(t_tcpserver *x, int client); #endif static void *tcpserver_send_buf_thread(void *arg); -static void *tcpserver_broadcast_thread(void *arg); +static void *tcpserver_broadcast_thread(void *arg); static void tcpserver_client_send(t_tcpserver *x, t_symbol *s, int argc, t_atom *argv); static void tcpserver_output_client_state(t_tcpserver *x, int client); static int tcpserver_get_socket_send_buf_size(int sockfd); @@ -407,7 +413,7 @@ static void tcpserver_send_bytes(int client, t_tcpserver *x, int argc, t_atom *a #ifdef DEBUG post ("%s: fname: %s", objName, fpath); #endif - fptr = fopen(fpath, "rb"); + fptr = sys_fopen(fpath, "rb"); if (fptr == NULL) { error("%s: unable to open \"%s\"", objName, fpath); @@ -455,7 +461,7 @@ static void tcpserver_send_bytes(int client, t_tcpserver *x, int argc, t_atom *a } } flen += j; - fclose(fptr); + sys_fclose(fptr); fptr = NULL; post("%s: read \"%s\" length %d byte%s", objName, fpath, flen, ((d==1)?"":"s")); } @@ -788,232 +794,232 @@ static void tcpserver_buf_size(t_tcpserver *x, t_symbol *s, int argc, t_atom *ar return; } -/* broadcasts messages to all clients */ -/* Ivica Ico Bukvic 5/6/10 rewrote broadcast to be xrun-free */ -static void *tcpserver_broadcast_thread(void *arg) -{ - t_tcpserver_broadcast_params *ttbp = (t_tcpserver_broadcast_params *)arg; - int client; - static char byte_buf[MAX_UDP_RECEIVE];// arbitrary maximum similar to max IP packet size - int i, j, d; - unsigned char c; - float f, e; - int length; - size_t flen = 0; - int sockfd = 0; - char fpath[FILENAME_MAX]; - FILE *fptr; - t_atom output_atom[3]; - t_tcpserver_send_params *ttsp; - pthread_t sender_thread; - pthread_attr_t sender_attr; - int sender_thread_result; - int result; - - for (i = j = 0; i < ttbp->argc; ++i) - { - if (ttbp->argv[i].a_type == A_FLOAT) - { /* load floats into buffer as long as they are integers on [0..255]*/ - f = ttbp->argv[i].a_w.w_float; - d = (int)f; - e = f - d; -#ifdef DEBUG - post("%s: argv[%d]: float:%f int:%d delta:%f", objName, i, f, d, e); -#endif - if (e != 0) - { - error("%s_broadcast_thread: item %d (%f) is not an integer", objName, i, f); - freebytes (arg, sizeof (t_tcpserver_broadcast_params)); - return NULL; - } - if ((d < 0) || (d > 255)) - { - error("%s_broadcast_thread: item %d (%f) is not between 0 and 255", objName, i, f); - freebytes (arg, sizeof (t_tcpserver_broadcast_params)); - return NULL; - } - c = (unsigned char)d; /* make sure it doesn't become negative; this only matters for post() */ -#ifdef DEBUG - post("%s_broadcast_thread: argv[%d]: %d", objName, i, c); -#endif - byte_buf[j++] = c; - if (j >= MAX_UDP_RECEIVE) - { /* if the argument list is longer than our buffer, send the buffer whenever it's full */ -//LOOP - /* enumerate through the clients and send each the message */ - for(client = 0; client < ttbp->x->x_nconnections; client++) /* check if connection exists */ - { -#ifdef SIOCOUTQ - if (tcpserver_send_buffer_avaliable_for_client(ttbp->x, client) < j) - { - error("%s_broadcast_thread: buffer too small for client(%d)", objName, client); - freebytes (arg, sizeof (t_tcpserver_broadcast_params)); - return NULL; - } -#endif // SIOCOUTQ - if(ttbp->x->x_sr[client]->sr_fd >= 0) - { /* socket exists for this client */ - sockfd = ttbp->x->x_sr[client]->sr_fd; - result = send(sockfd, byte_buf, j, 0); - if (result <= 0) - { - sys_sockerror("tcpserver_broadcast_thread: send"); - post("%s_broadcast_thread: could not send data to client %d", objName, client+1); - freebytes (arg, sizeof (t_tcpserver_broadcast_params)); - return NULL; - } - } - } - flen += j; - j = 0; - } - } - else if (ttbp->argv[i].a_type == A_SYMBOL) - { /* symbols are interpreted to be file names; attempt to load the file and send it */ - atom_string(&ttbp->argv[i], fpath, FILENAME_MAX); -#ifdef DEBUG - post ("%s_broadcast_thread: fname: %s", objName, fpath); -#endif - fptr = fopen(fpath, "rb"); - if (fptr == NULL) - { - error("%s_broadcast_thread: unable to open \"%s\"", objName, fpath); - freebytes (arg, sizeof (t_tcpserver_broadcast_params)); - return NULL; - } - rewind(fptr); -#ifdef DEBUG - post("%s_broadcast_thread: d is %d", objName, d); -#endif - while ((d = fgetc(fptr)) != EOF) - { - byte_buf[j++] = (char)(d & 0x0FF); -#ifdef DEBUG - post("%s_broadcast_thread: byte_buf[%d] = %d", objName, j-1, byte_buf[j-1]); -#endif - if (j >= MAX_UDP_RECEIVE) - { /* if the file is longer than our buffer, send the buffer whenever it's full */ -//LOOP - /* enumerate through the clients and send each the message */ - for(client = 0; client < ttbp->x->x_nconnections; client++) /* check if connection exists */ - { - /* this might be better than allocating huge amounts of memory */ -#ifdef SIOCOUTQ - if (tcpserver_send_buffer_avaliable_for_client(x, client) < j) - { - error("%s_broadcast_thread: buffer too small for client(%d)", objName, client); - freebytes (arg, sizeof (t_tcpserver_broadcast_params)); - return NULL; - } -#endif // SIOCOUTQ - if(ttbp->x->x_sr[client]->sr_fd >= 0) - { /* socket exists for this client */ - sockfd = ttbp->x->x_sr[client]->sr_fd; - result = send(sockfd, byte_buf, j, 0); - if (result <= 0) - { - sys_sockerror("tcpserver_broadcast_thread: send"); - post("%s_broadcast_thread: could not send data to client %d", objName, client+1); - freebytes (arg, sizeof (t_tcpserver_broadcast_params)); - return NULL; - } - } - } - flen += j; - j = 0; - } - } - flen += j; - fclose(fptr); - fptr = NULL; - post("%s_broadcast_thread: read \"%s\" length %d byte%s", objName, fpath, flen, ((d==1)?"":"s")); - } - else - { /* arg was neither a float nor a valid file name */ - error("%s_broadcast_thread: item %d is not a float or a file name", objName, i); - freebytes (arg, sizeof (t_tcpserver_broadcast_params)); - return NULL; - } - } - length = j; - if (length > 0) - { /* send whatever remains in our buffer */ - /* enumerate through the clients and send each the message */ - for(client = 0; client < ttbp->x->x_nconnections; client++) /* check if connection exists */ - { -#ifdef SIOCOUTQ - if (tcpserver_send_buffer_avaliable_for_client(x, client) < length) - { - error("%s_broadcast_thread: buffer too small for client(%d)", objName, client); - freebytes (arg, sizeof (t_tcpserver_broadcast_params)); - return NULL; - } -#endif // SIOCOUTQ - if(ttbp->x->x_sr[client]->sr_fd >= 0) - { /* socket exists for this client */ - sockfd = ttbp->x->x_sr[client]->sr_fd; - result = send(sockfd, byte_buf, length, 0); - if (result <= 0) - { - sys_sockerror("tcpserver_broadcast_thread: send"); - post("%s_broadcast_thread: could not send data to client %d", objName, client+1); - freebytes (arg, sizeof (t_tcpserver_broadcast_params)); - return NULL; - } - } - } - flen += length; - } - else post("%s_broadcast_thread: not a valid socket number (%d)", objName, sockfd); - freebytes (arg, sizeof (t_tcpserver_broadcast_params)); - return NULL; -} - -static void tcpserver_broadcast(t_tcpserver *x, t_symbol *s, int argc, t_atom *argv) -/* initializes separate thread that broadcasts to all clients */ -/* Ivica Ico Bukvic 5/6/10 rewrote broadcast to be xrun-free */ -{ - int i; - t_tcpserver_broadcast_params *ttbp; - pthread_t broadcast_thread; - pthread_attr_t broadcast_attr; - int broadcast_thread_result; - - if (x->x_nconnections != 0) - { - /* sender thread should start out detached so its resouces will be freed when it is done */ - if (0!= (broadcast_thread_result = pthread_attr_init(&broadcast_attr))) - { - error("%s_broadcast: pthread_attr_init failed: %d", objName, broadcast_thread_result); - } - else - { - if(0 != (broadcast_thread_result = pthread_attr_setdetachstate(&broadcast_attr, PTHREAD_CREATE_DETACHED))) - { - error("%s_broadcast: pthread_attr_setdetachstate failed: %d", objName, broadcast_thread_result); - } - else - { - ttbp = (t_tcpserver_broadcast_params *)getbytes(sizeof(t_tcpserver_broadcast_params)); - if (ttbp == NULL) - { - error("%s_broadcast: unable to allocate %d bytes for t_tcpserver_broadcast_params", objName, sizeof(t_tcpserver_broadcast_params)); - } - else - { - ttbp->x = x; - ttbp->argc = argc; - for (i = 0; i < argc; i++) ttbp->argv[i] = argv[i]; - if (0 != (broadcast_thread_result = pthread_create(&broadcast_thread, &broadcast_attr, tcpserver_broadcast_thread, (void *)ttbp))) - { - error("%s_broadcast: couldn't create broadcast thread (%d)", objName, broadcast_thread_result); - freebytes (ttbp, sizeof (t_tcpserver_broadcast_params)); - } - } - } - } - } -} +/* broadcasts messages to all clients */ +/* Ivica Ico Bukvic 5/6/10 rewrote broadcast to be xrun-free */ +static void *tcpserver_broadcast_thread(void *arg) +{ + t_tcpserver_broadcast_params *ttbp = (t_tcpserver_broadcast_params *)arg; + int client; + static char byte_buf[MAX_UDP_RECEIVE];// arbitrary maximum similar to max IP packet size + int i, j, d; + unsigned char c; + float f, e; + int length; + size_t flen = 0; + int sockfd = 0; + char fpath[FILENAME_MAX]; + FILE *fptr; + t_atom output_atom[3]; + t_tcpserver_send_params *ttsp; + pthread_t sender_thread; + pthread_attr_t sender_attr; + int sender_thread_result; + int result; + + for (i = j = 0; i < ttbp->argc; ++i) + { + if (ttbp->argv[i].a_type == A_FLOAT) + { /* load floats into buffer as long as they are integers on [0..255]*/ + f = ttbp->argv[i].a_w.w_float; + d = (int)f; + e = f - d; +#ifdef DEBUG + post("%s: argv[%d]: float:%f int:%d delta:%f", objName, i, f, d, e); +#endif + if (e != 0) + { + error("%s_broadcast_thread: item %d (%f) is not an integer", objName, i, f); + freebytes (arg, sizeof (t_tcpserver_broadcast_params)); + return NULL; + } + if ((d < 0) || (d > 255)) + { + error("%s_broadcast_thread: item %d (%f) is not between 0 and 255", objName, i, f); + freebytes (arg, sizeof (t_tcpserver_broadcast_params)); + return NULL; + } + c = (unsigned char)d; /* make sure it doesn't become negative; this only matters for post() */ +#ifdef DEBUG + post("%s_broadcast_thread: argv[%d]: %d", objName, i, c); +#endif + byte_buf[j++] = c; + if (j >= MAX_UDP_RECEIVE) + { /* if the argument list is longer than our buffer, send the buffer whenever it's full */ +//LOOP + /* enumerate through the clients and send each the message */ + for(client = 0; client < ttbp->x->x_nconnections; client++) /* check if connection exists */ + { +#ifdef SIOCOUTQ + if (tcpserver_send_buffer_avaliable_for_client(ttbp->x, client) < j) + { + error("%s_broadcast_thread: buffer too small for client(%d)", objName, client); + freebytes (arg, sizeof (t_tcpserver_broadcast_params)); + return NULL; + } +#endif // SIOCOUTQ + if(ttbp->x->x_sr[client]->sr_fd >= 0) + { /* socket exists for this client */ + sockfd = ttbp->x->x_sr[client]->sr_fd; + result = send(sockfd, byte_buf, j, 0); + if (result <= 0) + { + sys_sockerror("tcpserver_broadcast_thread: send"); + post("%s_broadcast_thread: could not send data to client %d", objName, client+1); + freebytes (arg, sizeof (t_tcpserver_broadcast_params)); + return NULL; + } + } + } + flen += j; + j = 0; + } + } + else if (ttbp->argv[i].a_type == A_SYMBOL) + { /* symbols are interpreted to be file names; attempt to load the file and send it */ + atom_string(&ttbp->argv[i], fpath, FILENAME_MAX); +#ifdef DEBUG + post ("%s_broadcast_thread: fname: %s", objName, fpath); +#endif + fptr = sys_fopen(fpath, "rb"); + if (fptr == NULL) + { + error("%s_broadcast_thread: unable to open \"%s\"", objName, fpath); + freebytes (arg, sizeof (t_tcpserver_broadcast_params)); + return NULL; + } + rewind(fptr); +#ifdef DEBUG + post("%s_broadcast_thread: d is %d", objName, d); +#endif + while ((d = fgetc(fptr)) != EOF) + { + byte_buf[j++] = (char)(d & 0x0FF); +#ifdef DEBUG + post("%s_broadcast_thread: byte_buf[%d] = %d", objName, j-1, byte_buf[j-1]); +#endif + if (j >= MAX_UDP_RECEIVE) + { /* if the file is longer than our buffer, send the buffer whenever it's full */ +//LOOP + /* enumerate through the clients and send each the message */ + for(client = 0; client < ttbp->x->x_nconnections; client++) /* check if connection exists */ + { + /* this might be better than allocating huge amounts of memory */ +#ifdef SIOCOUTQ + if (tcpserver_send_buffer_avaliable_for_client(x, client) < j) + { + error("%s_broadcast_thread: buffer too small for client(%d)", objName, client); + freebytes (arg, sizeof (t_tcpserver_broadcast_params)); + return NULL; + } +#endif // SIOCOUTQ + if(ttbp->x->x_sr[client]->sr_fd >= 0) + { /* socket exists for this client */ + sockfd = ttbp->x->x_sr[client]->sr_fd; + result = send(sockfd, byte_buf, j, 0); + if (result <= 0) + { + sys_sockerror("tcpserver_broadcast_thread: send"); + post("%s_broadcast_thread: could not send data to client %d", objName, client+1); + freebytes (arg, sizeof (t_tcpserver_broadcast_params)); + return NULL; + } + } + } + flen += j; + j = 0; + } + } + flen += j; + sys_fclose(fptr); + fptr = NULL; + post("%s_broadcast_thread: read \"%s\" length %d byte%s", objName, fpath, flen, ((d==1)?"":"s")); + } + else + { /* arg was neither a float nor a valid file name */ + error("%s_broadcast_thread: item %d is not a float or a file name", objName, i); + freebytes (arg, sizeof (t_tcpserver_broadcast_params)); + return NULL; + } + } + length = j; + if (length > 0) + { /* send whatever remains in our buffer */ + /* enumerate through the clients and send each the message */ + for(client = 0; client < ttbp->x->x_nconnections; client++) /* check if connection exists */ + { +#ifdef SIOCOUTQ + if (tcpserver_send_buffer_avaliable_for_client(x, client) < length) + { + error("%s_broadcast_thread: buffer too small for client(%d)", objName, client); + freebytes (arg, sizeof (t_tcpserver_broadcast_params)); + return NULL; + } +#endif // SIOCOUTQ + if(ttbp->x->x_sr[client]->sr_fd >= 0) + { /* socket exists for this client */ + sockfd = ttbp->x->x_sr[client]->sr_fd; + result = send(sockfd, byte_buf, length, 0); + if (result <= 0) + { + sys_sockerror("tcpserver_broadcast_thread: send"); + post("%s_broadcast_thread: could not send data to client %d", objName, client+1); + freebytes (arg, sizeof (t_tcpserver_broadcast_params)); + return NULL; + } + } + } + flen += length; + } + else post("%s_broadcast_thread: not a valid socket number (%d)", objName, sockfd); + freebytes (arg, sizeof (t_tcpserver_broadcast_params)); + return NULL; +} + +static void tcpserver_broadcast(t_tcpserver *x, t_symbol *s, int argc, t_atom *argv) +/* initializes separate thread that broadcasts to all clients */ +/* Ivica Ico Bukvic 5/6/10 rewrote broadcast to be xrun-free */ +{ + int i; + t_tcpserver_broadcast_params *ttbp; + pthread_t broadcast_thread; + pthread_attr_t broadcast_attr; + int broadcast_thread_result; + + if (x->x_nconnections != 0) + { + /* sender thread should start out detached so its resouces will be freed when it is done */ + if (0!= (broadcast_thread_result = pthread_attr_init(&broadcast_attr))) + { + error("%s_broadcast: pthread_attr_init failed: %d", objName, broadcast_thread_result); + } + else + { + if(0 != (broadcast_thread_result = pthread_attr_setdetachstate(&broadcast_attr, PTHREAD_CREATE_DETACHED))) + { + error("%s_broadcast: pthread_attr_setdetachstate failed: %d", objName, broadcast_thread_result); + } + else + { + ttbp = (t_tcpserver_broadcast_params *)getbytes(sizeof(t_tcpserver_broadcast_params)); + if (ttbp == NULL) + { + error("%s_broadcast: unable to allocate %d bytes for t_tcpserver_broadcast_params", objName, sizeof(t_tcpserver_broadcast_params)); + } + else + { + ttbp->x = x; + ttbp->argc = argc; + for (i = 0; i < argc; i++) ttbp->argv[i] = argv[i]; + if (0 != (broadcast_thread_result = pthread_create(&broadcast_thread, &broadcast_attr, tcpserver_broadcast_thread, (void *)ttbp))) + { + error("%s_broadcast: couldn't create broadcast thread (%d)", objName, broadcast_thread_result); + freebytes (ttbp, sizeof (t_tcpserver_broadcast_params)); + } + } + } + } + } +} /* ---------------- main tcpserver (receive) stuff --------------------- */ /* tcpserver_notify is called by */ -- cgit v1.2.1