Example #1
0
int fd_collection::addpipe(int fdrd, int fdwr)
{
	fdcoll_logfunc("fdrd=%d, fdwr=%d", fdrd, fdwr);

	if (!is_valid_fd(fdrd) || !is_valid_fd(fdwr))
		return -1;

	lock();

	// Sanity check to remove any old objects using the same fd!!
	socket_fd_api* p_fdrd_api_obj = get_sockfd(fdrd);
	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_fdrd_api_obj) {
		fdcoll_logwarn("[fd=%d] Deleting old duplicate object (%p)", fdrd, p_fdrd_api_obj);
		unlock();
		handle_close(fdrd, true);
		lock();
	}
	BULLSEYE_EXCLUDE_BLOCK_END
	socket_fd_api* p_fdwr_api_obj = get_sockfd(fdwr);
	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_fdwr_api_obj) {
		fdcoll_logwarn("[fd=%d] Deleting old duplicate object (%p)", fdwr, p_fdwr_api_obj);
		unlock();
		handle_close(fdwr, true);
		lock();
	}
	BULLSEYE_EXCLUDE_BLOCK_END

	unlock();
	p_fdrd_api_obj = new pipeinfo(fdrd);
	p_fdwr_api_obj = new pipeinfo(fdwr);
	lock();

	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_fdrd_api_obj == NULL) {
		fdcoll_logpanic("[fd=%d] Failed creating new pipeinfo (%m)", fdrd);
	}
	if (p_fdwr_api_obj == NULL) {
		fdcoll_logpanic("[fd=%d] Failed creating new pipeinfo (%m)", fdwr);
	}
	BULLSEYE_EXCLUDE_BLOCK_END

	m_p_sockfd_map[fdrd] = p_fdrd_api_obj;
	m_p_sockfd_map[fdwr] = p_fdwr_api_obj;

	unlock();

	return 0;
}
Example #2
0
int fd_collection::addepfd(int epfd, int size)
{
	fdcoll_logfunc("epfd=%d", epfd);

	if (!is_valid_fd(epfd))
		return -1;

	lock();

	// Sanity check to remove any old sockinfo object using the same fd!!
	epfd_info* p_fd_info = get_epfd(epfd);
	if (p_fd_info) {
		fdcoll_logwarn("[fd=%d] Deleting old duplicate sockinfo object (%p)", epfd, p_fd_info);
		unlock();
		handle_close(epfd, true);
		lock();
	}

	unlock();
	p_fd_info = new epfd_info(epfd, size);
	lock();

	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_fd_info == NULL) {
		fdcoll_logpanic("[fd=%d] Failed creating new sockinfo (%m)", epfd);
	}
	BULLSEYE_EXCLUDE_BLOCK_END
	m_p_epfd_map[epfd] = p_fd_info;
	m_epfd_lst.push_back(p_fd_info);

	unlock();

	return 0;
}
Example #3
0
static inline ssize_t
tls_pull(gnutls_transport_ptr ptr, void *buf, size_t size)
{
    struct gnutella_socket *s = ptr;
    ssize_t ret;
    int saved_errno;

    socket_check(s);
    g_assert(is_valid_fd(s->file_desc));

    ret = s_read(s->file_desc, buf, size);
    saved_errno = errno;
    tls_signal_pending(s);
    if ((ssize_t) -1 == ret) {
        tls_set_errno(s, saved_errno);
        if (!is_temporary_error(saved_errno)) {
            socket_connection_reset(s);
        }
    } else if (0 == ret) {
        socket_eof(s);
    }
    tls_transport_debug("tls_pull", s, size, ret);
    errno = saved_errno;
    return ret;
}
Example #4
0
static struct file_object *
file_object_alloc(const int fd, const char * const pathname, int accmode)
{
    static const struct file_object zero_fo;
    struct file_object *fo;
    hikset_t *ht;

    g_return_val_if_fail(fd >= 0, NULL);
    g_return_val_if_fail(pathname, NULL);
    g_return_val_if_fail(is_absolute_path(pathname), NULL);
    g_return_val_if_fail(!file_object_find(pathname, accmode), NULL);

    ht = file_object_mode_get_table(accmode);
    g_return_val_if_fail(ht, NULL);

    WALLOC(fo);
    *fo = zero_fo;
    fo->magic = FILE_OBJECT_MAGIC;
    fo->ref_count = 1;
    fo->fd = fd;
    fo->accmode = accmode;
    fo->pathname = atom_str_get(pathname);

    file_object_check(fo);
    g_assert(is_valid_fd(fo->fd));
    hikset_insert(ht, fo);

    return fo;
}
Example #5
0
/**
 * Uses fstat() or getsockopt() to determine whether the given file descriptor
 * is a socket.
 *
 * @param fd An arbitrary file descriptor.
 * @return TRUE if fd is a socket, FALSE otherwise.
 */
bool
is_a_socket(int fd)
#ifdef S_ISSOCK
{
	filestat_t sb;

	return is_valid_fd(fd) && 0 == fstat(fd, &sb) && 0 != S_ISSOCK(sb.st_mode);
}
Example #6
0
void fd_collection::del_tapfd(int fd)
{
	if (!is_valid_fd(fd))
		return;

	lock();
	m_p_tap_map[fd] = NULL;
	unlock();
}
Example #7
0
int close(int fd)
{
	if (!is_valid_fd(fd))
		return -1;

	fd_array[fd].type = FILEIO_TYPE_EMPTY;

	return 0;
}
Example #8
0
int fd_collection::add_cq_channel_fd(int cq_ch_fd, ring* p_ring)
{
	fdcoll_logfunc("cq_ch_fd=%d", cq_ch_fd);

	if (!is_valid_fd(cq_ch_fd))
		return -1;

	lock();

	epfd_info* p_fd_info = get_epfd(cq_ch_fd);
	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_fd_info) {
		fdcoll_logwarn("[fd=%d] Deleting old duplicate sockinfo object (%p)", cq_ch_fd, p_fd_info);
		unlock();
		handle_close(cq_ch_fd, true);
		lock();
	}
	BULLSEYE_EXCLUDE_BLOCK_END

	// Sanity check to remove any old objects using the same fd!!
	socket_fd_api* p_cq_ch_fd_api_obj = get_sockfd(cq_ch_fd);
	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_cq_ch_fd_api_obj) {
		fdcoll_logwarn("[fd=%d] Deleting old duplicate object (%p)", cq_ch_fd, p_cq_ch_fd_api_obj);
		unlock();
		handle_close(cq_ch_fd, true);
		lock();
	}
	BULLSEYE_EXCLUDE_BLOCK_END

	// Check if cq_channel_info was already created
	cq_channel_info* p_cq_ch_info = get_cq_channel_fd(cq_ch_fd);
	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_cq_ch_info) {
		fdcoll_logwarn("cq channel fd already exists in fd_collection");
		m_p_cq_channel_map[cq_ch_fd] = NULL;
		delete p_cq_ch_info;
		p_cq_ch_info = NULL;
	}
	BULLSEYE_EXCLUDE_BLOCK_END

	unlock();
	p_cq_ch_info = new cq_channel_info(p_ring);
	lock();

	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_cq_ch_info == NULL) {
		fdcoll_logpanic("[fd=%d] Failed creating new cq_channel_info (%m)", cq_ch_fd);
	}
	BULLSEYE_EXCLUDE_BLOCK_END
	m_p_cq_channel_map[cq_ch_fd] = p_cq_ch_info;

	unlock();

	return 0;
}
Example #9
0
/**
 * Standard recv function for the libc.
 *
 * @param fd     socket file descriptor
 * @param buf    pointer to the array where the packet should be stored
 * @param len    maximum length in bytes of the packet
 * @param flags  currently unused, should be 0
 * @return       the number of bytes that have been received successfully
 */
int recv(int fd, void *buf, int len, int flags)
{
	if (!is_valid_fd(fd))
		return -1;

	forth_push((unsigned long)buf);
	forth_push(len);
	forth_push(fd_array[fd].read_xt);
	return forth_eval_pop("EXECUTE");
}
Example #10
0
/**
 * Standard send function for the libc.
 *
 * @param fd     socket file descriptor
 * @param buf    pointer to the array with the output packet
 * @param len    length in bytes of the packet
 * @param flags  currently unused, should be 0
 * @return       the number of bytes that have been sent successfully
 */
int send(int fd, const void *buf, int len, int flags)
{
	if (!is_valid_fd(fd))
		return -1;

	forth_push((unsigned long)buf);
	forth_push(len);
	forth_push(fd_array[fd].write_xt);
	return forth_eval_pop("EXECUTE");

}
Example #11
0
/**
 * Open stream to specified file descriptor.
 */
ostream_t *
ostream_open_fd(int fd)
{
	ostream_t *os;

	g_assert(is_valid_fd(fd));

	os = ostream_alloc(OSTREAM_T_FD);
	os->u.fd = fd;

	return os;
}
Example #12
0
    void ZookeeperClient::ZKIOCallback(struct aeEventLoop *eventLoop, int fd,
		    void *clientData, int mask)
    {
	if (fd > 0 && !is_valid_fd(fd))
	{
	    aeDeleteFileEvent(eventLoop, fd, AE_READABLE | AE_WRITABLE);
	    return;
	}

	int events = 0;
	if (mask & AE_READABLE)
	{
	    events |= ZOOKEEPER_READ;
	}
	if (mask & AE_WRITABLE)
	{
	    events |= ZOOKEEPER_WRITE;
	}
	ZookeeperClient* zk = (ZookeeperClient*) clientData;
	zhandle_t* zhandler = zk->m_zk;
	if (0 != events && -1 != fd)
	{
	    int rc = zookeeper_process(zhandler, events);
	    if (rc != ZOK && !is_valid_fd(fd))
	    {
		aeDeleteFileEvent(eventLoop, fd, AE_READABLE | AE_WRITABLE);
		if (zk->m_zk_fd == fd)
		{
		    zk->m_zk_fd = -1;
		}
	    }
	}
	if (zhandler != zk->m_zk)
	{
	    //already closed
	    return;
	}
	zk->CheckConn();
    }
Example #13
0
/**
 * Acquires a file object for a given pathname and access mode. If
 * no matching file object exists, NULL is returned.
 *
 * @param pathname An absolute pathname.
 * @return	On failure NULL is returned. On success a file object is
 *			returned.
 */
struct file_object *
file_object_open(const char * const pathname, int accmode)
{
    struct file_object *fo;

    g_return_val_if_fail(pathname, NULL);
    g_return_val_if_fail(is_absolute_path(pathname), NULL);

    fo = file_object_find(pathname, accmode);
    if (fo) {
        fo->ref_count++;
        g_assert(is_valid_fd(fo->fd));
    }
    return fo;
}
Example #14
0
int fd_collection::addtapfd(int tapfd, ring_tap* p_ring)
{
	fdcoll_logfunc("tapfd=%d, p_ring=%p", tapfd, p_ring);

	if (!is_valid_fd(tapfd))
		return -1;

	lock();

	if (get_tapfd(tapfd)) {
		fdcoll_logwarn("[tapfd=%d] already exist in the collection (ring %p)", tapfd, get_tapfd(tapfd));
		return -1;
	}

	m_p_tap_map[tapfd] = p_ring;

	unlock();

	return 0;
}
Example #15
0
int fd_collection::del(int fd, bool b_cleanup, cls **map_type)
{
	fdcoll_logfunc("fd=%d%s", fd, 
	               b_cleanup ? ", cleanup case: trying to remove old socket handler":"");

	if (!is_valid_fd(fd))
		return -1;

	lock();
	cls* p_obj = map_type[fd];
	if (p_obj) {
		map_type[fd] = NULL;
		unlock();
		p_obj->clean_obj();
		return 0;
	}
	if (!b_cleanup) {
		fdcoll_logdbg("[fd=%d] Could not find related object", fd);
	}
	unlock();
	return -1;
}
Example #16
0
static inline ssize_t
tls_push(gnutls_transport_ptr ptr, const void *buf, size_t size)
{
    struct gnutella_socket *s = ptr;
    ssize_t ret;
    int saved_errno;

    socket_check(s);
    g_assert(is_valid_fd(s->file_desc));

    ret = s_write(s->file_desc, buf, size);
    saved_errno = errno;
    tls_signal_pending(s);
    if ((ssize_t) -1 == ret) {
        tls_set_errno(s, saved_errno);
        if (ECONNRESET == saved_errno || EPIPE == saved_errno) {
            socket_connection_reset(s);
        }
    }
    tls_transport_debug("tls_push", s, size, ret);
    errno = saved_errno;
    return ret;
}
Example #17
0
/**
 * Find an existing file object associated with the given pathname
 * for the given access mode.
 *
 * @return If no file object with the given pathname is found NULL
 *		   is returned.
 */
