Esempio n. 1
0
FKERN_API f8_status ex_stop()
{
	struct kernel_t * kernel = (struct kernel_t*)&g_kernel;
	
	printf("Shutting down F8 runtime kernel...\n");

	taskFlag = TSK_STOPPING;
	
	if(kthreadId){
		stop_rthread((RTK_HANDLE)kthreadId);
		close_handle((RTK_HANDLE)kthreadId);
	}
	if(agentThreadId){
		taskFlag = TSK_STOPPING;
		stop_rthread((RTK_HANDLE)agentThreadId);
		close_handle((RTK_HANDLE)agentThreadId);
	}
	kthreadId = 0;
	agentThreadId = 0;
	printf("F8 runtime kernel stopped.\n");
	ke_lock(kernel, 0);
	ki_save_nvram(kernel);
	ke_unlock(kernel,0);

	return F8_SUCCESS;
}
Esempio n. 2
0
static void debug_event_destroy( struct object *obj )
{
    struct debug_event *event = (struct debug_event *)obj;
    assert( obj->ops == &debug_event_ops );

    /* If the event has been sent already, the handles are now under the */
    /* responsibility of the debugger process, so we don't touch them    */
    if (event->state == EVENT_QUEUED)
    {
        struct process *debugger = event->debugger->process;
        switch(event->data.code)
        {
        case CREATE_THREAD_DEBUG_EVENT:
            close_handle( debugger, event->data.info.create_thread.handle, NULL );
            break;
        case CREATE_PROCESS_DEBUG_EVENT:
            if (event->data.info.create_process.file)
                close_handle( debugger, event->data.info.create_process.file, NULL );
            close_handle( debugger, event->data.info.create_process.thread, NULL );
            close_handle( debugger, event->data.info.create_process.process, NULL );
            break;
        case LOAD_DLL_DEBUG_EVENT:
            if (event->data.info.load_dll.handle)
                close_handle( debugger, event->data.info.load_dll.handle, NULL );
            break;
        }
    }
    if (event->sender->context == &event->context) event->sender->context = NULL;
    release_object( event->sender );
    release_object( event->debugger );
}
Esempio n. 3
0
extern void unmake_timer_thread(void)
{
  CONTEXT timer_thread_context;
  BOOL result;
  DIAGNOSTIC(2,"unmaking timer thread",0,0);
  suspend_thread(timer_thread);
  DIAGNOSTIC(3,"timer thread suspended",0,0);
  timer_thread_context.ContextFlags = CONTEXT_CONTROL;
  result = GetThreadContext((HANDLE)timer_thread,
			    &timer_thread_context);
  if (result == FALSE)
    error("GetThreadContext(timer) failed; GetLastError() returns %d",
	  GetLastError());
  DIAGNOSTIC(3,"timer thread context obtained",0,0);
  timer_thread_context.Eip = (DWORD)timer_thread_end;
  result = SetThreadContext((HANDLE)timer_thread,
			    &timer_thread_context);
  if (result == FALSE)
    error("SetThreadContext(timer) failed; GetLastError() returns %d",
	  GetLastError());
  DIAGNOSTIC(3,"timer thread context set",0,0);
  set_event(timer_event);
  DIAGNOSTIC(3,"timer event set",0,0);
  resume_thread(timer_thread);
  DIAGNOSTIC(3,"timer thread resumed",0,0);
  wait_for_event(timer_thread);
  DIAGNOSTIC(3,"timer thread signalled",0,0);
  close_handle(timer_thread);
  close_handle(timer_event);
  DIAGNOSTIC(2,"timer thread unmade and forgotten",0,0);
}
Esempio n. 4
0
int shim_do_pipe2 (int * filedes, int flags)
{
    if (!filedes)
        return -EINVAL;

    int ret = 0;

    struct shim_handle * hdl1 = get_new_handle();
    struct shim_handle * hdl2 = get_new_handle();

    if (!hdl1 || !hdl2) {
        ret = -ENOMEM;
        goto out;
    }

    hdl1->type       = TYPE_PIPE;
    set_handle_fs(hdl1, &pipe_builtin_fs);
    hdl1->flags      = O_RDONLY;
    hdl1->acc_mode   = MAY_READ;

    hdl2->type       = TYPE_PIPE;
    set_handle_fs(hdl2, &pipe_builtin_fs);
    hdl2->flags      = O_WRONLY;
    hdl2->acc_mode   = MAY_WRITE;

    if ((ret = create_pipes(&hdl1->info.pipe.pipeid,
                            &hdl1->pal_handle, &hdl2->pal_handle,
                            &hdl1->uri, flags)) < 0)
        goto out;

    qstrcopy(&hdl2->uri, &hdl2->uri);

    flags = flags & O_CLOEXEC ? FD_CLOEXEC : 0;
    int vfd1 = set_new_fd_handle(hdl1, flags, NULL);
    int vfd2 = set_new_fd_handle(hdl2, flags, NULL);

    if (vfd1 < 0 || vfd2 < 0) {
        if (vfd1 >= 0) {
            struct shim_handle * tmp = detach_fd_handle(vfd1, NULL, NULL);
            if (tmp)
                close_handle(tmp);
        }
        if (vfd2 >= 0) {
            struct shim_handle * tmp = detach_fd_handle(vfd2, NULL, NULL);
            if (tmp)
                close_handle(tmp);
        }
        goto out;
    }

    filedes[0] = vfd1;
    filedes[1] = vfd2;
out:
    if (hdl1)
        put_handle(hdl1);
    if (hdl2)
        put_handle(hdl2);
    return ret;
}
Esempio n. 5
0
static __uint _on_add_edit_tags(PCRTK_PACKET p)
{
	ONLINE_CONFIG::reload_tags_ack *ack;
	RTK_CURSOR	hNode, hTag, hGroup;
	RTK_TAG		*pTag;
	RTK_GROUP	grp;
	__bool		bEdit;
	
	__uint tagcount, i;

	ack = (ONLINE_CONFIG::reload_tags_ack *)p->data;
	tagcount = p->data_size / sizeof(*ack);
	if(p->data_size % sizeof(*ack)){
		return 0;
	}
	ZeroMemory(&grp, sizeof(grp));

	if( !lock_rtdb(__true, 100) ){
		return 0;
	}

	hNode = HNODE_LOCAL_MACHINE;
	hTag = hGroup = 0;
	host_to_node(&g_ThisNode->key, &grp.node);

	if(PACKET_TYPE(p) == PT_EditTag){
		bEdit = __true;
	}else{
		bEdit = __false;
	}

	for(i=0; i<tagcount; i++){
		hGroup = open_group(hNode, &ack[i].tag.group);
		grp.key = ack[i].tag.group;
		if(!hGroup){
			hGroup = create_group(hNode, &grp);
		}
		if(hGroup){
			hTag = create_tag(hGroup, &ack[i].tag.key, &ack[i].tag.s);
			pTag  = (RTK_TAG*)cursor_get_item(hTag);
			if(pTag){
				*pTag = ack[i].tag;
				mark_expired(pTag);
				close_handle(hTag);
				if(bEdit){
					// add-tag event is auto-fired
					fire_rtdb_event(EV_ModifyTag, pTag);
				}				
			}					
		}
		close_handle(hGroup);
	}

	unlock_rtdb();

	return tagcount;
}
Esempio n. 6
0
/*
	determine which tags should be saved to history database.
*/
void CInMemoryBuffer::buildStreamList()
{
	RTK_CURSOR hNode;
	RTK_CURSOR hGroup;
	RTK_CURSOR hTag;
	PCRTK_TAG  pTag;
	TAG_NAME tn;
	char nodeName[rtkm_node_key_length + 1];
	
	GetPrivateProfileString(
		"PMC",
		"ServerName",
		"LocalServer",
		nodeName,
		sizeof(nodeName),
		get_config_file()
		);
	CNodeName nodeKey(nodeName);

	//utils_debug("wlock 3\n");
	WriteLock();
	
	if(!lock_rtdb(__false, 100)){
		//utils_debug("release 6\n");
		Release();
		return;
	}
	
	// clear list
	clearStreamList();
	
	hNode = open_node(nodeKey);
	if(hNode){
		hGroup = cursor_open_first_subitem(hNode);
		while(!cursor_is_end(hGroup)){
			hTag = cursor_open_first_subitem(hGroup);
			while(!cursor_is_end(hTag)){
				pTag = (PCRTK_TAG)cursor_get_item(hTag);
				if(pTag->s.Flags & TF_SaveToHistory){
					tn.node = pTag->node;
					tn.sname.group = pTag->group;
					tn.sname.tag = pTag->key;
					addTag(&tn);
				}
				cursor_move_next(hTag);
			}
			close_handle(hTag);
			cursor_move_next(hGroup);
		}
		close_handle(hGroup);
	}

	unlock_rtdb();
	
	//utils_debug("release 7\n");
	Release();
}
Esempio n. 7
0
__uint _fastcall _read_tags(
	__uint count, 
	PCTAG_NAME names, 
	Ppmc_value_t values,
	__uint & existed
	)
{
	RTK_CURSOR	hNode, hTag;
	NODE_KEY	cachedNode;
	RTK_TAG		*pTag;
	__uint		i, valids;

	valids = 0;
	existed = 0;
	ZeroMemory(values, sizeof(values[0]) * count);
	if(!lock_rtdb(false, 1000)){
		return 0;
	}
	hNode = 0;
	hTag = 0;
	RTK_TIME now;
	rtk_time_mark(&now);
	hNode = 0;
	memset(&cachedNode, 0, sizeof(cachedNode));
	for(i=0; i<count; i++){
		if(!(cachedNode == names[i].node)){
			close_handle(hNode);
			hNode = 0;			
		}
		if(!hNode){
			hNode = open_node(&names[i].node);
			cachedNode = names[i].node;
		}
		if(!hNode){
			values[i].Flags &= ~TF_Valid;
			continue;
		}		
		hTag = open_tag(hNode, &names[i].sname);
		if(hTag){
			existed++;
			pTag = (RTK_TAG*)cursor_get_item(hTag);
			double diff;
			diff = rtk_time_diff(&now, &pTag->d.CachedTime);
			if(diff > (g_fltTagLife*2)){
				mark_expired(pTag);
			}
			values[i] = pTag->d.Value;
			valids++;
			close_handle(hTag);
		}else{
			values[i].Flags &= ~TF_Valid;
		}		
	}
	close_handle(hNode);
	unlock_rtdb();
	return valids;
}
Esempio n. 8
0
extern void native_unmake_thread(struct c_state *c_state)
{
  DIAGNOSTIC(2,"unmaking native thread",0,0);
  c_state->eip = (word)native_thread_exit;
  set_event(c_state->native.event);
  DIAGNOSTIC(3,"set event on thread to unmake, waiting on thread",0,0);
  wait_for_event(c_state->native.thread);
  DIAGNOSTIC(3,"unmade thread signalled, closing handles",0,0);
  close_handle(c_state->native.thread);
  close_handle(c_state->native.event);
  DIAGNOSTIC(3,"closed handles; native thread is history",0,0);
}
Esempio n. 9
0
static void close_all(bt_push_t *push)
{
    bt_client_t *client = push->client;
    close_handle(push->port.protocol, push->server);
    while (client != NULL) {
        bt_client_t *next = client->next;
        close_handle(push->port.protocol, client->handle);
        pcsl_mem_free(client);
        client = next;
    }
    push->client = NULL;
}
Esempio n. 10
0
int free_resources_and_exit(const int return_code) {
    close_handle(in_read);
    close_handle(in_write);
    close_handle(out_read);
    close_handle(out_write);

    if (wsl_lib) {
        FreeLibrary(wsl_lib);
    }

    return return_code;
}
Esempio n. 11
0
File: tftp.c Progetto: olsner/lwip
/** @ingroup tftp
 * Deinitialize ("turn off") TFTP client/server.
 */
