150276Speter/**************************************************************************** 2174993Srafan * Copyright (c) 1998-2003,2007 Free Software Foundation, Inc. * 350276Speter * * 450276Speter * Permission is hereby granted, free of charge, to any person obtaining a * 550276Speter * copy of this software and associated documentation files (the * 650276Speter * "Software"), to deal in the Software without restriction, including * 750276Speter * without limitation the rights to use, copy, modify, merge, publish, * 850276Speter * distribute, distribute with modifications, sublicense, and/or sell * 950276Speter * copies of the Software, and to permit persons to whom the Software is * 1050276Speter * furnished to do so, subject to the following conditions: * 1150276Speter * * 1250276Speter * The above copyright notice and this permission notice shall be included * 1350276Speter * in all copies or substantial portions of the Software. * 1450276Speter * * 1550276Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 1650276Speter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 1750276Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 1850276Speter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 1950276Speter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 2050276Speter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 2150276Speter * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 2250276Speter * * 2350276Speter * Except as contained in this notice, the name(s) of the above copyright * 2450276Speter * holders shall not be used in advertising or otherwise to promote the * 2550276Speter * sale, use or other dealings in this Software without prior written * 2650276Speter * authorization. * 2750276Speter ****************************************************************************/ 2850276Speter 2950276Speter/**************************************************************************** 3050276Speter * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 3150276Speter * and: Eric S. Raymond <esr@snark.thyrsus.com> * 3250276Speter ****************************************************************************/ 3350276Speter 3450276Speter/* 3550276Speter** setbuf.c 3650276Speter** 3750276Speter** Support for set_term(), reset_shell_mode(), reset_prog_mode(). 3850276Speter** 3950276Speter*/ 4050276Speter 4150276Speter#include <curses.priv.h> 4250276Speter 43174993SrafanMODULE_ID("$Id: setbuf.c,v 1.13 2007/05/12 19:04:02 tom Exp $") 4450276Speter 4550276Speter/* 4650276Speter * If the output file descriptor is connected to a tty (the typical case) it 4750276Speter * will probably be line-buffered. Keith Bostic pointed out that we don't want 4850276Speter * this; it hoses people running over networks by forcing out a bunch of small 4950276Speter * packets instead of one big one, so screen updates on ptys look jerky. 5050276Speter * Restore block buffering to prevent this minor lossage. 5150276Speter * 5250276Speter * The buffer size is a compromise. Ideally we'd like a buffer that can hold 5350276Speter * the maximum possible update size (the whole screen plus cup commands to 5450276Speter * change lines as it's painted). On a 66-line xterm this can become 5550276Speter * excessive. So we min it with the amount of data we think we can get through 5650276Speter * two Ethernet packets (maximum packet size - 100 for TCP/IP overhead). 5750276Speter * 5850276Speter * Why two ethernet packets? It used to be one, on the theory that said 5950276Speter * packets define the maximum size of atomic update. But that's less than the 6050276Speter * 2000 chars on a 25 x 80 screen, and we don't want local updates to flicker 6150276Speter * either. Two packet lengths will handle up to a 35 x 80 screen. 6250276Speter * 6350276Speter * The magic '6' is the estimated length of the end-of-line cup sequence to go 6450276Speter * to the next line. It's generous. We used to mess with the buffering in 6550276Speter * init_mvcur() after cost computation, but that lost the sequences emitted by 6650276Speter * init_acs() in setupscreen(). 6750276Speter * 6850276Speter * "The setvbuf function may be used only after the stream pointed to by stream 6950276Speter * has been associated with an open file and before any other operation is 7050276Speter * performed on the stream." (ISO 7.9.5.6.) 7150276Speter * 7250276Speter * Grrrr... 7350276Speter * 7450276Speter * On a lighter note, many implementations do in fact allow an application to 7550276Speter * reset the buffering after it has been written to. We try to do this because 7650276Speter * otherwise we leave stdout in buffered mode after endwin() is called. (This 7750276Speter * also happens with SVr4 curses). 7850276Speter * 7950276Speter * There are pros/cons: 8050276Speter * 8150276Speter * con: 8250276Speter * There is no guarantee that we can reestablish buffering once we've 8350276Speter * dropped it. 8450276Speter * 8550276Speter * We _may_ lose data if the implementation does not coordinate this with 8650276Speter * fflush. 8750276Speter * 8850276Speter * pro: 8950276Speter * An implementation is more likely to refuse to change the buffering than 9050276Speter * to do it in one of the ways mentioned above. 9150276Speter * 9250276Speter * The alternative is to have the application try to change buffering 9350276Speter * itself, which is certainly no improvement. 9450276Speter * 9550276Speter * Just in case it does not work well on a particular system, the calls to 9650276Speter * change buffering are all via the macro NC_BUFFERED. Some implementations 9750276Speter * do indeed get confused by changing setbuf on/off, and will overrun the 9850276Speter * buffer. So we disable this by default (there may yet be a workaround). 9950276Speter */ 10076726SpeterNCURSES_EXPORT(void) 101166124Srafan_nc_set_buffer(FILE *ofp, bool buffered) 10250276Speter{ 10376726Speter /* optional optimization hack -- do before any output to ofp */ 10450276Speter#if HAVE_SETVBUF || HAVE_SETBUFFER 105174993Srafan if (SP->_buffered != buffered) { 106166124Srafan unsigned buf_len; 107166124Srafan char *buf_ptr; 10850276Speter 109166124Srafan if (getenv("NCURSES_NO_SETBUF") != 0) 110166124Srafan return; 11150276Speter 112166124Srafan fflush(ofp); 113166124Srafan#ifdef __DJGPP__ 114166124Srafan setmode(ofp, O_BINARY); 115166124Srafan#endif 116166124Srafan if (buffered != 0) { 117166124Srafan buf_len = min(LINES * (COLS + 6), 2800); 118166124Srafan if ((buf_ptr = SP->_setbuf) == 0) { 119166124Srafan if ((buf_ptr = typeMalloc(char, buf_len)) == NULL) 120166124Srafan return; 121166124Srafan SP->_setbuf = buf_ptr; 122166124Srafan /* Don't try to free this! */ 123166124Srafan } 12450276Speter#if !USE_SETBUF_0 125166124Srafan else 126166124Srafan return; 12750276Speter#endif 128166124Srafan } else { 12950276Speter#if !USE_SETBUF_0 130166124Srafan return; 13150276Speter#else 132166124Srafan buf_len = 0; 133166124Srafan buf_ptr = 0; 13450276Speter#endif 135166124Srafan } 13650276Speter 13750276Speter#if HAVE_SETVBUF 13876726Speter#ifdef SETVBUF_REVERSED /* pre-svr3? */ 139166124Srafan (void) setvbuf(ofp, buf_ptr, buf_len, buf_len ? _IOFBF : _IOLBF); 14050276Speter#else 141166124Srafan (void) setvbuf(ofp, buf_ptr, buf_len ? _IOFBF : _IOLBF, buf_len); 14250276Speter#endif 14350276Speter#elif HAVE_SETBUFFER 144166124Srafan (void) setbuffer(ofp, buf_ptr, (int) buf_len); 14550276Speter#endif 14650276Speter 147166124Srafan SP->_buffered = buffered; 148166124Srafan } 14950276Speter#endif /* HAVE_SETVBUF || HAVE_SETBUFFER */ 15050276Speter} 151