Doxygen Source Code Documentation
niml_stream.c File Reference
#include "niml_private.h"
#include <signal.h>
#include <fcntl.h>
Go to the source code of this file.
Define Documentation
|
How to close a socket, given the descriptor ss. Definition at line 32 of file niml_stream.c. Referenced by iochan_close(), iochan_goodcheck(), iochan_init(), NI_stream_close_keep(), NI_stream_goodcheck(), NI_stream_open(), tcp_accept(), tcp_connect(), tcp_listen(), and tcp_sigurg_handler(). |
|
Definition at line 560 of file niml_stream.c. Referenced by add_trusted_host(), and init_trusted_list(). |
|
Definition at line 559 of file niml_stream.c. Referenced by init_trusted_list(). |
|
Duh. Definition at line 49 of file niml_stream.c. |
|
Next delay in milliseconds, given current delay. Definition at line 54 of file niml_stream.c. Referenced by iochan_clearcheck(), iochan_goodcheck(), iochan_readcheck(), iochan_recvall(), iochan_sendall(), iochan_writecheck(), NI_stream_goodcheck(), SHM_goodcheck(), SHM_readcheck(), SHM_sendall(), and SHM_writecheck(). |
|
To print a system error message. Definition at line 12 of file niml_stream.c. Referenced by iochan_recv(), iochan_send(), NI_stream_read(), NI_stream_write(), shm_attach(), SHM_attach(), shm_create(), SHM_create(), shm_nattach(), SHM_nattach(), shm_size(), SHM_size(), tcp_accept(), tcp_alivecheck(), tcp_connect(), tcp_listen(), tcp_readcheck(), and tcp_writecheck(). |
|
This is used to set the send/receive buffer size for sockets. It should be below the upper limit on all Unix systems. Definition at line 37 of file niml_stream.c. Referenced by tcp_connect(), and tcp_listen(). |
|
This macro is used so I can replace recv() with something else if I want. Definition at line 41 of file niml_stream.c. Referenced by iochan_recv(), NI_stream_read(), and tcp_alivecheck(). |
|
This macro is used so I can replace send() with something else if I want. Definition at line 45 of file niml_stream.c. Referenced by NI_stream_close_keep(), and NI_stream_write(). |
Function Documentation
|
Add a stream to the open list. Definition at line 79 of file niml_stream.c. References num_open_streams, and realloc. Referenced by NI_stream_open(), and NI_stream_reopen().
00080 { 00081 int nn = num_open_streams ; 00082 00083 if( ns == NULL ) return ; /* bad input */ 00084 00085 open_streams = (NI_stream_type **)realloc( (void *)open_streams , 00086 sizeof(NI_stream_type *)*(nn+1) ); 00087 00088 open_streams[nn] = ns ; num_open_streams++ ; return ; 00089 } |
|
Add a host to the trusted list (internal version). ------------------------------------------------------------------ Definition at line 603 of file niml_stream.c. References host_list, host_num, hostname_dotted(), HSIZE, NI_free, NI_hostname_to_inet(), NI_malloc, and NI_realloc. Referenced by init_trusted_list(), and NI_add_trusted_host().
00604 { 00605 char *hh=NULL ; 00606 int ii ; 00607 00608 if( hnam == NULL || hnam[0] == '\0' ) return ; 00609 00610 if( !hostname_dotted(hnam) ){ /* not a dotted number */ 00611 hh = NI_hostname_to_inet( hnam ) ; /* so do a lookup on it */ 00612 if( hh == NULL ) return ; /* failed? */ 00613 00614 } else if( strlen(hnam) > HSIZE-1 ){ /* something bad? */ 00615 return ; 00616 } else { 00617 hh = hnam ; /* store dotted number */ 00618 } 00619 00620 host_list = NI_realloc(host_list, char*,sizeof(char *)*(host_num+1)) ; 00621 host_list[host_num] = NI_malloc(char, HSIZE) ; 00622 strcpy( host_list[host_num] , hh ) ; host_num++ ; 00623 00624 if( hh != hnam ) NI_free(hh) ; 00625 } |
|
At program exit, close all open streams. Definition at line 113 of file niml_stream.c. References doing_atexit, NI_sleep(), NI_stream_close_keep(), and num_open_streams. Referenced by NI_stream_open().
00114 { 00115 int ii ; 00116 if( doing_atexit ) return ; 00117 doing_atexit = 1 ; 00118 for( ii=0 ; ii < num_open_streams ; ii++ ){ 00119 NI_sleep(2) ; 00120 NI_stream_close_keep( open_streams[ii] , 5 ) ; 00121 } 00122 return ; 00123 } |
|
Check if hostname is in dotted form. ------------------------------------------------------------------ Definition at line 589 of file niml_stream.c. Referenced by add_trusted_host(), and NI_trust_host().
00590 { 00591 int ii, nh ; 00592 if( hnam == NULL ) return 0 ; 00593 nh = strlen(hnam) ; 00594 for( ii=0 ; ii < nh ; ii++ ) 00595 if( !isdigit(hnam[ii]) && hnam[ii] != '.' ) return 0 ; 00596 return 1 ; 00597 } |
|
Initialize trusted list from the internal table and the environment. ---------------------------------------------------------------------------- Definition at line 631 of file niml_stream.c. References add_trusted_host(), getenv(), host_list, host_num, HSIZE, init_hosts, INIT_NHO, and NI_malloc. Referenced by NI_add_trusted_host(), and NI_trust_host().
00632 { 00633 int ii ; 00634 char ename[HSIZE] , *str ; 00635 00636 if( host_num == 0 ){ /** only execute this once **/ 00637 host_num = INIT_NHO ; 00638 host_list = NI_malloc(char*, sizeof(char *) * INIT_NHO ) ; 00639 for( ii=0 ; ii < INIT_NHO ; ii++ ){ 00640 host_list[ii] = NI_malloc(char, HSIZE) ; 00641 strcpy( host_list[ii] , init_hosts[ii] ) ; 00642 } 00643 00644 for( ii=0 ; ii <= 99 ; ii++ ){ 00645 sprintf(ename,"NIML_TRUSTHOST_%02d",ii) ; str = getenv(ename) ; 00646 if( str == NULL && ii <= 9 ){ 00647 sprintf(ename,"NIML_TRUSTHOST_%1d",ii) ; str = getenv(ename) ; 00648 } 00649 if( str == NULL && ii <= 9 ){ 00650 sprintf(ename,"NIML_TRUSTHOST_O%1d",ii) ; str = getenv(ename) ; 00651 } 00652 if( str != NULL ) add_trusted_host(str) ; 00653 } 00654 00655 for( ii=0 ; ii <= 99 ; ii++ ){ 00656 sprintf(ename,"AFNI_TRUSTHOST_%02d",ii) ; str = getenv(ename) ; 00657 if( str == NULL && ii <= 9 ){ 00658 sprintf(ename,"AFNI_TRUSTHOST_%1d",ii) ; str = getenv(ename) ; 00659 } 00660 if( str == NULL && ii <= 9 ){ 00661 sprintf(ename,"AFNI_TRUSTHOST_O%1d",ii) ; str = getenv(ename) ; 00662 } 00663 if( str != NULL ) add_trusted_host(str) ; 00664 } 00665 } 00666 return ; 00667 } |
|
Externally callable routine to add a host to the trusted list. If call with NULL, will just initialize the default trusted host list. ---------------------------------------------------------------------------- Definition at line 675 of file niml_stream.c. References add_trusted_host(), host_num, and init_trusted_list(). Referenced by main(), NI_suck_stream(), and TRUST_addhost().
00676 { 00677 if( host_num == 0 ) init_trusted_list() ; 00678 if( hostname == NULL || hostname[0] == '\0' ) return ; 00679 add_trusted_host(hostname) ; 00680 } |
|
Return the Internet address (in 'dot' format, as a string) given the name of the host. If NULL is returned, some error occurrrrred. The string is NI_malloc()-ed, and should be NI_free()-ed when no longer needed. ------------------------------------------------------------------ Definition at line 569 of file niml_stream.c. References NI_strdup(). Referenced by add_trusted_host(), and NI_trust_host().
00570 { 00571 struct hostent *hostp ; 00572 char * iname = NULL , *str ; 00573 int ll ; 00574 00575 if( host == NULL || host[0] == '\0' ) return NULL ; 00576 00577 hostp = gethostbyname(host) ; if( hostp == NULL ) return NULL ; 00578 00579 str = inet_ntoa(*((struct in_addr *)(hostp->h_addr))) ; 00580 if( str == NULL || str[0] == '\0' ) return NULL ; 00581 00582 iname = NI_strdup(str) ; return iname ; 00583 } |
|
Clear the buffer of a str: writing NI_stream. This is intended to let you write anew without having to close and open again. ------------------------------------------------------------------------- Definition at line 2219 of file niml_stream.c. References NI_stream_type::buf, NI_stream_type::bufsize, NI_stream_type::io_mode, NI_stream_type::nbuf, NI_free, NI_malloc, NI_OUTPUT_MODE, NI_STRING_TYPE, and NI_stream_type::type.
02220 { 02221 if( ns == NULL || 02222 ns->type != NI_STRING_TYPE || 02223 ns->io_mode != NI_OUTPUT_MODE ) return ; /* bad inputs */ 02224 02225 NI_free(ns->buf) ; 02226 ns->nbuf = 0 ; 02227 ns->bufsize = 1 ; 02228 ns->buf = NI_malloc(char, 1) ; /* 1 byte set to zero */ 02229 } |
|
|
Close a NI_stream, but don't free the insides. If (flag&1 != 0) send a "close_this" message to the other end. If (flag&2 != 0) use TCP OOB data to send a SIGURG to the other end. If (flag&4 != 0) don't remove from open_stream list [only from atexit()] ----------------------------------------------------------------------------- Definition at line 2389 of file niml_stream.c. References NI_stream_type::bad, NI_stream_type::buf, CLOSEDOWN, NI_stream_type::fp, NI_stream_type::io_mode, MARKED_FOR_DEATH, NI_FD_TYPE, NI_FILE_TYPE, NI_free, NI_OUTPUT_MODE, NI_REMOTE_TYPE, NI_SHM_TYPE, NI_sleep(), NI_stream_writecheck(), NI_stream_writestring(), NI_STRING_TYPE, NI_TCP_TYPE, NI_stream_type::orig_name, remove_open_stream(), NI_stream_type::sd, SHM_close(), NI_stream_type::shmioc, tcp_send, and NI_stream_type::type. Referenced by atexit_open_streams(), NI_do(), NI_stream_close(), NI_stream_closenow(), NI_stream_kill(), and NI_stream_reopen().
02390 { 02391 if( ns == NULL || !isgraph(ns->orig_name[0]) ) return ; 02392 02393 if( (flag & 4) == 0 ) /* 22 Apr 2005 */ 02394 remove_open_stream( ns ) ; /* 02 Jan 2004 */ 02395 02396 if( ns->bad == MARKED_FOR_DEATH ){ 02397 if( ns->buf != NULL ){ NI_free(ns->buf); ns->buf = NULL;} 02398 return ; 02399 } 02400 02401 /*-- 20 Dec 2002: write a farewell message to the other end? --*/ 02402 02403 if( (flag & 1) != 0 && 02404 (ns->type == NI_TCP_TYPE || ns->type == NI_SHM_TYPE) && 02405 NI_stream_writecheck(ns,1) > 0 ){ 02406 02407 NI_stream_writestring( ns , "<?ni_do ni_verb='close_this' ?>\n" ) ; 02408 NI_sleep(9) ; /* give it an instant to read the message */ 02409 } 02410 02411 /*-- mechanics of closing for different stream types --*/ 02412 02413 switch( ns->type ){ 02414 02415 #ifndef DONT_USE_SHM 02416 case NI_SHM_TYPE: 02417 NI_sleep(9) ; /* 31 Mar 2005 */ 02418 SHM_close( ns->shmioc ) ; /* detach shared memory */ 02419 break ; 02420 #endif 02421 02422 case NI_FD_TYPE: 02423 if( ns->fp != NULL && ns->io_mode == NI_OUTPUT_MODE ) fflush(ns->fp) ; 02424 break ; 02425 02426 case NI_REMOTE_TYPE: 02427 case NI_STRING_TYPE: /* nothing to do */ 02428 break ; 02429 02430 case NI_FILE_TYPE: 02431 if( ns->fp != NULL ) fclose(ns->fp) ; /* close file */ 02432 break ; 02433 02434 case NI_TCP_TYPE: 02435 if( ns->sd >= 0 ){ 02436 if( (flag & 2) != 0 ){ 02437 tcp_send( ns->sd , "X" , 1 , MSG_OOB ) ; /* 02 Jan 2004 */ 02438 NI_sleep(9) ; 02439 } 02440 NI_sleep(2) ; /* 31 Mar 2005 */ 02441 CLOSEDOWN(ns->sd) ; /* close socket */ 02442 } 02443 break ; 02444 } 02445 02446 ns->bad = MARKED_FOR_DEATH ; /* label this as unclean, not to be touched */ 02447 if( (flag & 4) == 0 ){ /* only free buf if program is NOT exiting */ 02448 NI_free(ns->buf) ; ns->buf = NULL ; 02449 } 02450 return ; 02451 } |
|
Close a NI_stream without sending a "close_this" message to the other end of the stream. Definition at line 2469 of file niml_stream.c. References NI_free, and NI_stream_close_keep(). Referenced by AFNI_niml_atexit(), AFNI_niml_workproc(), AFNI_serverlog(), AIVVV_niml_quitter(), AIVVV_workproc(), main(), NI_stream_reopen(), NI_suck_stream(), and NIML_to_stderr().
02470 { 02471 NI_stream_close_keep(ns,0) ; NI_free(ns) ; return ; 02472 } |
|
Try to fill up the stream's input buffer. Don't call this function until NI_stream_goodcheck() is 1!
Definition at line 2865 of file niml_stream.c. References NI_stream_type::buf, NI_stream_type::bufsize, NI_stream_type::nbuf, NI_clock_time(), NI_REMOTE_TYPE, NI_stream_goodcheck(), NI_stream_read(), NI_stream_readcheck(), NI_STRING_TYPE, and NI_stream_type::type. Referenced by NI_decode_one_double(), NI_decode_one_string(), NI_stream_readbuf(), NI_stream_readbuf64(), and scan_for_angles().
02866 { 02867 int nn , ii , ntot=0 , ngood=0 , mwait=0 ; 02868 int start_msec = NI_clock_time() ; 02869 02870 if( NI_stream_goodcheck(ns,0) < 0 ) return -1 ; /* bad input */ 02871 02872 if( ns->type == NI_STRING_TYPE ) return -1 ; /* goofy input */ 02873 if( ns->type == NI_REMOTE_TYPE ) return -1 ; /* goofy input */ 02874 02875 if( ns->nbuf >= ns->bufsize ) return 0 ; /* buffer already full */ 02876 02877 if( msec < 0 ) msec = 999999999 ; /* a long time (11+ days) */ 02878 02879 /* read loop */ 02880 02881 while(1){ 02882 02883 ngood = NI_stream_readcheck(ns,mwait); /* check if data can be read */ 02884 02885 if( ngood < 0 ) break ; /* data stream gone bad, so exit */ 02886 02887 if( ngood > 0 ){ /* we can read ==> */ 02888 /* try to fill buffer completely */ 02889 02890 ii = NI_stream_read( ns, ns->buf+ns->nbuf, ns->bufsize-ns->nbuf ) ; 02891 02892 if( ii > 0 ){ /* we got data! */ 02893 ns->nbuf += ii ; /* buffer is now longer */ 02894 ntot += ii ; /* total bytes read here so far */ 02895 02896 /* if buffer is full, 02897 or we have all the data that was asked for, then exit */ 02898 02899 if( ns->nbuf >= ns->bufsize || ntot >= minread ) break ; 02900 02901 } else if( ii < 0 ){ /* stream suddenly died horribly? */ 02902 ngood = -1 ; break ; 02903 } 02904 } 02905 02906 /* if we don't require data, then exit no matter what our status is */ 02907 02908 if( minread <= 0 ) break ; 02909 02910 /* if the max time has elapsed, then exit */ 02911 02912 if( NI_clock_time()-start_msec >= msec ) break ; 02913 02914 /* otherwise, sleep a little bit before trying again */ 02915 02916 if( mwait < 9 ) mwait++ ; 02917 } 02918 02919 /* if didn't get any data, and 02920 if the NI_stream was bad, return -1 as a flag of displeasure */ 02921 02922 if( ntot == 0 && ngood < 0 ) ntot = -1 ; 02923 02924 return ntot ; /* otherwise, return # of bytes read (may be 0) */ 02925 } |
|
Return the output string buffer for a NI_stream of str: type. If the input is not a "w" str: stream, then NULL is returned. Otherwise a pointer to the internal buffer is returned. This will be a NUL terminated string. ------------------------------------------------------------------------- Definition at line 2204 of file niml_stream.c. References NI_stream_type::bad, NI_stream_type::buf, NI_stream_type::io_mode, MARKED_FOR_DEATH, NI_OUTPUT_MODE, NI_STRING_TYPE, and NI_stream_type::type. Referenced by Dtable_to_nimlstring(), main(), nifti_set_afni_extension(), and SUMA_DsetInfo().
02205 { 02206 if( ns == NULL || 02207 ns->type != NI_STRING_TYPE || 02208 ns->io_mode != NI_OUTPUT_MODE || 02209 ns->bad == MARKED_FOR_DEATH ) return NULL ; /* bad inputs */ 02210 02211 return ns->buf ; 02212 } |
|
Get the input buffer size for a NI_stream. Returns -1 if the stream is bad, or has been sentenced to death. ------------------------------------------------------------------------- Definition at line 2191 of file niml_stream.c. References NI_stream_type::bad, NI_stream_type::bufsize, and MARKED_FOR_DEATH.
02192 { 02193 if( ns == NULL || ns->bad == MARKED_FOR_DEATH ) return -1 ; 02194 return ns->bufsize ; 02195 } |
|
Check if the given NI_stream is properly opened for I/O. If not, wait up to msec milliseconds to establish the connection to the other end; if msec < 0, will wait nearly forever. Returns 1 if ready; 0 if not (but may become good later); -1 if an error occurs. Possible -1 errors are:
Definition at line 2276 of file niml_stream.c. References NI_stream_type::bad, CLOSEDOWN, NI_stream_type::fp, NI_stream_type::io_mode, MARKED_FOR_DEATH, MIN, NI_stream_type::name, NEXTDMS, NI_dpr(), NI_FD_TYPE, NI_FILE_TYPE, NI_free, NI_INPUT_MODE, NI_REMOTE_TYPE, NI_SHM_TYPE, NI_sleep(), NI_stream_readcheck(), NI_STRING_TYPE, NI_strncpy(), NI_TCP_TYPE, NI_stream_type::port, NI_stream_type::sd, SHM_goodcheck(), NI_stream_type::shmioc, tcp_accept(), tcp_alivecheck(), tcp_connect(), tcp_readcheck(), and NI_stream_type::type. Referenced by AFNI_niml_redisplay_CB(), AFNI_niml_viewpoint_CB(), AFNI_niml_workproc(), AIVVV_workproc(), main(), NI_read_columns(), NI_read_element(), NI_stream_fillbuf(), NI_stream_read(), NI_stream_readcheck(), NI_stream_reopen(), NI_stream_writecheck(), NI_suck_stream(), NI_write_columns(), NI_write_element(), NI_write_procins(), SUMA_Engine(), SUMA_niml_workproc(), SUMA_SendToAfni(), and SUMA_SendToSuma().
02277 { 02278 int ii , jj ; 02279 char *bbb ; 02280 02281 /** check inputs for OK-osity **/ 02282 02283 if( ns == NULL || ns->bad == MARKED_FOR_DEATH ) return -1 ; 02284 02285 switch( ns->type ){ 02286 02287 #ifndef DONT_USE_SHM 02288 /** Shared memory **/ 02289 02290 case NI_SHM_TYPE: 02291 return SHM_goodcheck( ns->shmioc , msec ) ; 02292 #endif 02293 02294 /** File I/O [there is never any waiting here] **/ 02295 02296 case NI_FILE_TYPE: 02297 if( ns->fp == NULL ) return -1 ; /* should never happen */ 02298 if( ns->io_mode == NI_INPUT_MODE ) 02299 return NI_stream_readcheck(ns,0) ; /* input mode */ 02300 else 02301 return 1 ; /* output mode */ 02302 02303 case NI_FD_TYPE: 02304 return 1 ; /* no way to check */ 02305 02306 /** String I/O **/ 02307 02308 case NI_STRING_TYPE: 02309 if( ns->io_mode == NI_INPUT_MODE ) 02310 return NI_stream_readcheck(ns,0) ; /* input mode */ 02311 else 02312 return 1 ; /* output mode */ 02313 02314 /** remote Web input */ 02315 02316 case NI_REMOTE_TYPE: 02317 if( ns->io_mode == NI_INPUT_MODE ) 02318 return NI_stream_readcheck(ns,0) ; /* input mode */ 02319 else 02320 return -1 ; /* output mode */ 02321 02322 /** Socket I/O **/ 02323 02324 case NI_TCP_TYPE: 02325 if( ns->bad == 0 ){ /** if good before, then check if is still good **/ 02326 int ich ; 02327 ich = tcp_alivecheck(ns->sd) ; 02328 02329 #ifdef NIML_DEBUG 02330 if( ich == 0 ) /* 17 Jun 2003 */ 02331 NI_dpr("++ Socket %s (port %d) has gone bad!\n",ns->name,ns->port); 02332 #endif 02333 02334 if( ich == 0 ) return -1 ; 02335 return 1 ; 02336 } 02337 02338 /** wasn't good before, so check if that condition has changed **/ 02339 02340 /** TCP/IP waiting to accept call from another host **/ 02341 02342 if( ns->bad == TCP_WAIT_ACCEPT ){ 02343 ii = tcp_readcheck(ns->sd,msec) ; /* see if ready */ 02344 if( ii > 0 ){ /* if socket ready: */ 02345 jj = tcp_accept( ns->sd , NULL,&bbb ) ; /* accept connection */ 02346 if( jj >= 0 ){ /* if accept worked */ 02347 CLOSEDOWN( ns->sd ) ; /* close old socket */ 02348 NI_strncpy(ns->name,bbb,256) ; /* put IP into name */ 02349 NI_free(bbb); ns->bad = 0; ns->sd = jj; /* and ready to go! */ 02350 fcntl( ns->sd, F_SETOWN, (int)getpid() ); /* 02 Jan 2004 */ 02351 } 02352 } 02353 } 02354 02355 /** TCP/IP waiting to connect call to another host **/ 02356 02357 else if( ns->bad == TCP_WAIT_CONNECT ){ 02358 int dms=0 , ms ; 02359 02360 if( msec < 0 ) msec = 999999999 ; /* a long time (11+ days) */ 02361 for( ms=0 ; ms < msec ; ms += dms ){ 02362 ns->sd = tcp_connect( ns->name , ns->port ); /* try to connect */ 02363 if( ns->sd >= 0 ) break ; /* worked? get out */ 02364 dms = NEXTDMS(dms); dms = MIN(dms,msec-ms); NI_sleep(dms); 02365 } 02366 if( ns->sd < 0 ) /* one last try? */ 02367 ns->sd = tcp_connect( ns->name , ns->port ) ; 02368 02369 if( ns->sd >= 0 ) ns->bad = 0 ; /* succeeded? */ 02370 if( ns->sd >= 0 ) 02371 fcntl( ns->sd, F_SETOWN, (int)getpid() ); /* 02 Jan 2004 */ 02372 } 02373 02374 /** see if it turned from bad to good **/ 02375 02376 return (ns->bad == 0) ; 02377 } 02378 02379 return -1 ; /* unreachable, I hope */ 02380 } |
|
Check if the NI_stream has data read to be read, or has data stored in its internal buffer.
Definition at line 2490 of file niml_stream.c. References NI_stream_type::bad, MARKED_FOR_DEATH, NI_stream_type::nbuf, NI_stream_readcheck(), and NI_stream_type::npos. Referenced by AFNI_niml_workproc(), AIVVV_workproc(), NI_read_columns(), and SUMA_niml_workproc().
02491 { 02492 if( ns == NULL || ns->bad == MARKED_FOR_DEATH ) return -1 ; 02493 02494 if( ns->npos < ns->nbuf ) return 1 ; /* check if has data in buffer */ 02495 return NI_stream_readcheck( ns , msec ) ; /* see if any data can be read */ 02496 } |
|
Definition at line 2478 of file niml_stream.c. References NI_free, and NI_stream_close_keep(). Referenced by SUMA_niml_hangup().
02479 { 02480 NI_stream_close_keep(ns,3) ; NI_free(ns) ; return ; 02481 } |
|
Return the name set in the NI_stream header. (This is the pointer to the internal string, so don't free it!) ------------------------------------------------------------------------- Definition at line 2151 of file niml_stream.c. References NI_stream_type::name. Referenced by AFNI_niml_workproc(), and SUMA_niml_workproc().
02152 { 02153 if( ns == NULL ) return NULL ; 02154 return ns->name ; 02155 } |
|
Open a NIML input or output stream, and return a pointer to it.
name = "tcp:host:port" to connect a socket to system "host" on the given port number. One process should open in "w" mode and one in "r" mode. name = "shm:keyname:size1+size2" to connect to a shared memory segment created with "keyname" for the ID and with I/O buffer sizes of size1 ("w" process to "r" process) and size2 ("r" process to "w" process).
name = "http://hostname/filename" to read data from a Web server name = "ftp://hostname/filename" to read data from an FTP server
mode = "w" to open a stream for writing
The inputs "host" (for tcp:) and "filename" (for file:) are limited to a maximum of 127 bytes. For str:, there is no limit for the "r" stream (but clearly you can't have any NUL bytes in there). For shm:, "keyname" is limited to 127 bytes also. Since opening a socket or shared memory segment requires sychronizing two processes, you can't read or write to a tcp: or shm: stream immediately. Instead you have to check if it is "good" first. This can be done using the function NI_stream_goodcheck(). After a tcp: "r" stream is good, then the string ns->name contains the IP address of the connecting host, in "dot" form (e.g., "201.202.203.204"); here, "ns" is the NI_stream returned by this routine.
Definition at line 1609 of file niml_stream.c. References add_open_stream(), atexit(), atexit_is_setup, atexit_open_streams(), NI_stream_type::b64_numleft, NI_stream_type::bad, NI_stream_type::bin_thresh, NI_stream_type::buf, NI_stream_type::bufsize, CLOSEDOWN, fd, fdopen(), NI_stream_type::fp, NI_stream_type::fsize, getenv(), NI_stream_type::goodcheck_time, NI_stream_type::io_mode, NI_stream_type::name, name, NI_stream_type::nbuf, NI_BUFSIZE, NI_FD_TYPE, NI_FILE_TYPE, NI_filesize(), NI_free, NI_INPUT_MODE, NI_malloc, NI_malloc_enable_tracking(), NI_OUTPUT_MODE, NI_read_URL(), NI_REMOTE_TYPE, NI_SHM_TYPE, NI_STRING_TYPE, NI_strlen(), NI_strncpy(), NI_TCP_TYPE, NI_stream_type::npos, NI_stream_type::orig_name, NI_stream_type::port, NI_stream_type::sd, SHM_init(), NI_stream_type::shmioc, sigurg, tcp_accept(), tcp_connect(), tcp_listen(), tcp_readcheck(), tcp_sigurg_handler(), and NI_stream_type::type. Referenced by AFNI_niml_workproc(), AFNI_serverlog(), AFNI_start_version_check(), AFNI_version_check(), AIVVV_workproc(), Dtable_from_nimlstring(), Dtable_to_nimlstring(), DWI_Open_NIML_stream(), main(), NI_do(), NI_read_file_nohead(), NI_stream_reopen(), NI_suck_stream(), nifti_set_afni_extension(), NIML_to_stderr(), open_URL_hpf(), SUMA_DsetInfo(), SUMA_Engine(), SUMA_FakeIt(), SUMA_LoadNimlDset(), SUMA_LoadVisualState(), SUMA_nel_stdout(), SUMA_niml_call(), SUMA_niml_workproc(), SUMA_OpenDrawnROI_NIML(), SUMA_SaveVisualState(), SUMA_SendToSuma(), SUMA_ShowNel(), SUMA_Write_DrawnROI_NIML(), THD_load_3D(), THD_open_3D(), THD_open_nifti(), THD_read_niml_atr(), THD_write_nimlatr(), v2s_write_outfile_niml(), XSAVE_input(), and XSAVE_output().
01610 { 01611 NI_stream_type *ns ; 01612 int do_create , do_accept ; 01613 01614 /** perhaps initialize debug output **/ 01615 01616 #ifdef NIML_DEBUG 01617 if( dfp == NULL ){ 01618 char *eee = getenv("NIML_DEBUG") ; 01619 if( eee != NULL ){ 01620 dfp = (strcmp(eee,"stderr")==0) ? stderr : fopen(eee,"w") ; 01621 if( dfp == NULL ){ dfp = stderr; eee = "stderr [defaulted]"; } 01622 fprintf(stderr,"NIML: debug output to %s\n",eee) ; 01623 } 01624 } 01625 #endif 01626 01627 #ifdef NIML_DEBUG 01628 NI_malloc_enable_tracking() ; 01629 #endif 01630 01631 /** check if inputs are reasonable **/ 01632 01633 if( NI_strlen(name) < 4 ) return NULL ; 01634 01635 if( mode == NULL ) return NULL ; 01636 01637 do_create = (*mode == 'w' || *mode == 'a') ; 01638 do_accept = (*mode == 'r') ; 01639 01640 if( !do_create && !do_accept ) return NULL ; 01641 01642 if( ! atexit_is_setup ){ /* 22 Apr 2005 */ 01643 atexit(atexit_open_streams) ; atexit_is_setup = 1 ; 01644 } 01645 01646 /************************************/ 01647 /***** deal with TCP/IP sockets *****/ 01648 01649 if( strncmp(name,"tcp:",4) == 0 ){ 01650 char host[256] , *hend ; 01651 int port=-1 , ii , jj ; 01652 01653 if( NI_strlen(name) > 127 ) return NULL ; 01654 01655 /** find "host" substring **/ 01656 01657 hend = strstr( name+4 , ":" ) ; 01658 if( hend == NULL || hend-name > 255 ) return NULL ; 01659 01660 for( ii=4 ; name[ii] != ':' ; ii++ ) host[ii-4] = name[ii] ; 01661 host[ii-4] = '\0' ; 01662 01663 /** get "port" number **/ 01664 01665 port = strtol( name+ii+1 , NULL , 10 ) ; 01666 if( port <= 0 ) return NULL ; 01667 01668 /** initialize NI_stream_type output struct **/ 01669 01670 ns = NI_malloc(NI_stream_type, sizeof(NI_stream_type) ) ; 01671 01672 ns->type = NI_TCP_TYPE; /* what kind is this? */ 01673 ns->port = port ; /* save the port # */ 01674 ns->nbuf = 0 ; /* buffer is empty */ 01675 ns->npos = 0 ; /* scan starts at 0 */ 01676 ns->b64_numleft = 0 ; 01677 01678 ns->buf = NI_malloc(char, NI_BUFSIZE) ; 01679 ns->bufsize = NI_BUFSIZE ; 01680 ns->name[0] = '\0' ; 01681 NI_strncpy(ns->orig_name,name,256) ; /* 23 Aug 2002 */ 01682 01683 ns->bin_thresh = -1 ; /* write in text mode */ 01684 01685 /* 02 Jan 2004: setup SIGURG handler for OOB data reception. */ 01686 01687 if( !sigurg ){ signal(SIGURG,tcp_sigurg_handler); sigurg = 1; } 01688 01689 /** attach to incoming call "r" **/ 01690 01691 if( do_accept ){ 01692 ns->io_mode = NI_INPUT_MODE ; 01693 ns->sd = tcp_listen( port ) ; /* set up to listen */ 01694 if( ns->sd < 0 ){ /* error? must die! */ 01695 NI_free(ns->buf); NI_free(ns); return NULL; 01696 } 01697 ns->bad = TCP_WAIT_ACCEPT ; /* not connected yet */ 01698 ii = tcp_readcheck(ns->sd,1) ; /* see if ready */ 01699 if( ii > 0 ){ /* if socket ready: */ 01700 jj = tcp_accept( ns->sd , NULL,&hend ) ; /* accept connection */ 01701 if( jj >= 0 ){ /* if accept worked */ 01702 CLOSEDOWN( ns->sd ) ; /* close old socket */ 01703 NI_strncpy(ns->name,hend,256) ; /* put IP into name */ 01704 NI_free(hend); ns->bad = 0; ns->sd = jj ; /* and ready to go! */ 01705 fcntl( ns->sd, F_SETOWN, (int)getpid() ) ; /* 02 Jan 2004 */ 01706 } 01707 } 01708 01709 add_open_stream(ns) ; /* 02 Jan 2004 */ 01710 ns->goodcheck_time = -99 ; /* 23 Nov 2004 */ 01711 return ns ; 01712 } 01713 01714 /** place an outgoing call "w" **/ 01715 01716 if( do_create ){ 01717 struct hostent *hostp ; 01718 ns->io_mode = NI_OUTPUT_MODE ; 01719 hostp = gethostbyname(host) ; /* lookup host on net */ 01720 if( hostp == NULL ){ /* fails? must die! */ 01721 NI_free(ns->buf); NI_free(ns); return NULL; 01722 } 01723 ns->sd = tcp_connect( host , port ) ; /* connect to host */ 01724 ns->bad = (ns->sd < 0) ? TCP_WAIT_CONNECT : 0 ; /* fails? must wait */ 01725 NI_strncpy(ns->name,host,256) ; /* save the host name */ 01726 if( ns->sd >= 0 ) 01727 fcntl( ns->sd, F_SETOWN, (int)getpid() ) ; /* 02 Jan 2004 */ 01728 01729 add_open_stream(ns) ; /* 02 Jan 2004 */ 01730 ns->goodcheck_time = -99 ; /* 23 Nov 2004 */ 01731 return ns ; 01732 } 01733 return NULL ; /* should never be reached */ 01734 } 01735 01736 #ifndef DONT_USE_SHM 01737 /*********************************************/ 01738 /***** deal with shared memory transport *****/ 01739 01740 if( strncmp(name,"shm:",4) == 0 ){ 01741 SHMioc *ioc ; 01742 01743 if( *mode == 'a' ) mode = "w" ; 01744 ioc = SHM_init( name , mode ) ; /* open segment */ 01745 if( ioc == NULL ) return NULL ; /* this is bad bad bad */ 01746 01747 /** initialize NI_stream_type output **/ 01748 01749 ns = NI_malloc(NI_stream_type, sizeof(NI_stream_type) ) ; 01750 01751 ns->type = NI_SHM_TYPE; /* what kind is this? */ 01752 ns->nbuf = 0 ; /* buffer is empty */ 01753 ns->npos = 0 ; /* scan starts at 0 */ 01754 ns->io_mode = do_create ? NI_OUTPUT_MODE 01755 : NI_INPUT_MODE ; 01756 ns->bad = 0 ; 01757 ns->shmioc = ioc ; 01758 ns->b64_numleft = 0 ; 01759 01760 ns->buf = NI_malloc(char, NI_BUFSIZE) ; 01761 ns->bufsize = NI_BUFSIZE ; 01762 01763 NI_strncpy( ns->name , name , 256 ) ; 01764 01765 NI_strncpy(ns->orig_name,name,256) ; /* 23 Aug 2002 */ 01766 01767 add_open_stream(ns) ; /* 02 Jan 2004 */ 01768 ns->goodcheck_time = -99 ; /* 23 Nov 2004 */ 01769 return ns ; 01770 } 01771 #endif /* DONT_USE_SHM */ 01772 01773 /**********************************/ 01774 /***** deal with simple files *****/ 01775 01776 if( strncmp(name,"file:",5) == 0 ){ 01777 01778 char *fname = name+5 , *fmode ; 01779 FILE *fp ; 01780 01781 if( NI_strlen(name) > 255 || NI_strlen(fname) < 1 ) return NULL ; 01782 01783 if( *mode == 'a' ) fmode = "ab" ; 01784 else fmode = do_create ? (char *)"wb" : (char *)"rb" ; 01785 fp = fopen( fname , fmode ) ; 01786 01787 if( fp == NULL ) return NULL ; 01788 01789 /** initialize NI_stream_type output **/ 01790 01791 ns = NI_malloc(NI_stream_type, sizeof(NI_stream_type) ) ; 01792 01793 ns->type = NI_FILE_TYPE; /* what kind is this? */ 01794 ns->nbuf = 0 ; /* buffer is empty */ 01795 ns->npos = 0 ; /* scan starts at 0 */ 01796 ns->fp = fp ; 01797 ns->io_mode = do_create ? NI_OUTPUT_MODE 01798 : NI_INPUT_MODE ; 01799 ns->bad = 0 ; 01800 ns->b64_numleft = 0 ; 01801 01802 ns->bufsize = do_create ? 16 : NI_BUFSIZE ; 01803 ns->buf = NI_malloc(char, ns->bufsize) ; 01804 01805 NI_strncpy( ns->name , fname , 256 ) ; 01806 01807 NI_strncpy(ns->orig_name,name,256) ; /* 23 Aug 2002 */ 01808 01809 if( ns->io_mode == NI_INPUT_MODE ) /* save the file size */ 01810 ns->fsize = NI_filesize( fname ) ; /* if we are reading */ 01811 else 01812 ns->fsize = -1 ; 01813 01814 add_open_stream(ns) ; /* 02 Jan 2004 */ 01815 ns->goodcheck_time = -99 ; /* 23 Nov 2004 */ 01816 return ns ; 01817 } 01818 01819 /********************************************************************/ 01820 /***** fd: very similar to a file, but we don't have to open it *****/ 01821 01822 if( strncmp(name,"stdin:" ,6) == 0 ) name = "fd:0" ; /* 25 Mar 2003 */ 01823 else if( strncmp(name,"stdout:",7) == 0 ) name = "fd:1" ; 01824 else if( strncmp(name,"stderr:",7) == 0 ) name = "fd:2" ; 01825 01826 if( strncmp(name,"fd:",3) == 0 ){ 01827 int fd=-1 ; FILE *fp ; 01828 01829 sscanf(name+3,"%d",&fd) ; 01830 if( fd < 0 ) return NULL ; /* bad integer */ 01831 01832 switch( fd ){ 01833 default: 01834 fp = fdopen( fd , do_create ? "wb" : "rb" ) ; 01835 if( fp == NULL ) return NULL ; 01836 break ; 01837 01838 case 0: 01839 fp = stdin ; 01840 if( do_create ) return NULL ; 01841 break ; 01842 01843 case 1: 01844 fp = stdout ; 01845 if( !do_create ) return NULL ; 01846 break ; 01847 01848 case 2: 01849 fp = stderr ; 01850 if( !do_create ) return NULL ; 01851 break ; 01852 } 01853 01854 /** initialize NI_stream_type output **/ 01855 01856 ns = NI_malloc(NI_stream_type, sizeof(NI_stream_type) ) ; 01857 01858 ns->type = NI_FD_TYPE; /* what kind is this? */ 01859 ns->nbuf = 0 ; /* buffer is empty */ 01860 ns->npos = 0 ; /* scan starts at 0 */ 01861 ns->fp = fp ; 01862 ns->io_mode = do_create ? NI_OUTPUT_MODE 01863 : NI_INPUT_MODE ; 01864 ns->bad = 0 ; 01865 ns->b64_numleft = 0 ; 01866 01867 ns->bufsize = do_create ? 16 : NI_BUFSIZE ; 01868 ns->buf = NI_malloc(char, ns->bufsize) ; 01869 01870 NI_strncpy( ns->name , name , 256 ) ; 01871 01872 NI_strncpy(ns->orig_name,name,256) ; /* 23 Aug 2002 */ 01873 01874 ns->fsize = -1 ; 01875 01876 add_open_stream(ns) ; /* 02 Jan 2004 */ 01877 ns->goodcheck_time = -99 ; /* 23 Nov 2004 */ 01878 return ns ; 01879 } 01880 01881 /*********************************/ 01882 /***** str: string array I/O *****/ 01883 01884 if( strncmp(name,"str:",4) == 0 ){ 01885 01886 int nn = NI_strlen(name+4) ; /* may be 0 */ 01887 01888 ns = NI_malloc(NI_stream_type, sizeof(NI_stream_type) ) ; 01889 01890 ns->type = NI_STRING_TYPE; /* what kind is this? */ 01891 ns->io_mode = do_create ? NI_OUTPUT_MODE 01892 : NI_INPUT_MODE ; 01893 ns->bad = 0 ; 01894 ns->npos = 0 ; /* scan starts at 0 */ 01895 ns->b64_numleft = 0 ; 01896 01897 /* Note that bufsize == nbuf+1 for str: 01898 This is because we don't count the terminal NUL 01899 in nbuf (number of readable bytes), 01900 but do count it in bufsize (size of the buf array) */ 01901 01902 if( do_accept ){ /* read from stuff after str: */ 01903 ns->nbuf = nn ; 01904 ns->bufsize = nn+1 ; 01905 ns->buf = NI_malloc(char, nn+1) ; 01906 strcpy(ns->buf,name+4) ; 01907 } else { /* write to a string */ 01908 ns->nbuf = 0 ; 01909 ns->bufsize = 1 ; 01910 ns->buf = NI_malloc(char, 1) ; /* 1 byte set to zero */ 01911 } 01912 01913 strcpy( ns->name , "ElvisHasLeftTheBuilding" ) ; 01914 01915 NI_strncpy(ns->orig_name,name,256) ; /* 23 Aug 2002 */ 01916 01917 add_open_stream(ns) ; /* 02 Jan 2004 */ 01918 ns->goodcheck_time = -99 ; /* 23 Nov 2004 */ 01919 return ns ; 01920 } 01921 01922 /*********************************/ 01923 /***** http:// or ftp:// I/O *****/ 01924 01925 if( strncmp(name,"http://",7) == 0 || strncmp(name,"ftp://",6) == 0 ){ 01926 int nn ; 01927 char *data=NULL ; 01928 01929 if( do_create ) return NULL ; /* bad */ 01930 01931 nn = NI_read_URL( name , &data ) ; 01932 01933 if( data == NULL || nn <= 4 ){ /* bad */ 01934 NI_free(data); return NULL; 01935 } 01936 01937 ns = NI_malloc(NI_stream_type, sizeof(NI_stream_type) ) ; 01938 01939 ns->type = NI_REMOTE_TYPE; /* what kind is this? */ 01940 ns->io_mode = NI_INPUT_MODE ; 01941 ns->bad = 0 ; 01942 ns->npos = 0 ; /* scan starts at 0 */ 01943 ns->nbuf = nn ; 01944 ns->bufsize = nn ; 01945 ns->buf = data ; 01946 ns->b64_numleft = 0 ; 01947 01948 NI_strncpy( ns->name , name , 256 ) ; 01949 01950 NI_strncpy(ns->orig_name,name,256) ; /* 23 Aug 2002 */ 01951 01952 add_open_stream(ns) ; /* 02 Jan 2004 */ 01953 ns->goodcheck_time = -99 ; /* 23 Nov 2004 */ 01954 return ns ; 01955 } 01956 01957 return NULL ; /* should never be reached */ 01958 } |
|
Read up to nbytes of data from the NI_stream, into buffer. Returns the number of bytes actually read. For both the case of sockets and files, this may be less than nbytes (may even be 0). If an error occurs and no data is read, -1 is returned. For tcp: streams, if no data is available, this function will wait until something can be read. If this behavior is undesirable, then you should use NI_stream_readcheck() before calling this function in order to see if any data is available. For shm: streams, will return immediately if no data is available. For file: streams, this function simply tries to read from the file. Whether or not it succeeds, it will return immediately. It should never return -1; if it returns 0, this means end-of-file. --------------------------------------------------------------------------- Definition at line 2783 of file niml_stream.c. References NI_stream_type::bad, NI_stream_type::buf, NI_stream_type::fp, NI_stream_type::io_mode, NI_stream_type::nbuf, NI_dpr(), NI_FD_TYPE, NI_FILE_TYPE, NI_OUTPUT_MODE, NI_REMOTE_TYPE, NI_SHM_TYPE, NI_stream_goodcheck(), NI_STRING_TYPE, NI_TCP_TYPE, NI_stream_type::npos, PERROR, NI_stream_type::sd, SHM_recv(), NI_stream_type::shmioc, tcp_readcheck(), tcp_recv, and NI_stream_type::type. Referenced by main(), NI_stream_fillbuf(), and read_URL_http().
02784 { 02785 int ii ; 02786 02787 /** check for reasonable inputs **/ 02788 02789 if( ns == NULL || ns->bad || buffer == NULL || nbytes < 0 ) return -1 ; 02790 02791 if( nbytes == 0 ) return 0 ; 02792 02793 #ifdef NIML_DEBUG 02794 NI_dpr("ENTER NI_stream_read\n") ; 02795 #endif 02796 02797 switch( ns->type ){ 02798 02799 #ifndef DONT_USE_SHM 02800 case NI_SHM_TYPE: 02801 return SHM_recv( ns->shmioc , buffer , nbytes ) ; 02802 #endif 02803 02804 /** tcp: just use recv **/ 02805 02806 case NI_TCP_TYPE: 02807 ii = NI_stream_goodcheck(ns,1) ; if( ii != 1 ) return ii ; 02808 #if 0 02809 /* wait 'till we can read fer shur */ 02810 do{ ii=tcp_readcheck(ns->sd,1); } while( ii==0 ) ; 02811 if( ii < 0 ) return -1 ; 02812 #endif 02813 errno = 0 ; 02814 ii = tcp_recv( ns->sd , buffer , nbytes , 0 ) ; 02815 if( ii == -1 || errno != 0 ) PERROR("NI_stream_read(recv)") ; 02816 #ifdef NIML_DEBUG 02817 NI_dpr(" tcp: got %d/%d bytes ***\n",ii,nbytes) ; 02818 #endif 02819 return ii ; 02820 02821 /** file: just use fread **/ 02822 02823 case NI_FD_TYPE: 02824 case NI_FILE_TYPE: 02825 if( ns->fp == NULL || ns->io_mode == NI_OUTPUT_MODE ) return -1 ; 02826 ii = fread( buffer , 1 , nbytes , ns->fp ) ; 02827 return ii ; 02828 02829 /** str: copy bytes out of the buffer string **/ 02830 02831 case NI_REMOTE_TYPE: 02832 case NI_STRING_TYPE: 02833 if( ns->io_mode == NI_OUTPUT_MODE ) return -1 ; /* bad stream */ 02834 ii = ns->nbuf - ns->npos ; /* how much is left */ 02835 if( ii <= 0 ) return -1 ; /* no data left */ 02836 if( ii > nbytes ) ii = nbytes ; /* amount to copy */ 02837 memcpy( buffer , ns->buf+ns->npos , ii ) ; /* copy it */ 02838 ns->npos += ii ; /* advance position */ 02839 return ii ; 02840 } 02841 02842 return -1 ; /* should not be reached */ 02843 } |
|
Return 1 if it is legal to read from this stream, 0 if it isn't. This doesn't say anything about if it is practical to read at this moment; for that, use NI_stream_readcheck(). ------------------------------------------------------------------------- Definition at line 2126 of file niml_stream.c. References NI_stream_type::bad, NI_stream_type::io_mode, MARKED_FOR_DEATH, NI_INPUT_MODE, NI_SHM_TYPE, NI_TCP_TYPE, and NI_stream_type::type. Referenced by NI_read_columns(), NI_stream_readbuf(), and NI_stream_readbuf64().
02127 { 02128 if( ns == NULL || ns->bad == MARKED_FOR_DEATH ) return 0 ; 02129 if( ns->type == NI_TCP_TYPE || ns->type == NI_SHM_TYPE ) return 1 ; 02130 return (ns->io_mode == NI_INPUT_MODE) ; 02131 } |
|
Buffered read from a NI_stream. Unlike NI_stream_read(), will try to read all nbytes of data, waiting if necessary. Also works through the internal buffer, rather than directly to the stream. Return value is number of bytes read. May be less than nbytes if the stream closed (or was used up) before nbytes of data was read. Will return -1 if something is rotten. ------------------------------------------------------------------------- Definition at line 2937 of file niml_stream.c. References NI_stream_type::buf, NI_stream_type::bufsize, MIN, NI_stream_type::nbuf, NI_REMOTE_TYPE, NI_reset_buffer(), NI_stream_fillbuf(), NI_stream_readable(), NI_STRING_TYPE, NI_stream_type::npos, and NI_stream_type::type. Referenced by NI_binary_to_val(), and NI_read_columns().
02938 { 02939 int ii , jj , bs , nout=0 ; 02940 02941 /** check for reasonable inputs **/ 02942 02943 if( nbytes == 0 ) return 0; /* that was real easy */ 02944 if( buffer == NULL || nbytes < 0 ) return -1; /* stupid caller */ 02945 if( ns->buf == NULL || ns->bufsize == 0 ) return -1; /* shouldn't happen */ 02946 if( !NI_stream_readable(ns) ) return -1; /* stupid stream */ 02947 02948 /* see how many unused bytes are already in the input buffer */ 02949 02950 ii = ns->nbuf - ns->npos ; 02951 02952 if( ii >= nbytes ){ /* have all the data we need already */ 02953 memcpy( buffer , ns->buf + ns->npos , nbytes ) ; 02954 ns->npos += nbytes ; 02955 if( ns->npos == ns->nbuf ) ns->nbuf = ns->npos = 0 ; /* buffer used up */ 02956 return nbytes ; 02957 } 02958 02959 /* copy what data we already have, if any */ 02960 02961 if( ii > 0 ){ 02962 memcpy( buffer , ns->buf + ns->npos , ii ) ; nout = ii ; 02963 } 02964 ns->nbuf = ns->npos = 0 ; /* buffer used up */ 02965 02966 /* input streams with fixed length buffers ==> can't do no more */ 02967 02968 if( ns->type == NI_REMOTE_TYPE || ns->type == NI_STRING_TYPE ) 02969 return (nout > 0) ? nout : -1 ; 02970 02971 /* otherwise, fill the buffer and try again */ 02972 02973 bs = ns->bufsize ; 02974 02975 while( nout < nbytes ){ 02976 02977 jj = MIN( bs , nbytes-nout ) ; /* how much to try to read */ 02978 ii = NI_stream_fillbuf( ns,jj,1666 ) ; /* read into stream buffer */ 02979 02980 if( ii > 0 ){ /* got something */ 02981 ii = ns->nbuf ; /* how much now in buffer */ 02982 if( ii > nbytes-nout ) ii = nbytes-nout ; 02983 memcpy( buffer+nout , ns->buf , ii ) ; nout += ii ; 02984 ns->npos += ii ; NI_reset_buffer( ns ) ; 02985 } else { /* got nothing */ 02986 break ; /* so quit */ 02987 } 02988 } 02989 02990 if( nout == 0 && ii < 0 ) nout = -1 ; /* no data and an I/O error */ 02991 return nout ; 02992 } |
|
Buffered read from a NI_stream, like NI_stream_readbuf, but also:
Definition at line 3004 of file niml_stream.c. References a, B64_decode4, B64_decode_count, B64_goodchar, NI_stream_type::b64_left, NI_stream_type::b64_numleft, NI_stream_type::buf, NI_stream_type::bufsize, c, load_decode_table(), NI_stream_type::nbuf, NI_reset_buffer(), NI_stream_fillbuf(), NI_stream_readable(), and NI_stream_type::npos. Referenced by NI_base64_to_val(), and NI_read_columns().
03005 { 03006 int ii , jj , bs , nout=0 ; 03007 byte a ,b ,c , w,x,y,z ; 03008 byte ag,bg,cg ; 03009 int num_reread , bpos ; 03010 03011 /** check for reasonable inputs **/ 03012 03013 if( nbytes == 0 ) return 0; /* that was real easy */ 03014 if( buffer == NULL || nbytes < 0 ) return -1; /* stupid caller */ 03015 if( ns->buf == NULL || ns->bufsize == 0 ) return -1; /* shouldn't happen */ 03016 if( !NI_stream_readable(ns) ) return -1; /* stupid stream */ 03017 03018 /* are there decoded leftover bytes from a previous call? 03019 if so, use them up first */ 03020 03021 if( ns->b64_numleft > 0 ){ 03022 03023 if( ns->b64_numleft >= nbytes ){ /* have enough leftovers for all! */ 03024 memcpy( buffer , ns->b64_left , nbytes ) ; 03025 ns->b64_numleft -= nbytes ; 03026 if( ns->b64_numleft > 0 ) /* must shift remaining leftovers down */ 03027 memmove( ns->b64_left , ns->b64_left + nbytes , ns->b64_numleft ) ; 03028 return nbytes ; /* done done done! */ 03029 } 03030 03031 /* if here, have a few bytes leftover, but not enough */ 03032 03033 memcpy( buffer , ns->b64_left , ns->b64_numleft ) ; 03034 nout = ns->b64_numleft ; /* how many so far */ 03035 ns->b64_numleft = 0 ; /* have none left now */ 03036 } 03037 03038 /* now need to decode some bytes from the input stream; 03039 this is done 4 input bytes at a time, 03040 which are decoded to 3 output bytes */ 03041 03042 load_decode_table() ; /* prepare for Base64 decoding */ 03043 03044 /** loopback point for reading more data from stream into internal buffer **/ 03045 03046 num_reread = 0 ; 03047 Base64Reread: 03048 ag = bg = cg = 0 ; 03049 num_reread++ ; if( num_reread > 5 ) goto Base64Done ; /* done waiting! */ 03050 03051 /* read more data into buffer, if needed */ 03052 03053 if( num_reread > 1 || ns->nbuf - ns->npos < 4 ){ 03054 NI_reset_buffer(ns) ; /* discard used up data => ns->npos==0 */ 03055 ii = 5 - ns->nbuf ; if( ii <= 1 ) ii = 2 ; 03056 ii = NI_stream_fillbuf( ns , ii , 1666 ) ; 03057 if( ns->nbuf < 4 ) goto Base64Done ; /* can't get no satisfaction! */ 03058 } 03059 03060 /*** Copy valid Base64 bytes out of buffer (skipping others), 03061 converting them to binary as we get full quads, 03062 putting the results into buffer. 03063 03064 Exit loop if we hit a '<' character (end of NIML element), 03065 or hit an '=' character (end of Base64 data stream). 03066 03067 Jump back to Base64Reread (above) if we run out of data in the 03068 buffer before we fulfill the caller's demand for nbytes of output. ***/ 03069 03070 while( 1 ){ 03071 ag = bg = cg = 0 ; 03072 bpos = ns->npos ; /* scan forward in buffer using bpos */ 03073 03074 /* get next valid Base64 character into w; 03075 skip whitespaces and other non-Base64 stuff; 03076 if we hit the end token '<' first, quit; 03077 if we hit the end of the buffer first, need more data */ 03078 03079 w = ns->buf[bpos++] ; 03080 while( !B64_goodchar(w) && w != '<' && bpos < ns->nbuf ) 03081 w = ns->buf[bpos++] ; 03082 ns->npos = bpos-1 ; /** if we have to reread, will start here, at w **/ 03083 if( w == '<' ) goto Base64Done; 03084 if( bpos == ns->nbuf ) goto Base64Reread; /* not enuf data yet */ 03085 03086 /* repeat to fill x */ 03087 03088 x = ns->buf[bpos++] ; 03089 while( !B64_goodchar(x) && x != '<' && bpos < ns->nbuf ) 03090 x = ns->buf[bpos++] ; 03091 if( x == '<' ){ ns->npos = bpos-1; goto Base64Done; } 03092 if( bpos == ns->nbuf ) goto Base64Reread; 03093 03094 /* repeat to fill y */ 03095 03096 y = ns->buf[bpos++] ; 03097 while( !B64_goodchar(y) && y != '<' && bpos < ns->nbuf ) 03098 y = ns->buf[bpos++] ; 03099 if( y == '<' ){ ns->npos = bpos-1; goto Base64Done; } 03100 if( bpos == ns->nbuf ) goto Base64Reread; 03101 03102 /* repeat to fill z */ 03103 03104 z = ns->buf[bpos++] ; 03105 while( !B64_goodchar(z) && z != '<' && bpos < ns->nbuf ) 03106 z = ns->buf[bpos++] ; 03107 if( z == '<' ){ ns->npos = bpos-1; goto Base64Done; } 03108 03109 /* at this point, have w,x,y,z to decode */ 03110 03111 ns->npos = bpos ; /* scan continues at next place in buffer */ 03112 03113 B64_decode4(w,x,y,z,a,b,c) ; /* decode 4 bytes into 3 */ 03114 03115 if( z == '=' ){ /* got to the end of Base64? */ 03116 int nn = B64_decode_count(w,x,y,z) ; /* see how many bytes to save */ 03117 ag = (nn > 0) ; /* a byte is good? */ 03118 bg = (nn > 1) ; /* b byte is good? */ 03119 cg = 0 ; /* c byte is bad!! */ 03120 03121 /* save good bytes into output buffer; 03122 if we reach end of the required number of bytes, we're done */ 03123 03124 if( ag ){ buffer[nout++]=a; ag=0; if(nout >= nbytes) goto Base64Done; } 03125 if( bg ){ buffer[nout++]=b; bg=0; if(nout >= nbytes) goto Base64Done; } 03126 goto Base64Done ; 03127 } 03128 03129 /* not at the end of Base64 => 03130 save bytes, and skip out if we fill up the output array */ 03131 03132 ag = bg = cg = 1 ; /* all 3 bytes are good */ 03133 buffer[nout++]=a; ag=0; if(nout >= nbytes) goto Base64Done; 03134 buffer[nout++]=b; bg=0; if(nout >= nbytes) goto Base64Done; 03135 buffer[nout++]=c; cg=0; if(nout >= nbytes) goto Base64Done; 03136 03137 /* now, loop back to decode the next 4 bytes; 03138 BUT, if we don't have at least 4 bytes in the input buffer, 03139 must do a re-read first! */ 03140 03141 num_reread = 1 ; /* finished at least 1 quad ==> reset penalty clock */ 03142 if( ns->nbuf - ns->npos < 4 ) goto Base64Reread ; 03143 03144 } /* end of while(1) loop */ 03145 03146 /* At this point: 03147 have finished reading and decoding, 03148 have nout bytes in output buffer, 03149 and might have some good bytes left that need to be saved */ 03150 03151 Base64Done: 03152 ns->b64_numleft = 0 ; 03153 if( ag ) ns->b64_left[ ns->b64_numleft++ ] = a ; 03154 if( bg ) ns->b64_left[ ns->b64_numleft++ ] = b ; 03155 if( cg ) ns->b64_left[ ns->b64_numleft++ ] = c ; 03156 03157 return nout ; 03158 } |
|
Check if the NI_stream is ready to have data read out of it. If not, the routine will wait up to msec milliseconds for data to be available. If msec < 0, this routine will wait nearly forever. The return value is 1 if data is ready, 0 if not; -1 will be returned if some unrecoverable error is detected:
Definition at line 2512 of file niml_stream.c. References NI_stream_type::bad, NI_stream_type::fp, NI_stream_type::fsize, NI_stream_type::io_mode, MARKED_FOR_DEATH, NI_stream_type::nbuf, NI_FD_TYPE, NI_FILE_TYPE, NI_OUTPUT_MODE, NI_REMOTE_TYPE, NI_SHM_TYPE, NI_stream_goodcheck(), NI_STRING_TYPE, NI_TCP_TYPE, NI_stream_type::npos, NI_stream_type::sd, SHM_readcheck(), NI_stream_type::shmioc, tcp_alivecheck(), tcp_readcheck(), and NI_stream_type::type. Referenced by main(), NI_read_element(), NI_stream_fillbuf(), NI_stream_goodcheck(), NI_stream_hasinput(), open_URL_hpf(), read_URL_http(), and SUMA_niml_workproc().
02513 { 02514 int ii ; 02515 02516 if( ns == NULL || ns->bad == MARKED_FOR_DEATH ) return -1 ; 02517 02518 switch( ns->type ){ 02519 02520 #ifndef DONT_USE_SHM 02521 case NI_SHM_TYPE: 02522 ii = SHM_readcheck( ns->shmioc , msec ) ; 02523 if( ii > 0 ) ii = 1 ; 02524 return ii ; 02525 #endif 02526 02527 /** tcp: ==> uses the Unix "select" mechanism **/ 02528 02529 case NI_TCP_TYPE: 02530 ii = NI_stream_goodcheck(ns,0) ; /* check if it is connected */ 02531 if( ii == -1 ) return -1 ; /* some error */ 02532 if( ii == 0 ){ /* not good yet */ 02533 ii = NI_stream_goodcheck(ns,msec) ; /* so wait for it to get good */ 02534 if( ii != 1 ) return ii ; /* if still not good, exit */ 02535 } 02536 ii = tcp_alivecheck( ns->sd ) ; /* see if it is still open */ 02537 if( !ii ) return -1 ; /* if not open, error exit */ 02538 ii = tcp_readcheck( ns->sd , msec ) ; /* see if any data is there */ 02539 return ii ; 02540 02541 /** fd: ==> use select, as in tcp: **/ 02542 02543 case NI_FD_TYPE: 02544 ii = tcp_readcheck( fileno(ns->fp) , msec ) ; 02545 return ii ; 02546 02547 /** file: ==> check current file position and length of file **/ 02548 02549 case NI_FILE_TYPE:{ 02550 long f_len , f_pos ; 02551 02552 if( ns->fp == NULL || 02553 ns->io_mode == NI_OUTPUT_MODE ) return -1 ; /* never? */ 02554 02555 f_len = ns->fsize ; /* length of file */ 02556 if( f_len < 0 ) return -1 ; /* file not found (?) */ 02557 02558 f_pos = ftell( ns->fp ) ; /* where are we now? */ 02559 if( f_pos < 0 ) return -1 ; /* should never happen */ 02560 02561 return (f_pos < f_len) ? 1 : -1 ; /* is good or bad, but */ 02562 /* never just neutral */ 02563 } 02564 02565 /** str: ==> check current buffer position **/ 02566 02567 case NI_REMOTE_TYPE: 02568 case NI_STRING_TYPE:{ 02569 if( ns->io_mode == NI_OUTPUT_MODE ) return -1 ; /* never? */ 02570 02571 return (ns->npos < ns->nbuf) ? 1 : -1 ; /* is data left? */ 02572 } 02573 } 02574 02575 return -1 ; /* should never happen */ 02576 } |
|
Re-open a NI_stream on a different channel. This is only possible if the input original stream (ns) is tcp: type.
Return value is 1 if things are OK, 0 if not. Failure can occur because:
Definition at line 1986 of file niml_stream.c. References add_open_stream(), NI_stream_type::bad, getenv(), MARKED_FOR_DEATH, NI_stream_type::name, NI_dpr(), NI_free, NI_stream_close_keep(), NI_stream_closenow(), NI_stream_goodcheck(), NI_stream_open(), NI_stream_write(), NI_strncpy(), NI_TCP_TYPE, NI_stream_type::orig_name, NI_stream_type::port, remove_open_stream(), and NI_stream_type::type. Referenced by DWI_Open_NIML_stream(), main(), and SUMA_niml_call().
01987 { 01988 NI_stream_type *nsnew ; 01989 int typ_new=0 , port_new=0 , jj,kk ; 01990 char msg[1024] ; 01991 01992 /* check inputs for sanity */ 01993 01994 if( ns == NULL || ns->type != NI_TCP_TYPE ) return 0 ; /* bad input stream */ 01995 if( ns->bad == MARKED_FOR_DEATH ) return 0 ; /* really bad */ 01996 if( nname == NULL || nname[0] == '\0' ) return 0 ; /* bad new name */ 01997 01998 if( strncmp(nname,"tcp::",5) == 0 ){ /* new is tcp:? */ 01999 typ_new = NI_TCP_TYPE ; 02000 port_new = strtol(nname+5,NULL,10) ; 02001 if( port_new <= 0 ) return 0 ; /* bad new port */ 02002 if( port_new == ns->port ) return 1 ; /* same as before? */ 02003 #ifndef DONT_USE_SHM 02004 } else if( strncmp(nname,"shm:" ,4) == 0 ){ /* new is shm:? */ 02005 char *eee = getenv("AFNI_NOSHM") ; /* 06 Jun 2003 */ 02006 if( eee != NULL && toupper(*eee) == 'Y' ){ /* shm: is disabled */ 02007 fprintf(stderr,"** NI_stream_reopen: shm is disabled\n"); 02008 return 0 ; 02009 } 02010 if( strstr(ns->orig_name,":localhost:") == NULL ){ /* can't do shm: */ 02011 fprintf(stderr,"** NI_stream_reopen: shm not localhost!\n"); /* but on localhost */ 02012 return 0 ; 02013 } 02014 #endif 02015 } else { 02016 fprintf(stderr,"** NI_stream_reopen: illegal input '%s'\n",nname); 02017 return 0 ; /* bad new name */ 02018 } 02019 02020 #ifdef NIML_DEBUG 02021 NI_dpr("NI_stream_reopen: waiting for original connection to be good\n") ; 02022 #endif 02023 02024 /* wait for existing stream to be connected */ 02025 02026 for( kk=0 ; kk < 10 ; kk++ ){ 02027 jj = NI_stream_goodcheck( ns , 1000 ) ; /* wait 1 sec */ 02028 if( jj > 0 ) break; /* good :-) */ 02029 if( kk == 0 ) 02030 fprintf(stderr,"++ NI_stream_reopen: Waiting for socket connection") ; 02031 else 02032 fprintf(stderr,".") ; 02033 } 02034 if( kk == 10 ){ fprintf(stderr," *Failed*\n"); return 0; } 02035 if( kk > 0 ) fprintf(stderr," *Good*\n") ; 02036 02037 /* open new stream as the writer */ 02038 02039 if( strncmp(nname,"tcp::",5) == 0 ){ 02040 sprintf(msg,"tcp:%s:%d",ns->name,port_new) ; /* old hostname */ 02041 } 02042 #ifndef DONT_USE_SHM 02043 else if( strncmp(nname,"shm:" ,4) == 0 ){ 02044 NI_strncpy(msg,nname,1024) ; 02045 } 02046 #endif 02047 02048 #ifdef NIML_DEBUG 02049 NI_dpr("NI_stream_reopen: opening new stream %s\n",msg) ; 02050 #endif 02051 02052 nsnew = NI_stream_open( msg, "w" ) ; 02053 if( nsnew == NULL ) return 0 ; /* bad :-( */ 02054 02055 /* send message on old stream to other 02056 program, telling it to open the new stream */ 02057 02058 sprintf(msg,"<?ni_do ni_verb='reopen_this' ni_object='%s' ?>\n",nname) ; 02059 kk = strlen(msg) ; 02060 02061 #ifdef NIML_DEBUG 02062 NI_dpr("NI_stream_reopen: sending message %s",msg) ; 02063 #endif 02064 02065 jj = NI_stream_write( ns , msg , kk ) ; 02066 if( jj < kk ){ 02067 NI_stream_closenow(nsnew) ; return 0 ; /* bad write! */ 02068 } 02069 02070 /* now wait for other program to open the new stream */ 02071 02072 #ifdef NIML_DEBUG 02073 NI_dpr("NI_stream_reopen: waiting for new stream to be good\n") ; 02074 #endif 02075 02076 jj = NI_stream_goodcheck( nsnew , 5000 ) ; /* wait up to 5 sec */ 02077 if( jj <= 0 ){ 02078 NI_stream_closenow(nsnew) ; return 0 ; /* never got good */ 02079 } 02080 02081 /* if here, new stream is ready: 02082 close the old stream and replace its 02083 contents with the contents of the new stream */ 02084 02085 #ifdef NIML_DEBUG 02086 NI_dpr("NI_stream_reopen: closing old stream\n") ; 02087 #endif 02088 02089 NI_stream_close_keep(ns,0) ; /* will be removed from open streams list */ 02090 02091 *ns = *nsnew ; 02092 02093 /* 10 Jun 2005: at this point, nsnew is in the open streams list, 02094 but the pointer nsnew is about to die, and so we 02095 must munge the open streams list around now to 02096 make sure that nsnew is removed and ns is re-added! */ 02097 02098 remove_open_stream(nsnew) ; NI_free(nsnew) ; add_open_stream(ns) ; 02099 02100 return 1 ; /* :-) */ 02101 } |
|
Seek file: stream to a specific offset location.
Definition at line 2109 of file niml_stream.c. References NI_stream_type::bad, NI_stream_type::fp, MARKED_FOR_DEATH, NI_stream_type::nbuf, NI_FILE_TYPE, NI_stream_type::npos, offset, and NI_stream_type::type.
02110 { 02111 if( ns == NULL || 02112 ns->bad == MARKED_FOR_DEATH || 02113 ns->type != NI_FILE_TYPE || 02114 ns->fp == NULL ) return ; 02115 02116 fseek( ns->fp , offset , whence ) ; /* seek file */ 02117 ns->nbuf = ns->npos = 0 ; /* clear buffer */ 02118 } |
|
Reset the input string buffer for a NI_stream of str: type. If the input is not a "r" str: stream, then nothing happens. Otherwise, the current contents of the buffer are discarded, and the buffer is replaced with a copy of the input string. ------------------------------------------------------------------------- Definition at line 2238 of file niml_stream.c. References NI_stream_type::bad, NI_stream_type::buf, NI_stream_type::bufsize, NI_stream_type::io_mode, MARKED_FOR_DEATH, NI_stream_type::nbuf, NI_free, NI_INPUT_MODE, NI_malloc, NI_STRING_TYPE, NI_strlen(), NI_stream_type::npos, and NI_stream_type::type. Referenced by Dtable_from_nimlstring(), and THD_open_nifti().
02239 { 02240 int nn ; 02241 02242 if( ns == NULL || 02243 ns->type != NI_STRING_TYPE || 02244 ns->io_mode != NI_INPUT_MODE || 02245 str == NULL || 02246 ns->bad == MARKED_FOR_DEATH ) return ; /* bad inputs */ 02247 02248 NI_free(ns->buf) ; /* take out the trash */ 02249 nn = NI_strlen(str) ; /* size of new buffer string */ 02250 ns->nbuf = nn ; /* set num char in new buffer */ 02251 ns->npos = 0 ; /* reset scan position */ 02252 ns->bufsize = nn+1 ; /* allow space for NUL byte */ 02253 ns->buf = NI_malloc(char, nn+1) ; /* and make the buffer */ 02254 strcpy(ns->buf,str) ; /* and set its contents */ 02255 return ; 02256 } |
|
Alter the input buffer size for a NI_stream.
Definition at line 2165 of file niml_stream.c. References NI_stream_type::bad, NI_stream_type::buf, NI_stream_type::bufsize, NI_stream_type::io_mode, MARKED_FOR_DEATH, NI_stream_type::nbuf, NI_FD_TYPE, NI_FILE_TYPE, NI_INPUT_MODE, NI_realloc, NI_SHM_TYPE, NI_STRING_TYPE, NI_TCP_TYPE, and NI_stream_type::type. Referenced by AFNI_niml_workproc(), and THD_read_niml_atr().
02166 { 02167 char *qbuf ; 02168 if( ns == NULL || 02169 ns->type == NI_STRING_TYPE || 02170 ns->bad == MARKED_FOR_DEATH || 02171 bs < 666 || 02172 bs < ns->nbuf ) return -1 ; /* bad inputs */ 02173 02174 if( !( ns->type == NI_TCP_TYPE || ns->type == NI_SHM_TYPE || 02175 (ns->type == NI_FILE_TYPE && ns->io_mode == NI_INPUT_MODE) || 02176 (ns->type == NI_FD_TYPE && ns->io_mode == NI_INPUT_MODE) ) ) 02177 return -1 ; 02178 02179 qbuf = NI_realloc( ns->buf , char , bs ) ; 02180 if( qbuf == NULL ) return -1 ; /* this is bad */ 02181 ns->buf = qbuf ; 02182 ns->bufsize = bs ; 02183 return 1 ; 02184 } |
|
Send nbytes of data from buffer down the NI_stream. Return value is the number of bytes actually sent, or is -1 if some error occurs (which means that the NI_stream is bad). If 0 is returned, this means you tried to write to something that is temporarily unavailable.
Definition at line 2674 of file niml_stream.c. References NI_stream_type::bad, NI_stream_type::buf, NI_stream_type::bufsize, NI_stream_type::fp, MARKED_FOR_DEATH, NI_stream_type::nbuf, NI_dpr(), NI_FD_TYPE, NI_FILE_TYPE, NI_realloc, NI_REMOTE_TYPE, NI_SHM_TYPE, NI_stream_writecheck(), NI_STRING_TYPE, NI_TCP_TYPE, nosigpipe, PERROR, NI_stream_type::sd, SHM_sendall(), NI_stream_type::shmioc, tcp_send, tcp_writecheck(), and NI_stream_type::type. Referenced by AFNI_serverlog(), main(), NI_stream_reopen(), NI_stream_writestring(), NI_write_columns(), NI_write_element(), and open_URL_hpf().
02675 { 02676 int ii , nsent ; 02677 02678 /** check for reasonable inputs **/ 02679 02680 if( ns == NULL || ns->bad || 02681 buffer == NULL || nbytes < 0 || ns->bad == MARKED_FOR_DEATH ) return -1; 02682 02683 if( nbytes == 0 ) return 0 ; /* that was easy */ 02684 02685 #ifdef NIML_DEBUG 02686 NI_dpr("ENTER NI_stream_write\n") ; 02687 #endif 02688 02689 if( ns->type != NI_TCP_TYPE ){ 02690 ii = NI_stream_writecheck(ns,66) ; /* check if stream is still OK */ 02691 if( ii < 0 ) return ii ; /* if not, vamoose the ranch */ 02692 } 02693 02694 switch( ns->type ){ 02695 02696 #ifndef DONT_USE_SHM 02697 case NI_SHM_TYPE: 02698 return SHM_sendall( ns->shmioc , buffer , nbytes ) ; 02699 #endif 02700 02701 /** tcp: ==> just use send **/ 02702 02703 case NI_TCP_TYPE: 02704 02705 if( ns->bad ) return 0 ; /* socket not ready yet */ 02706 02707 /* turn off SIGPIPE signals, which will otherwise be 02708 raised if we send to a socket when the other end has crashed */ 02709 02710 if( !nosigpipe ){ signal(SIGPIPE,SIG_IGN); nosigpipe = 1; } 02711 02712 #if 0 02713 /* 03 Mar 2002: wait until we can write fer shur */ 02714 do{ ii=tcp_writecheck(ns->sd,1) ; } while(ii==0) ; 02715 if( ii < 0 ) return -1 ; 02716 #endif 02717 02718 errno = 0 ; 02719 nsent = tcp_send( ns->sd , buffer , nbytes , 0 ) ; 02720 if( nsent < nbytes || errno != 0 ) PERROR("NI_stream_write(send)") ; 02721 if( nsent == 0 ){ fprintf(stderr,"tcp send: 0/%d\n",nbytes); nsent=-1; } 02722 return nsent ; 02723 02724 /** file: ==> just fwrite **/ 02725 02726 case NI_FD_TYPE: 02727 case NI_FILE_TYPE: 02728 #ifdef NIML_DEBUG 02729 NI_dpr(" file: about to write %d bytes\n",nbytes) ; 02730 #endif 02731 nsent = fwrite( buffer , 1 , nbytes , ns->fp ) ; 02732 if( nsent < nbytes ) PERROR("NI_stream_write(fwrite)") ; 02733 #ifdef NIML_DEBUG 02734 NI_dpr(" file: actually wrote %d bytes\n",nsent) ; 02735 #endif 02736 if( nsent == 0 ) nsent = -1 ; 02737 fflush(ns->fp) ; 02738 return nsent ; 02739 02740 /** str: ==> append to buffer in stream struct **/ 02741 02742 case NI_STRING_TYPE: 02743 #ifdef NIML_DEBUG 02744 NI_dpr("NI_stream_write str: input=%s\n",ns->buf) ; 02745 #endif 02746 ns->buf = NI_realloc( ns->buf , char , ns->bufsize+nbytes ) ; 02747 memcpy( ns->buf+ns->nbuf , buffer , nbytes ) ; 02748 ns->nbuf += nbytes ; ns->buf[ns->nbuf] = '\0' ; 02749 ns->bufsize += nbytes ; 02750 #ifdef NIML_DEBUG 02751 NI_dpr("NI_stream_write str: output=%s\n",ns->buf) ; 02752 #endif 02753 return nbytes ; 02754 02755 /** ftp: or http: ==> can't write! */ 02756 02757 case NI_REMOTE_TYPE: 02758 return -1 ; 02759 } 02760 02761 return -1 ; /* should not be reached */ 02762 } |
|
Return 1 if it is legal to write to this stream, 0 if it isn't. This doesn't say anything about if it is practical to write at this moment; for that, use NI_stream_writecheck(). ------------------------------------------------------------------------- Definition at line 2139 of file niml_stream.c. References NI_stream_type::bad, NI_stream_type::io_mode, MARKED_FOR_DEATH, NI_OUTPUT_MODE, NI_SHM_TYPE, NI_TCP_TYPE, and NI_stream_type::type. Referenced by NI_stream_writecheck(), NI_write_columns(), NI_write_element(), and NI_write_procins().
02140 { 02141 if( ns == NULL || ns->bad == MARKED_FOR_DEATH ) return 0 ; 02142 if( ns->type == NI_TCP_TYPE || ns->type == NI_SHM_TYPE ) return 1 ; 02143 return (ns->io_mode == NI_OUTPUT_MODE) ; 02144 } |
|
Check if the NI_stream is ready to have data written into it. If not, the routine will wait up to msec milliseconds for writing to be allowable. If msec < 0, this routine will wait nearly forever. The return value is 1 if data can be sent, 0 if not; -1 will be returned if some unrecoverable error is detected:
Definition at line 2590 of file niml_stream.c. References NI_stream_type::bad, NI_stream_type::fp, NI_stream_type::io_mode, NI_FD_TYPE, NI_FILE_TYPE, NI_OUTPUT_MODE, NI_REMOTE_TYPE, NI_SHM_TYPE, NI_stream_goodcheck(), NI_stream_writeable(), NI_STRING_TYPE, NI_TCP_TYPE, NI_stream_type::sd, SHM_writecheck(), NI_stream_type::shmioc, tcp_writecheck(), and NI_stream_type::type. Referenced by AFNI_serverlog(), DWI_Open_NIML_stream(), main(), NI_stream_close_keep(), NI_stream_write(), NI_write_columns(), NI_write_element(), NI_write_procins(), open_URL_hpf(), and SUMA_niml_call().
02591 { 02592 int ii ; 02593 02594 if( !NI_stream_writeable(ns) ) return -1 ; 02595 02596 switch( ns->type ){ 02597 02598 #ifndef DONT_USE_SHM 02599 case NI_SHM_TYPE: 02600 ii = SHM_writecheck( ns->shmioc , msec ) ; 02601 if( ii > 0 ) ii = 1 ; 02602 return ii ; 02603 #endif 02604 02605 /** tcp: ==> uses the Unix "select" mechanism **/ 02606 02607 case NI_TCP_TYPE: 02608 if( ns->bad ){ /* not marked as good */ 02609 ii = NI_stream_goodcheck(ns,0) ; /* check if has become good */ 02610 if( ii == -1 ) return -1 ; /* some error when checking */ 02611 if( ii == 0 ){ /* not good yet, */ 02612 ii = NI_stream_goodcheck(ns,msec); /* so wait for it to get good */ 02613 if( ii != 1 ) return ii ; /* if still not good, exit */ 02614 } 02615 } 02616 /* socket is good, so */ 02617 return tcp_writecheck(ns->sd,msec) ; /* check if we can write bytes */ 02618 02619 /** fd: ==> use select, as in tcp: **/ 02620 02621 case NI_FD_TYPE: 02622 return tcp_writecheck( fileno(ns->fp) , msec ) ; 02623 02624 /** file: ==> if the file was opened in write mode **/ 02625 02626 case NI_FILE_TYPE: 02627 return ( (ns->fp != NULL && ns->io_mode == NI_OUTPUT_MODE) ? 1 02628 : -1 ) ; 02629 02630 /** str: ==> if the string was opened in write mode **/ 02631 02632 case NI_STRING_TYPE: 02633 return ( (ns->io_mode == NI_OUTPUT_MODE) ? 1 02634 : -1 ) ; 02635 /** http: or ftp: **/ 02636 02637 case NI_REMOTE_TYPE: /* can't write to remote files */ 02638 return -1 ; 02639 } 02640 02641 return -1 ; /* should never be reached */ 02642 } |
|
Send a string (without the NUL byte) down the NI_stream. [15 Oct 2002] ------------------------------------------------------------------------------ Definition at line 2648 of file niml_stream.c. References NI_stream_write(). Referenced by NI_stream_close_keep(), NI_write_columns(), NI_write_element(), NI_write_procins(), nifti_set_afni_extension(), and THD_write_nimlatr().
02649 { 02650 if( str == NULL ) return -1 ; 02651 return NI_stream_write( ns , str , strlen(str) ) ; 02652 } |
|
Return 1 if we like hostid, 0 if we don't. ----------------------------------------------------------------------------- Definition at line 686 of file niml_stream.c. References getenv(), host_list, host_num, hostname_dotted(), init_trusted_list(), NI_free, and NI_hostname_to_inet(). Referenced by tcp_accept().
00687 { 00688 int ii ; 00689 char *hh = hostid ; 00690 00691 /* if the trusted list is empty, 00692 see if we want to be completely trusting; 00693 if not, then initialize the trusted list and then check */ 00694 00695 if( host_num == 0 ){ 00696 char *eee = getenv("NIML_COMPLETE_TRUST") ; 00697 if( eee != NULL && toupper(*eee) == 'Y' ) return 1 ; /* complete trust */ 00698 init_trusted_list() ; 00699 } 00700 00701 if( hostid == NULL || hostid[0] == '\0' ) return 0 ; 00702 00703 if( !hostname_dotted(hostid) ){ 00704 hh = NI_hostname_to_inet(hostid) ; /* will be NI_malloc()-ed */ 00705 if( hh == NULL ) return 0 ; 00706 } 00707 00708 /* to be trusted, hostid must start with same 00709 string as something in the trusted host_list array */ 00710 00711 for( ii=0 ; ii < host_num ; ii++ ){ 00712 if( strstr(hh,host_list[ii]) == hh ){ 00713 if( hh != hostid ) NI_free(hh) ; 00714 return 1 ; 00715 } 00716 } 00717 00718 if( hh != hostid ) NI_free(hh) ; 00719 return 0 ; 00720 } |
|
Remove a stream from the open list. Definition at line 94 of file niml_stream.c. References doing_atexit, and num_open_streams. Referenced by NI_stream_close_keep(), and NI_stream_reopen().
00095 { 00096 int nn = num_open_streams , ii,jj ; 00097 00098 if( doing_atexit || nn <= 0 || ns == NULL ) return ; /* bad input */ 00099 00100 for( ii=0 ; ii < nn ; ii++ ) /* find input */ 00101 if( open_streams[ii] == ns ) break ; 00102 if( ii == nn ) return ; /* not found!? */ 00103 00104 for( jj=ii+1 ; jj < nn ; jj++ ) /* move those above down */ 00105 open_streams[jj-1] = open_streams[jj] ; 00106 00107 open_streams[nn-1] = NULL ; num_open_streams-- ; return ; 00108 } |
|
Get a pre-existing shmem segment. Returns the shmid >= 0 if successful; returns -1 if failure. ----------------------------------------------------------------- Definition at line 755 of file niml_stream.c. References key, and SHM_string_to_key(). Referenced by SHM_goodcheck(), and SHM_init().
00756 { 00757 key_t key ; 00758 int shmid ; 00759 00760 key = SHM_string_to_key( key_string ) ; 00761 shmid = shmget( key , 0 , 0777 ) ; 00762 return shmid ; 00763 } |
|
Check if the shmem segment is alive (has 2 attached processes). Returns 0 if not alive, 1 if life is happy. --------------------------------------------------------------------------- Definition at line 1073 of file niml_stream.c. References SHM_nattach(). Referenced by SHM_goodcheck().
01074 { 01075 if( shmid < 0 ) return 0 ; 01076 return (SHM_nattach(shmid) == 2) ; 01077 } |
|
Actually attach to the shmem segment. Returns the pointer to the segment start. NULL is returned if an error occurs. ----------------------------------------------------------------- Definition at line 787 of file niml_stream.c. References PERROR. Referenced by SHM_fill_accept(), and SHM_init().
00788 { 00789 char *adr ; 00790 adr = (char *) shmat( shmid , NULL , 0 ) ; 00791 if( adr == (char *) -1 ){ adr = NULL ; PERROR("SHM_attach") ; } 00792 return adr ; 00793 } |
|
Close a SHMioc. Note that this will free what ioc points to. ------------------------------------------------------------------------- Definition at line 1170 of file niml_stream.c. References SHMioc::bad, SHMioc::id, NI_free, SHM_IS_DEAD, and SHMioc::shmbuf. Referenced by NI_stream_close_keep().
01171 { 01172 if( ioc == NULL ) return ; 01173 01174 if( ioc->id >= 0 && ioc->bad != SHM_IS_DEAD ){ 01175 shmdt( ioc->shmbuf ) ; /* detach */ 01176 shmctl( ioc->id , IPC_RMID , NULL ) ; /* delete */ 01177 ioc->bad = SHM_IS_DEAD ; /* leave for dead */ 01178 } 01179 01180 NI_free(ioc) ; return ; 01181 } |
|
Connect to, or create if needed, a shmem segment. Returns the shmid >= 0 if successful; returns -1 if failure. ----------------------------------------------------------------- Definition at line 770 of file niml_stream.c. References key, PERROR, and SHM_string_to_key(). Referenced by SHM_init().
00771 { 00772 key_t key ; 00773 int shmid ; 00774 00775 key = SHM_string_to_key( key_string ) ; 00776 shmid = shmget( key , size , 0777 | IPC_CREAT ) ; 00777 if( shmid < 0 ) PERROR("SHM_create") ; 00778 return shmid ; 00779 } |
|
Fill a SHMioc struct that has just been attached as an "r".
Definition at line 858 of file niml_stream.c. References SHMioc::bad, SHMioc::bend1, SHMioc::bend2, SHMioc::bstart1, SHMioc::bstart2, SHMioc::buf1, SHMioc::buf2, SHMioc::bufsize1, SHMioc::bufsize2, SHMioc::id, NI_sleep(), SHM_attach(), SHM_BEND1, SHM_BEND2, SHM_BSTART1, SHM_BSTART2, SHM_HSIZE, SHM_IS_DEAD, SHM_nattach(), SHM_size(), SHM_SIZE1, SHM_SIZE2, SHMioc::shmbuf, and SHMioc::shmhead. Referenced by SHM_goodcheck(), and SHM_init().
00859 { 00860 char *bbb ; 00861 int jj ; 00862 00863 if( ioc == NULL || ioc->id < 0 ) return -1 ; /* bad inputs? */ 00864 00865 NI_sleep(2) ; /* wait a bit */ 00866 bbb = SHM_attach( ioc->id ) ; /* attach it */ 00867 if( bbb == NULL ) return -1 ; /* can't? quit */ 00868 00869 if( SHM_nattach(ioc->id) != 2 ){ /* 2 processes? */ 00870 NI_sleep(10) ; /* wait a bit, */ 00871 if( SHM_nattach(ioc->id) != 2 ){ /* and try again */ 00872 shmdt( bbb ) ; /* this is bad! */ 00873 shmctl( ioc->id , IPC_RMID , NULL ) ; 00874 ioc->bad = SHM_IS_DEAD ; return -1 ; 00875 } 00876 } 00877 00878 jj = SHM_size(ioc->id) ; /* shmbuf size */ 00879 if( jj <= SHM_HSIZE ){ /* too small? */ 00880 shmdt( bbb ) ; /* this is bad! */ 00881 shmctl( ioc->id , IPC_RMID , NULL ) ; 00882 ioc->bad = SHM_IS_DEAD ; return -1 ; 00883 } 00884 00885 ioc->shmbuf = bbb ; /* buffer */ 00886 ioc->shmhead = (int *) bbb ; /* buffer as int */ 00887 00888 ioc->bufsize1 = ioc->shmhead[SHM_SIZE1] ; /* size of buf 1 */ 00889 ioc->bstart1 = ioc->shmhead + SHM_BSTART1 ; /* start marker 1*/ 00890 ioc->bend1 = ioc->shmhead + SHM_BEND1 ; /* end marker 1 */ 00891 ioc->buf1 = ioc->shmbuf + SHM_HSIZE ; /* buffer 1 */ 00892 00893 ioc->bufsize2 = ioc->shmhead[SHM_SIZE2] ; /* size of buf 2 */ 00894 ioc->bstart2 = ioc->shmhead + SHM_BSTART2 ; /* start marker 2*/ 00895 ioc->bend2 = ioc->shmhead + SHM_BEND2 ; /* end marker 2 */ 00896 ioc->buf2 = ioc->buf1 + ioc->bufsize1 ; /* buffer 2 */ 00897 00898 if( jj < SHM_HSIZE+ioc->bufsize1+ioc->bufsize2 ){ /* too small? */ 00899 shmdt( bbb ) ; /* this is bad! */ 00900 shmctl( ioc->id , IPC_RMID , NULL ) ; 00901 ioc->bad = SHM_IS_DEAD ; return -1 ; 00902 } 00903 00904 ioc->bad = 0 ; return 1 ; /** DONE **/ 00905 } |
|
Check if the given SHMioc is ready for I/O. If not, wait up to msec milliseconds to establish the connection to the other end; if msec < 0, will wait indefinitely. Returns 1 if ready; 0 if not; -1 if an error occurs. Possible errors are: + SHMioc was connected, and now has become disconnected + SHMioc is passed in as NULL --------------------------------------------------------------------------- Definition at line 1094 of file niml_stream.c. References SHMioc::bad, SHMioc::goodcheck_time, SHMioc::id, MIN, SHMioc::name, NEXTDMS, NI_clock_time(), NI_dpr(), NI_sleep(), SHM_accept(), SHM_alivecheck(), SHM_fill_accept(), SHM_IS_DEAD, SHM_nattach(), and SHMioc::shmbuf. Referenced by NI_stream_goodcheck(), SHM_readcheck(), SHM_recv(), SHM_send(), and SHM_writecheck().
01095 { 01096 int ii , jj , ct ; 01097 char *bbb ; 01098 01099 /** check inputs for OK-osity **/ 01100 01101 if( ioc == NULL || ioc->bad == SHM_IS_DEAD ) return -1 ; 01102 01103 /** if it was good before, then check if it is still good **/ 01104 01105 if( ioc->bad == 0 ){ 01106 ct = NI_clock_time() ; 01107 if( ct - ioc->goodcheck_time > 2 ){ /* 23 Nov 2004 */ 01108 ii = SHM_alivecheck(ioc->id) ; 01109 ioc->goodcheck_time = ct ; 01110 } else { 01111 ii = 1 ; 01112 } 01113 if( ii <= 0 ){ /* has died */ 01114 #ifdef NIML_DEBUG 01115 NI_dpr("++ Shared memory connection %s has gone bad!\n", 01116 ioc->name ) ; 01117 #endif 01118 shmdt( ioc->shmbuf ) ; ioc->bad = SHM_IS_DEAD ; 01119 shmctl( ioc->id , IPC_RMID , NULL ) ; return -1 ; 01120 } 01121 return 1 ; 01122 } 01123 01124 /** wasn't good before, so check if that condition has changed **/ 01125 01126 /** shm "r" process waiting for creation by the "w" process **/ 01127 01128 if( ioc->bad == SHM_WAIT_CREATE ){ 01129 int dms=0 , ms ; 01130 01131 if( msec < 0 ) msec = 999999999 ; /* a long time (11+ days) */ 01132 for( ms=0 ; ms < msec ; ms += dms ){ 01133 ioc->id = SHM_accept( ioc->name ) ; /* try to attach to shmem segment */ 01134 if( ioc->id >= 0 ) break ; /* works? break out */ 01135 dms = NEXTDMS(dms) ; dms = MIN(dms,msec-ms) ; NI_sleep(dms) ; 01136 } 01137 if( ioc->id < 0 ) /* one last try? */ 01138 ioc->id = SHM_accept( ioc->name ) ; 01139 01140 if( ioc->id >= 0 ){ /* found it? */ 01141 jj = SHM_fill_accept( ioc ) ; /* fill struct */ 01142 if( jj < 0 ) return -1 ; /* this is bad */ 01143 ioc->bad = 0 ; /* mark as ready */ 01144 return 1 ; 01145 } 01146 return 0 ; 01147 } 01148 01149 /** shmem "w" process waiting for "r" process to attach */ 01150 01151 else if( ioc->bad == SHM_WAIT_ACCEPT ){ 01152 int dms=0 , ms ; 01153 01154 if( msec < 0 ) msec = 999999999 ; /* a long time (11+ days) */ 01155 for( ms=0 ; ms < msec ; ms += dms ){ 01156 if( SHM_nattach(ioc->id) > 1 ){ ioc->bad = 0 ; return 1 ; } 01157 dms = NEXTDMS(dms) ; dms = MIN(dms,msec-ms) ; NI_sleep(dms) ; 01158 } 01159 if( SHM_nattach(ioc->id) > 1 ){ ioc->bad = 0 ; return 1 ; } 01160 return 0 ; 01161 } 01162 01163 return 0 ; /* should never be reached */ 01164 } |
|
Create a SHMioc struct for use as a 2-way I/O channel, and return a pointer to it. NULL is returned if an error occurs. name = "shm:name:size1+size2" to connect a shared memory segment with buffers of length size1 and size2 bytes. The creator process will write to the size1 buffer and read from the size2 buffer. The acceptor process will reverse this.
The input "name" is limited to a maximum of 127 bytes. ----------------------------------------------------------------- Definition at line 927 of file niml_stream.c. References SHMioc::bad, SHMioc::bend1, SHMioc::bend2, SHMioc::bstart1, SHMioc::bstart2, SHMioc::buf1, SHMioc::buf2, SHMioc::bufsize1, SHMioc::bufsize2, SHMioc::goodcheck_time, SHMioc::id, key, SHMioc::name, name, NI_free, NI_malloc, NI_sleep(), SHM_accept(), SHM_ACCEPTOR, SHM_attach(), SHM_BEND1, SHM_BEND2, SHM_BSTART1, SHM_BSTART2, SHM_create(), SHM_CREATOR, SHM_DEFAULT_SIZE, SHM_fill_accept(), SHM_HSIZE, SHM_nattach(), SHM_SIZE1, SHM_SIZE2, SHMioc::shmbuf, SHMioc::shmhead, and SHMioc::whoami. Referenced by NI_stream_open().
00928 { 00929 SHMioc *ioc ; 00930 int do_create , do_accept ; 00931 char key[128] , *kend ; 00932 int size1=SHM_DEFAULT_SIZE , ii , jj , size2=SHM_DEFAULT_SIZE ; 00933 00934 /** check if inputs are reasonable **/ 00935 00936 if( name == NULL || 00937 strlen(name) > 127 || 00938 strncmp(name,"shm:",4) != 0 || 00939 mode == NULL ) return NULL ; 00940 00941 do_create = (*mode == 'w') ; /* writer */ 00942 do_accept = (*mode == 'r') ; /* reader */ 00943 00944 if( !do_create && !do_accept ) return NULL ; 00945 00946 /** get keystring (after "shm:") **/ 00947 00948 for( ii=4 ; name[ii] != ':' && name[ii] != '\0' ; ii++ ) 00949 key[ii-4] = name[ii] ; 00950 key[ii-4] = '\0' ; 00951 00952 /** get size1 (after "shm:name:"), if we stopped at a ':' **/ 00953 00954 if( do_create && name[ii] == ':' && name[ii+1] != '\0' ){ 00955 00956 size1 = strtol( name+ii+1 , &kend , 10 ) ; 00957 if( size1 <= 0 ) size1 = SHM_DEFAULT_SIZE ; 00958 else { 00959 if( *kend == 'K' || *kend == 'k' ){ size1 *= 1024 ; kend++; } 00960 else if( *kend == 'M' || *kend == 'm' ){ size1 *= 1024*1024; kend++; } 00961 } 00962 size2 = size1 ; /* 23 Aug 2002 */ 00963 00964 /** get size2, if we stopped at a + **/ 00965 00966 if( *kend == '+' ){ 00967 size2 = strtol( kend+1 , &kend , 10 ) ; 00968 if( size2 <= 0 ) size2 = SHM_DEFAULT_SIZE ; 00969 else { 00970 if( *kend == 'K' || *kend == 'k' ){ size2 *= 1024 ; kend++; } 00971 else if( *kend == 'M' || *kend == 'm' ){ size2 *= 1024*1024; kend++; } 00972 } 00973 } 00974 } 00975 00976 /** initialize SHMioc **/ 00977 00978 ioc = NI_malloc(SHMioc, sizeof(SHMioc) ) ; 00979 00980 strcpy( ioc->name , key ) ; /* save the key name */ 00981 00982 /** attach to existing shmem segment **/ 00983 00984 if( do_accept ){ 00985 ioc->whoami = SHM_ACCEPTOR ; 00986 for( ii=0 ; ii < 4 ; ii++ ){ /* try to find segment */ 00987 ioc->id = SHM_accept( key ) ; /* several times */ 00988 if( ioc->id >= 0 ) break ; /* works? break out */ 00989 NI_sleep(ii+1) ; /* wait 1 millisecond */ 00990 } 00991 if( ioc->id < 0 ) 00992 ioc->id = SHM_accept( key ) ; /* 1 last try? */ 00993 00994 if( ioc->id < 0 ){ /* failed to find segment? */ 00995 ioc->bad = SHM_WAIT_CREATE ; /* mark for waiting */ 00996 return ioc ; /* and we are DONE for now */ 00997 ioc->goodcheck_time = -99 ; /* 23 Nov 2004 */ 00998 00999 } else { /* found it? */ 01000 01001 jj = SHM_fill_accept( ioc ) ; /* fill struct */ 01002 01003 if( jj < 0 ){ /* this is bad */ 01004 NI_free(ioc); return NULL; 01005 } 01006 01007 return ioc ; /** DONE **/ 01008 ioc->goodcheck_time = -99 ; /* 23 Nov 2004 */ 01009 } 01010 } 01011 01012 /** create a new shmem segment **/ 01013 01014 if( do_create ){ 01015 char *bbb ; 01016 01017 ioc->whoami = SHM_CREATOR ; 01018 ioc->id = SHM_create( key, size1+size2+SHM_HSIZE+4 ) ; /* create it */ 01019 if( ioc->id < 0 ){ /* can't? quit */ 01020 NI_free(ioc); return NULL; 01021 } 01022 bbb = SHM_attach( ioc->id ) ; /* attach it */ 01023 if( bbb == NULL ){ /* can't? quit */ 01024 NI_free(ioc); return NULL; 01025 } 01026 01027 ioc->shmbuf = bbb ; /* buffer */ 01028 ioc->shmhead = (int *) bbb ; /* buffer as int */ 01029 01030 ioc->bufsize1 = ioc->shmhead[SHM_SIZE1] = size1 ; /* size of buf 1 */ 01031 ioc->bstart1 = ioc->shmhead + SHM_BSTART1 ; /* start marker 1*/ 01032 ioc->bend1 = ioc->shmhead + SHM_BEND1 ; /* end marker 1 */ 01033 ioc->buf1 = ioc->shmbuf + SHM_HSIZE ; /* buffer 1 */ 01034 01035 ioc->bufsize2 = ioc->shmhead[SHM_SIZE2] = size2 ; /* size of buf 2 */ 01036 ioc->bstart2 = ioc->shmhead + SHM_BSTART2 ; /* start marker 2*/ 01037 ioc->bend2 = ioc->shmhead + SHM_BEND2 ; /* end marker 2 */ 01038 ioc->buf2 = ioc->buf1 + size1 ; /* buffer 2 */ 01039 01040 *(ioc->bstart1) = 0 ; /* init markers 1*/ 01041 *(ioc->bend1) = size1-1 ; 01042 *(ioc->bstart2) = 0 ; /* init markers 2*/ 01043 *(ioc->bend2) = size2-1 ; 01044 01045 NI_sleep(3) ; 01046 jj = SHM_nattach(ioc->id) ; /* # processes */ 01047 01048 if( jj < 2 ){ 01049 NI_sleep(3) ; jj = SHM_nattach(ioc->id) ; 01050 } 01051 01052 if( jj > 2 ){ /* should not */ 01053 shmdt( bbb ) ; /* happen ever */ 01054 shmctl( ioc->id , IPC_RMID , NULL ) ; 01055 NI_free(ioc); return NULL; 01056 } 01057 01058 ioc->bad = (jj < 2) /* ready if both */ 01059 ? SHM_WAIT_ACCEPT /* processes are */ 01060 : 0 ; /* attached to shm */ 01061 ioc->goodcheck_time = -99 ; /* 23 Nov 2004 */ 01062 return ioc ; 01063 } 01064 01065 return NULL ; /* should never be reached */ 01066 } |
|
Find the number of attaches to a shmem segment. Returns -1 if an error occurs. ----------------------------------------------------------------- Definition at line 816 of file niml_stream.c. References calloc, free, getenv(), NI_sleep(), and PERROR. Referenced by SHM_alivecheck(), SHM_fill_accept(), SHM_goodcheck(), and SHM_init().
00817 { 00818 int ii ; 00819 static struct shmid_ds buf ; 00820 char *eee = getenv( "NIML_DNAME" ) ; 00821 00822 if( shmid < 0 ) return -1 ; 00823 ii = shmctl( shmid , IPC_STAT , &buf ) ; 00824 if( ii < 0 ){ 00825 if( eee != NULL ) fprintf(stderr,"SHM_nattach: trying again!\n") ; 00826 NI_sleep(9) ; 00827 ii = shmctl( shmid , IPC_STAT , &buf ) ; 00828 } 00829 if( ii < 0 ){ 00830 char *ppp ; 00831 if( eee != NULL ){ 00832 ppp = (char *)calloc(1,strlen(eee)+32) ; 00833 strcpy(ppp,"SHM_nattach (") ; 00834 strcat(ppp,eee) ; strcat(ppp,")") ; 00835 } else { 00836 ppp = strdup("SHM_nattach") ; 00837 } 00838 PERROR(ppp); 00839 fprintf(stderr,"%s: called shmctl(%x,%x,%p), got %d\n", 00840 ppp,(unsigned int)shmid, (unsigned int)IPC_STAT, (void *)&buf, 00841 ii ) ; 00842 free((void *)ppp); return -1; 00843 } else if( eee != NULL ){ 00844 fprintf(stderr,"SHM_nattach (%s): called shmctl(%x,%x,%p), got %d\n", 00845 eee, 00846 (unsigned int)shmid, (unsigned int)IPC_STAT, (void *)&buf, 00847 (int)buf.shm_nattch ) ; 00848 } 00849 return (int)buf.shm_nattch ; 00850 } |
|
Check if the SHMioc is ready to have data read out of it. If not, the routine will wait up to msec milliseconds for data to be available. If msec < 0, this routine will wait indefinitely. For shmem segments, the return value is how many bytes can be read (0 if none are available). -1 will be returned if some unrecoverable error is detected. ----------------------------------------------------------------------------- Definition at line 1192 of file niml_stream.c. References SHMioc::bad, SHMioc::bend1, SHMioc::bend2, SHMioc::bstart1, SHMioc::bstart2, SHMioc::bufsize1, SHMioc::bufsize2, SHMioc::goodcheck_time, MIN, NEXTDMS, NI_clock_time(), NI_sleep(), SHM_ACCEPTOR, SHM_CREATOR, SHM_goodcheck(), and SHMioc::whoami. Referenced by NI_stream_readcheck().
01193 { 01194 int ii , ct ; 01195 int nread , dms=0 , ms ; 01196 int *bstart, *bend , bsize ; /* for the chosen buffer */ 01197 01198 /** check if the SHMioc is good **/ 01199 01200 ct = NI_clock_time() ; 01201 if( ct - ioc->goodcheck_time > 2 ){ /* 23 Nov 2004 */ 01202 ii = SHM_goodcheck(ioc,0) ; 01203 ioc->goodcheck_time = ct ; 01204 if( ii <= 0 ){ /* not good yet */ 01205 ii = SHM_goodcheck(ioc,msec) ; /* so wait for it to get good */ 01206 if( ii <= 0 ) return ii ; /* if still not good, exit */ 01207 } 01208 } else if( ioc->bad ) return 0 ; 01209 01210 /** choose buffer from which to read **/ 01211 01212 switch( ioc->whoami ){ 01213 01214 default: return -1 ; /* should never happen */ 01215 01216 case SHM_ACCEPTOR: 01217 bstart = ioc->bstart1 ; 01218 bend = ioc->bend1 ; 01219 bsize = ioc->bufsize1 ; 01220 break ; 01221 01222 case SHM_CREATOR: 01223 bstart = ioc->bstart2 ; 01224 bend = ioc->bend2 ; 01225 bsize = ioc->bufsize2 ; 01226 break ; 01227 } 01228 01229 /** must loop and wait **/ 01230 01231 if( msec < 0 ) msec = 999999999 ; /* a long time (11+ days) */ 01232 01233 /** Compute the number of readable bytes into nread. **/ 01234 01235 for( ms=0 ; ms < msec ; ms += dms ){ 01236 nread = (*bend - *bstart + bsize + 1) % bsize ; 01237 if( nread > 0 ) return nread ; 01238 dms = NEXTDMS(dms) ; dms = MIN(dms,msec-ms) ; NI_sleep(dms) ; 01239 ii = SHM_goodcheck(ioc,0) ; if( ii == -1 ) return -1 ; 01240 } 01241 nread = (*bend - *bstart + bsize + 1) % bsize ; 01242 if( nread > 0 ) return nread ; 01243 return 0 ; 01244 } |
|
Read up to nbytes of data from the SHMioc, into buffer. Returns the number of bytes actually read. This may be less than nbytes (may even be 0). If an error occurs, -1 is returned. ------------------------------------------------------------------------------ Definition at line 1416 of file niml_stream.c. References SHMioc::bad, SHMioc::bend1, SHMioc::bend2, SHMioc::bstart1, SHMioc::bstart2, SHMioc::buf1, SHMioc::buf2, SHMioc::bufsize1, SHMioc::bufsize2, SHM_ACCEPTOR, SHM_CREATOR, SHM_goodcheck(), and SHMioc::whoami. Referenced by NI_stream_read().
01417 { 01418 int *bstart, *bend , bsize ; /* for the chosen buffer */ 01419 char *buf ; 01420 int nread, sbot,stop , ii ; 01421 01422 /** check for reasonable inputs **/ 01423 01424 if( ioc == NULL || ioc->bad || 01425 buffer == NULL || nbytes < 0 ) return -1 ; 01426 01427 if( nbytes == 0 ) return 0 ; 01428 01429 ii = SHM_goodcheck(ioc,1) ; 01430 if( ii <= 0 ) return ii ; 01431 01432 /** choose buffer from which to read **/ 01433 01434 switch( ioc->whoami ){ 01435 01436 default: return -1 ; /* should never happen */ 01437 01438 case SHM_ACCEPTOR: 01439 bstart = ioc->bstart1 ; 01440 bend = ioc->bend1 ; 01441 bsize = ioc->bufsize1 ; 01442 buf = ioc->buf1 ; 01443 break ; 01444 01445 case SHM_CREATOR: 01446 bstart = ioc->bstart2 ; 01447 bend = ioc->bend2 ; 01448 bsize = ioc->bufsize2 ; 01449 buf = ioc->buf2 ; 01450 break ; 01451 } 01452 01453 /** read from the circular buffer, starting at bstart **/ 01454 01455 nread = ( *bend - *bstart + bsize + 1 ) % bsize ; /* readable amount */ 01456 if( nread <= 0 ) return 0 ; /* nothing!? */ 01457 if( nread > nbytes ) nread = nbytes ; /* amount to read */ 01458 01459 sbot = *bstart ; stop = sbot + nread-1 ; /* from sbot to stop */ 01460 01461 if( stop < bsize ){ /* 1 piece to copy */ 01462 memcpy( buffer, buf+sbot, nread ) ; /* copy the data */ 01463 *bstart = (stop+1) % bsize ; /* move bstart up */ 01464 } else { /* 2 pieces to copy */ 01465 int nn = bsize - sbot ; /* size of piece 1 */ 01466 memcpy( buffer , buf + sbot, nn ) ; /* copy piece 1 */ 01467 memcpy( buffer+nn, buf , nread-nn ) ; /* copy piece 2 */ 01468 *bstart = nread-nn ; /* move bstart up */ 01469 } 01470 return nread ; 01471 } |
|
Send nbytes of data from buffer down the SHMioc. Return value is the number of bytes actually sent, or is -1 if some error occurs. ------------------------------------------------------------------------------ Definition at line 1309 of file niml_stream.c. References SHMioc::bad, SHMioc::bend1, SHMioc::bend2, SHMioc::bstart1, SHMioc::bstart2, SHMioc::buf1, SHMioc::buf2, SHMioc::bufsize1, SHMioc::bufsize2, SHM_ACCEPTOR, SHM_CREATOR, SHM_goodcheck(), SHM_writecheck(), and SHMioc::whoami. Referenced by SHM_sendall().
01310 { 01311 int ii ; 01312 int nread,nwrite , ebot,etop ; 01313 int *bstart, *bend , bsize ; /* for the chosen buffer */ 01314 char *buf ; 01315 01316 /** check for reasonable inputs **/ 01317 01318 if( ioc == NULL || ioc->bad || 01319 buffer == NULL || nbytes < 0 ) return -1 ; 01320 01321 if( nbytes == 0 ) return 0 ; /* stupid user */ 01322 01323 ii = SHM_goodcheck(ioc,1) ; /* can't send if it ain't good */ 01324 if( ii <= 0 ) return ii ; 01325 01326 ii = SHM_writecheck(ioc,1) ; /* is something is writeable? */ 01327 if( ii <= 0 ) return ii ; 01328 01329 /** choose buffer in which to write **/ 01330 01331 switch( ioc->whoami ){ 01332 01333 default: return -1 ; /* should never happen */ 01334 01335 case SHM_ACCEPTOR: 01336 bstart = ioc->bstart2 ; 01337 bend = ioc->bend2 ; 01338 bsize = ioc->bufsize2 ; 01339 buf = ioc->buf2 ; 01340 break ; 01341 01342 case SHM_CREATOR: 01343 bstart = ioc->bstart1 ; 01344 bend = ioc->bend1 ; 01345 bsize = ioc->bufsize1 ; 01346 buf = ioc->buf1 ; 01347 break ; 01348 } 01349 01350 /** write into the circular buffer, past "bend" **/ 01351 01352 nread = ( *bend - *bstart + bsize + 1 ) % bsize; /* amount readable */ 01353 nwrite = bsize - 1 - nread ; /* amount writeable */ 01354 if( nwrite <= 0 ) return 0 ; /* can't write! */ 01355 01356 if( nwrite > nbytes ) nwrite = nbytes ; /* how much to write */ 01357 01358 ebot = *bend+1 ; if( ebot >= bsize ) ebot = 0 ; /* start at ebot */ 01359 etop = ebot+nwrite-1 ; /* end at etop */ 01360 01361 if( etop < bsize ){ /* 1 piece to copy */ 01362 memcpy( buf + ebot, buffer, nwrite ) ; /* copy data */ 01363 *bend = etop ; /* change bend */ 01364 } else { /* 2 pieces to copy */ 01365 int nn = bsize - ebot ; /* size of piece 1 */ 01366 memcpy( buf + ebot, buffer , nn ) ; /* copy piece 1 */ 01367 memcpy( buf , buffer+nn, nwrite-nn ) ; /* copy piece 2 */ 01368 *bend = nwrite-nn-1 ; /* change bend */ 01369 } 01370 return nwrite ; 01371 } |
|
Send (exactly) nbytes of data from the buffer down the SHMioc. The only difference between this and SHM_send is that this function will not return until all the data is sent, even if it takes forever. Under these circumstances, it would be good if the reader process is still working. ------------------------------------------------------------------------------ Definition at line 1381 of file niml_stream.c. References SHMioc::bad, NEXTDMS, NI_sleep(), and SHM_send(). Referenced by NI_stream_write().
01382 { 01383 int ii , ntot=0 , dms=0 ; 01384 01385 /** check for reasonable inputs **/ 01386 01387 if( ioc == NULL || ioc->bad || 01388 buffer == NULL || nbytes < 0 ) return -1 ; 01389 01390 if( nbytes == 0 ) return 0 ; 01391 01392 while(1){ 01393 ii = SHM_send( ioc , buffer+ntot , nbytes-ntot ); /* send what's left */ 01394 if( ii == -1 ) return -1 ; /* an error!? */ 01395 01396 if( ii == 0 ){ /* nothing sent? */ 01397 dms = NEXTDMS(dms) ; 01398 } else { /* sent something! */ 01399 ntot += ii ; /* total sent so far */ 01400 if( ntot >= nbytes ) return nbytes ; /* all done!? */ 01401 dms = 1 ; 01402 } 01403 01404 NI_sleep(dms) ; /* wait a bit */ 01405 } 01406 return -1 ; /* should never be reached */ 01407 } |
|
Find the size of a shmem segment. Returns -1 if an error occurs. ----------------------------------------------------------------- Definition at line 800 of file niml_stream.c. References PERROR. Referenced by SHM_fill_accept().
00801 { 00802 int ii ; 00803 struct shmid_ds buf ; 00804 00805 if( shmid < 0 ) return -1 ; 00806 ii = shmctl( shmid , IPC_STAT , &buf ) ; 00807 if( ii < 0 ){ PERROR("SHM_size") ; return -1 ; } 00808 return buf.shm_segsz ; 00809 } |
|
Convert a string to a key, for IPC operations. ----------------------------------------------------------------- Definition at line 732 of file niml_stream.c. Referenced by SHM_accept(), and SHM_create().
00733 { 00734 int ii , sum ; 00735 key_t kk ; 00736 00737 sum = 987654321 ; 00738 if( key_string == NULL ) return (key_t) sum ; 00739 00740 for( ii=0 ; key_string[ii] != '\0' ; ii++ ) 00741 sum += ((int)key_string[ii]) << ((ii%3)*8) ; 00742 00743 kk = (key_t) sum ; 00744 #ifdef IPC_PRIVATE 00745 if( kk == IPC_PRIVATE || kk <= 0 ) kk = 666 ; 00746 #endif 00747 return kk ; 00748 } |
|
Check if the SHMioc is ready to have data written into it. If not, the routine will wait up to msec milliseconds for writing to be allowable. If msec < 0, this routine will wait indefinitely. The return value is the number of bytes that can be sent (0 if none, positive if some). -1 will be returned if some unrecoverable error is detected. ----------------------------------------------------------------------------- Definition at line 1255 of file niml_stream.c. References SHMioc::bend1, SHMioc::bend2, SHMioc::bstart1, SHMioc::bstart2, SHMioc::bufsize1, SHMioc::bufsize2, MIN, NEXTDMS, NI_sleep(), SHM_ACCEPTOR, SHM_CREATOR, SHM_goodcheck(), and SHMioc::whoami. Referenced by NI_stream_writecheck(), and SHM_send().
01256 { 01257 int ii ; 01258 int nread , dms=0 , ms , nwrite ; 01259 int *bstart, *bend , bsize ; /* for the chosen buffer */ 01260 01261 /** check if the SHMioc is good **/ 01262 01263 ii = SHM_goodcheck(ioc,0) ; 01264 if( ii == -1 ) return -1 ; /* some error */ 01265 if( ii == 0 ){ /* not good yet */ 01266 ii = SHM_goodcheck(ioc,msec) ; /* so wait for it to get good */ 01267 if( ii <= 0 ) return ii ; /* if still not good, exit */ 01268 } 01269 01270 /** choose buffer to which to write **/ 01271 01272 switch( ioc->whoami ){ 01273 01274 default: return -1 ; /* should never happen */ 01275 01276 case SHM_ACCEPTOR: 01277 bstart = ioc->bstart2 ; 01278 bend = ioc->bend2 ; 01279 bsize = ioc->bufsize2 ; 01280 break ; 01281 01282 case SHM_CREATOR: 01283 bstart = ioc->bstart1 ; 01284 bend = ioc->bend1 ; 01285 bsize = ioc->bufsize1 ; 01286 break ; 01287 } 01288 01289 if( msec < 0 ) msec = 999999999 ; /* a long time (11+ days) */ 01290 01291 for( ms=0 ; ms < msec ; ms += dms ){ 01292 nread = (*bend - *bstart + bsize + 1) % bsize ; 01293 nwrite = bsize - 1 - nread ; 01294 if( nwrite > 0 ) return nwrite ; 01295 dms = NEXTDMS(dms) ; dms = MIN(dms,msec-ms) ; NI_sleep(dms) ; 01296 ii = SHM_goodcheck(ioc,0) ; if( ii == -1 ) return -1 ; 01297 } 01298 nread = (*bend - *bstart + bsize + 1) % bsize ; 01299 nwrite = bsize - 1 - nread ; 01300 if( nwrite > 0 ) return nwrite ; 01301 return 0 ; 01302 } |
|
Accept incoming connection on a socket. Return value is the attached socket (which is not the original socket!). If -1 is returned, some error occured. If the accept works, then the original socket is still open and listening for further attachments. Under many circumstances, you will want to close the original socket immediately. This can be done with CLOSEDOWN(sd), where sd is the input socket. If hostname is not NULL, then the char * it points to will be filled with a pointer to the official name of the host that connected. If hostaddr is not NULL, then the char * it points to will be filled with a pointer to the Internet address (in 'dot' form) of the host that connected. Both the char * pointers returned are from NI_malloc(), and should be NI_free()-d when no longer needed. If they aren't needed at all, just pass in NULL for these arguments. Note that this routine will block until somebody connects. You can use tcp_readcheck(sd,0) to see if anyone is waiting to connect before calling this routine. However, if someone connects and the IP address isn't on the trusted list, then the connection will be closed immediately. --------------------------------------------------------------------------- Definition at line 508 of file niml_stream.c. References CLOSEDOWN, NI_strdup(), NI_trust_host(), PERROR, and tcp_set_cutoff().
00509 { 00510 struct sockaddr_in pin ; 00511 int addrlen , sd_new ; 00512 struct hostent *hostp ; 00513 char *str ; 00514 00515 /** accept the connection **/ 00516 00517 addrlen = sizeof(pin) ; 00518 sd_new = accept( sd , (struct sockaddr *)&pin , &addrlen ) ; 00519 if( sd_new == -1 ){ PERROR("tcp_accept"); return -1; } 00520 00521 /** get dotted form address of connector **/ 00522 00523 str = inet_ntoa( pin.sin_addr ) ; 00524 00525 if( !NI_trust_host(str) ){ 00526 fprintf(stderr,"\n** ILLEGAL attempt to connect from host %s\n",str) ; 00527 CLOSEDOWN( sd_new ) ; 00528 return -1 ; 00529 } 00530 00531 if( hostaddr != NULL ) *hostaddr = NI_strdup(str) ; 00532 00533 /** get name of connector **/ 00534 00535 if( hostname != NULL ){ 00536 hostp = gethostbyaddr( (char *) (&pin.sin_addr) , 00537 sizeof(struct in_addr) , AF_INET ) ; 00538 00539 if( hostp != NULL ) *hostname = NI_strdup(hostp->h_name) ; 00540 else *hostname = NI_strdup("UNKNOWN") ; /* bad lookup */ 00541 } 00542 00543 tcp_set_cutoff( sd_new ) ; /* let it die quickly, we hope */ 00544 return sd_new ; 00545 } |
|
Check if an already active socket is still alive. If it is dead, then readcheck will say we can read, but we won't actually get any bytes when we try (using peek mode). Returns 1 if things are OK, 0 if not. --------------------------------------------------------------------- Definition at line 303 of file niml_stream.c. References PERROR, tcp_readcheck(), and tcp_recv.
00304 { 00305 int ii ; 00306 char bbb[4] ; 00307 00308 ii = tcp_readcheck(sd,0) ; /* can I read? */ 00309 if( ii == 0 ) return 1 ; /* can't read is OK */ 00310 if( ii < 0 ) return 0 ; /* some error is bad */ 00311 errno = 0 ; 00312 ii = tcp_recv( sd , bbb , 1 , MSG_PEEK ) ; /* try to read one byte */ 00313 if( ii == 1 ) return 1 ; /* if we get it, good */ 00314 if( errno ) PERROR("tcp_alivecheck") ; 00315 return 0 ; /* no data ==> death! */ 00316 } |
|
Open a socket to the given host, to the given TCP port. This function is used to "reach out" to a server that is supposed to be listening on the same port. Returns socket id; if -1, some error occured (e.g., nobody listening). -------------------------------------------------------------------------- Definition at line 326 of file niml_stream.c. References CLOSEDOWN, getenv(), l, NI_dpr(), PERROR, q, socket, SOCKET_BUFSIZE, and tcp_set_cutoff().
00327 { 00328 int sd , l , q,qq ; 00329 struct sockaddr_in sin ; 00330 struct hostent *hostp ; 00331 00332 if( host == NULL || port < 1 ) return -1 ; /* bad inputs */ 00333 00334 #ifdef NIML_DEBUG 00335 NI_dpr("Enter tcp_connect: host=%s port=%d\n",host,port) ; 00336 #endif 00337 00338 /** open a socket **/ 00339 00340 sd = socket( AF_INET , SOCK_STREAM , 0 ) ; 00341 if( sd == -1 ){ PERROR("tcp_connect(socket)"); return -1; } 00342 00343 /** set socket options (no delays, large buffers) **/ 00344 00345 #if 0 00346 { char *eee=getenv( "NIML_TCP_NAGLE" ) ; 00347 if( eee == NULL || toupper(*eee) != 'Y' ){ 00348 /** disable the Nagle algorithm **/ 00349 l = 1; 00350 setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, (void *)&l, sizeof(int)) ; 00351 } 00352 } 00353 #endif 00354 00355 /* but large buffers are good */ 00356 00357 #ifdef SOCKET_BUFSIZE 00358 q = 0 ; qq = sizeof(int) ; /* 03 Dec 2002: */ 00359 getsockopt(sd, SOL_SOCKET, SO_SNDBUF, (void *)&q, &qq ) ; /* only modify */ 00360 if( q < SOCKET_BUFSIZE ){ /* if current buffer */ 00361 l = SOCKET_BUFSIZE ; /* is too small */ 00362 setsockopt(sd, SOL_SOCKET, SO_SNDBUF, (void *)&l, sizeof(int)) ; 00363 } 00364 q = 0 ; qq = sizeof(int) ; 00365 getsockopt(sd, SOL_SOCKET, SO_RCVBUF, (void *)&q, &qq ) ; 00366 if( q < SOCKET_BUFSIZE ){ 00367 l = SOCKET_BUFSIZE ; 00368 setsockopt(sd, SOL_SOCKET, SO_RCVBUF, (void *)&l, sizeof(int)) ; 00369 } 00370 #endif 00371 00372 /** set port on remote computer **/ 00373 00374 memset( &sin , 0 , sizeof(sin) ) ; 00375 sin.sin_family = AF_INET ; 00376 sin.sin_port = htons(port) ; 00377 00378 /** set remote computer IP address from its name **/ 00379 00380 hostp = gethostbyname(host) ; 00381 if( hostp == NULL ){ 00382 PERROR("tcp_connect(gethostbyname)"); 00383 #ifdef NIML_DEBUG 00384 NI_dpr(" tcp_connect: can't gethostbyname(); errno=%d\n",errno); 00385 #endif 00386 CLOSEDOWN(sd); return -1; 00387 } 00388 sin.sin_addr.s_addr = ((struct in_addr *)(hostp->h_addr))->s_addr ; 00389 00390 errno = 0 ; 00391 if( connect(sd,(struct sockaddr *)&sin,sizeof(sin)) != 0 ){ 00392 if( errno != ECONNREFUSED ) PERROR("tcp_connect(connect)") ; 00393 #ifdef NIML_DEBUG 00394 NI_dpr(" tcp_connect: can't connect(); errno=%d\n",errno); 00395 #endif 00396 CLOSEDOWN(sd); return -1; 00397 } 00398 00399 #ifdef NIML_DEBUG 00400 NI_dpr(" tcp_connect: connected!\n"); 00401 #endif 00402 00403 tcp_set_cutoff( sd ) ; 00404 return sd ; 00405 } |
|
Set up to listen for a connection on a given port. This is intended for use by a server, which will wait for some other program to actively connect to this port. There is no security here - connections will be taken from any IP address. This function does not actually form the connection. That must be done separately. Whether someone is trying to connect can be checked for with the routine "tcp_readcheck" and then accepted with "tcp_accept". The return value is the descriptor for the listening socket. ---------------------------------------------------------------------------- Definition at line 421 of file niml_stream.c. References CLOSEDOWN, getenv(), l, PERROR, q, socket, SOCKET_BUFSIZE, and tcp_set_cutoff().
00422 { 00423 int sd , l , q,qq ; 00424 struct sockaddr_in sin ; 00425 00426 if( port < 1 ) return -1 ; /* bad input */ 00427 00428 /** open a socket **/ 00429 00430 sd = socket( AF_INET , SOCK_STREAM , 0 ) ; 00431 if( sd == -1 ){ PERROR("tcp_listen(socket)"); return -1; } 00432 00433 /** set socket options (no delays, large buffers) **/ 00434 00435 #if 0 00436 { char *eee=getenv( "NIML_TCP_NAGLE" ) ; 00437 if( eee == NULL || toupper(*eee) != 'Y' ){ 00438 /** disable the Nagle algorithm **/ 00439 l = 1; 00440 setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, (void *)&l, sizeof(int)) ; 00441 } 00442 } 00443 #endif 00444 00445 #ifdef SOCKET_BUFSIZE 00446 q = 0 ; qq = sizeof(int) ; 00447 getsockopt(sd, SOL_SOCKET, SO_SNDBUF, (void *)&q, &qq ) ; 00448 if( q < SOCKET_BUFSIZE ){ 00449 l = SOCKET_BUFSIZE ; 00450 setsockopt(sd, SOL_SOCKET, SO_SNDBUF, (void *)&l, sizeof(int)) ; 00451 } 00452 q = 0 ; qq = sizeof(int) ; 00453 getsockopt(sd, SOL_SOCKET, SO_RCVBUF, (void *)&q, &qq ) ; 00454 if( q < SOCKET_BUFSIZE ){ 00455 l = SOCKET_BUFSIZE ; 00456 setsockopt(sd, SOL_SOCKET, SO_RCVBUF, (void *)&l, sizeof(int)) ; 00457 } 00458 #endif 00459 00460 /** set port on remote computer **/ 00461 00462 memset( &sin , 0 , sizeof(sin) ) ; 00463 sin.sin_family = AF_INET ; 00464 sin.sin_port = htons(port) ; 00465 sin.sin_addr.s_addr = INADDR_ANY ; /* reader reads from anybody */ 00466 00467 if( bind(sd , (struct sockaddr *)&sin , sizeof(sin)) == -1 ){ 00468 PERROR("tcp_listen(bind)"); CLOSEDOWN(sd); return -1; 00469 } 00470 00471 if( listen(sd,1) == -1 ){ 00472 PERROR("tcp_listen(listen)"); CLOSEDOWN(sd); return -1; 00473 } 00474 00475 tcp_set_cutoff( sd ) ; 00476 return sd ; 00477 } |
|
See if the given socket (file descriptor sd) is ready to read. msec is the number of milliseconds to wait:
Definition at line 204 of file niml_stream.c. References PERROR.
00205 { 00206 int ii ; 00207 fd_set rfds ; 00208 struct timeval tv , *tvp ; 00209 00210 if( sd < 0 ) return -1 ; /* bad socket id */ 00211 00212 FD_ZERO(&rfds) ; FD_SET(sd, &rfds) ; /* check only sd */ 00213 00214 if( msec >= 0 ){ /* set timer */ 00215 tv.tv_sec = msec/1000 ; 00216 tv.tv_usec = (msec%1000)*1000 ; 00217 tvp = &tv ; 00218 } else { 00219 tvp = NULL ; /* forever */ 00220 } 00221 00222 ii = select(sd+1, &rfds, NULL, NULL, tvp) ; /* check it */ 00223 if( ii == -1 ) PERROR( "tcp_readcheck(select)" ) ; 00224 return ii ; 00225 } |
|
Set a socket so that it will cutoff quickly when it is closed. See http://www.manualy.sk/sock-faq/unix-socket-faq.html for more information about this stuff. -------------------------------------------------------------------------- Definition at line 269 of file niml_stream.c.
00270 { 00271 if( sd < 0 ) return ; /* bad input */ 00272 00273 #ifdef SO_LINGER 00274 /* Turn off "lingering". */ 00275 00276 { struct linger lg ; 00277 lg.l_onoff = 1 ; 00278 lg.l_linger = 0 ; 00279 setsockopt(sd, SOL_SOCKET, SO_LINGER, (void *)&lg, sizeof(struct linger)) ; 00280 } 00281 #endif 00282 00283 #ifdef SO_REUSEADDR 00284 /* Let the address be reused quickly, 00285 in case of another connection from the same host on the same port. */ 00286 00287 { int optval = 1; 00288 setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(optval)) ; 00289 } 00290 #endif 00291 00292 return ; 00293 } |
|
Signal handler for SIGURG -- for incoming OOB data on a socket. We just close the NI_stream that the socket is attached to. But first we have to find it! -------------------------------------------------------------------- Definition at line 135 of file niml_stream.c. References NI_stream_type::bad, CLOSEDOWN, MARKED_FOR_DEATH, NI_TCP_TYPE, num_open_streams, NI_stream_type::sd, and NI_stream_type::type. Referenced by NI_stream_open().
00136 { 00137 int nn = num_open_streams , ii , sd,sdtop ; 00138 NI_stream_type *ns ; 00139 fd_set efds ; 00140 struct timeval tv ; 00141 static volatile int busy=0 ; 00142 00143 if( sig != SIGURG || 00144 busy || 00145 num_open_streams <= 0 || open_streams == NULL ) return ; /* bad */ 00146 00147 busy = 1 ; /* prevent recursion! */ 00148 00149 /* find largest socket descriptor in list of streams, 00150 and make list of all open socket descriptors in streams */ 00151 00152 FD_ZERO(&efds) ; sdtop = -1 ; 00153 for( ii=0 ; ii < nn ; ii++ ){ 00154 if( open_streams[ii] != NULL && 00155 open_streams[ii]->bad != MARKED_FOR_DEATH && 00156 open_streams[ii]->type == NI_TCP_TYPE && 00157 open_streams[ii]->sd >= 0 ){ 00158 00159 FD_SET( open_streams[ii]->sd , &efds ) ; 00160 if( open_streams[ii]->sd > sdtop ) sdtop = open_streams[ii]->sd; 00161 } 00162 } 00163 if( sdtop < 0 ){ busy=0 ; return; } /* no sockets found? */ 00164 00165 /* do a select to find which socket has an exceptional condition */ 00166 00167 tv.tv_sec = 0 ; 00168 tv.tv_usec = 666 ; 00169 ii = select(sdtop+1, NULL, NULL, &efds, &tv) ; /* check it */ 00170 if( ii <= 0 ){ busy=0 ; return; } /* no sockets found? */ 00171 00172 /* loop over found sockets and close their streams */ 00173 00174 for( ii=0 ; ii < nn ; ii++ ){ 00175 if( open_streams[ii] != NULL && open_streams[ii]->type == NI_TCP_TYPE ){ 00176 if( FD_ISSET( open_streams[ii]->sd , &efds ) ){ 00177 CLOSEDOWN( open_streams[ii]->sd ) ; 00178 open_streams[ii]->bad = MARKED_FOR_DEATH ; 00179 } 00180 } 00181 } 00182 00183 busy=0 ; return ; 00184 } |
|
See if the given socket (file descriptor sd) is ready to write. msec = max amount of time to wait, in milliseconds.
Definition at line 240 of file niml_stream.c. References PERROR.
00241 { 00242 int ii ; 00243 fd_set wfds ; 00244 struct timeval tv , *tvp ; 00245 00246 if( sd < 0 ) return -1 ; /* bad socket id */ 00247 00248 FD_ZERO(&wfds) ; FD_SET(sd, &wfds) ; /* check only sd */ 00249 00250 if( msec >= 0 ){ /* set timer */ 00251 tv.tv_sec = msec/1000 ; 00252 tv.tv_usec = (msec%1000)*1000 ; 00253 tvp = &tv ; 00254 } else { 00255 tvp = NULL ; /* forever */ 00256 } 00257 00258 ii = select(sd+1, NULL , &wfds, NULL, tvp); /* check it */ 00259 if( ii == -1 ) PERROR( "tcp_writecheck(select)" ) ; 00260 return ii ; 00261 } |
Variable Documentation
|
Variable to indicate that the atexit() call has/hasn't been made Definition at line 127 of file niml_stream.c. Referenced by NI_stream_open(). |
|
Signal that we are doing atexit() stuff. Definition at line 74 of file niml_stream.c. Referenced by atexit_open_streams(), and remove_open_stream(). |
|
IP addresses in dotted form. Definition at line 552 of file niml_stream.c. Referenced by add_trusted_host(), init_trusted_list(), and NI_trust_host(). |
|
Number of trusted hosts. Definition at line 551 of file niml_stream.c. Referenced by add_trusted_host(), init_trusted_list(), NI_add_trusted_host(), and NI_trust_host(). |
|
Initial value: { "127.0.0.1" , "192.168." , "128.231.21" } Definition at line 554 of file niml_stream.c. Referenced by init_trusted_list(). |
|
For tcp - indicates that SIGPIPE is ignored; will be set the first time tcp_send is called. Definition at line 23 of file niml_stream.c. Referenced by NI_stream_write(). |
|
Number of entries on the list of currently open streams. This list is needed so we can deal with the SIGURG signal, which we use as a message to shut a socket down. The signal call itself doesn't tell us which socket was the trigger, so we have to search all the open sockets for a match: hence, this list of open streams. --------------------------------------------------------------------- Definition at line 66 of file niml_stream.c. Referenced by add_open_stream(), atexit_open_streams(), remove_open_stream(), and tcp_sigurg_handler(). |
|
The actual array of open NIML streams. Definition at line 70 of file niml_stream.c. |
|
For tcp - indicates that the SIGURG handler is installed; will be set the first time a TCP socket is created. Definition at line 28 of file niml_stream.c. Referenced by NI_stream_open(). |