void tftp_cleanup(void)
{
  LWIP_ASSERT("Cleanup called on non-initialized TFTP", tftp_state.upcb != NULL);
  udp_remove(tftp_state.upcb);
  close_handle();
  memset(&tftp_state, 0, sizeof(tftp_state));
}
Esempio n. 12
0
int iterate_usb(int (is_interesting)(struct usb_device *), 
	int (do_open)(struct usb_dev_handle *),
	int (do_process)(struct usb_dev_handle *),
	int (do_close)(struct usb_dev_handle *)
	)
{
	usb_find_busses();
	usb_find_devices();

	int result = 0;
	struct usb_bus *bus;
	struct usb_device *dev;
 
	for (bus = usb_busses; bus; bus = bus->next) {
		for (dev = bus->devices; dev; dev = dev->next) {
			if (is_interesting(dev)) {
				struct usb_dev_handle *handle = open_handle_for_device(dev, do_open);
				if (handle) {
					if (do_process) 
						result += do_process(handle);
					
					if (do_close)
						result += close_handle(handle, do_close);
				}
				else {
					result += 1;
				}
			}
		}
	}
	return result;
}
Esempio n. 13
0
static int fill_create_process_event( struct debug_event *event, const void *arg )
{
    struct process *debugger = event->debugger->process;
    struct thread *thread = event->sender;
    struct process *process = thread->process;
    struct process_dll *exe_module = get_process_exe_module( process );
    const client_ptr_t *entry = arg;
    obj_handle_t handle;

    /* documented: PROCESS_VM_READ | PROCESS_VM_WRITE */
    if (!(handle = alloc_handle( debugger, process, PROCESS_ALL_ACCESS, 0 ))) return 0;
    event->data.create_process.process = handle;

    /* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
    if (!(handle = alloc_handle( debugger, thread, THREAD_ALL_ACCESS, 0 )))
    {
        close_handle( debugger, event->data.create_process.process );
        return 0;
    }
    event->data.create_process.thread     = handle;
    event->data.create_process.file       = 0;
    event->data.create_process.teb        = thread->teb;
    event->data.create_process.base       = exe_module->base;
    event->data.create_process.start      = *entry;
    event->data.create_process.dbg_offset = exe_module->dbg_offset;
    event->data.create_process.dbg_size   = exe_module->dbg_size;
    event->data.create_process.name       = exe_module->name;
    event->data.create_process.unicode    = 1;

    if (exe_module->mapping)  /* the doc says write access too, but this doesn't seem a good idea */
        event->data.create_process.file = open_mapping_file( debugger, exe_module->mapping, GENERIC_READ,
                                                             FILE_SHARE_READ | FILE_SHARE_WRITE );
    return 1;
}
Esempio n. 14
0
bool redir_t::spawn_child(LPCTSTR cmdline, HANDLE h_stdout, HANDLE h_stdin, HANDLE h_stderr, LPCTSTR working_directory)
{
	PROCESS_INFORMATION pi;
	STARTUPINFO si = {0};

	si.cb = sizeof(si);
	si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
	si.wShowWindow = SW_HIDE;
	si.hStdInput = h_stdin;
	si.hStdOutput = h_stdout;
	si.hStdError = h_stderr;

	if(!::CreateProcess(nullptr, (LPTSTR)cmdline,
		nullptr, nullptr,
		TRUE,
		CREATE_NEW_CONSOLE,
		NULL,
		working_directory,
		&si, &pi))
	{
		return false;
	}

	_h_child_process = pi.hProcess;
	close_handle(pi.hThread);

	return true;
}
Esempio n. 15
0
static void
send_data(void)
{
  u16_t *payload;
  int ret;

  if(tftp_state.last_data != NULL) {
    pbuf_free(tftp_state.last_data);
  }
  
  tftp_state.last_data = pbuf_alloc(PBUF_TRANSPORT, TFTP_HEADER_LENGTH + TFTP_MAX_PAYLOAD_SIZE, PBUF_RAM);
  if(tftp_state.last_data == NULL) {
    return;
  }

  payload = (u16_t *) tftp_state.last_data->payload;
  payload[0] = PP_HTONS(TFTP_DATA);
  payload[1] = lwip_htons(tftp_state.blknum);

  ret = tftp_state.ctx->read(tftp_state.handle, &payload[2], TFTP_MAX_PAYLOAD_SIZE);
  if (ret < 0) {
    send_error(&tftp_state.addr, tftp_state.port, TFTP_ERROR_ACCESS_VIOLATION, "Error occured while reading the file.");
    close_handle();
    return;
  }

  pbuf_realloc(tftp_state.last_data, (u16_t)(TFTP_HEADER_LENGTH + ret));
  resend_data();
}
Esempio n. 16
0
void tftp_tmr(void)
{
    tftp_state.timer++;

    if (tftp_state.handle == NULL)
        return;

    if ((tftp_state.timer - tftp_state.last_pkt) >
        (TFTP_TIMEOUT_MSECS / TFTP_TIMER_MSECS))
    {
        if (tftp_state.last_data != NULL &&
            tftp_state.retries < TFTP_MAX_RETRIES)
        {
            LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE,
                    ("tftp: timeout, retrying\n"));

            resend_data(tftp_state.upcb, tftp_state.addr,
                        tftp_state.port, &tftp_state);
            tftp_state.retries++;
        } else {
            LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE,
                    ("tftp: timeout\n"));
            close_handle(&tftp_state);
        }

    }
}
Esempio n. 17
0
struct fnode *fnode_set_path(struct fnode *node, const char *path) {

