예제 #1
0
static int async_ipc_estream_func(estream_t *e, u8 *data, int len)
{
    async_ipc_t *aipc = estream_get_data(e);
    async_ipc_read_op_t *op;

    if (!len)
	return 0; /* Finished writing */

    if (!(op = aipc->queue))
    {
	rg_error(LERR, "Async IPC: Received %d unexpected bytes", len);
	goto Error;
    }

    switch (op->state)
    {
	case AIPC_WAIT_FOR_N:
	case AIPC_WAIT_FOR_N_AND_DATA:
	    if (len != sizeof(*op->n))
	    {
		rg_error(LERR, "Async IPC: Received %d while reading N", len);
		goto Error;
	    }
	    /* Avoid possible misalignment of data */
	    memcpy(op->n, data, sizeof(*op->n));
	    *op->n = ntohl(*op->n);
	    if (op->state == AIPC_WAIT_FOR_N_AND_DATA && *op->n)
	    {
		op->state = AIPC_WAIT_FOR_DATA;
		estream_read(aipc->e, *op->n);
	    }
	    else
		async_ipc_process_op(aipc);
	    break;
	case AIPC_WAIT_FOR_DATA:
	    if (len != *op->n)
	    {
		rg_error(LERR, "Async IPC: Expected %d bytes, received %d",
		    *op->n, len);
		goto Error;
	    }
	    *op->data = memdup_e(data, len);
	    if (op->is_string)
	    {
		/* '\0' should be sent by the other side, we want to be on the
		 * safe side */
		(*op->data)[len-1] = 0;
	    }
	    async_ipc_process_op(aipc);
	    break;
    }

    return 0;
Error:
    async_ipc_notify(aipc, -1);
    return 0;
}
int gpl_sys_rg_chrdev_open(int type, int mode)
{
    int fd = open("/dev/rg_chrdev", mode, 0);

    if (fd < 0)
    {
	rg_error(LERR, "Cannot open /dev/rg_chrdev %d %m", type);
	return fd;
    }

    if (ioctl(fd, RG_IOCTL_SIOCSETRGCHRDEVTYPE, type))
	return rg_error(LERR, "Cannot open /dev/rg_chrdev %d %m", type);

    return fd;
}
예제 #3
0
파일: ipc.c 프로젝트: livebox/livebox2
int ipc_wait_for_server(u16 port)
{
    struct sockaddr_in sa;
    int fd;

    MZERO(sa);
    sa.sin_family = AF_INET;
    sa.sin_addr.s_addr = inet_addr("127.0.0.1");
    sa.sin_port = port;

    if ((fd = sock_socket(SOCK_STREAM, 0, 0)) < 0)
    {
	rg_error(LERR, "failed creating socket");
	return -1;
    }
    
    /* Try to connect to server infinitely */ 
    while (1)
    {
 	if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) >= 0)
	    break;

	/* Sleep for 10ms before trying again */
	usleep(10000);
    }

    /* Once the server accepts the connection, it tries to send the client a
     * sync message. It will fail if we close the socket now. So we keep the
     * socket open until a sync is received, to keep the server happy. */
    ipc_client_sync(fd);

    socket_close(fd);
    
    return 0;
}
예제 #4
0
void *memdup_log(rg_error_level_t severity, void *ptr, int len)
{
    void *dst;

    if (!(dst = memdup(ptr, len)))
	rg_error(severity, "memdup(buf %p len %d) failed", ptr, len);
    return dst;
}
예제 #5
0
파일: alloc.c 프로젝트: livebox/livebox2
void *zalloc_log(rg_error_level_t level, size_t size)
{
    void *mem;

    if (!(mem = zalloc(size)))
	rg_error(level, "zalloc_e(%d): failed", size);
    return mem;
}
void *strdup_log(rg_error_level_t level, char *s)
{
    char *str;

    if (!(str = strdup(s)))
	rg_error(level, "strdup() failed");
    return str;
}
예제 #7
0
void *realloc_log(rg_error_level_t level, void *p, size_t size)
{
    void *mem;

    if (!(mem = realloc(p, size)))
	rg_error(level, "realloc_e(%zd): failed", size);
    return mem;
}
예제 #8
0
void *malloc_log(rg_error_level_t level, size_t size)
{
    void *mem;

    mem = malloc(size);
    if (!mem)
	rg_error(level, "malloc_e(%zd): failed", size);
    return mem;
}
/* normally should be called with src_ip==0 and src_port==0 */
int sock_socket(int type, u32 src_ip, u16 src_port)
{
    int sock = -1;
    struct sockaddr_in sa;

    if ((sock = socket(AF_INET, type, 0))<0)
	return rg_error(LERR, "sock_socket: failed socket()");
    MZERO(sa);
    sa.sin_family = AF_INET;
    sa.sin_addr.s_addr = src_ip;
    sa.sin_port = src_port; 
    if (src_port)
    {
	int opt = 1;
	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, 
	    (void *)&opt, sizeof(opt))<0)
	{
	    rg_error(LERR, "sock_socket: failed setsockopt(SO_REUSEADDR)");
	    goto Error;
	}
	if ((bind(sock, (struct sockaddr *)&sa, sizeof(sa)))<0)
	{
	    rg_error(LERR, "sock_socket: failed bind(): %s", strerror(errno));
	    goto Error;
	}
    }
    else
    {
	if ((bind(sock, (struct sockaddr *)&sa, sizeof(sa)))<0)
	{
	    rg_error(LERR, "sock_socket: failed bind()");
	    goto Error;
	}
    }
    
    rg_error(LDEBUG, "sock_socket: created fd %d for ip %s port %d", sock,
	inet_ntoa(sa.sin_addr), ntohs(sa.sin_port));
    return sock;
    
