Ejemplo n.º 1
0
int el::lib_event_pipe_t::wait_event()
{
	//!!!这里的日志不能使用线程打印,否则是死循环,继续调用日志事件!!!	

	timeval time_out_val;
	time_out_val.tv_sec = 0;
	time_out_val.tv_usec = 100000;//100毫秒

	fd_set fd_read_set;
	FD_ZERO(&fd_read_set);
	FD_SET(this->select_fd_max, &fd_read_set);

	int r = HANDLE_EINTR(::select(this->select_fd_max + 1, &fd_read_set, NULL, NULL, &time_out_val));
	if (0 == r){//time out
		return 0;
	}

	if (ERR == r){
		if (EBADF == errno){
			//ALERT_LOG("[err_code:%d, err:%s]", errno, strerror(errno));
		}
		return ERR;
	}

	if(FD_ISSET(this->select_fd_max, &fd_read_set)){
		char sz[100];
		int ret = (int)HANDLE_EINTR(::read(this->select_fd_max, sz, sizeof(sz)));
		return ret;
	}

	return 0;
}
Ejemplo n.º 2
0
nsresult
CreateTransport(base::ProcessId aProcIdOne,
                TransportDescriptor* aOne,
                TransportDescriptor* aTwo)
{
  wstring id = IPC::Channel::GenerateVerifiedChannelID(std::wstring());
  // Use MODE_SERVER to force creation of the socketpair
  Transport t(id, Transport::MODE_SERVER, nullptr);
  int fd1 = t.GetFileDescriptor();
  int fd2, dontcare;
  t.GetClientFileDescriptorMapping(&fd2, &dontcare);
  if (fd1 < 0 || fd2 < 0) {
    return NS_ERROR_TRANSPORT_INIT;
  }

  // The Transport closes these fds when it goes out of scope, so we
  // dup them here
  fd1 = dup(fd1);
  fd2 = dup(fd2);
  if (fd1 < 0 || fd2 < 0) {
    HANDLE_EINTR(close(fd1));
    HANDLE_EINTR(close(fd2));
    return NS_ERROR_DUPLICATE_HANDLE;
  }

  aOne->mFd = base::FileDescriptor(fd1, true/*close after sending*/);
  aTwo->mFd = base::FileDescriptor(fd2, true/*close after sending*/);
  return NS_OK;
}
Ejemplo n.º 3
0
static int
OpenDeletedDirectory()
{
  // We don't need this directory to persist between invocations of
  // the program (nor need it to be cleaned up if something goes wrong
  // here, because mkdtemp will choose a fresh name), so /tmp as
  // specified by FHS is adequate.
  char path[] = "/tmp/mozsandbox.XXXXXX";
  if (!mkdtemp(path)) {
    SANDBOX_LOG_ERROR("mkdtemp: %s", strerror(errno));
    return -1;
  }
  int fd = HANDLE_EINTR(open(path, O_RDONLY | O_DIRECTORY));
  if (fd < 0) {
    SANDBOX_LOG_ERROR("open %s: %s", path, strerror(errno));
    // Try to clean up.  Shouldn't fail, but livable if it does.
    DebugOnly<bool> ok = HANDLE_EINTR(rmdir(path)) == 0;
    MOZ_ASSERT(ok);
    return -1;
  }
  if (HANDLE_EINTR(rmdir(path)) != 0) {
    SANDBOX_LOG_ERROR("rmdir %s: %s", path, strerror(errno));
    AlwaysClose(fd);
    return -1;
  }
  return fd;
}
Ejemplo n.º 4
0
// SBCELT_HelperMonitor implements a monitor thread that runs
// when libsbcelt decides to use SBCELT_MODE_FUTEX.  It is
// response for determining whether the helper process has died,
// and if that happens, restart it.
static void *SBCELT_HelperMonitor(void *udata) {
	(void) udata;

	while (1) {
		uint64_t now = mtime();
		uint64_t elapsed = now - lastdead;
		lastdead = now;

		// Throttle helper re-launches to around 1 per sec.
		if (elapsed < 1*USEC_PER_SEC) {
			usleep(1*USEC_PER_SEC);
		}

		debugf("restarted sbcelt-helper; %lu usec since last death", elapsed);

		pid_t child = fork();
		if (child == -1) {
			// We're memory constrained. Wait and try again...
			usleep(5*USEC_PER_SEC);
			continue;
		} else if (child == 0) {
			// For SBCELT_SANDBOX_SECCOMP_BPF, it shouldn't matter
			// whether the child inherits any file descriptors, since
			// the only useful system call the process can make is futex(2).
			//
			// However, if we're running in Futex mode without a sandbox,
			// closing the file descriptors is indeed a good idea, which
			// is why we do it unconditionally below.
			(void) HANDLE_EINTR(close(0));
			(void) HANDLE_EINTR(close(1));
#ifndef DEBUG
			xclosefrom(2);
#else
			xclosefrom(3);
#endif

			char *const argv[] = {
				SBCELT_HelperBinary(),
				NULL,
			};
			execv(argv[0], argv);
			_exit(100);
		}

		int status;
		int retval = HANDLE_EINTR(waitpid(child, &status, 0));
		if (retval == child) {
			if (WIFEXITED(status)) {
				debugf("sbcelt-helper died with exit status: %i", WEXITSTATUS(status));
			} else if (WIFSIGNALED(status)) {
				debugf("sbcelt-helper died with signal: %i", WTERMSIG(status));
			}
		} else if (retval == -1 && errno == EINVAL) {
			fprintf(stderr, "libsbcelt: waitpid() failed with EINVAL; internal error!\n");
			fflush(stderr);
			exit(1);
		}
	}
}
Ejemplo n.º 5
0
static int
compare_timezone_to_localtime( ScanDataRec*  scan,
                               const char*   path )
{
    struct  stat  st;
    int           fd1, fd2, result = 0;

    D( "%s: comparing %s:", __FUNCTION__, path );

    if ( stat( path, &st ) < 0 ) {
        D( " can't stat: %s\n", strerror(errno) );
        return 0;
    }

    if ( st.st_size != scan->localtime_st.st_size ) {
        D( " size mistmatch (%zd != %zd)\n", (size_t)st.st_size, (size_t)scan->localtime_st.st_size );
        return 0;
    }

    fd1 = open( scan->localtime, O_RDONLY );
    if (fd1 < 0) {
        D(" can't open %s: %s\n", scan->localtime, strerror(errno) );
        return 0;
    }
    fd2 = open( path, O_RDONLY );
    if (fd2 < 0) {
        D(" can't open %s: %s\n", path, strerror(errno) );
        close(fd1);
        return 0;
    }
    do {
        off_t  nn;

        for (nn = 0; nn < st.st_size; nn++) {
            char  temp[2];
            int   ret;

            ret = HANDLE_EINTR(read(fd1, &temp[0], 1));
            if (ret < 0) break;

            ret = HANDLE_EINTR(read(fd2, &temp[1], 1));
            if (ret < 0) break;

            if (temp[0] != temp[1])
                break;
        }

        result = (nn == st.st_size);

    } while (0);

    D( result ? " MATCH\n" : "no match\n" );

    close(fd2);
    close(fd1);

    return result;
}
Ejemplo n.º 6
0
void connector(attendant__pipe_t in, attendant__pipe_t out) {
  const char *pipe = "pipe\n";
  int err;
  HANDLE_EINTR(write(in, pipe, strlen(pipe)), err);
  ok(err != -1, "request pipe");
  HANDLE_EINTR(read(out, fifo, sizeof(fifo)), err);
  fifo[strlen(fifo) - 1] = '\0';
  ok(err != -1, "get pipe # %s", fifo);
}
Ejemplo n.º 7
0
static int SBCELT_RWHelper() {
	while (1) {
		// Wait for the lib to signal us.
		if (HANDLE_EINTR(read(0, &workpage->pingpong, 1)) == -1) {
			return -2;
		}

		SBCELT_DecodeSingleFrame();

		if (HANDLE_EINTR(write(1, &workpage->pingpong, 1)) == -1) {
			return -3;
		}
	}
}
Ejemplo n.º 8
0
// Block until child_pid exits, then exit. Try to preserve the exit code.
static void WaitForChildAndExit(pid_t child_pid) {
  int exit_code = -1;
  siginfo_t reaped_child_info;

  // Don't "Core" on SIGABRT. SIGABRT is sent by the Chrome OS session manager
  // when things are hanging.
  // Here, the current process is going to waitid() and _exit(), so there is no
  // point in generating a crash report. The child process is the one
  // blocking us.
  if (signal(SIGABRT, ExitWithErrorSignalHandler) == SIG_ERR) {
    FatalError("Failed to change signal handler");
  }

  int wait_ret =
      HANDLE_EINTR(waitid(P_PID, child_pid, &reaped_child_info, WEXITED));

  if (!wait_ret && reaped_child_info.si_pid == child_pid) {
    if (reaped_child_info.si_code == CLD_EXITED) {
      exit_code = reaped_child_info.si_status;
    } else {
      // Exit with code 0 if the child got signaled.
      exit_code = 0;
    }
  }
  _exit(exit_code);
}
Ejemplo n.º 9
0
/**
	socket_send_to : 'socket -> buf:string -> pos:int -> length:int -> addr:{host:'int32,port:int} -> int
	<doc>
	Send data from an unconnected UDP socket to the given address.
	</doc>
**/
static value socket_send_to( value o, value data, value pos, value len, value vaddr ) {
	int p,l,dlen;
	value host, port;
	struct sockaddr_in addr;
	val_check_kind(o,k_socket);
	val_check(data,string);
	val_check(pos,int);
	val_check(len,int);
	val_check(vaddr,object);
	host = val_field(vaddr, f_host);
	port = val_field(vaddr, f_port);
	val_check(host,int32);
	val_check(port,int);
	p = val_int(pos);
	l = val_int(len);
	dlen = val_strlen(data);
	memset(&addr,0,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(val_int(port));
	*(int*)&addr.sin_addr.s_addr = val_int32(host);
	if( p < 0 || l < 0 || p > dlen || p + l > dlen )
		neko_error();
	POSIX_LABEL(send_again);
	dlen = sendto(val_sock(o), val_string(data) + p , l, MSG_NOSIGNAL, (struct sockaddr*)&addr, sizeof(addr));
	if( dlen == SOCKET_ERROR ) {
		HANDLE_EINTR(send_again);
		return block_error();
	}
	return alloc_int(dlen);
}
Ejemplo n.º 10
0
bool
app_launcher::get_output(int pipe, vogl::dynamic_string &output, size_t max_output)
{
    if (pipe != -1)
    {
        if (max_output <= 0)
            return true;

        for(;;)
        {
            char buf[4096];
            size_t nbytes = max_output;
            if (nbytes >= sizeof(buf))
                nbytes = sizeof(buf);

            // Try to read in nbytes. read returns 0:end of file, -1:error.
            ssize_t length = HANDLE_EINTR(read(pipe, buf, nbytes));
            if (length < 0)
                return false;

            max_output -= length;
            output.append(buf, (uint)length);

            if ((length != (ssize_t)nbytes) || (max_output <= 0))
                return true;
        }
    }

    return false;
}
Ejemplo n.º 11
0
// SBCELT_CheckSeccomp checks for kernel support for
// SECCOMP.
//
// On success, the function returns a valid sandbox
// mode (see SBCELT_SANDBOX_*).
//
// On failure, the function returns
//  -1 if the helper process did not execute correctly.
//  -2 if the fork system call failed. This signals that the
//     host system is running low on memory. This is a
//     recoverable error, and in our case we should simply
//     wait a bit and try again.
static int SBCELT_CheckSeccomp() {
 	int status, err;
	pid_t child;

	child = fork();
	if (child == -1) {
 		return -2;
	} else if (child == 0) {
		char *const argv[] = {
			SBCELT_HelperBinary(),
			"detect",
			NULL,
		};
		execv(argv[0], argv);
		_exit(100);
	}

	if (HANDLE_EINTR(waitpid(child, &status, 0)) == -1) {
		return -1;
	}

	if (!WIFEXITED(status)) {
		return -1;
	}

	int code = WEXITSTATUS(status);
	if (!SBCELT_SANDBOX_VALID(code)) {
		return -1;
	}

	return code;
}
Ejemplo n.º 12
0
/**
	socket_close : 'socket -> void
	<doc>Close a socket. Any subsequent operation on this socket will fail</doc>
**/
static value socket_close( value o ) {
	POSIX_LABEL(close_again);
	if( closesocket(val_sock(o)) ) {
		HANDLE_EINTR(close_again);
	}
	return alloc_bool(true);
}
Ejemplo n.º 13
0
/**
	socket_select : read : 'socket array -> write : 'socket array -> others : 'socket array -> timeout:number? -> 'socket array array
	<doc>Perform the [select] operation. Timeout is in seconds or [null] if infinite</doc>
**/
static value socket_select( value rs, value ws, value es, value timeout ) {
	struct timeval tval;
	struct timeval *tt;
	SOCKET n = 0;
	fd_set rx, wx, ex;
	fd_set *ra, *wa, *ea;
	value r;
	POSIX_LABEL(select_again);
	ra = make_socket_array(rs,val_array_size(rs),&rx,&n);
	wa = make_socket_array(ws,val_array_size(ws),&wx,&n);
	ea = make_socket_array(es,val_array_size(es),&ex,&n);
	if( ra == &INVALID || wa == &INVALID || ea == &INVALID )
		neko_error();
	if( val_is_null(timeout) )
		tt = NULL;
	else {
		val_check(timeout,number);
		tt = &tval;
		init_timeval(val_number(timeout),tt);
	}
	if( select((int)(n+1),ra,wa,ea,tt) == SOCKET_ERROR ) {
		HANDLE_EINTR(select_again);
		neko_error();
	}
	r = alloc_array(3);
	val_array_ptr(r)[0] = make_array_result(rs,ra);
	val_array_ptr(r)[1] = make_array_result(ws,wa);
	val_array_ptr(r)[2] = make_array_result(es,ea);
	return r;
}
Ejemplo n.º 14
0
/**
	socket_recv : 'socket -> buf:string -> pos:int -> len:int -> int
	<doc>Read up to [len] bytes from [buf] starting at [pos] from a connected socket.
	Return the number of bytes readed.</doc>
**/
static value socket_recv( value o, value data, value pos, value len ) {
	int p,l,dlen,ret;
	int retry = 0;
	val_check_kind(o,k_socket);
	val_check(data,string);
	val_check(pos,int);
	val_check(len,int);
	p = val_int(pos);
	l = val_int(len);
	dlen = val_strlen(data);
	if( p < 0 || l < 0 || p > dlen || p + l > dlen )
		neko_error();
	POSIX_LABEL(recv_again);
	if( retry++ > NRETRYS ) {
		sock_tmp t;
		t.sock = val_sock(o);
		t.buf = val_string(data) + p;
		t.size = l;
		neko_thread_blocking(tmp_recv,&t);
		ret = t.ret;
	} else
		ret = recv(val_sock(o), val_string(data) + p , l, MSG_NOSIGNAL);
	if( ret == SOCKET_ERROR ) {
		HANDLE_EINTR(recv_again);
		return block_error();
	}
	return alloc_int(ret);
}
Ejemplo n.º 15
0
static value socket_recv_from( value o, value dataBuf, value pos, value len, value addr ) {
	int p,l,ret;
	int retry = 0;
	struct sockaddr_in saddr;
	SockLen slen = sizeof(saddr);
	val_check_kind(o,k_socket);
	val_check(dataBuf,buffer);
	buffer buf = val_to_buffer(dataBuf);
   char *data = buffer_data(buf);
   int dlen = buffer_size(buf);
	val_check(pos,int);
	val_check(len,int);
	val_check(addr,object);
	p = val_int(pos);
	l = val_int(len);

	if( p < 0 || l < 0 || p > dlen || p + l > dlen )
		neko_error();
   SOCKET sock = val_sock(o);
   gc_enter_blocking();
	POSIX_LABEL(recv_from_again);
	if( retry++ > NRETRYS ) {
      ret = recv(sock,data+p,l,MSG_NOSIGNAL);
	} else
		ret = recvfrom(sock, data + p , l, MSG_NOSIGNAL, (struct sockaddr*)&saddr, &slen);
	if( ret == SOCKET_ERROR ) {
		HANDLE_EINTR(recv_from_again);
		return block_error();
	}
   gc_exit_blocking();
	alloc_field(addr,f_host,alloc_int32(*(int*)&saddr.sin_addr));
	alloc_field(addr,f_port,alloc_int(ntohs(saddr.sin_port)));
	return alloc_int(ret);
}
Ejemplo n.º 16
0
/**
	socket_send_to : 'socket -> buf:string -> pos:int -> length:int -> addr:{host:'int32,port:int} -> int
	<doc>
	Send data from an unconnected UDP socket to the given address.
	</doc>
**/
static value socket_send_to( value o, value dataBuf, value pos, value len, value vaddr ) {
	int p,l;
	value host, port;
	struct sockaddr_in addr;
	val_check_kind(o,k_socket);
   buffer buf = val_to_buffer(dataBuf);
	const char *cdata = buffer_data(buf);
	int dlen = buffer_size(buf);
	val_check(pos,int);
	val_check(len,int);
	val_check(vaddr,object);
	host = val_field(vaddr, f_host);
	port = val_field(vaddr, f_port);
	val_check(host,int);
	val_check(port,int);
	p = val_int(pos);
	l = val_int(len);
	memset(&addr,0,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(val_int(port));
	*(int*)&addr.sin_addr.s_addr = val_int(host);
	if( p < 0 || l < 0 || p > dlen || p + l > dlen )
		neko_error();

   SOCKET sock = val_sock(o);
	gc_enter_blocking();
	POSIX_LABEL(send_again);
	dlen = sendto(sock, cdata + p , l, MSG_NOSIGNAL, (struct sockaddr*)&addr, sizeof(addr));
	if( dlen == SOCKET_ERROR ) {
		HANDLE_EINTR(send_again);
		return block_error();
	}
	gc_exit_blocking();
	return alloc_int(dlen);
}
Ejemplo n.º 17
0
/*
 * Asynchronous I/O callback launched when framebuffer notifications are ready
 * to be read.
 * Param:
 *  opaque - FrameBufferImpl instance.
 */
static void
_fbUpdatesImpl_io_callback(void* opaque, int fd, unsigned events)
{
    FrameBufferImpl* fbi = opaque;
    int  ret;

    // Read updates while they are immediately available.
    for (;;) {
        // Read next chunk of data.
        ret = HANDLE_EINTR(
                socket_recv(fbi->sock,
                            fbi->reader_buffer + fbi->reader_offset,
                            fbi->reader_bytes - fbi->reader_offset));
        if (ret < 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
            // Chunk is not avalable at this point. Come back later.
            return;
        }
        if (ret <= 0) {
            /* disconnection ! */
            derror("Unable to receive framebuffer data: %s\n",
                   ret < 0 ? strerror(errno), "unexpected disconnection");
            fbUpdatesImpl_destroy();
            return;
        }

        fbi->reader_offset += ret;
        if (fbi->reader_offset != fbi->reader_bytes) {
            // There are still some data left in the pipe.
            continue;
        }

        // All expected data has been read. Time to change the state.
        if (fbi->fb_state == EXPECTS_HEADER) {
            // Update header has been read. Prepare for the pixels.
            fbi->fb_state = EXPECTS_PIXELS;
            fbi->reader_offset = 0;
            fbi->reader_bytes = fbi->update_header.w *
                                      fbi->update_header.h *
                                      (fbi->bits_per_pixel / 8);
            fbi->reader_buffer = malloc(fbi->reader_bytes);
            if (fbi->reader_buffer == NULL) {
                APANIC("Unable to allocate memory for framebuffer update\n");
            }
        } else {
            // Pixels have been read. Prepare for the header.
             uint8_t* pixels = fbi->reader_buffer;

            fbi->fb_state = EXPECTS_HEADER;
            fbi->reader_offset = 0;
            fbi->reader_bytes = sizeof(FBUpdateMessage);
            fbi->reader_buffer = (uint8_t*)&fbi->update_header;

            // Perform the update. Note that pixels buffer must be freed there.
            _update_rect(fbi->fb, fbi->update_header.x,
                        fbi->update_header.y, fbi->update_header.w,
                        fbi->update_header.h, fbi->bits_per_pixel,
                        pixels);
        }
    }
Ejemplo n.º 18
0
static bool
CanCreateUserNamespace()
{
  // Unfortunately, the only way to verify that this process can
  // create a new user namespace is to actually create one; because
  // this process's namespaces shouldn't be side-effected (yet), it's
  // necessary to clone (and collect) a child process.  See also
  // Chromium's sandbox::Credentials::SupportsNewUserNS.
  //
  // This is somewhat more expensive than the other tests, so it's
  // cached in the environment to prevent child processes from having
  // to re-run the test.
  //
  // This is run at static initializer time, while single-threaded, so
  // locking isn't needed to access the environment.
  static const char kCacheEnvName[] = "MOZ_ASSUME_USER_NS";
  const char* cached = getenv(kCacheEnvName);
  if (cached) {
    return cached[0] > '0';
  }

  // Valgrind might allow the clone, but doesn't know what to do with
  // unshare.  Check for that by unsharing nothing.  (Valgrind will
  // probably need sandboxing disabled entirely, but no need to break
  // things worse than strictly necessary.)
  if (syscall(__NR_unshare, 0) != 0) {
#ifdef MOZ_VALGRIND
    MOZ_ASSERT(errno == ENOSYS);
#else
    // If something else can cause that call to fail, we's like to know
    // about it; the right way to handle it might not be the same.
    MOZ_ASSERT(false);
#endif
    return false;
  }

  pid_t pid = syscall(__NR_clone, SIGCHLD | CLONE_NEWUSER,
                      nullptr, nullptr, nullptr, nullptr);
  if (pid == 0) {
    // In the child.  Do as little as possible.
    _exit(0);
  }
  if (pid == -1) {
    // Failure.
    MOZ_ASSERT(errno == EINVAL || // unsupported
               errno == EPERM  || // root-only, or we're already chrooted
               errno == EUSERS);  // already at user namespace nesting limit
    setenv(kCacheEnvName, "0", 1);
    return false;
  }
  // Otherwise, in the parent and successful.
  bool waitpid_ok = HANDLE_EINTR(waitpid(pid, nullptr, 0)) == pid;
  MOZ_ASSERT(waitpid_ok);
  if (!waitpid_ok) {
    return false;
  }
  setenv(kCacheEnvName, "1", 1);
  return true;
}
Ejemplo n.º 19
0
int I2C::i2c_read(uint8_t *data, int length, int &read_length)
{
    const int res = HANDLE_EINTR(::read(m_fd, data, length));
    if (res < 0)
        return errno;
    read_length = res;
    return 0;
}
Ejemplo n.º 20
0
int I2C::i2c_set_slave_address(int address)
{
    if (m_fd == -1)
        return EBADF;

    const int res = HANDLE_EINTR(::ioctl(m_fd, I2C_SLAVE_FORCE, address));
    return res ? errno : 0;
}
Ejemplo n.º 21
0
static int do_close( int fd ) {
	POSIX_LABEL(close_again);
	if( close(fd) != 0 ) {
		HANDLE_EINTR(close_again);
		return 1;
	}
	return 0;
}
Ejemplo n.º 22
0
void I2C::shutdown()
{
    logger(LOG_INFO, "i2c shutting down");
    if (m_fd != -1)
    {
        HANDLE_EINTR(::close(m_fd));
        m_fd = -1;
    }
}
Ejemplo n.º 23
0
/**
	socket_poll_events : 'poll -> timeout:float -> void
	<doc>
	Update the read/write flags arrays that were created with [socket_poll_prepare].
	</doc>
**/
static value socket_poll_events( value pdata, value timeout ) {
	polldata *p;
#	ifdef NEKO_WINDOWS
	unsigned int i;
	int k = 0;
	struct timeval t;
	val_check_kind(pdata,k_poll);
	p = val_poll(pdata);
	memcpy(p->outr,p->fdr,FDSIZE(p->fdr->fd_count));
	memcpy(p->outw,p->fdw,FDSIZE(p->fdw->fd_count));
	val_check(timeout,number);
	init_timeval(val_number(timeout),&t);
	gc_enter_blocking();
	if( p->fdr->fd_count + p->fdw->fd_count != 0 && select(0,p->outr,p->outw,NULL,&t) == SOCKET_ERROR )
	{
		gc_exit_blocking();
		return alloc_null();
	}
	gc_exit_blocking();
	k = 0;
	for(i=0;i<p->fdr->fd_count;i++)
		if( FD_ISSET(p->fdr->fd_array[i],p->outr) )
			val_array_set_i(p->ridx,k++,alloc_int(i));
	val_array_set_i(p->ridx,k,alloc_int(-1));
	k = 0;
	for(i=0;i<p->fdw->fd_count;i++)
		if( FD_ISSET(p->fdw->fd_array[i],p->outw) )
			val_array_set_i(p->widx,k++, alloc_int(i));
	val_array_set_i(p->widx,k,alloc_int(-1));
#else
	int i,k;
	int tot;
	val_check_kind(pdata,k_poll);
	val_check(timeout,number);
	p = val_poll(pdata);
	tot = p->rcount + p->wcount;
	gc_enter_blocking();
	POSIX_LABEL(poll_events_again);
	if( poll(p->fds,tot,(int)(val_number(timeout) * 1000)) < 0 ) {
		HANDLE_EINTR(poll_events_again);
		gc_exit_blocking();
		return alloc_null();
	}
	gc_exit_blocking();
	k = 0;
	for(i=0;i<p->rcount;i++)
		if( p->fds[i].revents & (POLLIN|POLLHUP) )
			val_array_set_i(p->ridx,k++,alloc_int(i));
	val_array_set_i(p->ridx,k, alloc_int(-1));
	k = 0;
	for(;i<tot;i++)
		if( p->fds[i].revents & (POLLOUT|POLLHUP) )
			val_array_set_i(p->widx,k++, alloc_int(i - p->rcount));
	val_array_set_i(p->widx,k, alloc_int(-1));
#endif
	return val_null;
}
Ejemplo n.º 24
0
int el::lib_event_pipe_t::notify_event()
{
	char f;
	int r = (int)HANDLE_EINTR(::write(this->event_pipe.write_fd(), &f, 1));
	if (-1 == r){
		ALERT_LOG("[err_code:%d, err:%s]", errno, strerror(errno));
	}
	return r;
}
Ejemplo n.º 25
0
/**
	socket_close : 'socket -> void
	<doc>Close a socket. Any subsequent operation on this socket will fail</doc>
**/
static value socket_close( value o ) {
	val_check_kind(o,k_socket);
	POSIX_LABEL(close_again);
	if( closesocket(val_sock(o)) ) {
		HANDLE_EINTR(close_again);
	}
	val_kind(o) = NULL;
	return val_true;
}
Ejemplo n.º 26
0
/* Reads 'nbyte' bytes from 'fd' into 'buf', retrying on interrupts.
 * Exit()s if the read fails for any other reason.
 */
static int
read_or_die(int fd, void *buf, size_t nbyte)
{
    int ret = HANDLE_EINTR(read(fd, buf, nbyte));
    if (ret < 0) {
        derror("read failed: %s", strerror(errno));
        exit(1);
    }
    return ret;
}
Ejemplo n.º 27
0
int i2c_smbus_access(int fh, uint8_t read_write, uint8_t command, int size, union i2c_smbus_data *data)
{
    i2c_smbus_ioctl_data args;

    args.read_write = read_write;
    args.command = command;
    args.size = size;
    args.data = data;

    return HANDLE_EINTR(::ioctl(fh, I2C_SMBUS, &args));
}
// static
void MessagePumpLibevent::OnWakeup(int socket, short flags, void* context) {
    MessagePumpLibevent* that = static_cast<MessagePumpLibevent*>(context);
    assert(that->wakeup_pipe_out_ == socket);
    // Remove and discard the wakeup byte.
    char buf;
    long nread = HANDLE_EINTR(read(socket, &buf, 1));
    assert(nread == 1);
    that->processed_io_events_ = true;
    // Tell libevent to break out of inner loop.
    event_base_loopbreak(that->event_base_);
}
Ejemplo n.º 29
0
static value ssl_handshake( value ssl ) {
	int r;
	val_check_kind(ssl,k_ssl);
	POSIX_LABEL(handshake_again);
	r = mbedtls_ssl_handshake( val_ssl(ssl) );
	if( r == SOCKET_ERROR ) {
		HANDLE_EINTR(handshake_again);
		return block_error();
	}else if( r != 0 )
		return ssl_error(r);
	return val_true;
}
Ejemplo n.º 30
0
/**
	socket_accept : 'socket -> 'socket
	<doc>Accept an incoming connection request</doc>
**/
static value socket_accept( value o ) {
	struct sockaddr_in addr;
	unsigned int addrlen = sizeof(addr);
	SOCKET s;
	val_check_kind(o,k_socket);
	POSIX_LABEL(accept_again);
	s = accept(val_sock(o),(struct sockaddr*)&addr,&addrlen);
	if( s == INVALID_SOCKET ) {
		HANDLE_EINTR(accept_again);
		return block_error();
	}
	return alloc_abstract(k_socket,(value)(int_val)s);
}