    int lenstr = 0;

    if (strlen(path) > PATH_MAX)
        return NULL;

    if (NULL == node)
        return NULL;

    if (NULL != node->path) {
        free(node->path);
        node->path = NULL;

        /* Also close the filehandle if it's open--otherwise it would get
           lost */
        close_handle(node);
    }

    if (NULL == path)
        return node;

    lenstr = strlen(path) + 1;
    node->path = calloc(1, sizeof(char)*lenstr);

    if (NULL == node->path)
        return NULL;

    strncpy(node->path, path, lenstr);

    return node;
}
Esempio n. 18
0
FILE *fnode_fopen(struct fnode *node) {

    struct stat pathstat;

    exfiles_trace_msg("Entering fnode_fopen");

    if (NULL == node || NULL == node->path)
        return NULL;

    /* handle is already open */
    if (NULL != node->handle && (-1 != fileno(node->handle))) {

        if (stat(node->path, &pathstat) != 0)
            /* stat failed */
            return NULL;

        /* If open file has as late mtime as path, then just rewind the
         * handle and return it */
        if (pathstat.st_mtime <= node->mtime) {
            rewind(node->handle);
            return node->handle;
        }

        /* Otherwise, start over */
        close_handle(node);
    }

    exfiles_open_file(node->path, &(node->handle));

    exfiles_set_close_on_exec(node->handle);

    return node->handle;
}
Esempio n. 19
0
File: tftp.c Progetto: olsner/lwip
static void
send_data(const ip_addr_t *addr, u16_t port)
{
  u16_t *payload;
  int ret;

  if (tftp_state.last_data != NULL) {
    pbuf_free(tftp_state.last_data);
  }

  tftp_state.last_data = init_packet(TFTP_DATA, tftp_state.blknum, TFTP_MAX_PAYLOAD_SIZE);
  if (tftp_state.last_data == NULL) {
    return;
  }

  payload = (u16_t *) tftp_state.last_data->payload;

  ret = tftp_state.ctx->read(tftp_state.handle, &payload[2], TFTP_MAX_PAYLOAD_SIZE);
  if (ret < 0) {
    send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Error occured while reading the file.");
    close_handle();
    return;
  }

  pbuf_realloc(tftp_state.last_data, (u16_t)(TFTP_HEADER_LENGTH + ret));
  resend_data(addr, port);
}
Esempio n. 20
0
RTDB_API void PMC_API uninit_rtdb(void)
{
	lock_rtdb(__true, INFINITE);
	RTK_CURSOR hNode;	
	
	close_handle(g_hLocalNode);
	g_hLocalNode = 0;
	
	hNode = open_first_node();
	while( !cursor_is_end(hNode) ){
		cursor_delete(hNode);
		hNode = open_first_node();
	}
	close_handle(hNode);
	unlock_rtdb();
}
Esempio n. 21
0
__uint PMC_API _on_drop_groups(PCRTK_PACKET packet)
{
	__uint count, i, ret=0;
	RTK_CURSOR hNode, hGroup;
	PGROUP_KEY pgk;
	TAG_NAME name;
	NODE_KEY nk;

	count = packet->data_size / sizeof(GROUP_KEY);
	if(packet->data_size % sizeof(GROUP_KEY)){
		return 0;
	}
	if( !lock_rtdb(true, 100) ){
		return 0;
	}
	host_to_node(&packet->src.host, &nk);
	name.node = nk;
	hNode = open_node(&nk);
	if(hNode){
		for(i=0, pgk=(PGROUP_KEY)packet->data; i<count; i++, pgk++){
			name.sname.group = *pgk;
			hGroup = open_group(hNode, pgk);
			if(hGroup){
				cursor_delete(hGroup);
				rtk_queue_event(PT_DropGroup, &name, &packet->src);
				ret++;
			}
		}
		close_handle(hNode);
	}
	unlock_rtdb();
	return ret;
}
Esempio n. 22
0
void WindowsModule::GarbageCollect(ScanAddress *process)
/* Ensures that all the objects are retained and their addresses updated. */
{
    POLYUNSIGNED i;
    /* Entries in the file table. These are marked as weak references so may
       return 0 for unreferenced streams. */
    for(i = 0; i < maxHandleTab; i++)
    {
        PHANDLETAB str = &(handleTable[i]);
        if (str->token != 0)
        {
            if (str->entryType == HE_PROCESS)
            {
                /* Update the references to opened streams but
                   do this only as weak references.  If the stream
                   has gone away then that's fine. */
                if (str->entry.process.readToken)
                    process->ScanRuntimeAddress(&str->entry.process.readToken, ScanAddress::STRENGTH_WEAK);
                if (str->entry.process.writeToken)
                    process->ScanRuntimeAddress(&str->entry.process.writeToken, ScanAddress::STRENGTH_WEAK);
            }
            process->ScanRuntimeAddress(&str->token, ScanAddress::STRENGTH_WEAK);
            /* Unreferenced entries may return zero. */ 
            if (str->token == 0 && str->entryType != HE_UNUSED)
                close_handle(str);
        }
    }
}
Esempio n. 23
0
void unblock_terminal(struct terminal *term)
{
    close_handle((void *)term->blocked);
    term->blocked = -1;
    set_handlers(term->fdin, (void (*)(void *))in_term, NULL, (void (*)(void *))destroy_terminal, term);
    unblock_itrm(term->fdin);
    redraw_terminal_cls(term);
}
Esempio n. 24
0
static void
do_closedir (void)
{
    int handle;

    rpc_get (msock, RPC_INT, &handle, RPC_END);
    close_handle (handle - 1);
}
Esempio n. 25
0
Image::~Image()
{
	close_handle(fFileHandle);
	delete [] fPath;
	delete fHeader;
	delete [] fSectionTable;
	delete [] fProgramHeaderTable;
	delete [] fSectionStringTable;
}
Esempio n. 26
0
static int close_on_exec (struct shim_fd_handle * fd_hdl,
                          struct shim_handle_map * map, void * arg)
{
    if (fd_hdl->flags & FD_CLOEXEC) {
        struct shim_handle * hdl = __detach_fd_handle(fd_hdl, NULL, map);
        close_handle(hdl);
    }
    return 0;
}
Esempio n. 27
0
int shim_do_close (int fd)
{
    struct shim_handle * handle = detach_fd_handle(fd, NULL, NULL);
    if (!handle)
        return -EBADF;

    close_handle(handle);
    return 0;
}
Esempio n. 28
0
File: kbd.c Progetto: Efreak/elinks
/** A select_handler_T read_func and error_func for the pipe (long) @a h.
 * This is called when the subprocess started on the terminal of this
 * ELinks process exits.  ELinks then resumes using the terminal.  */