static struct file_object *
file_object_find(const char * const pathname, int accmode)
{
    struct file_object *fo;

    g_return_val_if_fail(ht_file_objects_rdonly, NULL);
    g_return_val_if_fail(ht_file_objects_wronly, NULL);
    g_return_val_if_fail(ht_file_objects_rdwr, NULL);
    g_return_val_if_fail(pathname, NULL);
    g_return_val_if_fail(is_absolute_path(pathname), NULL);

    fo = hikset_lookup(file_object_mode_get_table(O_RDWR), pathname);

    /*
     * We need to find a more specific file object if looking for O_WRONLY
     * or O_RDONLY ones.
     */

    if (O_RDWR != accmode) {
        struct file_object *xfo;
        xfo = hikset_lookup(file_object_mode_get_table(accmode), pathname);
        if (xfo != NULL) {
            g_assert(xfo->accmode == accmode);
            fo = xfo;
        }
    }

    if (fo) {
        file_object_check(fo);
        g_assert(is_valid_fd(fo->fd));
        g_assert(0 == strcmp(pathname, fo->pathname));
        g_assert(accmode_is_valid(fo->fd, accmode));
        g_assert(!fo->removed);
    }

    return fo;
}
Example #18
0
static inline int
emulate_poll_with_select(struct pollfd *fds, unsigned int n, int timeout)
{
	struct timeval tv;
	unsigned i;
	fd_set rfds, wfds, efds;
	int ret, max_fd = -1;

	FD_ZERO(&rfds);
	FD_ZERO(&wfds);
	FD_ZERO(&efds);

	for (i = 0; i < n; i++) {
		int fd = cast_to_fd(fds[i].fd);

		safety_assert(!is_valid_fd(fd) || is_a_socket(fd) || is_a_fifo(fd));

		if (!is_okay_for_select(fd) || i >= FD_SETSIZE) {
			fds[i].revents = POLLERR;
			continue;
		}

		max_fd = MAX(fd, max_fd);
		fds[i].revents = 0;

		if (POLLIN & fds[i].events) {
			FD_SET(socket_fd(fd), &rfds);
		}
		if (POLLOUT & fds[i].events) {
			FD_SET(socket_fd(fd), &wfds);
		}
		FD_SET(socket_fd(fd), &efds);
	}

	if (timeout >= 0) {
		tv.tv_sec = timeout / 1000;
		tv.tv_usec = (timeout % 1000) * 1000UL;
	}

	ret = select(max_fd + 1, &rfds, &wfds, &efds, timeout < 0 ? NULL : &tv);

	if (ret > 0) {

		n = MIN(n, FD_SETSIZE);	/* POLLERR is already set above */
		for (i = 0; i < n; i++) {
			int fd = cast_to_fd(fds[i].fd);

			if (!is_okay_for_select(fd))
				continue;

			if (FD_ISSET(fd, &rfds)) {
				fds[i].revents |= POLLIN;
			}
			if (FD_ISSET(fd, &wfds)) {
				fds[i].revents |= POLLOUT;
			}
			if (FD_ISSET(fd, &efds)) {
				fds[i].revents |= POLLERR;
			}
		}
	} else if (ret < 0) {
		s_warning("error during select(): %m");
	}
	return ret;
}
Example #19
0
static inline int
is_okay_for_select(int fd)
{
	return is_valid_fd(fd) &&
		(is_running_on_mingw() || UNSIGNED(fd) < FD_SETSIZE);
}
Example #20
0
/* returns Py_None if the fd is not valid */
static PyObject*
create_stdio(PyObject* io,
    int fd, int write_mode, const char* name,
    const char* encoding, const char* errors)
{
    PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res;
    const char* mode;
    const char* newline;
    PyObject *line_buffering;
    int buffering, isatty;
    _Py_IDENTIFIER(open);
    _Py_IDENTIFIER(isatty);
    _Py_IDENTIFIER(TextIOWrapper);
    _Py_IDENTIFIER(mode);

    if (!is_valid_fd(fd))
        Py_RETURN_NONE;

    /* stdin is always opened in buffered mode, first because it shouldn't
       make a difference in common use cases, second because TextIOWrapper
       depends on the presence of a read1() method which only exists on
       buffered streams.
    */
    if (Py_UnbufferedStdioFlag && write_mode)
        buffering = 0;
    else
        buffering = -1;
    if (write_mode)
        mode = "wb";
    else
        mode = "rb";
    buf = _PyObject_CallMethodId(io, &PyId_open, "isiOOOi",
                                 fd, mode, buffering,
                                 Py_None, Py_None, /* encoding, errors */
                                 Py_None, 0); /* newline, closefd */
    if (buf == NULL)
        goto error;

    if (buffering) {
        _Py_IDENTIFIER(raw);
        raw = _PyObject_GetAttrId(buf, &PyId_raw);
        if (raw == NULL)
            goto error;
    }
    else {
        raw = buf;
        Py_INCREF(raw);
    }

    text = PyUnicode_FromString(name);
    if (text == NULL || _PyObject_SetAttrId(raw, &PyId_name, text) < 0)
        goto error;
    res = _PyObject_CallMethodId(raw, &PyId_isatty, "");
    if (res == NULL)
        goto error;
    isatty = PyObject_IsTrue(res);
    Py_DECREF(res);
    if (isatty == -1)
        goto error;
    if (isatty || Py_UnbufferedStdioFlag)
        line_buffering = Py_True;
    else
        line_buffering = Py_False;

    Py_CLEAR(raw);
    Py_CLEAR(text);

#ifdef MS_WINDOWS
    /* sys.stdin: enable universal newline mode, translate "\r\n" and "\r"
       newlines to "\n".
       sys.stdout and sys.stderr: translate "\n" to "\r\n". */
    newline = NULL;
#else
    /* sys.stdin: split lines at "\n".
       sys.stdout and sys.stderr: don't translate newlines (use "\n"). */
    newline = "\n";
#endif

    stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OsssO",
                                    buf, encoding, errors,
                                    newline, line_buffering);
    Py_CLEAR(buf);
    if (stream == NULL)
        goto error;

    if (write_mode)
        mode = "w";
    else
        mode = "r";
    text = PyUnicode_FromString(mode);
    if (!text || _PyObject_SetAttrId(stream, &PyId_mode, text) < 0)
        goto error;
    Py_CLEAR(text);
    return stream;