Error:
    if (sock>=0)
	close(sock);
    return -1;
}
예제 #10
0
파일: ipc.c 프로젝트: livebox/livebox2
int ipc_accept(int server_fd)
{
    int fd;

    if ((fd = bio_accept(server_fd)) < 0)
    {
	rg_error(LERR, "%d: failed ipc accept %m", server_fd);
	return -1;
    }
    if (ipc_server_sync(fd))
    {
	rg_error(LERR, "%d: failed ipc accept sync", server_fd);
	goto Error;
    }
    return fd;

Error:
    socket_close(fd);
    return -1;
}
예제 #11
0
파일: ipc.c 프로젝트: livebox/livebox2
static int __ipc_connect_ip(u16 port, u32 addr, int quiet)
{
    struct sockaddr_in sa;
    int fd = -1;

    while (1)
    {
	if ((fd = sock_socket(SOCK_STREAM, 0, 0)) < 0)
	    return -1;
	
	MZERO(sa);
	sa.sin_family = AF_INET;
	sa.sin_addr.s_addr = addr;
	sa.sin_port = port;
 	if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0)
	{
	    socket_close(fd);
	    if (!quiet)
		rg_error(LERR, "failed ipc connect %m");
	    return -1;
	}
	/* Linux 2.4 kernel has a bug with localhost connections.
	 * After the server calls listen(), then the client calls
	 * connect() and returns with success immediately, before
	 * the server calls accept()!
	 * Therefore, a SYNC_STR command is used to make sure the connect
	 * succeeded.
	 * This has not been tested on Linux 2.2 whether it too has
	 * this bug. It probably does not exist on VxWorks, since VxWorks
	 * TCP/IP stack is completely different (its BSD based).
	 */
	if (!ipc_client_sync(fd))
	    break;
	socket_close(fd);
	if (!quiet)
	    rg_error(LWARN, "failed ipc connect sync - retrying");
	sys_sleep(1);
    }

    return fd;
}
예제 #12
0
파일: alloc.c 프로젝트: livebox/livebox2
void *realloc_log(rg_error_level_t level, void *p, size_t size)
{
    void *mem;

    /* uClibc crashes on realloc(p, 0) */
    if (!size)
	size = 4;

    if (!(mem = realloc(p, size)))
	rg_error(level, "realloc_e(%d): failed", size);
    return mem;
}
예제 #13
0
static void async_ipc_estream_closed(void *context)
{
    async_ipc_t *aipc = context;

    event_timer_del(async_ipc_estream_timed_out, aipc);
    aipc->e = NULL;
    if (aipc->cb)
    {
	rg_error(LERR, "Async IPC: Peer closed connection");
	async_ipc_notify(aipc, -1);
    }
}
int snprintf_l(char *str, size_t size, const char *format, ...)
{
    int retval;
    va_list ap;

    va_start(ap, format);
    retval = vsnprintf(str, size, format, ap);
    if (retval<0)
	rg_error(LERR, "String '%s' truncated", str);
    va_end(ap);
    return retval;
}
예제 #15
0
파일: alloc.c 프로젝트: livebox/livebox2
void *malloc_log(rg_error_level_t level, size_t size)
{
    void *mem;

    /* uClibc crashes on malloc(0) */
    if (!size)
	size = 4;

    mem = malloc(size);
    if (!mem)
	rg_error(level, "malloc_e(%d): failed", size);
    return mem;
}
예제 #16
0
static int async_ipc_connected(estream_t *e, int connected)
{
    async_ipc_t *aipc = estream_get_data(e);

    if (!connected)
    {
	rg_error(LERR, "Async IPC: Could not connect");
	async_ipc_notify(aipc, -1);
	return 0;
    }

    estream_set_func(e, async_ipc_estream_func);
    async_ipc_read_start(aipc);
    return 0;
}
static void rg_reboot(void)
{
    rg_error(LINFO, "rebooting!");

#ifdef HAVE_KILL
   /* signal the init process (openrg or init) to reboot. */
    kill(1, SIGINT);
#else
    /* This code generates three types of exception: 
     * division by 0 - handled by FPU/Emulator, 
     * unaligned access (float at wrong alignment) - for non-MMU out there
     * segmentation  - 1 is not legal at most MMU platforms.
     */
    *(float *)1 = 1 / 0.0;
#endif
}
예제 #18
0
파일: ipc.c 프로젝트: livebox/livebox2
int ipc_server_sync(int fd)
{
    char *sync = NULL;
    int rc = -1;

    if (!(sync = ipc_string_read(fd)) || strcmp(sync, SYNC_STR))
	goto Exit;
    if (ipc_string_write(fd, SYNC_STR))
	goto Exit;
    rc = 0;

Exit:
    if (rc)
	rg_error(LERR, "%d: failed ipc server sync", fd);
    nfree(sync);
    return rc;
}
예제 #19
0
파일: ipc.c 프로젝트: livebox/livebox2
int ipc_listen_ip(u16 port, u32 addr)
{
    int fd;
    
    if ((fd = sock_socket(SOCK_STREAM, addr, port)) < 0)
	return -1;
    /* 5 is a big enough queue length */
    if (listen(fd, 5) < 0)
    {
	rg_error(LERR, "failed ipc listen %m");
	goto Error;
    }
    return fd;

Error:
    socket_close(fd);
    return -1;
}
예제 #20
0
static void process_sync(async_ipc_t *aipc)
{
    if ((aipc->n != sizeof(RG_IPC_SYNC_STR) || 
	strcmp(aipc->sync, RG_IPC_SYNC_STR)))
    {
	rg_error(LERR, "Async IPC: Bad sync");
	async_ipc_notify(aipc, -1);
	return;
    }

    aipc->got_sync = 1;

    if (aipc->closing)
    {
	/* We got the sync upon end of message */
	async_ipc_notify(aipc, 0);
	async_ipc_free(aipc);
    }
    else
	async_ipc_read_start(aipc);
}
예제 #21
0
void rg_error_init(int _reboot_on_exit, int _reboot_on_panic,
    int strace, char *process, rg_error_level_t console_level,
    int (*_main_addr)(int, char *[]), const char *_main_name)
{
    if (inited)
	rg_error(LEXIT, "rg_error_init: already inited");
    inited = 1;
    if (strace)
	strace_init();
    if (process)
    {
	strncpy(proc_name, process, MAX_PROC_NAME);
	proc_name[MAX_PROC_NAME-1] = 0;
    }
    else
	strcpy(proc_name, get_proc_name());
    rg_error_console_level = console_level;
    main_addr = _main_addr;
    main_name = _main_name;
    reboot_on_exit = _reboot_on_exit;
    reboot_on_panic = _reboot_on_panic;
}