예제 #1
0
/** Allocate frame
 *
 *  @param nic_data 	The NIC driver data
 *  @param size	        Frame size in bytes
 *  @return pointer to allocated frame if success, NULL otherwise
 */
nic_frame_t *nic_alloc_frame(nic_t *nic_data, size_t size)
{
	nic_frame_t *frame;
	fibril_mutex_lock(&nic_globals.lock);
	if (nic_globals.frame_cache_size > 0) {
		link_t *first = list_first(&nic_globals.frame_cache);
		list_remove(first);
		nic_globals.frame_cache_size--;
		frame = list_get_instance(first, nic_frame_t, link);
		fibril_mutex_unlock(&nic_globals.lock);
	} else {
		fibril_mutex_unlock(&nic_globals.lock);
		frame = malloc(sizeof(nic_frame_t));
		if (!frame)
			return NULL;
		
		link_initialize(&frame->link);
	}

	frame->data = malloc(size);
	if (frame->data == NULL) {
		free(frame);
		return NULL;
	}

	frame->size = size;
	return frame;
}
예제 #2
0
/** Connect client to clonable service.
 *
 * @param service Service to be connected to.
 * @param call    Pointer to call structure.
 * @param callid  Call ID of the request.
 *
 * @return Zero on success or a value from @ref errno.h.
 *
 */
void connect_to_clonable(sysarg_t service, ipc_call_t *call,
    ipc_callid_t callid)
{
	assert(service == SERVICE_LOAD);
	
	cs_req_t *csr = malloc(sizeof(cs_req_t));
	if (csr == NULL) {
		ipc_answer_0(callid, ENOMEM);
		return;
	}
	
	/* Spawn a loader. */
	int rc = loader_spawn("loader");
	
	if (rc < 0) {
		free(csr);
		ipc_answer_0(callid, rc);
		return;
	}
	
	link_initialize(&csr->link);
	csr->service = service;
	csr->call = *call;
	csr->callid = callid;
	
	/*
	 * We can forward the call only after the server we spawned connects
	 * to us. Meanwhile we might need to service more connection requests.
	 * Thus we store the call in a queue.
	 */
	list_append(&csr->link, &cs_req);
}
예제 #3
0
static void unused_initialize(unused_t *u, service_id_t service_id)
{
	link_initialize(&u->link);
	u->service_id = service_id;
	u->next = 0;
	u->remaining = ((uint64_t)((fs_index_t)-1)) + 1;
	list_initialize(&u->freed_list);
}
예제 #4
0
파일: irq.c 프로젝트: narke/Einherjar.tmp
/** Initialize one IRQ structure.
 *
 * @param irq Pointer to the IRQ structure to be initialized.
 *
 */
void irq_initialize(irq_t *irq)
{
	memsetb(irq, sizeof(irq_t), 0);
	link_initialize(&irq->link);
	irq_spinlock_initialize(&irq->lock, "irq.lock");
	irq->inr = -1;
	irq->devno = -1;
	
	irq_initialize_arch(irq);
}
예제 #5
0
static void tmpfs_node_initialize(tmpfs_node_t *nodep)
{
	nodep->bp = NULL;
	nodep->index = 0;
	nodep->service_id = 0;
	nodep->type = TMPFS_NONE;
	nodep->lnkcnt = 0;
	nodep->size = 0;
	nodep->data = NULL;
	link_initialize(&nodep->nh_link);
	list_initialize(&nodep->cs_list);
}
예제 #6
0
static mouse_dev_t *mouse_dev_new(void)
{
	mouse_dev_t *mdev = calloc(1, sizeof(mouse_dev_t));
	if (mdev == NULL) {
		printf("%s: Error allocating keyboard device. "
		    "Out of memory.\n", NAME);
		return NULL;
	}
	
	link_initialize(&mdev->mouse_devs);
	
	return mdev;
}
예제 #7
0
파일: devconn.c 프로젝트: jvesely/helenos
static vhc_virtdev_t *vhc_virtdev_create(void)
{
	vhc_virtdev_t *dev = malloc(sizeof(vhc_virtdev_t));
	if (dev == NULL) {
		return NULL;
	}
	dev->address = 0;
	dev->dev_sess = NULL;
	dev->dev_local = NULL;
	dev->plugged = true;
	link_initialize(&dev->link);
	fibril_mutex_initialize(&dev->guard);
	list_initialize(&dev->transfer_queue);

	return dev;
}
예제 #8
0
/*
 * Helper functions.
 */
