⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 getline.c

📁 BCAST Implementation for NS2
💻 C
📖 第 1 页 / 共 5 页
字号:
    const struct GlDefSignal *sig = gl_signal_list + i;    if(gl_trap_signal(gl, sig->signo, sig->flags, sig->after,		       sig->errno_value))      return del_GetLine(gl);  };/* * Allocate an empty table of key bindings. */  gl->bindings = _new_KeyTab();  if(!gl->bindings)    return del_GetLine(gl);/* * Define the available actions that can be bound to key sequences. */  for(i=0; i<sizeof(gl_actions)/sizeof(gl_actions[0]); i++) {    if(_kt_set_action(gl->bindings, gl_actions[i].name, gl_actions[i].fn))      return del_GetLine(gl);  };/* * Set up the default bindings. */  if(gl_change_editor(gl, gl->editor))    return del_GetLine(gl);/* * Allocate termcap buffers. */#ifdef USE_TERMCAP  gl->tgetent_buf = (char *) malloc(TERMCAP_BUF_SIZE);  gl->tgetstr_buf = (char *) malloc(TERMCAP_BUF_SIZE);  if(!gl->tgetent_buf || !gl->tgetstr_buf) {    fprintf(stderr, "new_GetLine: Insufficient memory for termcap buffers.\n");    return del_GetLine(gl);  };#endif/* * Set up for I/O assuming stdin and stdout. */  if(gl_change_terminal(gl, stdin, stdout, getenv("TERM")))    return del_GetLine(gl);/* * Create a freelist for use in allocating GlFdNode list nodes. */#ifdef HAVE_SELECT  gl->fd_node_mem = _new_FreeList("new_GetLine", sizeof(GlFdNode),				  GLFD_FREELIST_BLOCKING);  if(!gl->fd_node_mem)    return del_GetLine(gl);#endif/* * We are done for now. */  return gl;}/*....................................................................... * Delete a GetLine object. * * Input: *  gl     GetLine *  The object to be deleted. * Output: *  return GetLine *  The deleted object (always NULL). */GetLine *del_GetLine(GetLine *gl){  if(gl) {    gl->glh = _del_GlHistory(gl->glh);    gl->cpl = del_WordCompletion(gl->cpl);    gl->ef = del_ExpandFile(gl->ef);    gl->capmem = _del_StringGroup(gl->capmem);    if(gl->line)      free(gl->line);    if(gl->cutbuf)      free(gl->cutbuf);    if(gl->vi.undo.line)      free(gl->vi.undo.line);    gl->sig_mem = _del_FreeList(NULL, gl->sig_mem, 1);    gl->sigs = NULL;       /* Already freed by freeing sig_mem */    gl->bindings = _del_KeyTab(gl->bindings);#ifdef USE_TERMCAP    if(gl->tgetent_buf)      free(gl->tgetent_buf);    if(gl->tgetstr_buf)      free(gl->tgetstr_buf);#endif    if(gl->file_fp)      fclose(gl->file_fp);    if(gl->term)      free(gl->term);#ifdef HAVE_SELECT    gl->fd_node_mem = _del_FreeList(NULL, gl->fd_node_mem, 1);#endif    free(gl);  };  return NULL;}/*....................................................................... * Bind a control or meta character to an action. * * Input: *  gl         GetLine *  The resource object of this program. *  binder    KtBinder    The source of the binding. *  c             char    The control or meta character. *                        If this is '\0', the call is ignored. *  action  const char *  The action name to bind the key to. * Output: *  return         int    0 - OK. *                        1 - Error. */static int gl_bind_control_char(GetLine *gl, KtBinder binder, char c,				const char *action){  char keyseq[2];/* * Quietly reject binding to the NUL control character, since this * is an ambiguous prefix of all bindings. */  if(c == '\0')    return 0;/* * Making sure not to bind characters which aren't either control or * meta characters. */  if(IS_CTRL_CHAR(c) || IS_META_CHAR(c)) {    keyseq[0] = c;    keyseq[1] = '\0';  } else {    return 0;  };/* * Install the binding. */  return _kt_set_keybinding(gl->bindings, binder, keyseq, action);}/*....................................................................... * Read a line from the user. * * Input: *  gl       GetLine *  A resource object returned by new_GetLine(). *  prompt      char *  The prompt to prefix the line with. *  start_line  char *  The initial contents of the input line, or NULL *                      if it should start out empty. *  start_pos    int    If start_line isn't NULL, this specifies the *                      index of the character over which the cursor *                      should initially be positioned within the line. *                      If you just want it to follow the last character *                      of the line, send -1. * Output: *  return      char *  An internal buffer containing the input line, or *                      NULL at the end of input. If the line fitted in *                      the buffer there will be a '\n' newline character *                      before the terminating '\0'. If it was truncated *                      there will be no newline character, and the remains *                      of the line should be retrieved via further calls *                      to this function. */char *gl_get_line(GetLine *gl, const char *prompt,		  const char *start_line, int start_pos){  int waserr = 0;    /* True if an error occurs */  gl->is_net = 0;    /* Reset the 'is_net' flag */  gl->net_may_block = 0;  gl->net_read_attempt = 0;  gl->user_event_value = 0;/* * Check the arguments. */  if(!gl || !prompt) {    fprintf(stderr, "gl_get_line: NULL argument(s).\n");    return NULL;  };/* * If this is the first call to this function since new_GetLine(), * complete any postponed configuration. */  if(!gl->configured) {    (void) gl_configure_getline(gl, NULL, NULL, TECLA_CONFIG_FILE);    gl->configured = 1;  };/* * If input is temporarily being taken from a file, return lines * from the file until the file is exhausted, then revert to * the normal input stream. */  if(gl->file_fp) {    if(fgets(gl->line, gl->linelen, gl->file_fp))      return gl->line;    gl_revert_input(gl);  };/* * Is input coming from a non-interactive source? */  if(!gl->is_term)    return fgets(gl->line, gl->linelen, gl->input_fp);/* * Record the new prompt and its displayed width. */  gl_replace_prompt(gl, prompt);/* * Before installing our signal handler functions, record the fact * that there are no pending signals. */  gl_pending_signal = -1;/* * Temporarily override the signal handlers of the calling program, * so that we can intercept signals that would leave the terminal * in a bad state. */  waserr = gl_override_signal_handlers(gl);/* * After recording the current terminal settings, switch the terminal * into raw input mode. */  waserr = waserr || gl_raw_terminal_mode(gl);/* * Attempt to read the line. */  waserr = waserr || gl_get_input_line(gl, start_line, start_pos, -1);/* * Restore terminal settings. */  gl_restore_terminal_attributes(gl);/* * Restore the signal handlers. */  gl_restore_signal_handlers(gl);/* * Having restored the program terminal and signal environment, * re-submit any signals that were received. */  if(gl_pending_signal != -1) {    raise(gl_pending_signal);    waserr = 1;  };/* * If gl_get_input_line() aborted input due to the user asking to * temporarily read lines from a file, read the first line from * this file. */  if(!waserr && gl->file_fp)    return gl_get_line(gl, prompt, NULL, 0);/* * Return the new input line. */  return waserr ? NULL : gl->line;}/*....................................................................... * Record of the signal handlers of the calling program, so that they * can be restored later. * * Input: *  gl    GetLine *   The resource object of this library. * Output: *  return    int     0 - OK. *                    1 - Error. */static int gl_override_signal_handlers(GetLine *gl){  GlSignalNode *sig;   /* A node in the list of signals to be caught *//* * Set up our signal handler. */  SigAction act;  act.sa_handler = gl_signal_handler;  sigemptyset(&act.sa_mask);  act.sa_flags = 0;/* * Get the process signal mask so that we can see which signals the * calling program currently has blocked, and so that we can restore this * mask before returning to the calling program. */  if(sigprocmask(SIG_SETMASK, NULL, &gl->old_signal_set) == -1) {    fprintf(stderr, "gl_get_line(): sigprocmask error: %s\n", strerror(errno));    return 1;  };/* * Form a new process signal mask from the list of signals that we have * been asked to trap. */  sigemptyset(&gl->new_signal_set);  for(sig=gl->sigs; sig; sig=sig->next) {/* * Trap this signal? If it is blocked by the calling program and we * haven't been told to unblock it, don't arrange to trap this signal. */    if(sig->flags & GLS_UNBLOCK_SIG ||       !sigismember(&gl->old_signal_set, sig->signo)) {      if(sigaddset(&gl->new_signal_set, sig->signo) == -1) {	fprintf(stderr, "gl_get_line(): sigaddset error: %s\n",		strerror(errno));	return 1;      };    };  };/* * Before installing our signal handlers, block all of the signals * that we are going to be trapping. */  if(sigprocmask(SIG_BLOCK, &gl->new_signal_set, NULL) == -1) {    fprintf(stderr, "gl_get_line(): sigprocmask error: %s\n", strerror(errno));    return 1;  };/* * Override the actions of the signals that we are trapping. */  for(sig=gl->sigs; sig; sig=sig->next) {    if(sigismember(&gl->new_signal_set, sig->signo) &&       sigaction(sig->signo, &act, &sig->original)) {      fprintf(stderr, "gl_get_line(): sigaction error: %s\n", strerror(errno));      return 1;    };  };/* * Just in case a SIGWINCH signal was sent to the process while our * SIGWINCH signal handler wasn't in place, check to see if the terminal * size needs updating. */#ifdef USE_SIGWINCH  if (gl->is_term) {    if(gl_resize_terminal(gl, 0))      return 1;  }#endif  return 0;}/*....................................................................... * Restore the signal handlers of the calling program. * * Input: *  gl     GetLine *  The resource object of this library. * Output: *  return     int    0 - OK. *                    1 - Error. */static int gl_restore_signal_handlers(GetLine *gl){  GlSignalNode *sig;   /* A node in the list of signals to be caught *//* * Restore application signal handlers that were overriden * by gl_override_signal_handlers(). */  for(sig=gl->sigs; sig; sig=sig->next) {    if(sigismember(&gl->new_signal_set, sig->signo) &&       sigaction(sig->signo, &sig->original, NULL)) {      fprintf(stderr, "gl_get_line(): sigaction error: %s\n", strerror(errno));      return 1;    };  };/* * Restore the original signal mask. */  if(sigprocmask(SIG_SETMASK, &gl->old_signal_set, NULL) == -1) {    fprintf(stderr, "gl_get_line(): sigprocmask error: %s\n", strerror(errno));    return 1;  };  return 0;}/*....................................................................... * This signal handler simply records the fact that a given signal was * caught in the file-scope gl_pending_signal variable. */static void gl_signal_handler(int signo){  gl_pending_signal = signo;  siglongjmp(gl_setjmp_buffer, 1);}/*.......................................................................

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -