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; }
/* Associate a buffer with a file and rename it to match the filename. Find a unique buffer name */ void set_filename(EditBuffer *b, const char *filename) { const char *p; pstrcpy(b->filename, sizeof(b->filename), filename); p = basename(filename); set_buffer_name(b, p); }
EditBuffer *new_shell_buffer(const char *name, const char *path, const char **argv, int is_shell) { ShellState *s; EditBuffer *b, *b_color; b = eb_new("", BF_SAVELOG); if (!b) return NULL; set_buffer_name(b, name); /* ensure that the name is unique */ eb_set_charset(b, &charset_vt100); s = malloc(sizeof(ShellState)); if (!s) { eb_free(b); return NULL; } memset(s, 0, sizeof(ShellState)); b->priv_data = s; b->close = shell_close; eb_add_callback(b, eb_offset_callback, &s->cur_offset); s->b = b; s->pty_fd = -1; s->pid = -1; s->is_shell = is_shell; s->qe_state = &qe_state; tty_init(s); /* add color buffer */ if (is_shell) { b_color = eb_new("*color*", BF_SYSTEM); if (!b_color) { eb_free(b); free(s); return NULL; } /* no undo info in this color buffer */ b_color->save_log = 0; eb_add_callback(b, shell_color_callback, s); s->b_color = b_color; } /* launch shell */ if (run_process(path, argv, &s->pty_fd, &s->pid) < 0) { eb_free(b); return NULL; } set_read_handler(s->pty_fd, shell_read_cb, s); set_pid_handler(s->pid, shell_pid_cb, s); return b; }
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; }