static void fat_node_initialize(fat_node_t *node)
{
	fibril_mutex_initialize(&node->lock);
	node->bp = NULL;
	node->idx = NULL;
	node->type = 0;
	link_initialize(&node->ffn_link);
	node->size = 0;
	node->lnkcnt = 0;
	node->refcnt = 0;
	node->dirty = false;
	node->lastc_cached_valid = false;
	node->lastc_cached_value = 0;
	node->currc_cached_valid = false;
	node->currc_cached_bn = 0;
	node->currc_cached_value = 0;
}
예제 #9
0
inet_addrobj_t *inet_addrobj_new(void)
{
	inet_addrobj_t *addr = calloc(1, sizeof(inet_addrobj_t));

	if (addr == NULL) {
		log_msg(LVL_ERROR, "Failed allocating address object. "
		    "Out of memory.");
		return NULL;
	}

	link_initialize(&addr->addr_list);
	fibril_mutex_lock(&addr_list_lock);
	addr->id = ++addr_id;
	fibril_mutex_unlock(&addr_list_lock);

	return addr;
}
예제 #10
0
static kbd_dev_t *kbd_dev_new(void)
{
	kbd_dev_t *kdev = calloc(1, sizeof(kbd_dev_t));
	if (kdev == NULL) {
		printf("%s: Error allocating keyboard device. "
		    "Out of memory.\n", NAME);
		return NULL;
	}
	
	link_initialize(&kdev->kbd_devs);
	
	kdev->mods = KM_NUM_LOCK;
	kdev->lock_keys = 0;
	kdev->active_layout = layout_create(layout[0]);
	
	return kdev;
}
예제 #11
0
파일: barber.c 프로젝트: jvesely/helenos
static void loc_callback(void)
{
	category_id_t led_cat;
	int rc = loc_category_get_id("led", &led_cat, IPC_FLAG_BLOCKING);
	if (rc != EOK)
		return;
	
	service_id_t *svcs;
	size_t count;
	rc = loc_category_get_svcs(led_cat, &svcs, &count);
	if (rc != EOK)
		return;
	
	for (size_t i = 0; i < count; i++) {
		bool known = false;
		
		/* Determine whether we already know this device. */
		list_foreach(led_devs, link, led_dev_t, dev) {
			if (dev->svc_id == svcs[i]) {
				known = true;
				break;
			}
		}
		
		if (!known) {
			led_dev_t *dev = (led_dev_t *) calloc(1, sizeof(led_dev_t));
			if (!dev)
				continue;
			
			link_initialize(&dev->link);
			dev->svc_id = svcs[i];
			dev->sess = loc_service_connect(svcs[i], INTERFACE_DDF, 0);
			
			list_append(&dev->link, &led_devs);
		}
	}
	
	// FIXME: Handle LED device removal
	
	free(svcs);
}
예제 #12
0
outdev_t *outdev_register(outdev_ops_t *ops, void *data)
{
	assert(ops->get_dimensions);
	
	outdev_t *dev = (outdev_t *) malloc(sizeof(outdev_t));
	if (dev == NULL)
		return NULL;
	
	link_initialize(&dev->link);
	
	dev->ops = *ops;
	dev->data = data;
	
	ops->get_dimensions(dev, &dev->cols, &dev->rows);
	dev->backbuf = chargrid_create(dev->cols, dev->rows,
	    CHARGRID_FLAG_NONE);
	if (dev->backbuf == NULL) {
		free(dev);
		return NULL;
	}
	
	list_append(&dev->link, &outdevs);
	return dev;
}
예제 #13
0
/** Allocate ad initialize endpoint_t structure.
 * @param address USB address.
 * @param endpoint USB endpoint number.
 * @param direction Communication direction.
 * @param type USB transfer type.
 * @param speed Communication speed.
 * @param max_packet_size Maximum size of data packets.
 * @param bw Required bandwidth.
 * @return Pointer to initialized endpoint_t structure, NULL on failure.
 */
