Exemple #1
0
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);
}
Exemple #2
0
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;
}
Exemple #3
0
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);
}
Exemple #4
0
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;
}
Exemple #5
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;
}
Exemple #6
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;
}
Exemple #7
0
/*
 *  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;
}
Exemple #8
0
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;
}
Exemple #9
0
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 );
	}

}
Exemple #10
0
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);
}