static void forked_child_init(void) { struct print_buffer *my_buffer = pthread_getspecific(buffer_key); struct print_buffer **pbuffer = &first_buffer; if (my_buffer) { /* Any content of my_buffer should be printed by our parent, not us. */ memset(my_buffer->ring, 0, my_buffer->size); my_buffer->read_pos = 0; my_buffer->write_pos = 0; } /* re-init to avoid finding it locked by some parent thread */ pthread_mutex_init(&buffer_lock, NULL); while (*pbuffer) { if (*pbuffer == my_buffer) pbuffer = &(*pbuffer)->next; else if ((unsigned long)*pbuffer - pool_start < pool_len) { cleanup_buffer(*pbuffer); pbuffer = &(*pbuffer)->next; } else cleanup_buffer(*pbuffer); } spawn_printer_thread(); }
int rt_print_init(size_t buffer_size, const char *buffer_name) { struct print_buffer *buffer = pthread_getspecific(__buffer_key); size_t size = buffer_size; if (!size) size = __default_buffer_size; else if (size < RT_PRINT_LINE_BREAK) return EINVAL; if (buffer) { /* Only set name if buffer size is unchanged or default */ if (size == buffer->size || !buffer_size) { set_buffer_name(buffer, buffer_name); return 0; } cleanup_buffer(buffer); } buffer = malloc(sizeof(*buffer)); if (!buffer) return ENOMEM; buffer->ring = malloc(size); if (!buffer->ring) { free(buffer); return ENOMEM; } memset(buffer->ring, 0, size); buffer->read_pos = 0; buffer->write_pos = 0; buffer->size = size; set_buffer_name(buffer, buffer_name); buffer->prev = NULL; pthread_mutex_lock(&__buffer_lock); buffer->next = __first_buffer; if (__first_buffer) __first_buffer->prev = buffer; __first_buffer = buffer; pthread_mutex_unlock(&__buffer_lock); pthread_setspecific(__buffer_key, buffer); return 0; }
void rt_print_cleanup(void) { struct print_buffer *buffer = pthread_getspecific(buffer_key); if (buffer) cleanup_buffer(buffer); else { pthread_mutex_lock(&buffer_lock); print_buffers(); pthread_mutex_unlock(&buffer_lock); } pthread_cancel(printer_thread); }
char *x_readline(const char *prompt) { static char buffer[1024]; if (prompt) fputs(prompt, stdout); fflush(stdout); for(;;) { int ok = read(STDIN_FILENO, buffer, sizeof(buffer)-1); if (ok < 0 && ok == EINTR) continue; if (ok <= 0) { if (prompt) fputc('\n', stdout); return NULL; } cleanup_buffer(buffer, ok); return buffer; } }
char *x_readline(const char *prompt) { static char buffer[1024]; char *cp; int count; if (!readline_init) { rl_readline_name = "GS+"; rl_attempted_completion_function = rl_acf; using_history(); stifle_history(HISTORY_SIZE); readline_init = 1; } cp = readline(prompt); if (!cp) { if (prompt) fputc('\n', stdout); return NULL; } count = strlen(cp); if (count > sizeof(buffer) - 1) { free(cp); return ""; } memcpy(buffer, cp, count); cleanup_buffer(buffer, count); free(cp); /* append to history, but only if unique from prev. entry */ if (*buffer) { HIST_ENTRY *h = history_get(history_length); if (h == NULL || strcmp(buffer, h->line)) add_history(buffer); } return buffer; }
char *x_readline(const char *prompt) { static char buffer[1024]; int count = 0; const char *cp; if (!el) { hist = history_init(); history(hist, &ev, H_SETSIZE, HISTORY_SIZE); history(hist, &ev, H_SETUNIQUE, 1); el = el_init("GS+", stdin, stdout, stderr); el_set(el, EL_EDITOR, "emacs"); el_set(el, EL_BIND, "-e", NULL, NULL, NULL); el_set(el, EL_HIST, history, hist); el_set(el, EL_PROMPT, prompt_fn); el_set(el, EL_SIGNAL, 1); el_source(el, NULL); } el_prompt = prompt; cp = el_gets(el, &count); el_prompt = NULL; if (count <= 0) { if (prompt) fputc('\n', stdout); return NULL; } if (count > sizeof(buffer) - 1) return ""; memcpy(buffer, cp, count); cleanup_buffer(buffer, count); if (*buffer) history(hist, &ev, H_ENTER, buffer); return buffer; }
int rt_print_init(size_t buffer_size, const char *buffer_name) { struct print_buffer *buffer = pthread_getspecific(buffer_key); size_t size = buffer_size; unsigned long old_bitmap; unsigned j; if (!size) size = __cobalt_print_bufsz; else if (size < RT_PRINT_LINE_BREAK) return EINVAL; if (buffer) { /* Only set name if buffer size is unchanged or default */ if (size == buffer->size || !buffer_size) { set_buffer_name(buffer, buffer_name); return 0; } cleanup_buffer(buffer); buffer = NULL; } /* Find a free buffer in the pool */ do { unsigned long bitmap; unsigned i; for (i = 0; i < pool_bitmap_len; i++) { old_bitmap = atomic_long_read(&pool_bitmap[i]); if (old_bitmap) goto acquire; } goto not_found; acquire: do { bitmap = old_bitmap; j = __builtin_ffsl(bitmap) - 1; old_bitmap = atomic_long_cmpxchg(&pool_bitmap[i], bitmap, bitmap & ~(1UL << j)); } while (old_bitmap != bitmap && old_bitmap); j += i * __WORDSIZE; } while (!old_bitmap); buffer = (struct print_buffer *)(pool_start + j * pool_buf_size); not_found: if (!buffer) { assert_nrt(); buffer = malloc(sizeof(*buffer)); if (!buffer) return ENOMEM; buffer->ring = malloc(size); if (!buffer->ring) return ENOMEM; rt_print_init_inner(buffer, size); } set_buffer_name(buffer, buffer_name); pthread_setspecific(buffer_key, buffer); return 0; }
char *x_readline(const char *prompt) { static char buffer[1024]; DWORD count = 0; BOOL ok; HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE); HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); /* MS CRT uses -2 to indicate there is no stdin/stdout/stderr fileno */ /* if (h == INVALID_HANDLE_VALUE) { //* cygwin? * / fputs("GetStdHandle\n", stderr); fflush(stderr); return NULL; char *cp; fputs(prompt, stdout); fflush(stdout); return fgets(buffer, sizeof(buffer), stdin); } */ if (!readline_init) { //struct stat st; CONSOLE_HISTORY_INFO chi; DWORD mode; memset(&chi, 0, sizeof(chi)); chi.cbSize = sizeof(CONSOLE_HISTORY_INFO); chi.HistoryBufferSize = HISTORY_SIZE; chi.NumberOfHistoryBuffers = 1; /* ???? */ chi.dwFlags = HISTORY_NO_DUP_FLAG; ok = SetConsoleHistoryInfo(&chi); if (!ok) { fprintf(stderr, "SetConsoleHistoryInfo: %lx\n", GetLastError()); fflush(stderr); } mode = ENABLE_ECHO_INPUT | ENABLE_EXTENDED_FLAGS | ENABLE_INSERT_MODE | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_QUICK_EDIT_MODE; ok = SetConsoleMode(hIn, mode); if (!ok) { fprintf(stderr, "SetConsoleMode: %lx (h = %p)\n", GetLastError(), hIn); fflush(stderr); } readline_init = 1; } fflush(stderr); fflush(stdout); ok = WriteConsole(hOut, prompt, strlen(prompt), NULL, NULL); if (!ok) { /* msys/cygwin? */ // fprintf(stderr, "WriteConsole: %lx (h = %p)\n", GetLastError(), hOut); fflush(stderr); if (prompt) fputs(prompt, stdout); fflush(stdout); char *cp = fgets(buffer, sizeof(buffer), stdin); if (!cp) { if (prompt) fputc('\n', stdout); return NULL; } cleanup_buffer(buffer, strlen(buffer)); return buffer; } ok = ReadConsole(hIn, buffer, sizeof(buffer), &count, NULL); if (!ok) { if (prompt) fputc('\n', stdout); // fflush(stdout); // fprintf(stderr, "Error: %lx (h = %p)\n", GetLastError(), hIn); // fprintf(stderr, "Type: %08x\n", GetFileType(hIn)); // fflush(stderr); return NULL; } cleanup_buffer(buffer, count); return buffer; }