endpoint_t * endpoint_create(usb_address_t address, usb_endpoint_t endpoint,
    usb_direction_t direction, usb_transfer_type_t type, usb_speed_t speed,
    size_t max_packet_size, size_t bw)
{
	endpoint_t *instance = malloc(sizeof(endpoint_t));
	if (instance) {
		instance->address = address;
		instance->endpoint = endpoint;
		instance->direction = direction;
		instance->transfer_type = type;
		instance->speed = speed;
		instance->max_packet_size = max_packet_size;
		instance->bandwidth = bw;
		instance->toggle = 0;
		instance->active = false;
		instance->hc_data.data = NULL;
		instance->hc_data.toggle_get = NULL;
		instance->hc_data.toggle_set = NULL;
		link_initialize(&instance->link);
		fibril_mutex_initialize(&instance->guard);
		fibril_condvar_initialize(&instance->avail);
	}
	return instance;
}
예제 #14
0
static int udp_assoc_queue_msg(udp_assoc_t *assoc, udp_sockpair_t *sp,
    udp_msg_t *msg)
{
	udp_rcv_queue_entry_t *rqe;

	log_msg(LVL_DEBUG, "udp_assoc_queue_msg(%p, %p, %p)",
	    assoc, sp, msg);

	rqe = calloc(1, sizeof(udp_rcv_queue_entry_t));
	if (rqe == NULL)
		return ENOMEM;

	link_initialize(&rqe->link);
	rqe->sp = *sp;
	rqe->msg = msg;

	fibril_mutex_lock(&assoc->lock);
	list_append(&rqe->link, &assoc->rcv_queue);
	fibril_mutex_unlock(&assoc->lock);

	fibril_condvar_broadcast(&assoc->rcv_queue_cv);

	return EOK;
}
예제 #15
0
int init_panel(window_t *win)
{
    button_t     *btn;
    progress_t   *prg;
    level_t      *lvl;
    slider_t     *sld;

    panel_t *panel = &win->panel;
    ctx_t   *ctx = &panel->ctx;

    link_initialize(&panel->ctrl.link);
    list_initialize(&panel->ctrl.child);

    panel->ctrl.handler = panel_proc;
    panel->ctrl.parent  = (ctrl_t*)win;

    panel->layout = 0;
    
    panel->bitmap.width  = 1920;
    panel->bitmap.height = PANEL_HEIGHT;
    panel->bitmap.flags  = 0;

    if( create_bitmap(&panel->bitmap) )
    {
        printf("not enough memory for panel bitmap\n");
        return 0;
    }

    ctx->pixmap   = &panel->bitmap;
    ctx->offset_x = 0;
    ctx->offset_y = 0;

    panel->ctrl.ctx = ctx;

    btn = create_button(NULL, ID_PLAY,0,19,32,32,&panel->ctrl);
    panel->play_btn = btn;

    btn->img_default = res_pause_btn;
    btn->img_hilite  = res_pause_btn;
    btn->img_pressed = res_pause_btn_pressed;

    btn = create_button(NULL, ID_STOP,0,19,24,24,&panel->ctrl);
    panel->stop_btn = btn;

    btn->img_default = res_stop_btn;
    btn->img_hilite  = res_stop_btn;
    btn->img_pressed = res_stop_btn_pressed;

    prg = create_progress(NULL,ID_PROGRESS,0,4,0,10,&panel->ctrl);
    panel->prg = prg;

    lvl = create_level(NULL, ID_VOL_LEVEL, 0, 20, 96, 10, &panel->ctrl);
    lvl->vol = -1875;
    panel->lvl = lvl;
    
    sld = create_slider(NULL, ID_VOL_CTRL, 0, 20, 96+12, 12, &panel->ctrl);
    panel->sld = sld; 
     
//    btn = create_button(NULL, ID_MINIMIZE,0,5,16,18,(ctrl_t*)cpt);
//    cpt->minimize_btn = btn;

//    btn->img_default = res_minimize_btn;
//    btn->img_hilite  = res_minimize_btn_hl;
//    btn->img_pressed = res_minimize_btn_pressed;



    update_panel_size(win);

    return 1;
};
예제 #16
0
/** Initialize command info structure.
 *
 * @param cmd Command info structure.
 *
 */
void cmd_initialize(cmd_info_t *cmd)
{
	spinlock_initialize(&cmd->lock, "cmd.lock");
	link_initialize(&cmd->link);
}
예제 #17
0
/** VFS_REGISTER protocol function.
 *
 * @param rid     Hash of the call with the request.
 * @param request Call structure with the request.
 *
 */
void vfs_register(ipc_callid_t rid, ipc_call_t *request)
{
	dprintf("Processing VFS_REGISTER request received from %p.\n",
	    request->in_phone_hash);
	
	vfs_info_t *vfs_info;
	int rc = async_data_write_accept((void **) &vfs_info, false,
	    sizeof(vfs_info_t), sizeof(vfs_info_t), 0, NULL);
	
	if (rc != EOK) {
		dprintf("Failed to deliver the VFS info into our AS, rc=%d.\n",
		    rc);
		async_answer_0(rid, rc);
		return;
	}
	
	/*
	 * Allocate and initialize a buffer for the fs_info structure.
	 */
	fs_info_t *fs_info = (fs_info_t *) malloc(sizeof(fs_info_t));
	if (!fs_info) {
		dprintf("Could not allocate memory for FS info.\n");
		async_answer_0(rid, ENOMEM);
		return;
	}
	
	link_initialize(&fs_info->fs_link);
	fs_info->vfs_info = *vfs_info;
	free(vfs_info);
	
	dprintf("VFS info delivered.\n");
	
	if (!vfs_info_sane(&fs_info->vfs_info)) {
		free(fs_info);
		async_answer_0(rid, EINVAL);
		return;
	}
	
	fibril_mutex_lock(&fs_list_lock);
	
	/*
	 * Check for duplicit registrations.
	 */
	if (fs_name_to_handle(fs_info->vfs_info.instance,
	    fs_info->vfs_info.name, false)) {
		/*
		 * We already register a fs like this.
		 */
		dprintf("FS is already registered.\n");
		fibril_mutex_unlock(&fs_list_lock);
		free(fs_info);
		async_answer_0(rid, EEXISTS);
		return;
	}
	
	/*
	 * Add fs_info to the list of registered FS's.
	 */
	dprintf("Inserting FS into the list of registered file systems.\n");
	list_append(&fs_info->fs_link, &fs_list);
	
	/*
	 * Now we want the client to send us the IPC_M_CONNECT_TO_ME call so
	 * that a callback connection is created and we have a phone through
	 * which to forward VFS requests to it.
	 */
	fs_info->sess = async_callback_receive(EXCHANGE_PARALLEL);
	if (!fs_info->sess) {
		dprintf("Callback connection expected\n");
		list_remove(&fs_info->fs_link);
		fibril_mutex_unlock(&fs_list_lock);
		free(fs_info);
		async_answer_0(rid, EINVAL);
		return;
	}
	
	dprintf("Callback connection to FS created.\n");
	
	/*
	 * The client will want us to send him the address space area with PLB.
	 */
	
	size_t size;
	ipc_callid_t callid;
	if (!async_share_in_receive(&callid, &size)) {
		dprintf("Unexpected call, method = %d\n", IPC_GET_IMETHOD(call));
		list_remove(&fs_info->fs_link);
		fibril_mutex_unlock(&fs_list_lock);
		async_hangup(fs_info->sess);
		free(fs_info);
		async_answer_0(callid, EINVAL);
		async_answer_0(rid, EINVAL);
		return;
	}
	
	/*
	 * We can only send the client address space area PLB_SIZE bytes long.
	 */
	if (size != PLB_SIZE) {
		dprintf("Client suggests wrong size of PFB, size = %d\n", size);
		list_remove(&fs_info->fs_link);
		fibril_mutex_unlock(&fs_list_lock);
		async_hangup(fs_info->sess);
		free(fs_info);
		async_answer_0(callid, EINVAL);
		async_answer_0(rid, EINVAL);
		return;
	}
	
	/*
	 * Commit to read-only sharing the PLB with the client.
	 */
	(void) async_share_in_finalize(callid, plb,
	    AS_AREA_READ | AS_AREA_CACHEABLE);
	
	dprintf("Sharing PLB.\n");
	
	/*
	 * That was it. The FS has been registered.
	 * In reply to the VFS_REGISTER request, we assign the client file
	 * system a global file system handle.
	 */
	fs_info->fs_handle = (fs_handle_t) atomic_postinc(&fs_handle_next);
	async_answer_1(rid, EOK, (sysarg_t) fs_info->fs_handle);
	
	fibril_condvar_broadcast(&fs_list_cv);
	fibril_mutex_unlock(&fs_list_lock);
	
	dprintf("\"%.*s\" filesystem successfully registered, handle=%d.\n",
	    FS_NAME_MAXLEN, fs_info->vfs_info.name, fs_info->fs_handle);
}
예제 #18
0
static void tmpfs_dentry_initialize(tmpfs_dentry_t *dentryp)
{
	link_initialize(&dentryp->link);
	dentryp->name = NULL;
	dentryp->node = NULL;
}
예제 #19
0
/** Perform a path lookup.
 *
 * @param path    Path to be resolved; it must be a NULL-terminated
 *                string.
 * @param lflag   Flags to be used during lookup.
 * @param result  Empty structure where the lookup result will be stored.
 *                Can be NULL.
 * @param altroot If non-empty, will be used instead of rootfs as the root
 *                of the whole VFS tree.
 *
 * @return EOK on success or an error code from errno.h.
 *
 */
int vfs_lookup_internal(char *path, int lflag, vfs_lookup_res_t *result,
    vfs_pair_t *altroot, ...)
{
	vfs_pair_t *root;

	if (altroot)
		root = altroot;
	else
		root = &rootfs;

	if (!root->fs_handle)
		return ENOENT;
	
	size_t len;
	path = canonify(path, &len);
	if (!path)
		return EINVAL;
	
	fs_index_t index = 0;
	if (lflag & L_LINK) {
		va_list ap;

		va_start(ap, altroot);
		index = va_arg(ap, fs_index_t);
		va_end(ap);
	}
	
	fibril_mutex_lock(&plb_mutex);

	plb_entry_t entry;
	link_initialize(&entry.plb_link);
	entry.len = len;

	size_t first;	/* the first free index */
	size_t last;	/* the last free index */

	if (list_empty(&plb_entries)) {
		first = 0;
		last = PLB_SIZE - 1;
	} else {
		plb_entry_t *oldest = list_get_instance(
		    list_first(&plb_entries), plb_entry_t, plb_link);
		plb_entry_t *newest = list_get_instance(
		    list_last(&plb_entries), plb_entry_t, plb_link);

		first = (newest->index + newest->len) % PLB_SIZE;
		last = (oldest->index - 1) % PLB_SIZE;
	}

	if (first <= last) {
		if ((last - first) + 1 < len) {
			/*
			 * The buffer cannot absorb the path.
			 */
			fibril_mutex_unlock(&plb_mutex);
			return ELIMIT;
		}
	} else {
		if (PLB_SIZE - ((first - last) + 1) < len) {
			/*
			 * The buffer cannot absorb the path.
			 */
			fibril_mutex_unlock(&plb_mutex);
			return ELIMIT;
		}
	}

	/*
	 * We know the first free index in PLB and we also know that there is
	 * enough space in the buffer to hold our path.
	 */

	entry.index = first;
	entry.len = len;

	/*
	 * Claim PLB space by inserting the entry into the PLB entry ring
	 * buffer.
	 */
	list_append(&entry.plb_link, &plb_entries);
	
	fibril_mutex_unlock(&plb_mutex);

	/*
	 * Copy the path into PLB.
	 */
	size_t cnt1 = min(len, (PLB_SIZE - first) + 1);
	size_t cnt2 = len - cnt1;
	
	memcpy(&plb[first], path, cnt1);
	memcpy(plb, &path[cnt1], cnt2);

	ipc_call_t answer;
	async_exch_t *exch = vfs_exchange_grab(root->fs_handle);
	aid_t req = async_send_5(exch, VFS_OUT_LOOKUP, (sysarg_t) first,
	    (sysarg_t) (first + len - 1) % PLB_SIZE,
	    (sysarg_t) root->service_id, (sysarg_t) lflag, (sysarg_t) index,
	    &answer);
	
	sysarg_t rc;
	async_wait_for(req, &rc);
	vfs_exchange_release(exch);
	
	fibril_mutex_lock(&plb_mutex);
	list_remove(&entry.plb_link);
	/*
	 * Erasing the path from PLB will come handy for debugging purposes.
	 */
	memset(&plb[first], 0, cnt1);
	memset(plb, 0, cnt2);
	fibril_mutex_unlock(&plb_mutex);
	
	if ((int) rc < EOK)
		return (int) rc;

	if (!result)
		return EOK;
	
	result->triplet.fs_handle = (fs_handle_t) rc;
	result->triplet.service_id = (service_id_t) IPC_GET_ARG1(answer);
	result->triplet.index = (fs_index_t) IPC_GET_ARG2(answer);
	result->size =
	    (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(answer), IPC_GET_ARG4(answer));
	result->lnkcnt = (unsigned int) IPC_GET_ARG5(answer);
	
	if (lflag & L_FILE)
		result->type = VFS_NODE_FILE;
	else if (lflag & L_DIRECTORY)
		result->type = VFS_NODE_DIRECTORY;
	else
		result->type = VFS_NODE_UNKNOWN;
	
	return EOK;
}
예제 #20
0
파일: vfs_file.c 프로젝트: jvesely/helenos
void vfs_pass_handle(task_id_t donor_id, task_id_t acceptor_id, int donor_fd)
{
	vfs_client_data_t *donor_data = NULL;
	vfs_client_data_t *acceptor_data = NULL;
	vfs_file_t *donor_file = NULL;
	vfs_file_t *acceptor_file = NULL;
	vfs_boxed_handle_t *bh;
	int acceptor_fd;

	acceptor_data = async_get_client_data_by_id(acceptor_id);
	if (!acceptor_data)
		return;

	bh = malloc(sizeof(vfs_boxed_handle_t));
	assert(bh);

	link_initialize(&bh->link);
	bh->handle = -1;

	donor_data = async_get_client_data_by_id(donor_id);
	if (!donor_data)
		goto out;

	donor_file = _vfs_file_get(donor_data, donor_fd);
	if (!donor_file)
		goto out;

	acceptor_fd = _vfs_fd_alloc(acceptor_data, false);
	if (acceptor_fd < 0)
		goto out;

	bh->handle = acceptor_fd;

	/*
	 * Add a new reference to the underlying VFS node.
	 */
	vfs_node_addref(donor_file->node);
	(void) vfs_open_node_remote(donor_file->node);

	acceptor_file = _vfs_file_get(acceptor_data, acceptor_fd);
	assert(acceptor_file);

	/*
	 * Inherit attributes from the donor.
	 */
	acceptor_file->node = donor_file->node;
	acceptor_file->append = donor_file->append;
	acceptor_file->pos = donor_file->pos;

out:
	fibril_mutex_lock(&acceptor_data->lock);
	list_append(&bh->link, &acceptor_data->passed_handles);
	fibril_condvar_broadcast(&acceptor_data->cv);
	fibril_mutex_unlock(&acceptor_data->lock);

	if (donor_data)
		async_put_client_data_by_id(donor_id);
	if (acceptor_data)
		async_put_client_data_by_id(acceptor_id);
	if (donor_file)
		_vfs_file_put(donor_data, donor_file);
	if (acceptor_file)
		_vfs_file_put(acceptor_data, acceptor_file);

}
예제 #21
0
static void tcp_sock_listen(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
{
	int socket_id;
	int backlog;
	socket_core_t *sock_core;
	tcp_sockdata_t *socket;
	tcp_error_t trc;
	tcp_sock_t lsocket;
	tcp_sock_t fsocket;
	tcp_conn_t *conn;
	tcp_sock_lconn_t *lconn;
	int i;

	log_msg(LVL_DEBUG, "tcp_sock_listen()");

	socket_id = SOCKET_GET_SOCKET_ID(call);
	backlog = SOCKET_GET_BACKLOG(call);

	if (backlog < 0) {
		async_answer_0(callid, EINVAL);
		return;
	}

	if (backlog > MAX_BACKLOG)
		backlog = MAX_BACKLOG;

	sock_core = socket_cores_find(&client->sockets, socket_id);
	if (sock_core == NULL) {
		async_answer_0(callid, ENOTSOCK);
		return;
	}

	socket = (tcp_sockdata_t *)sock_core->specific_data;

	/*
	 * Prepare @c backlog listening connections.
	 */
	fibril_mutex_lock(&socket->lock);

	socket->backlog = backlog;
	socket->lconn = calloc(sizeof(tcp_conn_t *), backlog);
	if (socket->lconn == NULL) {
		fibril_mutex_unlock(&socket->lock);
		async_answer_0(callid, ENOMEM);
		return;
	}

	log_msg(LVL_DEBUG, " - open connections");

	lsocket.addr.ipv4 = TCP_IPV4_ANY;
	lsocket.port = sock_core->port;
	fsocket.addr.ipv4 = TCP_IPV4_ANY;
	fsocket.port = TCP_PORT_ANY;

	for (i = 0; i < backlog; i++) {

		lconn = calloc(sizeof(tcp_sock_lconn_t), 1);
		if (lconn == NULL) {
			/* XXX Clean up */
			fibril_mutex_unlock(&socket->lock);
			async_answer_0(callid, ENOMEM);
			return;
		}

		trc = tcp_uc_open(&lsocket, &fsocket, ap_passive,
		    tcp_open_nonblock, &conn);
		if (conn == NULL) {
			/* XXX Clean up */
			fibril_mutex_unlock(&socket->lock);
			async_answer_0(callid, ENOMEM);
			return;
		}

		tcp_uc_set_cstate_cb(conn, tcp_sock_cstate_cb, lconn);

		assert(trc == TCP_EOK);
		conn->name = (char *)"S";

		lconn->conn = conn;
		lconn->socket = socket;
		link_initialize(&lconn->ready_list);
		socket->lconn[i] = lconn;
	}

	fibril_mutex_unlock(&socket->lock);
	async_answer_0(callid, EOK);
}
예제 #22
0
파일: main.c 프로젝트: jvesely/helenos
int main(int argc, char **argv)
{
	log_init(NAME);

	if (argc <= 3) {
		syntax_print();
		return 1;
	}

	const char *rfb_name = argv[1];
	
	char *endptr;
	unsigned long width = strtoul(argv[2], &endptr, 0);
	if (*endptr != 0) {
		fprintf(stderr, "Invalid width\n");
		syntax_print();
		return 1;
	}
	
	unsigned long height = strtoul(argv[3], &endptr, 0);
	if (*endptr != 0) {
		fprintf(stderr, "Invalid height\n");
		syntax_print();
		return 1;
	}
	
	unsigned long port = 5900;
	if (argc > 4) {
		port = strtoul(argv[4], &endptr, 0);
		if (*endptr != 0) {
			fprintf(stderr, "Invalid port number\n");
			syntax_print();
			return 1;
		}
	}
	
	rfb_init(&rfb, width, height, rfb_name);
	
	vis = malloc(sizeof(visualizer_t));
	if (vis == NULL) {
		fprintf(stderr, "Failed allocating visualizer struct\n");
		return 3;
	}
	
	graph_init_visualizer(vis);
	
	pixel_mode.mode.index = 0;
	pixel_mode.mode.version = 0;
	pixel_mode.mode.refresh_rate = 0;
	pixel_mode.mode.screen_aspect.width = rfb.width;
	pixel_mode.mode.screen_aspect.height = rfb.height;
	pixel_mode.mode.screen_width = rfb.width;
	pixel_mode.mode.screen_height = rfb.height;
	pixel_mode.mode.cell_aspect.width = 1;
	pixel_mode.mode.cell_aspect.height = 1;
	pixel_mode.mode.cell_visual.pixel_visual = VISUAL_RGB_8_8_8;
	
	link_initialize(&pixel_mode.link);
	list_append(&pixel_mode.link, &vis->modes);
	
	vis->def_mode_idx = 0;
	
	vis->ops = rfb_ops;
	vis->dev_ctx = NULL;

	async_set_fallback_port_handler(client_connection, NULL);

	int rc = loc_server_register(NAME);
	if (rc != EOK) {
		printf("%s: Unable to register server.\n", NAME);
		return rc;
	}

	char *service_name;
	rc = asprintf(&service_name, "rfb/%s", rfb_name);
	if (rc < 0) {
		printf(NAME ": Unable to create service name\n");
		return rc;
	}

	service_id_t service_id;
	
	rc = loc_service_register(service_name, &service_id);
	if (rc != EOK) {
		printf(NAME ": Unable to register service %s.\n", service_name);
		return rc;
	}
	
	free(service_name);

	category_id_t visualizer_category;
	rc = loc_category_get_id("visualizer", &visualizer_category, IPC_FLAG_BLOCKING);
	if (rc != EOK) {
		fprintf(stderr, NAME ": Unable to get visualizer category id.\n");
		return 1;
	}
	
	rc = loc_service_add_to_cat(service_id, visualizer_category);
	if (rc != EOK) {
		fprintf(stderr, NAME ": Unable to add service to visualizer category.\n");
		return 1;
	}
	
	rc = rfb_listen(&rfb, port);
	if (rc != EOK) {
		fprintf(stderr, NAME ": Unable to listen at rfb port\n");
		return 2;
	}
	
	printf("%s: Accepting connections\n", NAME);
	task_retval(0);
	async_manager();

	/* Not reached */
	return 0;
}