*** milter-greylist-3.0/Makefile.in.ORIG Fri Oct 6 11:14:39 2006 --- milter-greylist-3.0/Makefile.in Thu Jun 21 15:16:34 2007 *************** *** 53,59 **** TRUE= @TRUE@ OBJ= milter-greylist.o pending.o sync.o dnsrbl.o list.o macro.o \ ! conf_yacc.o dump_yacc.o conf.o autowhite.o dump.o spf.o acl.o SRC= milter-greylist.c pending.c sync.c conf.c macro.c \ autowhite.c dump.c spf.c acl.c dnsrbl.c list.c GENSRC= conf_yacc.c conf_lex.c dump_yacc.c dump_lex.c --- 53,59 ---- TRUE= @TRUE@ OBJ= milter-greylist.o pending.o sync.o dnsrbl.o list.o macro.o \ ! conf_yacc.o dump_yacc.o conf.o autowhite.o dump.o spf.o acl.o file_ext.o SRC= milter-greylist.c pending.c sync.c conf.c macro.c \ autowhite.c dump.c spf.c acl.c dnsrbl.c list.c GENSRC= conf_yacc.c conf_lex.c dump_yacc.c dump_lex.c *** milter-greylist-3.0/conf.c.ORIG Wed Sep 20 09:38:24 2006 --- milter-greylist-3.0/conf.c Fri Jun 8 14:53:50 2007 *************** *** 69,74 **** --- 69,76 ---- #include "dump.h" #include "milter-greylist.h" + #include "file_ext.h" + /* Default configuration */ struct conf defconf; *************** *** 132,138 **** mg_log(LOG_INFO, "%sloading config file \"%s\"", conf_cold ? "" : "re", conffile); ! if ((stream = fopen(conffile, "r")) == NULL) { mg_log(LOG_ERR, "cannot open config file %s: %s", conffile, strerror(errno)); mg_log(LOG_ERR, "continuing with no exception list"); --- 134,140 ---- mg_log(LOG_INFO, "%sloading config file \"%s\"", conf_cold ? "" : "re", conffile); ! if ((stream = Fopen(conffile, "r")) == NULL) { mg_log(LOG_ERR, "cannot open config file %s: %s", conffile, strerror(errno)); mg_log(LOG_ERR, "continuing with no exception list"); *************** *** 152,158 **** conf_parse(); ACL_UNLOCK; ! fclose(stream); if (!conf_cold || conf.c_debug) { (void)gettimeofday(&tv2, NULL); --- 154,160 ---- conf_parse(); ACL_UNLOCK; ! Fclose(stream); if (!conf_cold || conf.c_debug) { (void)gettimeofday(&tv2, NULL); *** milter-greylist-3.0/dnsrbl.c.ORIG Thu Oct 26 23:01:08 2006 --- milter-greylist-3.0/dnsrbl.c Thu Jun 21 15:06:56 2007 *************** *** 43,48 **** --- 43,51 ---- #include #include #include + #ifdef HAVE_STRINGS_H + #include /* bzero, ... */ + #endif #include #include #include *************** *** 63,69 **** #define NS_MAXMSG 65535 #endif ! #ifdef res_ninit #define HAVE_RESN 1 #ifndef res_ndestroy #define res_ndestroy(res) res_nclose(res) --- 66,72 ---- #define NS_MAXMSG 65535 #endif ! #if (defined(res_ninit) || (__RES >= 19991006) ) #define HAVE_RESN 1 #ifndef res_ndestroy #define res_ndestroy(res) res_nclose(res) *** milter-greylist-3.0/dump.c.ORIG Tue Sep 5 00:05:59 2006 --- milter-greylist-3.0/dump.c Wed Jun 6 16:32:25 2007 *************** *** 29,34 **** --- 29,35 ---- * OF THE POSSIBILITY OF SUCH DAMAGE. */ + #include "file_ext.h" #include "config.h" #ifdef HAVE_SYS_CDEFS_H *************** *** 120,142 **** exit(EX_OSERR); } for (;;) { ! /* XXX Not really dynamically adjustable */ ! switch (conf.c_dumpfreq) { ! case -1: ! sleep(DUMPFREQ); ! break; ! case 0: ! if ((error = pthread_cond_wait(&dump_sleepflag, ! &mutex)) != 0) ! mg_log(LOG_ERR, "pthread_cond_wait failed: %s", ! strerror(error)); ! break; ! default: ! sleep(conf.c_dumpfreq); ! break; } /* --- 121,150 ---- exit(EX_OSERR); } + error = 0; for (;;) { ! if (error) { ! /* short sleep for to try again the failed dump soon */ ! sleep(60); ! } ! else { ! /* XXX Not really dynamically adjustable */ ! switch (conf.c_dumpfreq) { ! case -1: ! sleep(DUMPFREQ); ! break; ! case 0: ! if ((error = pthread_cond_wait(&dump_sleepflag, ! &mutex)) != 0) ! mg_log(LOG_ERR, "pthread_cond_wait failed: %s", ! strerror(error)); ! break; ! default: ! sleep(conf.c_dumpfreq); ! break; ! } } /* *************** *** 145,151 **** if ((conf.c_dumpfreq == -1) || (dump_dirty == 0)) continue; ! dump_perform(); } /* NOTREACHED */ --- 153,159 ---- if ((conf.c_dumpfreq == -1) || (dump_dirty == 0)) continue; ! error = dump_perform(); } /* NOTREACHED */ *************** *** 155,161 **** return NULL; } ! void dump_perform(void) { FILE *dump; int dumpfd; --- 163,169 ---- return NULL; } ! int dump_perform(void) { FILE *dump; int dumpfd; *************** *** 193,205 **** if ((dumpfd = mkstemp(newdumpfile)) == -1) { mg_log(LOG_ERR, "mkstemp(\"%s\") failed: %s", newdumpfile, strerror(errno)); ! exit(EX_OSERR); } ! if ((dump = fdopen(dumpfd, "w")) == NULL) { mg_log(LOG_ERR, "cannot write dumpfile \"%s\": %s", ! newdumpfile, strerror(errno)); ! exit(EX_OSERR); } #define BIG_BUFFER (10 * 1024 * 1024) --- 201,218 ---- if ((dumpfd = mkstemp(newdumpfile)) == -1) { mg_log(LOG_ERR, "mkstemp(\"%s\") failed: %s", newdumpfile, strerror(errno)); ! /* exit(EX_OSERR); */ ! return 1; /* try again next time ... */ } ! errno = 0; ! if ((dump = Fdopen(dumpfd, "w")) == NULL) { mg_log(LOG_ERR, "cannot write dumpfile \"%s\": %s", ! newdumpfile, (errno == 0 ? "out of stdio streams" : strerror(errno) ) ); ! close(dumpfd); ! unlink(newdumpfile); /* clean up ... */ ! /* exit(EX_OSERR); */ ! return 1; /* try again next time ... */ } #define BIG_BUFFER (10 * 1024 * 1024) *************** *** 220,226 **** fprintf(dump, "#\n# Summary: %d records, %d greylisted, %d " "whitelisted\n#\n", done, greylisted_count, whitelisted_count); ! fclose(dump); if (s_buffer) free(s_buffer); --- 233,239 ---- fprintf(dump, "#\n# Summary: %d records, %d greylisted, %d " "whitelisted\n#\n", done, greylisted_count, whitelisted_count); ! Fclose(dump); /* should close the dumpfd descriptor also */ if (s_buffer) free(s_buffer); *************** *** 227,233 **** if (rename(newdumpfile, conf.c_dumpfile) != 0) { mg_log(LOG_ERR, "cannot replace \"%s\" by \"%s\": %s\n", conf.c_dumpfile, newdumpfile, strerror(errno)); ! exit(EX_OSERR); } if (conf.c_debug) { --- 240,248 ---- if (rename(newdumpfile, conf.c_dumpfile) != 0) { mg_log(LOG_ERR, "cannot replace \"%s\" by \"%s\": %s\n", conf.c_dumpfile, newdumpfile, strerror(errno)); ! unlink(newdumpfile); /* clean up ... */ ! /* exit(EX_OSERR); */ ! return 1; /* try again next time ... */ } if (conf.c_debug) { *************** *** 237,243 **** done, tv3.tv_sec, tv3.tv_usec); } ! return; } --- 252,258 ---- done, tv3.tv_sec, tv3.tv_usec); } ! return 0; } *** milter-greylist-3.0/dump.h.ORIG Tue Sep 5 00:05:59 2006 --- milter-greylist-3.0/dump.h Fri Jun 1 13:13:33 2007 *************** *** 78,83 **** void dump_flush(void); void dump_reload(void); void dump_header(FILE *); ! void dump_perform(void); #endif /* _DUMP_H_ */ --- 78,83 ---- void dump_flush(void); void dump_reload(void); void dump_header(FILE *); ! int dump_perform(void); #endif /* _DUMP_H_ */ *** milter-greylist-3.0/file_ext.c.ORIG Sun Feb 29 22:07:51 2004 --- milter-greylist-3.0/file_ext.c Fri Jun 15 10:33:19 2007 *************** *** 0 **** --- 1,364 ---- + /* + * file_ext.c Stdio stream function replacement for limited stdio implementations + * + * 2007-06-04 Johann E. Klasek, klasek@zid.tuwien.ac.at + * + * + * Description: + * Some stdio stream implementation suffers from limitation or + * backward compatibility. Especially Solaris 9 and previous + * versions in the LWP32 programming model have a limit in the + * FILE datastructure where the file descriptor field has only + * a width of 8 bits. Therefore stdio streams are only + * capable in handling file descriptors in the range from 0 to 255. + * Some application accessing the FILE structure components directly + * (e.g. the _file field) through the past years. The structure has + * never be change to provide backward compatibility for and prevent + * breaking existing applications (binaries). + * Even Solaris 9 offers a maximum number of 65536 file descriptors + * only descriptors 0 to 255 can be stored into the FILE structure. + * If descriptor values greater 255 are passed to e.g. fdopen() + * this library function simply fails with errno unset! + * + * Solaris 10 offers several solution to cope with this situation + * (based on source or binary applications). + * + * The solution is mainly for versions previous to Solaris 10. + * This module provides a replacement for the functions + * fdopen() and fclose(). The idea is to reserve a pool of + * open descriptors (associated /dev/null) + * with values <256 which are aquired as needed by fdopen_ext(). + * On the other hand fclose_ext() tries to return a descriptor + * lower than 256 to the reserved pool. The latter is could not + * assured in all cases because the real fclose() call releases + * the associated description which could not be reclaimed without + * a delay. A parallel running thread could grab the closed + * descriptor during the delay ... + * The whole system works only in situations where not more + * then 256 streams are used in parallel despite the maximum + * number of open descriptors could grow much greater. + * + * References: + * http://developers.sun.com/solaris/articles/stdio_256.html + * http://www.science.uva.nl/pub/solaris/solaris2.html + * 3.48) How can I increase the number of file descriptors per process? + * http://www.research.att.com/~gsf/download/ref/sfio/sfio.html + */ + + #include + #include + #include + #include + #include + #include + + #include + + #include + #include + #include + + #include + + #include "file_ext.h" + + /* size of the pool of low descriptors, from 4 to 256 */ + #define FD_POOL_SIZE 64 + + /* an array of free/used descriptors - representing the pool */ + static char fd_pool[256]; + + /* the current count of free low descriptors */ + static int fd_pool_free=0; + + #ifdef USE_FD_POOL + + /* take logging function from milter-greylist */ + #include "milter-greylist.h" + + #define fe_log mg_log + + #else + + /* ... otherwise define our own ... */ + + /* log to syslog if set */ + static int fe_log_syslog=0; + + static + /* VARARGS */ + void + fe_log(int level, char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + + if (! fe_log_syslog) { + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + } + else + vsyslog(level, fmt, ap); + + va_end(ap); + return; + } + + #endif + + /* public file which is used to aquire new open descriptors ... */ + #define FNAME "/dev/null" + + + /*** + *** aquire a new open file descriptor (by means of an open dummy file) + *** + *** return: >=0 | -1 ... open descriptor | error + ***/ + + int fd_new_desc() { + int descriptor; + + if ((descriptor = open(FNAME, O_RDWR)) < 0) { + fe_log(LOG_ERR, "file_ext: can't create dummy file descriptor file %s: %s", FNAME, + strerror(errno)); + return -1; + } + return descriptor; + } + + + /*** + *** aquire a new low valued open file descriptor + *** + *** return: 0 <= descriptor < 256 + ***/ + + int fd_new_low_desc() { + int descriptor; + + if ((descriptor = fd_new_desc()) >= 256 || descriptor < 0) { + fe_log(LOG_ERR, "file_ext: %s", (descriptor < 0 ? "can't allocate a new descriptor" : "can't allocate small dummy file descriptor (<256) - out of luck!") ); + exit(EX_OSERR); /* fatal situation - must exit */ + } + return descriptor; + } + + + /*** + *** initialize the module - build up the low file descriptor pool + *** + *** return: 0 + ***/ + + int file_ext_init(void) { + int i; + memset(fd_pool,0, sizeof(fd_pool)); + + for(i=0;i=0 ) { + + if ( fd_pool_free >= FD_POOL_SIZE ) { + return fclose(stream); /* pool is full, we dont want a low descriptor back ... */ + /* just pass to the original function */ + } + + /* we try to get a descriptor >= 256, if not put it back to */ + /* the low file descriptor pool */ + while( (new_descriptor = fd_new_desc()) < 256 && new_descriptor >= 0 + && fd_pool_free < FD_POOL_SIZE ) { + if (fd_pool[new_descriptor] == 0) { + fd_pool[new_descriptor] = 1; + fd_pool_free++; + fe_log(LOG_INFO, "fclose_ext: adding new descriptor %d into low fd pool", + new_descriptor); + } + + } + if ( new_descriptor < 256 && new_descriptor >= 0 && fd_pool_free >= FD_POOL_SIZE ) { + close(new_descriptor); /* not needed anymore ... */ + return fclose(stream); /* got only low valued descriptor but the pool is full ... */ + /* pass to the original function */ + } + if ( fd_pool_free >= FD_POOL_SIZE ) { + close(new_descriptor); /* not needed anymore ... */ + return fclose(stream); /* got only low valued descriptor and the pool is full ... */ + /* pass to the original function */ + } + if ( new_descriptor < 0 ) { + ret = fclose(stream); /* closes also the descriptor of the stream! */ + err = errno; + descriptor = fd_new_desc(); /* try to allocate again, after the fclose(), maybe */ + /* we can reclaim the closed descriptor ... */ + if ( descriptor < 0 ) { + fe_log(LOG_ERR, "fclose_ext: fd_new_desc failed: low descriptor %d lost! (%s)", + old_descriptor, strerror(errno)); + } + } + else { /* new_descriptor >= 256 */ + + ret = fclose(stream); /* closes also the descriptor of the stream! */ + err = errno; + descriptor = dup(new_descriptor); /* grab the closed/returned descriptor - the lowest */ + /* available descriptor will be aquired - bit of racy ... */ + /* maybe some other systemcall of another thread is faster */ + if ( descriptor < 0 ) { + fe_log(LOG_ERR, "fclose_ext: dup failed: low descriptor %d lost! (%s)", + old_descriptor, strerror(errno)); + } + close(new_descriptor); + } + /* but if we are in luck, we got some other low descriptor, not necessarily the one from the */ + /* closed stream */ + if ( descriptor >= 256 ) { + fe_log(LOG_ERR, "fclose_ext: low descriptor %d lost!", old_descriptor); + close(descriptor); + } + else if ( descriptor < 0 ) { + /* do nothing, an error has been already emitted above */ + } + else if ( fd_pool[descriptor] == 0 ) { + if ( fd_pool_free >= FD_POOL_SIZE ) { + /* pool already full, we do not need this low descriptor, release it */ + close(descriptor); + } + else { + fd_pool[descriptor] = 1; + fd_pool_free++; + fe_log(LOG_INFO, "fclose_ext: taking descriptor %d back into low fd pool", descriptor); + } + + } + /* else: fd_pool[descriptor] == 1 : some strangeness, descriptor already marked as */ + /* released into the FD pool. Should neven happen ... */ + + + errno = err; /* restore state from original fclose() call */ + return ret; + } + else return fclose(stream); /* descriptor not in lower range, let original function handle this case */ + + } + + + /*** + *** get_pool_desc + *** + *** return: < 0 | otherwise ... error | descriptor (in range 0-255) + ***/ + + int get_pool_desc(int desc) { + int i; + int fd; + + if (desc < 0) return desc; + + for(i=0; i<256; i++) { + if (fd_pool[i] == 1) { + /* dup a large fd to a small fd */ + fd = dup2(desc, i); close(desc); + fd_pool[i] = 0; + fd_pool_free--; + fe_log(LOG_INFO, "fdopen_ext: get_pool_desc: descriptor %d reused as %d", desc, i); + break; + } + } + if (i >= 256 || fd_pool_free == 0) { + return -1; + } + return i; + } + + + + /*** + *** fdopen_ext + *** + *** return: NULL | otherwise ... error | new opened stream + ***/ + + FILE *fdopen_ext(int fd, char *mode) { + int descriptor; + + if (fd >= 256) { + /* if we got a non low descriptor, try to map it into to low descriptor pool */ + descriptor = get_pool_desc(fd); + if (descriptor < 0) { + fe_log(LOG_ERR, "fdopen_ext: no free low file descriptor"); + return fdopen(fd, mode); + } + return fdopen(descriptor, mode); + } + return fdopen(fd, mode); + + } + + + + /*** + *** fopen_ext + *** + *** return: NULL | otherwise ... error | new opened stream + ***/ + + FILE *fopen_ext(char *path, char *mode) { + int descriptor; + FILE *stream; + int err; + + descriptor = fd_new_desc(); + if (descriptor >= 256) { + descriptor = get_pool_desc(descriptor); + } + if (descriptor < 0) return fopen(path, mode); + + /* we have a low descriptor */ + close(descriptor); + + /* after releasing it, we hope the following fopen() call can aquire it ... */ + stream = fopen(path, mode); + err = errno; + + if (stream != NULL) { + if ( descriptor == fileno(stream) ) { + /* we are in luck, fopen has successfully aquired our low descriptor ... */ + return stream; + } + else { + /* descriptor missed, some other has taken it, but fopen() successful! */ + fe_log(LOG_INFO, "fopen_ext: descriptor %d lost!", descriptor); + errno = err; + return stream; + } + } + else { + fe_log(LOG_ERR, "fopen_ext: failed and descriptor %d lost!", descriptor); + errno = err; + return stream; + } + + /* not very safe and can be raced out by other threads which may took the descriptor */ + /* earlier ... :( */ + } *** milter-greylist-3.0/file_ext.h.ORIG Sun Feb 29 22:07:51 2004 --- milter-greylist-3.0/file_ext.h Fri Jun 8 14:54:58 2007 *************** *** 0 **** --- 1,23 ---- + + + + #ifdef USE_FD_POOL + + #include + + extern int file_ext_init(void); + extern int fclose_ext(FILE *stream); + extern FILE *fdopen_ext(int fd, char *mode); + extern FILE *fopen_ext(char *path, char *mode); + + # define Fopen(path,mode) fopen_ext(path,mode) + # define Fdopen(fd,mode) fdopen_ext(fd,mode) + # define Fclose(stream) fclose_ext(stream) + + #else + + # define Fopen(path,mode) fopen(path,mode) + # define Fdopen(fd,mode) fdopen(fd,mode) + # define Fclose(stream) fclose(stream) + + #endif *** milter-greylist-3.0/milter-greylist.c.ORIG Tue Nov 7 06:12:11 2006 --- milter-greylist-3.0/milter-greylist.c Fri Jun 8 16:21:28 2007 *************** *** 29,34 **** --- 29,35 ---- * OF THE POSSIBILITY OF SUCH DAMAGE. */ + #include "file_ext.h" #include "config.h" #ifdef HAVE_SYS_CDEFS_H *************** *** 876,881 **** --- 877,887 ---- #endif macro_init(); + #ifdef USE_FD_POOL + /* initialize file descriptor pool */ + file_ext_init(); + #endif + /* * Load config file * We can do this without locking exceptlist, as *** milter-greylist-3.0/sync.c.ORIG Tue Nov 7 06:12:12 2006 --- milter-greylist-3.0/sync.c Wed Jun 13 16:49:03 2007 *************** *** 59,64 **** --- 59,66 ---- #include "autowhite.h" #include "milter-greylist.h" + #include "file_ext.h" + #define SYNC_PROTO_CURRENT 3 struct sync_master_sock { *************** *** 120,126 **** sync_free(sync); if (peer->p_stream != NULL) ! fclose(peer->p_stream); LIST_REMOVE(peer, p_list); free(peer->p_name); --- 122,128 ---- sync_free(sync); if (peer->p_stream != NULL) ! Fclose(peer->p_stream); LIST_REMOVE(peer, p_list); free(peer->p_name); *************** *** 281,287 **** mg_log(LOG_ERR, "closing connexion with peer %s: " "send buffer would overflow (%d entries queued)", peer->p_name, peer->p_qlen); ! fclose(peer->p_stream); peer->p_stream = NULL; return -1; } --- 283,289 ---- mg_log(LOG_ERR, "closing connexion with peer %s: " "send buffer would overflow (%d entries queued)", peer->p_name, peer->p_qlen); ! Fclose(peer->p_stream); peer->p_stream = NULL; return -1; } *************** *** 293,299 **** "complete line \"%s\" - bytes written: %i", peer->p_name, strerror(errno), peer->p_qlen, line, bw); ! fclose(peer->p_stream); peer->p_stream = NULL; return -1; } --- 295,301 ---- "complete line \"%s\" - bytes written: %i", peer->p_name, strerror(errno), peer->p_qlen, line, bw); ! Fclose(peer->p_stream); peer->p_stream = NULL; return -1; } *************** *** 311,317 **** mg_log(LOG_ERR, "lost connexion with peer %s: " "%s (%d entries queued)", peer->p_name, strerror(errno), peer->p_qlen); ! fclose(peer->p_stream); peer->p_stream = NULL; return -1; } --- 313,319 ---- mg_log(LOG_ERR, "lost connexion with peer %s: " "%s (%d entries queued)", peer->p_name, strerror(errno), peer->p_qlen); ! Fclose(peer->p_stream); peer->p_stream = NULL; return -1; } *************** *** 320,326 **** mg_log(LOG_ERR, "lost connexion with peer %s: " "%s (%d entries queued)", peer->p_name, strerror(errno), peer->p_qlen); ! fclose(peer->p_stream); peer->p_stream = NULL; return -1; } --- 322,328 ---- mg_log(LOG_ERR, "lost connexion with peer %s: " "%s (%d entries queued)", peer->p_name, strerror(errno), peer->p_qlen); ! Fclose(peer->p_stream); peer->p_stream = NULL; return -1; } *************** *** 336,342 **** mg_log(LOG_ERR, "Unexpected reply \"%s\" from %s, " "closing connexion (%d entries queued)", line, peer->p_name, peer->p_qlen); ! fclose(peer->p_stream); peer->p_stream = NULL; return -1; } --- 338,344 ---- mg_log(LOG_ERR, "Unexpected reply \"%s\" from %s, " "closing connexion (%d entries queued)", line, peer->p_name, peer->p_qlen); ! Fclose(peer->p_stream); peer->p_stream = NULL; return -1; } *************** *** 346,352 **** mg_log(LOG_ERR, "Unexpected reply \"%s\" from %s, " "closing connexion (%d entries queued)", line, peer->p_name, peer->p_qlen); ! fclose(peer->p_stream); peer->p_stream = NULL; return -1; } --- 348,354 ---- mg_log(LOG_ERR, "Unexpected reply \"%s\" from %s, " "closing connexion (%d entries queued)", line, peer->p_name, peer->p_qlen); ! Fclose(peer->p_stream); peer->p_stream = NULL; return -1; } *************** *** 539,552 **** peer->p_name, strerror(errno)); } ! if ((stream = fdopen(s, "w+")) == NULL) { mg_log(LOG_ERR, "cannot sync with peer %s, " "fdopen failed: %s (%d entries queued)", ! peer->p_name, strerror(errno), peer->p_qlen); close(s); return -1; } if (setvbuf(stream, NULL, _IOLBF, 0) != 0) mg_log(LOG_ERR, "cannot set line buffering with peer %s: %s", peer->p_name, strerror(errno)); --- 541,559 ---- peer->p_name, strerror(errno)); } ! errno = 0; ! if ((stream = Fdopen(s, "w+")) == NULL) { mg_log(LOG_ERR, "cannot sync with peer %s, " "fdopen failed: %s (%d entries queued)", ! peer->p_name, (errno == 0 ? "out of stdio streams" : strerror(errno) ), peer->p_qlen); close(s); return -1; } + #ifdef USE_FD_POOL + s = fileno(stream); /* the socket descriptor could have been replaced by Fdopen() ! */ + #endif + if (setvbuf(stream, NULL, _IOLBF, 0) != 0) mg_log(LOG_ERR, "cannot set line buffering with peer %s: %s", peer->p_name, strerror(errno)); *************** *** 592,598 **** return 0; bad: ! fclose(stream); peer->p_stream = NULL; return -1; --- 599,605 ---- return 0; bad: ! Fclose(stream); peer->p_stream = NULL; return -1; *************** *** 686,694 **** mg_log(LOG_ERR, "incoming connexion " "failed: %s", strerror(errno)); ! if (errno != ECONNABORTED) ! exit(EX_OSERR); ! continue; } unmappedaddr(SA(&raddr), &raddrlen); --- 693,726 ---- mg_log(LOG_ERR, "incoming connexion " "failed: %s", strerror(errno)); ! if ( 0 ! #ifdef EAGAIN ! || errno == EAGAIN ! #endif /* EAGAIN */ ! #ifdef ECONNABORTED ! || errno == ECONNABORTED ! #endif /* ECONNABORTED */ ! #ifdef EMFILE ! || errno == EMFILE ! #endif /* EMFILE */ ! #ifdef ENFILE ! || errno == ENFILE ! #endif /* ENFILE */ ! #ifdef ENOBUFS ! || errno == ENOBUFS ! #endif /* ENOBUFS */ ! #ifdef ENOMEM ! || errno == ENOMEM ! #endif /* ENOMEM */ ! #ifdef ENOSR ! || errno == ENOSR ! #endif /* ENOSR */ ! #ifdef EWOULDBLOCK ! || errno == EWOULDBLOCK ! #endif /* EWOULDBLOCK */ ! ) continue; ! exit(EX_OSERR); ! } unmappedaddr(SA(&raddr), &raddrlen); *************** *** 696,702 **** mg_log(LOG_INFO, "Incoming MX sync connexion from %s", peerstr); ! if ((stream = fdopen(fd, "w+")) == NULL) { mg_log(LOG_ERR, "incoming connexion from %s failed, " "fdopen fail: %s", peerstr, strerror(errno)); --- 728,734 ---- mg_log(LOG_INFO, "Incoming MX sync connexion from %s", peerstr); ! if ((stream = Fdopen(fd, "w+")) == NULL) { mg_log(LOG_ERR, "incoming connexion from %s failed, " "fdopen fail: %s", peerstr, strerror(errno)); *************** *** 717,723 **** fprintf(stream, "105 No more peers, shutting down!\n"); PEER_UNLOCK; ! fclose(stream); close(sms->sock); sms->sock = -1; sms->runs = 0; --- 749,755 ---- fprintf(stream, "105 No more peers, shutting down!\n"); PEER_UNLOCK; ! Fclose(stream); close(sms->sock); sms->sock = -1; sms->runs = 0; *************** *** 772,778 **** peerstr); fprintf(stream, "106 You have no permission to talk, go away!\n"); ! fclose(stream); continue; } --- 804,810 ---- peerstr); fprintf(stream, "106 You have no permission to talk, go away!\n"); ! Fclose(stream); continue; } *************** *** 781,787 **** mg_log(LOG_ERR, "incoming connexion from %s failed, " "pthread_create failed: %s", peerstr, strerror(error)); ! fclose(stream); continue; } if ((error = pthread_detach(tid)) != 0) { --- 813,819 ---- mg_log(LOG_ERR, "incoming connexion from %s failed, " "pthread_create failed: %s", peerstr, strerror(error)); ! Fclose(stream); continue; } if ((error = pthread_detach(tid)) != 0) { *************** *** 1139,1145 **** } fprintf(stream, "202 Good bye\n"); ! fclose(stream); return; --- 1171,1177 ---- } fprintf(stream, "202 Good bye\n"); ! Fclose(stream); return;