/* Even though readline() itself adds history automatically, the user can also add * lines. This is for compat with GNU Readline. */ void add_history(const char *p) { if (p == NULL || *p == '\0') return; hist_add(p); }
/* Adaptor for the hist_add() function, which handles signed history length. */ static void save_into_history(const char item[], hist_t *hist, int len) { if(len >= 0) { hist_add(hist, item, len); } }
/* get line from console ------------------------------------------------------- * get line from virtual console * args : vt_t *vt I virtual console * char *buff O buffer * in n I buffer size * return : status (1:ok,0:no input) *-----------------------------------------------------------------------------*/ extern int vt_gets(vt_t *vt, char *buff, int n) { char c; vt->n=vt->cur=vt->nesc=vt->brk=0; buff[0]='\0'; while (vt->state) { if (!vt_getc(vt,&c)) return 0; if (vt->brk) { /* break */ return vt_putc(vt,'\n'); } if (c=='\r') { /* end of line */ vt->buff[vt->n]='\0'; strncpy(buff,vt->buff,n-1); buff[n-1]='\0'; hist_add(vt,buff); return vt_putc(vt,'\n'); } } return 0; }
void* client(void *arg) { char request[1024]; int sock, ret, i, len; cpu_tick_t start, end; int server_num = (int) arg; int did_some_io = 1; int optval; // loop, making requests, & keeping stats while( 1 ) { state_idle++; // yield, if we didn't yet, ie, due to socket() or connect() failures if( !did_some_io ) sched_yield(); did_some_io = 0; state_idle--; state_connecting++; // new socket sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if( sock == -1 ) { if( debug ) printf("client() - error with socket(): %s\n", strerror(errno)); io_errors++; //perror("socket"); state_connecting--; continue; } // turn off TCP linger, to do a quick close of the socket if ( 0 ) { struct linger linger; linger.l_onoff = 1; linger.l_linger = 0; if (setsockopt (sock, SOL_SOCKET, SO_LINGER, &linger, sizeof (linger)) < 0) { if( debug ) printf("client() - error setting SO_LINGER: %s\n", strerror(errno)); io_errors++; state_connecting--; continue; } } // make the sockets reusable, so we don't wait as long for the // kernel to clean things up, and hence run out of sockets. // // FIXME: is this only meaningful for server sockets?? optval = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) { if( debug ) printf("client() - error setting SO_REUSEADDR: %s\n", strerror(errno)); io_errors++; state_connecting--; continue; } /* optval = SEND_BUFFER_SIZE; if (setsockopt (sock, SOL_SOCKET, SO_SNDBUF, &optval, sizeof (optval)) < 0) { if( debug ) printf("client() - error setting SO_SNDBUF: %s\n", strerror(errno)); io_errors++; state_connecting--; continue; } optval = RECV_BUFFER_SIZE; if (setsockopt (sock, SOL_SOCKET, SO_RCVBUF, &optval, sizeof (optval)) < 0) { if( debug ) printf("client() - error setting SO_RCVBUF: %s\n", strerror(errno)); io_errors++; state_connecting--; continue; } */ // Disable the Nagle algorithm so the kernel won't delay our // writes waiting for more data. if( 1 ) { optval = 1; //if (setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof (optval)) < 0) if (setsockopt (sock, SOL_TCP, TCP_NODELAY, &optval, sizeof (optval)) < 0) { if( debug ) printf("client() - error setting TCP_NODELAY: %s\n", strerror(errno)); io_errors++; state_connecting--; continue; } } if ( !bind_port(sock) ) { state_connecting--; continue; } // Disable the Nagle algorithm so the kernel won't delay our // writes waiting for more data. if( 1 ) { optval = 1; //if (setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof (optval)) < 0) if (setsockopt (sock, SOL_TCP, TCP_NODELAY, &optval, sizeof (optval)) < 0) { if( debug ) printf("client() - error setting TCP_NODELAY: %s\n", strerror(errno)); io_errors++; state_connecting--; continue; } } // connect //output("connecting...\n"); server_num++; server_num = server_num % num_servers; GET_REAL_CPU_TICKS(start); ret = connect(sock, (struct sockaddr *)&servers[server_num].addr, sizeof(servers[0].addr)); GET_REAL_CPU_TICKS(end); if( ret < 0 ) { state_connecting--; hist_add(err_connect_hist, HIST_INTERVAL(start,end)); if( errno == EADDRNOTAVAIL ) { addrnotavail++; } else { io_errors++; if( debug ) printf("client() - error with connect(): %s\n", strerror(errno)); } GET_REAL_CPU_TICKS(start); state_closing++; close(sock); state_closing--; GET_REAL_CPU_TICKS(end); hist_add(close_unconnected_hist, HIST_INTERVAL(start,end)); continue; } hist_add(connect_hist, HIST_INTERVAL(start,end)); // Disable the Nagle algorithm so the kernel won't delay our // writes waiting for more data. if( 1 ) { optval = 1; //if (setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof (optval)) < 0) if (setsockopt (sock, SOL_TCP, TCP_NODELAY, &optval, sizeof (optval)) < 0) { if( debug ) printf("client() - error setting TCP_NODELAY: %s\n", strerror(errno)); io_errors++; state_connecting--; continue; } } state_connecting--; // issue requests for( i=0; i<nreqs; i++ ) { len = snprintf(request, sizeof(request)-1, "GET /%s/dir%05d/class%d_%d HTTP/1.1\r\n" "Host: %s\r\n" //"User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; windows 98)\r\n" //"Accept: */*\r\n" //"Accept-Encoding: gzip, deflate\r\n" //"Accept-Language: en/us\r\n" //"Connection: Close\r\n" "\r\n", servers[server_num].url, spec_dir(), spec_class(), spec_file(), servers[server_num].hostname ); assert(len > 0); // note that we did some IO, so this thread has already yielded. did_some_io = 1; state_writing++; GET_REAL_CPU_TICKS(start); ret = write( sock, request, len ); GET_REAL_CPU_TICKS(end); hist_add(request_hist, HIST_INTERVAL(start,end)); state_writing--; // we do this here, instead of after connect b/c w/ Capriccio // the connect() call seems to always return immediately. good_conn++; if( len != ret ) { // FIXME: for now, don't add anything to the response hist, if we get a failure here if( errno == ETIMEDOUT ) { conn_timedout++; } else { if(debug) printf("client() - error writing request: %s\n", strerror(errno)); io_errors++; } break; } //output("reading response...\n"); state_reading++; GET_REAL_CPU_TICKS(start); if( read_response( sock ) == 0 ) requests_completed++; else bad_conn++; GET_REAL_CPU_TICKS(end); hist_add(response_hist, HIST_INTERVAL(start,end)); state_reading--; // FIXME: close the connection on errors? // sleep for a second if(i < nreqs-1 && sleep_ms > 0) { state_idle++; GET_REAL_CPU_TICKS(start); usleep(sleep_ms*1000); GET_REAL_CPU_TICKS(end); hist_add(sleep_hist, HIST_INTERVAL(start,end)); state_idle--; } } //output("closing...\n"); state_closing++; GET_REAL_CPU_TICKS(start); close( sock ); GET_REAL_CPU_TICKS(end); hist_add(close_hist, HIST_INTERVAL(start,end)); state_closing--; } return NULL; }
char *readline(const char *prompt) { char *line; /* Unless called by the user already. */ rl_initialize(); if (!isatty(0)) { tty_flush(); return read_redirected(); } if (!rl_line_buffer) { Length = MEM_INC; rl_line_buffer = malloc(sizeof(char) * Length); if (!rl_line_buffer) return NULL; } tty_info(); rl_prep_term_function(!rl_meta_chars); hist_add(NILSTR); ScreenSize = SCREEN_INC; Screen = malloc(sizeof(char) * ScreenSize); if (!Screen) return NULL; rl_prompt = prompt ? prompt : NILSTR; if (el_no_echo) { int old = el_no_echo; el_no_echo = 0; tty_puts(rl_prompt); tty_flush(); el_no_echo = old; } else { tty_puts(rl_prompt); } line = editinput(); if (line) { line = strdup(line); tty_puts(NEWLINE); tty_flush(); } rl_deprep_term_function(); free(Screen); free(H.Lines[--H.Size]); /* Add to history, unless no-echo or no-history mode ... */ if (!el_no_echo && !el_no_hist) { if (line != NULL && *line != '\0') hist_add(line); } if (el_intr_pending > 0) { int s = el_intr_pending; el_intr_pending = 0; kill(getpid(), s); } return line; }
void Querytextedit::errors_occured(bool errors) { if(!errors) hist_add(this->toPlainText()); }
char * tin_getline( const char *prompt, int number_only, /* 1=positive numbers only, 2=negative too */ const char *str, int max_chars, t_bool passwd, int which_hist) { int c, i, loc, tmp, gl_max; #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wint_t wc; #else char *buf = gl_buf; #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ is_passwd = passwd; set_xclick_off(); if (prompt == NULL) prompt = ""; gl_buf[0] = 0; /* used as end of input indicator */ gl_fixup(-1, 0); /* this resets gl_fixup */ gl_width = cCOLS - strlen(prompt); gl_prompt = prompt; gl_pos = gl_cnt = 0; if (max_chars == 0) { if (number_only) gl_max = 6; else gl_max = BUF_SIZE; } else gl_max = max_chars; my_fputs(prompt, stdout); cursoron(); my_flush(); if (gl_in_hook) { loc = gl_in_hook(gl_buf); if (loc >= 0) gl_fixup(0, BUF_SIZE); } if (!cmd_line && gl_max == BUF_SIZE) CleartoEOLN(); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) if (str != NULL) { wchar_t wbuf[LEN]; if (mbstowcs(wbuf, str, ARRAY_SIZE(wbuf) - 1) != (size_t) -1) { wbuf[ARRAY_SIZE(wbuf) - 1] = (wchar_t) '\0'; for (i = 0; wbuf[i]; i++) gl_addwchar(wbuf[i]); } } while ((wc = ReadWch()) != WEOF) { if ((gl_cnt < gl_max) && iswprint(wc)) { if (number_only) { if (iswdigit(wc)) { gl_addwchar(wc); /* Minus */ } else if (number_only == 2 && gl_pos == 0 && wc == (wint_t) '-') { gl_addwchar(wc); } else { ring_bell(); } } else gl_addwchar(wc); } else { c = (int) wc; switch (wc) { #else if (str != NULL) { for (i = 0; str[i]; i++) gl_addchar(str[i]); } while ((c = ReadCh()) != EOF) { c &= 0xff; if ((gl_cnt < gl_max) && my_isprint(c)) { if (number_only) { if (isdigit(c)) { gl_addchar(c); /* Minus */ } else if (number_only == 2 && gl_pos == 0 && c == '-') { gl_addchar(c); } else { ring_bell(); } } else gl_addchar(c); } else { switch (c) { #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ case ESC: /* abort */ #ifdef HAVE_KEY_PREFIX case KEY_PREFIX: #endif /* HAVE_KEY_PREFIX */ switch (get_arrow_key(c)) { case KEYMAP_UP: case KEYMAP_PAGE_UP: hist_prev(which_hist); break; case KEYMAP_PAGE_DOWN: case KEYMAP_DOWN: hist_next(which_hist); break; case KEYMAP_RIGHT: gl_fixup(-1, gl_pos + 1); break; case KEYMAP_LEFT: gl_fixup(-1, gl_pos - 1); break; case KEYMAP_HOME: gl_fixup(-1, 0); break; case KEYMAP_END: gl_fixup(-1, gl_cnt); break; case KEYMAP_DEL: gl_del(0); break; case KEYMAP_INS: #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_addwchar((wint_t) ' '); #else gl_addchar(' '); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ break; default: return (char *) 0; } break; case '\n': /* newline */ case '\r': gl_newline(which_hist); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wcstombs(buf, gl_buf, BUF_SIZE - 1); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ return buf; case CTRL_A: gl_fixup(-1, 0); break; case CTRL_B: gl_fixup(-1, gl_pos - 1); break; case CTRL_D: if (gl_cnt == 0) { gl_buf[0] = 0; my_fputc('\n', stdout); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wcstombs(buf, gl_buf, BUF_SIZE - 1); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ return buf; } else gl_del(0); break; case CTRL_E: gl_fixup(-1, gl_cnt); break; case CTRL_F: gl_fixup(-1, gl_pos + 1); break; case CTRL_H: case DEL: gl_del(-1); break; case TAB: if (gl_tab_hook) { tmp = gl_pos; loc = gl_tab_hook(gl_buf, strlen(gl_prompt), &tmp); if (loc >= 0 || tmp != gl_pos) gl_fixup(loc, tmp); } break; case CTRL_W: gl_kill_back_word(); break; case CTRL_U: gl_fixup(-1, 0); /* FALLTHROUGH */ case CTRL_K: gl_kill(); break; case CTRL_L: case CTRL_R: gl_redraw(); break; case CTRL_N: hist_next(which_hist); break; case CTRL_P: hist_prev(which_hist); break; default: ring_bell(); break; } } } #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) wcstombs(buf, gl_buf, BUF_SIZE - 1); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ return buf; } /* * adds the character c to the input buffer at current location if * the character is in the allowed template of characters */ static void #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_addwchar( wint_t wc) #else gl_addchar( int c) #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ { int i; /* * Crashing is always the worst solution IMHO. So as a quick hack, * ignore characters silently, if buffer is full. To allow a final * newline, leave space for one more character. Just a hack too. * This was the original code: * if (gl_cnt >= BUF_SIZE - 1) { error_message("tin_getline: input buffer overflow"); giveup(); } */ if (gl_cnt >= BUF_SIZE - 2) return; for (i = gl_cnt; i >= gl_pos; i--) gl_buf[i + 1] = gl_buf[i]; #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_buf[gl_pos] = (wchar_t) wc; #else gl_buf[gl_pos] = c; #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ gl_fixup(gl_pos, gl_pos + 1); } /* * Cleans up entire line before returning to caller. A \n is appended. * If line longer than screen, we redraw starting at beginning */ static void gl_newline( int w) { int change = gl_cnt; int len = gl_cnt; int loc = gl_width - 5; /* shifts line back to start position */ if (gl_cnt >= BUF_SIZE - 1) { /* * Like above: avoid crashing if possible. gl_addchar() now * leaves one space left for the newline, so this part of the * code should never be reached. A proper implementation is * desirable though. */ error_message("tin_getline: input buffer overflow"); giveup(); } hist_add(w); /* only adds if nonblank */ if (gl_out_hook) { change = gl_out_hook(gl_buf); #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) len = wcslen(gl_buf); #else len = strlen(gl_buf); #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ } if (loc > len) loc = len; gl_fixup(change, loc); /* must do this before appending \n */ #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) gl_buf[len] = (wchar_t) '\0'; #else gl_buf[len] = '\0'; #endif /* MULTIBYTE_ABLE && !NO_LOCALE */ } /* * Delete a character. The loc variable can be: * -1 : delete character to left of cursor * 0 : delete character under cursor */ static void gl_del( int loc) { int i; if ((loc == -1 && gl_pos > 0) || (loc == 0 && gl_pos < gl_cnt)) { for (i = gl_pos + loc; i < gl_cnt; i++) gl_buf[i] = gl_buf[i + 1]; gl_fixup(gl_pos + loc, gl_pos + loc); } else ring_bell(); }