void _stack_items_free(char **in_string, int in_count) { if (!in_string) return; for (int i = 0; i < in_count; i++) if (in_string[i]) _stack_free(in_string[i]); _stack_free(in_string); }
SerBuff* serbuff_create(Stack *in_stack, void *in_data, long in_size, int in_nocopy) { assert(IS_STACK(in_stack)); assert(IS_BOOL(in_nocopy)); SerBuff *buff = _stack_malloc(sizeof(struct SerBuff)); if (!buff) return _stack_panic_null(in_stack, STACK_ERR_MEMORY); buff->stack = in_stack; buff->readonly = 0; if (in_nocopy) { buff->data = in_data; buff->size = in_size; buff->alloc = in_size; buff->readonly = 1; } else { buff->data = _stack_malloc(in_size); if (!buff->data) { _stack_free(buff); return _stack_panic_null(in_stack, STACK_ERR_MEMORY); } buff->size = in_size; buff->alloc = in_size; memcpy(buff->data, in_data, in_size); } buff->read_offset = 0; return buff; }
void _undo_stack_destroy(Stack *in_stack) { if (!in_stack->undo_stack) return; stack_undo_flush(in_stack); if (in_stack->undo_stack) _stack_free(in_stack->undo_stack); }
static void _undo_stack_frame_clear(Stack *in_stack, int in_frame_index) { assert(in_stack->undo_stack != NULL); struct UndoFrame *frame = in_stack->undo_stack + in_frame_index; if (frame->description) _stack_free(frame->description); frame->description = NULL; for (int i = 0; i < frame->step_count; i++) { struct UndoStep *step = frame->steps + i; if (step->data) serbuff_destroy(step->data, 1); } if (frame->steps) _stack_free(frame->steps); frame->steps = NULL; frame->step_count = 0; }
static void _undo_process_frame(Stack *in_stack, struct UndoFrame *in_frame) { assert(in_stack->undo_stack != NULL); struct UndoFrame saved_frame; /* save the frame */ saved_frame = *in_frame; /* reset the input frame */ in_frame->step_count = 0; in_frame->steps = NULL; /* play back steps of saved frame */ in_stack->record_undo_steps = 1; for (int i = saved_frame.step_count-1; i >= 0; i--) { struct UndoStep *step = saved_frame.steps + i; _undo_play_step(in_stack, step->action, step->data); /* cleanup */ if (step->data) serbuff_destroy(step->data, 1); } if (saved_frame.steps) _stack_free(saved_frame.steps); in_stack->record_undo_steps = 0; }
/* * stack_res_get * --------------------------------------------------------------------------------------------- * Accesses the details and/or data of the resource with the specified ID and type. * Returns STACK_YES on success, STACK_NO otherwise. * * Only returns the arguments for which a non-NULL pointer is supplied. * * The result string and data remain valid until the next call, the stack is closed or * stack_res_type_n() is invoked. * * An error can occur because the resource cannot be found or because of an I/O error. */ int stack_res_get(Stack *in_stack, int in_id, char const *in_type, char **out_name, void **out_data, long *out_size) { assert(IS_STACK(in_stack)); assert(in_id >= 1); if (in_stack->_returned_res_str) _stack_free(in_stack->_returned_res_str); in_stack->_returned_res_str = NULL; if (in_stack->_returned_res_data) _stack_free(in_stack->_returned_res_data); in_stack->_returned_res_data = NULL; long data_size = 0; sqlite3_stmt *stmt; sqlite3_prepare_v2(in_stack->db, "SELECT resourcename,data FROM resource WHERE resourceid=?1 AND resourcetype=?2", -1, &stmt, NULL); sqlite3_bind_int(stmt, 1, in_id); sqlite3_bind_text(stmt, 2, in_type, -1, SQLITE_STATIC); int err = sqlite3_step(stmt); if (err == SQLITE_ROW) { in_stack->_returned_res_str = _stack_clone_cstr((char*)sqlite3_column_text(stmt, 0)); data_size = sqlite3_column_bytes(stmt, 1); in_stack->_returned_res_data = _stack_malloc(data_size); if (!in_stack->_returned_res_data) { _stack_panic_void(in_stack, STACK_ERR_MEMORY); sqlite3_finalize(stmt); return STACK_NO; } else memcpy(in_stack->_returned_res_data, sqlite3_column_blob(stmt, 1), data_size); } sqlite3_finalize(stmt); if (err == SQLITE_ROW) { if (out_name) *out_name = in_stack->_returned_res_str; if (out_data) *out_data = in_stack->_returned_res_data; if (out_size) *out_size = data_size; return STACK_YES; } else return STACK_NO; }
/* * stack_res_type_n * --------------------------------------------------------------------------------------------- * Returns the name of the resource type with the specified number. Use with * stack_res_type_count() to enumerate the various types of resources saved within the stack. * * The result string remains valid until the next call, the stack is closed or stack_res_get() * is invoked. * * Returns NULL if no such type exists. */ char const* stack_res_type_n(Stack *in_stack, int in_number) { assert(IS_STACK(in_stack)); assert(in_number >= 1); if (in_stack->_returned_res_str) _stack_free(in_stack->_returned_res_str); in_stack->_returned_res_str = NULL; sqlite3_stmt *stmt; sqlite3_prepare_v2(in_stack->db, "SELECT DISTINCT resourcetype FROM resource ORDER BY resourcetype LIMIT ?1,1", -1, &stmt, NULL); sqlite3_bind_int(stmt, 1, in_number-1); int err = sqlite3_step(stmt); if (err == SQLITE_ROW) { in_stack->_returned_res_str = _stack_clone_cstr((char*)sqlite3_column_text(stmt, 0)); } sqlite3_finalize(stmt); return in_stack->_returned_res_str; }
char const* stack_name(Stack *in_stack) { if (in_stack->name) return in_stack->name; char *temp = _stack_clone_cstr(in_stack->pathname); in_stack->name = _stack_clone_cstr( basename(temp) ); _stack_free(temp); long len = strlen(in_stack->name); for (long i = len-1; i >= 0; i--) { if (in_stack->name[i] == '.') { in_stack->name[i] = 0; break; } } return in_stack->name; }
void _zombify( pcb_t *pcb ) { pcb_t *parent; status_t stat; pid_t pid; key_t key; info_t *info; // sanity check if( pcb == NULL ) { _kpanic( "_zombify", "null pcb", 0 ); } // Locate the parent of this process parent = _pcb_find( pcb->ppid ); if( parent == NULL ) { c_printf( "** zombify(): pid %d ppid %d\n", pcb->pid, pcb->ppid ); _kpanic( "_zombify", "no process parent", 0 ); } // // Found the parent. If it's waiting for this process, // wake it up, give it this process' status, and clean up. // if( parent->state == WAITING ) { // get the address of the info structure from the // parent, and pull out the desired PID info = (info_t *) ARG(parent->context,1); pid = info->pid; // if the parent was waiting for any of its children // or was waiting for us specifically, give it our // information and terminate this process. // // if the parent was waiting for another child, // turn this process into a zombie. if( pid == 0 || pid == _current->pid ) { // pull the parent off the waiting queue key.u = parent->pid; stat = _q_remove_by_key(&_waiting,(void **)&parent,key); if( stat != E_SUCCESS ) { _kpanic( "_zombify", "wait remove status %s", stat ); } // return our PID and our termination status // to the parent info->pid = _current->pid; info->status = ARG(_current->context,1); // clean up this process stat = _stack_free( pcb->stack ); if( stat != E_SUCCESS ) { _kpanic( "_zombify", "stack free status %s", stat ); } stat = _pcb_free( pcb ); if( stat != E_SUCCESS ) { _kpanic( "_zombify", "pcb free status %s", stat ); } // schedule the parent; give it a quick dispatch _schedule( parent, PRIO_MAXIMUM ); return; } } // // Our parent either wasn't waiting, or was waiting for someone // else. Put this process on the zombie queue until our parent // wants us. // key.u = _current->pid; _current->state = ZOMBIE; stat = _q_insert( &_zombie, (void *)_current, key ); if( stat != E_SUCCESS ) { _kpanic( "_zombify", "zombie insert status %s", stat ); } }
void serbuff_destroy(SerBuff *in_buff, int in_cleanup_data) { if (in_buff->data && in_cleanup_data) _stack_free(in_buff->data); _stack_free(in_buff); }