error:
    Py_XDECREF(buf);
    Py_XDECREF(stream);
    Py_XDECREF(text);
    Py_XDECREF(raw);

    if (PyErr_ExceptionMatches(PyExc_OSError) && !is_valid_fd(fd)) {
        /* Issue #24891: the file descriptor was closed after the first
           is_valid_fd() check was called. Ignore the OSError and set the
           stream to None. */
        PyErr_Clear();
        Py_RETURN_NONE;
    }
    return NULL;
}
Example #21
0
/* Initialize sys.stdin, stdout, stderr and builtins.open */
static int
initstdio(void)
{
    PyObject *iomod = NULL, *wrapper;
    PyObject *bimod = NULL;
    PyObject *m;
    PyObject *std = NULL;
    int status = 0, fd;
    PyObject * encoding_attr;
    char *pythonioencoding = NULL, *encoding, *errors;

    /* Hack to avoid a nasty recursion issue when Python is invoked
       in verbose mode: pre-import the Latin-1 and UTF-8 codecs */
    if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) {
        goto error;
    }
    Py_DECREF(m);

    if (!(m = PyImport_ImportModule("encodings.latin_1"))) {
        goto error;
    }
    Py_DECREF(m);

    if (!(bimod = PyImport_ImportModule("builtins"))) {
        goto error;
    }

    if (!(iomod = PyImport_ImportModule("io"))) {
        goto error;
    }
    if (!(wrapper = PyObject_GetAttrString(iomod, "OpenWrapper"))) {
        goto error;
    }

    /* Set builtins.open */
    if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) {
        Py_DECREF(wrapper);
        goto error;
    }
    Py_DECREF(wrapper);

    encoding = _Py_StandardStreamEncoding;
    errors = _Py_StandardStreamErrors;
    if (!encoding || !errors) {
        if (!errors) {
            /* When the LC_CTYPE locale is the POSIX locale ("C locale"),
               stdin and stdout use the surrogateescape error handler by
               default, instead of the strict error handler. */
            char *loc = setlocale(LC_CTYPE, NULL);
            if (loc != NULL && strcmp(loc, "C") == 0)
                errors = "surrogateescape";
        }

        pythonioencoding = Py_GETENV("PYTHONIOENCODING");
        if (pythonioencoding) {
            char *err;
            pythonioencoding = _PyMem_Strdup(pythonioencoding);
            if (pythonioencoding == NULL) {
                PyErr_NoMemory();
                goto error;
            }
            err = strchr(pythonioencoding, ':');
            if (err) {
                *err = '\0';
                err++;
                if (*err && !_Py_StandardStreamErrors) {
                    errors = err;
                }
            }
            if (*pythonioencoding && !encoding) {
                encoding = pythonioencoding;
            }
        }
    }

    /* Set sys.stdin */
    fd = fileno(stdin);
    /* Under some conditions stdin, stdout and stderr may not be connected
     * and fileno() may point to an invalid file descriptor. For example
     * GUI apps don't have valid standard streams by default.
     */
    if (!is_valid_fd(fd)) {
        std = Py_None;
        Py_INCREF(std);
    }
    else {
        std = create_stdio(iomod, fd, 0, "<stdin>", encoding, errors);
        if (std == NULL)
            goto error;
    } /* if (fd < 0) */
    PySys_SetObject("__stdin__", std);
    _PySys_SetObjectId(&PyId_stdin, std);
    Py_DECREF(std);

    /* Set sys.stdout */
    fd = fileno(stdout);
    if (!is_valid_fd(fd)) {
        std = Py_None;
        Py_INCREF(std);
    }
    else {
        std = create_stdio(iomod, fd, 1, "<stdout>", encoding, errors);
        if (std == NULL)
            goto error;
    } /* if (fd < 0) */
    PySys_SetObject("__stdout__", std);
    _PySys_SetObjectId(&PyId_stdout, std);
    Py_DECREF(std);

#if 1 /* Disable this if you have trouble debugging bootstrap stuff */
    /* Set sys.stderr, replaces the preliminary stderr */
    fd = fileno(stderr);
    if (!is_valid_fd(fd)) {
        std = Py_None;
        Py_INCREF(std);
    }
    else {
        std = create_stdio(iomod, fd, 1, "<stderr>", encoding, "backslashreplace");
        if (std == NULL)
            goto error;
    } /* if (fd < 0) */

    /* Same as hack above, pre-import stderr's codec to avoid recursion
       when import.c tries to write to stderr in verbose mode. */
    encoding_attr = PyObject_GetAttrString(std, "encoding");
    if (encoding_attr != NULL) {
        const char * std_encoding;
        std_encoding = _PyUnicode_AsString(encoding_attr);
        if (std_encoding != NULL) {
            PyObject *codec_info = _PyCodec_Lookup(std_encoding);
            Py_XDECREF(codec_info);
        }
        Py_DECREF(encoding_attr);
    }
    PyErr_Clear();  /* Not a fatal error if codec isn't available */

    if (PySys_SetObject("__stderr__", std) < 0) {
        Py_DECREF(std);
        goto error;
    }
    if (_PySys_SetObjectId(&PyId_stderr, std) < 0) {
        Py_DECREF(std);
        goto error;
    }
    Py_DECREF(std);