static void
unblock_itrm_x(void *h)
{
	close_handle(h);
	if (!ditrm) return;
	unblock_itrm();

	/* Note: External editor support depends on this resize event. */
	resize_terminal();
}
Esempio n. 29
0
RTDB_API PRTK_NODE PMC_API query_node(
	PCNODE_KEY node
	)
{
	RTK_CURSOR hNode;
	PRTK_NODE nd;
	hNode = open_node(node);
	nd = (PRTK_NODE)cursor_get_item(hNode);
	close_handle(hNode);
	return nd;
}
Esempio n. 30
0
status_t mount(const char device[], const char dir[], const char type[], int,
	char*)
{
	int error;
	int devfd = -1;
	if (strlen(device) > 0) {
		devfd = open(device, 0);
		if (devfd < 0) {
			printf("mount: error opening device\n");
			return E_NO_SUCH_FILE;
		}
	}
	
	VNode *node;
	error = FileSystem::WalkPath(dir, strlen(dir), &node);
	if (error < 0) {
		printf("mount: mount point does not exist\n");
		close_handle(devfd);
		return error;
	}

	if (node->GetCoveredBy() != 0) {
		// Attempting to re-mount an already mounted directory
		printf("mount: filesystem already mounted at this point\n");
		node->ReleaseRef();
		close_handle(devfd);
		return E_NOT_ALLOWED;
	}

	FileSystem *fs;
	error = FileSystem::InstantiateFsType(type, devfd, &fs);
	if (error < 0) {
		node->ReleaseRef();
		close_handle(devfd);
		return error;
	}
	
	node->CoverWith(fs);
	fs->Cover(node);
	return 0;
}