#endif

    if (0) {
  error:
        status = -1;
    }

    /* We won't need them anymore. */
    if (_Py_StandardStreamEncoding) {
        PyMem_RawFree(_Py_StandardStreamEncoding);
        _Py_StandardStreamEncoding = NULL;
    }
    if (_Py_StandardStreamErrors) {
        PyMem_RawFree(_Py_StandardStreamErrors);
        _Py_StandardStreamErrors = NULL;
    }
    PyMem_Free(pythonioencoding);
    Py_XDECREF(bimod);
    Py_XDECREF(iomod);
    return status;
}
Example #22
0
int get_selects(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set *efds) {
    // Initialize
    FD_ZERO(rfds);
    FD_ZERO(wfds);
    FD_ZERO(efds);

    // Always select tun
    FD_SET(args->tun, rfds);
    FD_SET(args->tun, efds);
    int max = args->tun;

    // Select ICMP sockets
    struct icmp_session *i = icmp_session;
    while (i != NULL) {
        if (!i->stop) {
            if (is_valid_fd(i->socket)) {
                FD_SET(i->socket, efds);
                FD_SET(i->socket, rfds);
                if (i->socket > max)
                    max = i->socket;
            } else {
                log_android(ANDROID_LOG_WARN, "ICMP socket %d select error %d: %s",
                            i->socket, errno, strerror(errno));
                i->stop = 1;
            }
        }
        i = i->next;
    }

    // Select UDP sockets
    struct udp_session *u = udp_session;
    while (u != NULL) {
        if (u->state == UDP_ACTIVE) {
            if (is_valid_fd(u->socket)) {
                FD_SET(u->socket, efds);
                FD_SET(u->socket, rfds);
                if (u->socket > max)
                    max = u->socket;
            }
            else {
                log_android(ANDROID_LOG_WARN, "UDP socket %d select error %d: %s",
                            u->socket, errno, strerror(errno));
                u->state = UDP_FINISHING;
            }
        }
        u = u->next;
    }

    // Select TCP sockets
    struct tcp_session *t = tcp_session;
    while (t != NULL) {
        // Select sockets
        if (t->socket >= 0) {
            if (is_valid_fd(t->socket)) {
                if (t->state == TCP_LISTEN) {
                    // Check for errors
                    FD_SET(t->socket, efds);

                    // Check for connected = writable
                    FD_SET(t->socket, wfds);

                    if (t->socket > max)
                        max = t->socket;
                }
                else if (t->state == TCP_ESTABLISHED || t->state == TCP_CLOSE_WAIT) {
                    // Check errors
                    FD_SET(t->socket, efds);

                    // Check for incoming data
                    if (get_send_window(t) > 0)
                        FD_SET(t->socket, rfds);

                    // Check for outgoing data
                    if (t->forward != NULL)
                        FD_SET(t->socket, wfds);

                    if (t->socket > max)
                        max = t->socket;
                }
            }
            else {
                log_android(ANDROID_LOG_WARN, "TCP socket %d select error %d: %s",
                            t->socket, errno, strerror(errno));
                write_rst(args, t);
            }
        }

        t = t->next;
    }

    return max;
}
Example #23
0
/**
 * Initiates a new TLS session.
 *
 * @return 0 on success, -1 on error.
 */
int
tls_init(struct gnutella_socket *s)
{
    /**
     * ANON-DH is enabled because we don't use PKI.
     * DEFLATE is disabled because it seems to cause crashes.
     * ARCFOUR-40 is disabled because it is deprecated.
     */
    static const char prio_want[] = "NORMAL:+ANON-DH:-ARCFOUR-40:-COMP-DEFLATE";
    /* "-COMP-DEFLATE" is causing an error on MinGW with GnuTLS 2.10.2 */
    static const char prio_must[] = "NORMAL:+ANON-DH:-ARCFOUR-40";
    const bool server = SOCK_CONN_INCOMING == s->direction;
    struct tls_context *ctx;
    const char *fn;
    int e;

#define TRY(function) (fn = (#function)), e = function

    socket_check(s);

    WALLOC0(ctx);
    ctx->s = s;
    s->tls.ctx = ctx;

    if (
        TRY(gnutls_init)(&ctx->session, server ? GNUTLS_SERVER : GNUTLS_CLIENT)
    ) {
        ctx->session = NULL;
        goto failure;
    }

    if (TRY(gnutls_priority_set_direct)(ctx->session, prio_want, NULL)) {
        const char *error;
        if (TRY(gnutls_priority_set_direct)(ctx->session, prio_must, &error)) {
            g_warning("%s() failed at \"%s\"", fn, error);
            goto failure;
        }
    }

    if (TRY(gnutls_credentials_set)(ctx->session,
                                    GNUTLS_CRD_CERTIFICATE, cert_cred))
        goto failure;

    gnutls_dh_set_prime_bits(ctx->session, TLS_DH_BITS);

#ifdef USE_TLS_CUSTOM_IO
    gnutls_transport_set_ptr(ctx->session, s);
    gnutls_transport_set_push_function(ctx->session, tls_push);
    gnutls_transport_set_pull_function(ctx->session, tls_pull);
#if !HAS_TLS(2, 12)
    /*
     * This routine has been removed starting TLS 3.0.  It was used to disable
     * the lowat feature, and apparently this is now always the case in recent
     * TLS versions.	--RAM, 2011-09-28
     *
     * It's also flagged as deprecated in 2.12.x, so don't use it there.
     *		--RAM, 2011-12-15
     */
    gnutls_transport_set_lowat(ctx->session, 0);
#endif
#else	/* !USE_TLS_CUSTOM_IO */
    g_assert(is_valid_fd(s->file_desc));
    gnutls_transport_set_ptr(ctx->session, int_to_pointer(s->file_desc));
#endif	/* USE_TLS_CUSTOM_IO */

    if (server) {
        if (TRY(gnutls_anon_allocate_server_credentials)(&ctx->server_cred))
            goto failure;

        gnutls_anon_set_server_dh_params(ctx->server_cred, get_dh_params());

        if (TRY(gnutls_credentials_set)(ctx->session,
                                        GNUTLS_CRD_ANON, ctx->server_cred))
            goto failure;

    } else {
        if (TRY(gnutls_anon_allocate_client_credentials)(&ctx->client_cred))
            goto failure;

        if (TRY(gnutls_credentials_set)(ctx->session,
                                        GNUTLS_CRD_ANON, ctx->client_cred))
            goto failure;
    }

    return 0;

failure:
    g_warning("%s() failed: %s", EMPTY_STRING(fn), gnutls_strerror(e));
    tls_free(s);
    return -1;
#undef TRY
}
Example #24
0
void *handle_events(void *a) {
    int sdk;
    fd_set rfds;
    fd_set wfds;
    fd_set efds;
    struct timespec ts;
    sigset_t blockset;
    sigset_t emptyset;
    struct sigaction sa;

    struct arguments *args = (struct arguments *) a;
    log_android(ANDROID_LOG_WARN, "Start events tun=%d thread %x", args->tun, thread_id);

    // Attach to Java
    JNIEnv *env;
    jint rs = (*jvm)->AttachCurrentThread(jvm, &env, NULL);
    if (rs != JNI_OK) {
        log_android(ANDROID_LOG_ERROR, "AttachCurrentThread failed");
        return NULL;
    }
    args->env = env;

    // Get SDK version
    sdk = sdk_int(env);

    int maxsessions = 1024;
    struct rlimit rlim;
    if (getrlimit(RLIMIT_NOFILE, &rlim))
        log_android(ANDROID_LOG_WARN, "getrlimit error %d: %s", errno, strerror(errno));
    else {
        maxsessions = (int) (rlim.rlim_cur * 50 / 100);
        log_android(ANDROID_LOG_WARN, "getrlimit soft %d hard %d max sessions %d",
                    rlim.rlim_cur, rlim.rlim_max, maxsessions);
    }
    if (maxsessions > FD_SETSIZE)
        maxsessions = FD_SETSIZE;

    // Block SIGUSR1
    sigemptyset(&blockset);
    sigaddset(&blockset, SIGUSR1);
    sigprocmask(SIG_BLOCK, &blockset, NULL);

    /// Handle SIGUSR1
    sa.sa_sigaction = handle_signal;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    sigaction(SIGUSR1, &sa, NULL);

    // Terminate existing sessions not allowed anymore
    check_allowed(args);

    stopping = 0;
    signaled = 0;

    // Loop
    while (!stopping) {
        log_android(ANDROID_LOG_DEBUG, "Loop thread %x", thread_id);

        // Count sessions
        int isessions = get_icmp_sessions();
        int usessions = get_udp_sessions();
        int tsessions = get_tcp_sessions();
        int sessions = isessions + usessions + tsessions;

        // Check sessions
        check_icmp_sessions(args, sessions, maxsessions);
        check_udp_sessions(args, sessions, maxsessions);
        check_tcp_sessions(args, sessions, maxsessions);

        // https://bugzilla.mozilla.org/show_bug.cgi?id=1093893
        int idle = (tsessions + usessions + tsessions == 0 && sdk >= 16);
        log_android(ANDROID_LOG_DEBUG, "sessions ICMP %d UDP %d TCP %d max %d/%d idle %d sdk %d",
                    isessions, usessions, tsessions, sessions, maxsessions, idle, sdk);

        // Next event time
        ts.tv_sec = (sdk < 16 ? 5 : get_select_timeout(sessions, maxsessions));
        ts.tv_nsec = 0;
        sigemptyset(&emptyset);

        // Check if tun is writable
        FD_ZERO(&rfds);
        FD_ZERO(&wfds);
        FD_ZERO(&efds);
        FD_SET(args->tun, &wfds);
        if (pselect(args->tun + 1, &rfds, &wfds, &efds, &ts, &emptyset) == 0) {
            log_android(ANDROID_LOG_WARN, "tun not writable");
            continue;
        }

        // Select
        int max = get_selects(args, &rfds, &wfds, &efds);
        int ready = pselect(max + 1, &rfds, &wfds, &efds, idle ? NULL : &ts, &emptyset);

        if (ready < 0) {
            if (errno == EINTR) {
                if (stopping && signaled) { ;
                    log_android(ANDROID_LOG_WARN,
                                "pselect signaled tun %d thread %x", args->tun, thread_id);
                    report_exit(args, NULL);
                    break;
                } else {
                    log_android(ANDROID_LOG_DEBUG,
                                "pselect interrupted tun %d thread %x", args->tun, thread_id);
                    continue;
                }
            } else if (errno == EBADF) {
                if (is_valid_fd(args->tun)) {
                    log_android(ANDROID_LOG_ERROR, "pselect  error %d: %s", errno, strerror(errno));
                    report_exit(args, "pselect error %d: %s", errno, strerror(errno));
                    break;
                }
                else {
                    log_android(ANDROID_LOG_ERROR,
                                "tun socket %d select error %d: %s",
                                args->tun, errno, strerror(errno));
                    report_exit(args, "tun socket %d select error %d: %s",
                                args->tun, errno, strerror(errno));
                    break;
                }
            } else {
                log_android(ANDROID_LOG_ERROR,
                            "pselect tun %d thread %x error %d: %s",
                            args->tun, thread_id, errno, strerror(errno));
                report_exit(args, "pselect tun %d thread %x error %d: %s",
                            args->tun, thread_id, errno, strerror(errno));
                break;
            }
        }

        if (ready == 0)
            log_android(ANDROID_LOG_DEBUG, "pselect timeout");
        else {
            log_android(ANDROID_LOG_DEBUG, "pselect ready %d", ready);

            if (pthread_mutex_lock(&lock))
                log_android(ANDROID_LOG_ERROR, "pthread_mutex_lock failed");

#ifdef PROFILE_EVENTS
            struct timeval start, end;
            float mselapsed;
            gettimeofday(&start, NULL);
#endif

            // Check upstream
            int error = 0;
            if (check_tun(args, &rfds, &wfds, &efds, sessions, maxsessions) < 0)
                error = 1;
            else {
#ifdef PROFILE_EVENTS
                gettimeofday(&end, NULL);
                mselapsed = (end.tv_sec - start.tv_sec) * 1000.0 +
                            (end.tv_usec - start.tv_usec) / 1000.0;
                if (mselapsed > PROFILE_EVENTS)
                    log_android(ANDROID_LOG_WARN, "tun %f", mselapsed);

                gettimeofday(&start, NULL);
#endif

                // Check ICMP downstream
                check_icmp_sockets(args, &rfds, &wfds, &efds);

                // Check UDP downstream
                check_udp_sockets(args, &rfds, &wfds, &efds);

                // Check TCP downstream
                check_tcp_sockets(args, &rfds, &wfds, &efds);
            }

            if (pthread_mutex_unlock(&lock))
                log_android(ANDROID_LOG_ERROR, "pthread_mutex_unlock failed");

            if (error)
                break;

#ifdef PROFILE_EVENTS
            gettimeofday(&end, NULL);
            mselapsed = (end.tv_sec - start.tv_sec) * 1000.0 +
                        (end.tv_usec - start.tv_usec) / 1000.0;
            if (mselapsed > PROFILE_EVENTS)
                log_android(ANDROID_LOG_WARN, "sockets %f", mselapsed);
#endif
        }
    }

    (*env)->DeleteGlobalRef(env, args->instance);

    // Detach from Java
    rs = (*jvm)->DetachCurrentThread(jvm);
    if (rs != JNI_OK)
        log_android(ANDROID_LOG_ERROR, "DetachCurrentThread failed");

    // Cleanup
    free(args);

    log_android(ANDROID_LOG_WARN, "Stopped events tun=%d thread %x", args->tun, thread_id);
    thread_id = 0;
    return NULL;
}
Example #25
0
int fd_collection::addsocket(int fd, int domain, int type, bool check_offload /*= false*/)
{
	transport_t transport;
	const int SOCK_TYPE_MASK = 0xf;
	int sock_type = type & SOCK_TYPE_MASK;
	int sock_flags = type & ~SOCK_TYPE_MASK;

	if (check_offload && !create_offloaded_sockets()) {
		fdcoll_logdbg("socket [fd=%d, domain=%d, type=%d] is not offloaded by thread rules or by VMA_OFFLOADED_SOCKETS", fd, domain, type);
		return -1;
	}

	// IPV4 domain only (at least today)
	if (domain != AF_INET)
		return -1;

	fdcoll_logfunc("fd=%d", fd);

	if (!is_valid_fd(fd))
		return -1;

	lock();

	// Sanity check to remove any old sockinfo object using the same fd!!
	socket_fd_api* p_sfd_api_obj = get_sockfd(fd);
	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_sfd_api_obj) {
		fdcoll_logwarn("[fd=%d] Deleting old duplicate sockinfo object (%p)", fd, p_sfd_api_obj);
		unlock();
		handle_close(fd);
		lock();
	}
	BULLSEYE_EXCLUDE_BLOCK_END

	unlock();
	try {
		switch (sock_type) {
			case SOCK_DGRAM:
			{	transport = __vma_match_by_program(PROTO_UDP, safe_mce_sys().app_id);
				if (transport == TRANS_OS) {
					fdcoll_logdbg("All UDP rules are consistent and instructing to use OS. TRANSPORT: OS");
					return -1;
				}
				fdcoll_logdbg("UDP rules are either not consistent or instructing to use VMA. TRANSPORT: VMA");
				p_sfd_api_obj = new sockinfo_udp(fd);
				break;
			}
			case SOCK_STREAM:
			{
				transport = __vma_match_by_program(PROTO_TCP, safe_mce_sys().app_id);
				if (transport == TRANS_OS) {
					fdcoll_logdbg("All TCP rules are consistent and instructing to use OS.transport == USE_OS");
					return -1;
				}
				fdcoll_logdbg("TCP rules are either not consistent or instructing to use VMA.transport == USE_VMA");
				p_sfd_api_obj = new sockinfo_tcp(fd);
				break;
			}
			default:
				fdcoll_logdbg("unsupported socket type=%d", sock_type);
				return -1;
		}
	} catch (vma_exception& e) {
	  fdcoll_logdbg("recovering from %s", e.what());
	  return -1;
	}
	lock();

	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_sfd_api_obj == NULL) {
		fdcoll_logpanic("[fd=%d] Failed creating new sockinfo (%m)", fd);
	}
	BULLSEYE_EXCLUDE_BLOCK_END

	if (sock_flags) {
		if (sock_flags & SOCK_NONBLOCK)
			p_sfd_api_obj->fcntl(F_SETFL, O_NONBLOCK);
		if (sock_flags & SOCK_CLOEXEC)
			p_sfd_api_obj->fcntl(F_SETFD, FD_CLOEXEC);
	}

	m_p_sockfd_map[fd] = p_sfd_api_obj;

	unlock();

	return fd;
}
Example #26
0
void* rover_server_log(void* args)
{
  int retval, maxfd, num_fds;//, minfd, fddiff;
  char logbuf[k_LogBufSize];
  fd_set recv_set;
  struct timeval timeout;
  //const char* start_string = "logging started";

  //senders_ready = 0;
  // close(log_new_fd);
  // close(log_imu_new_fd1);
  // close(log_imu_new_fd2);  
  // close(log_imu_new_fd3);
  log_new_fd = -1;
  log_imu_new_fd1 = -1;
  //log_imu_new_fd2 = -1;
  //  log_imu_new_fd3 = -1;
  while (!log_thread_should_die)
    {//main accept() loop
      usleep(10000);
      // printf("At top of rover_server_log main accept loop"
      // 	     "log_new_fd = %d, log_sockfd = %d, "
      // 	     "log_imu_new_fd1 = %d, log_imu_new_fd2 = %d "
      //             "log_imu_new_fd3 = %d, log_imu_sockfd = %d\n",
      // 	     log_new_fd, log_sockfd, log_imu_new_fd1, log_imu_new_fd2,
      //             log_imu_new_fd3, log_imu_sockfd);
      /*
	AcceptConnection set to non-blocking, so will spin here until it either gets 
	a valid log_new_fd (and then goes into while loop below) or 
	log_thread_should_die becomes TRUE, which will cause the while loop 
	(and function) to exit.
       */
      if (!is_valid_fd(log_new_fd))
	{
	  log_new_fd = AcceptConnection(log_sockfd);
	  if (is_valid_fd(log_new_fd))
	    printf("Log connection established with log_sockfd = %d,"
		   "log_new_fd = %d\n", log_sockfd, log_new_fd);
	}
      if ((!is_valid_fd(log_imu_new_fd1)))
	{
	  log_imu_new_fd1 = AcceptConnection(log_imu_sockfd);
	  if (is_valid_fd(log_imu_new_fd1))
	    printf("IMU log connection #1 established with log_imu_sockfd = %d,"
		   "log_imu_new_fd1 = %d\n", log_imu_sockfd, log_imu_new_fd1);
	}

      // if ((!is_valid_fd(log_imu_new_fd2)))
      // 	{
      // 	  log_imu_new_fd2 = AcceptConnection(log_imu_sockfd);
      // 	  if (is_valid_fd(log_imu_new_fd2))
      // 	    printf("IMU log connection #2 established with log_imu_sockfd = %d,"
      // 		   "log_imu_new_fd2 = %d\n", log_imu_sockfd, log_imu_new_fd2);
      // 	}

      // if ((!is_valid_fd(log_imu_new_fd3)))
      // 	{
      // 	  log_imu_new_fd3 = AcceptConnection(log_imu_sockfd);
      // 	  if (is_valid_fd(log_imu_new_fd3))
      // 	    printf("IMU log connection #3 established with log_imu_sockfd = %d,"
      // 		   "log_imu_new_fd3 = %d\n", log_imu_sockfd, log_imu_new_fd3);
      // 	}

      if ((is_valid_fd(log_new_fd)) &&
	  (is_valid_fd(log_imu_new_fd1)))//  && 
	  // (is_valid_fd(log_imu_new_fd2)))
    //  &&
	  // (is_valid_fd(log_imu_new_fd3)))
    
	{
	  
	  //sort fds here 
	  int arr[3] = {log_new_fd, log_imu_new_fd1};//, log_imu_new_fd2};//, log_imu_new_fd3};
	  maxfd = arr[0];
	  for (int i = 0; i < 3; i++)
	    {
	      if (arr[i] > maxfd)
		maxfd = arr[i];
	    }
	  //printf("all fds valid, maxfd = %d\n", maxfd); 
	
	  while (!log_thread_should_die) 
	    {  
	      //*************CHECK FDS HERE****************
	      // printf("log_new_fd = %d, log_sockfd = %d\n", log_new_fd, log_sockfd);
	      // printf("log_imu_new_fd1 = %d, log_imu_sockfd = %d\n", 
	      // 	 log_imu_new_fd1, log_imu_sockfd);
	      memset(logbuf, 0, sizeof(logbuf));  //clear buffer
	      //wrapping recv in a select here to ensure loop checks 
	      //log_thread_should_die every timeout
	      FD_ZERO(&recv_set);
	      FD_SET(log_new_fd, &recv_set);
	      FD_SET(log_imu_new_fd1, &recv_set);
	      //FD_SET(log_imu_new_fd2, &recv_set);
	      //FD_SET(log_imu_new_fd3, &recv_set); 
	      timeout.tv_sec = 0;
	      timeout.tv_usec = 1000 * 10; //10ms timeout
	      //retval = select(log_new_fd+1, &recv_set, NULL, NULL, &timeout);
	      retval = select (maxfd + 1, &recv_set, NULL, NULL, &timeout);
	      if (retval < 0)
		perror("rover_server_log--select()");
	      //printf("select error\n");
	      else if (retval == 0) //timeout
		continue; //go back to the top of the loop and recheck log_thread_should_die
	      else //retval >= 1-->we have data to receive
		{
		  num_fds = retval; //this is the number of sockets with data ready
		  //first must see which socket received data
		  if (FD_ISSET(log_new_fd, &recv_set))
		    { //regular data log
		      if (!rover_server_recv_and_print(log_new_fd, log_file))
			break; //break if recv fails (due to error or remote shutdown)
		      //if we get here, we handled the message properly, so decrement
		      //num_fds and go back to top of loop if num_fds == 0
		      --num_fds;
		      if (num_fds == 0)
			continue;
		    }
		  else if (FD_ISSET(log_imu_new_fd1, &recv_set))
		    { //imu data log from 1st connection
		      if (!rover_server_recv_and_print(log_imu_new_fd1, imu_log_file))
			break; //break if recv fails (due to error or fd closure)
		      //if we get here, we handled the message properly, so decrement
		      //num_fds and go back to top of loop if num_fds == 0
		      --num_fds;
		      if (num_fds == 0)
			continue;
		    }
		  // else if (FD_ISSET(log_imu_new_fd2, &recv_set))
		  //   { //imu data log from 2nd connection
		  //     if (!rover_server_recv_and_print(log_imu_new_fd2, imu_log_file))
		  // 	break; //break if recv fails (due to error or fd closure)
		  //     //if we get here, we handled the message properly, so decrement
		  //     //num_fds and go back to top of loop if num_fds == 0
		  //     --num_fds;
		  //     if (num_fds == 0)
		  // 	continue;
		  //   }
		  // else if (FD_ISSET(log_imu_new_fd3, &recv_set))
		  //   { //imu data log from 3rd connection
		  //     // retval = recv(log_imu_new_fd3, &logbuf, sizeof(logbuf), 0);
		  //     // if (retval > 0) //received a valid message in logbuf
		  //     // 	{ //only log start message or if all 3 sensors have started
		  //     // 	  if (strstr(logbuf, start_string) != NULL)
		  //     // 	    {
		  //     // 	      fprintf(imu_log_file, "%s\n", logbuf);
		  //     // 	      senders_ready++;
		  //     // 	    }
		  //     // 	  else if (senders_ready == 3)
		  //     // 	    fprintf(imu_log_file, "%s\n", logbuf);
		  //     // 	}
		  //     // else if (retval < 0) //error
		  //     // 	{ //what error handling to do here??
		  //     // 	  printf("retval = %d\n", retval);
		  //     // 	  perror("rover_server_log:recv(imu_log_file)");
		  //     // 	  break;
		  //     // 	}
		  //     // else // retval == 0
		  //     // 	{//sender performed orderly shutdown, so don't print to log
		  //     // 	  close(log_imu_new_fd3);
		  //     // 	  break;
		  //     // 	}
		  //     if (!rover_server_recv_and_print(log_imu_new_fd3, imu_log_file))
		  // 	break; //break if recv fails (due to error or fd closure)
		  //     //if we get here, we handled the message properly, so decrement
		  //     //num_fds and go back to top of loop if num_fds == 0
		  //     --num_fds;
		  //     if (num_fds == 0)
		  // 	continue;
		  //   }
		  else //unknown fd in recv_set
		    {
		      printf("ERROR: rover_server_log(): unknown fd in recv_set\n");
		      break;
		    }
		}
	      //printf("at end of smaller loop\n");
	    }
	  //printf("at end of big if\n");
	}
      //printf("AT END OF MAIN LOOP\n");
    }
  //we only get here when log_thread_should_die is true
  //only close those that are still open, after waiting a bit
  usleep(100000);
  if (is_valid_fd(log_new_fd))
    close(log_new_fd);
  if (is_valid_fd(log_imu_new_fd1))
    close(log_imu_new_fd1);
  // if (is_valid_fd(log_imu_new_fd2))
  //   close(log_imu_new_fd2);
  // if(is_valid_fd(log_imu_new_fd3))
  //   close(log_imu_new_fd3); 
  return NULL;
}