int     unix_pass_trigger(const char *service, const char *buf, ssize_t len, int timeout)
{
    const char *myname = "unix_pass_trigger";
    int     pair[2];
    struct unix_pass_trigger *up;
    int     fd;

    if (msg_verbose > 1)
	msg_info("%s: service %s", myname, service);

    /*
     * Connect...
     */
    if ((fd = unix_pass_connect(service, BLOCKING, timeout)) < 0) {
	if (msg_verbose)
	    msg_warn("%s: connect to %s: %m", myname, service);
	return (-1);
    }
    close_on_exec(fd, CLOSE_ON_EXEC);

    /*
     * Create a pipe, and send one pipe end to the server.
     */
    if (pipe(pair) < 0)
	msg_fatal("%s: pipe: %m", myname);
    close_on_exec(pair[0], CLOSE_ON_EXEC);
    close_on_exec(pair[1], CLOSE_ON_EXEC);
    if (unix_send_fd(fd, pair[0]) < 0)
	msg_fatal("%s: send file descriptor: %m", myname);

    /*
     * Stash away context.
     */
    up = (struct unix_pass_trigger *) mymalloc(sizeof(*up));
    up->fd = fd;
    up->service = mystrdup(service);
    up->pair[0] = pair[0];
    up->pair[1] = pair[1];

    /*
     * Write the request...
     */
    if (write_buf(pair[1], buf, len, timeout) < 0
	|| write_buf(pair[1], "", 1, timeout) < 0)
	if (msg_verbose)
	    msg_warn("%s: write to %s: %m", myname, service);

    /*
     * Wakeup when the peer disconnects, or when we lose patience.
     */
    if (timeout > 0)
	event_request_timer(unix_pass_trigger_event, (char *) up, timeout + 100);
    event_enable_read(fd, unix_pass_trigger_event, (char *) up);
    return (0);
}
void* fable_connect_shmem_pipe(const char* name, int direction) {

  // As the connection initiator, it's our responsibility to supply shared memory.

  char random_name[22];
  int ring_pages = pow(2, ring_order);
  
  int shm_fd = -1;
  errno = EEXIST;
  for(int i = 0; i < 100 && shm_fd == -1 && errno == EEXIST; ++i) {
    strcpy(random_name, "/fable_segment_XXXXXX");
    if(!mktemp(random_name))
      break;
    shm_fd = shm_open(random_name, O_RDWR|O_CREAT|O_EXCL, 0600);
  }

  if(shm_fd == -1)
    return 0;

  shm_unlink(random_name);
  if (ftruncate(shm_fd, PAGE_SIZE * ring_pages) < 0) {
    close(shm_fd);
    return 0;
  }

  void* ring_addr = mmap(NULL, PAGE_SIZE * ring_pages, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0);
 
  void* unix_handle = fable_connect_unixdomain(name, FABLE_DIRECTION_DUPLEX);
  if(!unix_handle)
    return 0;

  int unix_fd = *((int*)unix_handle);
  free(unix_handle);

  // OK, send our partner the FD and the appropriate size to mmap.
  int send_ret = unix_send_fd(unix_fd, shm_fd);
  close(shm_fd);
  
  if(send_ret <= 0) {
    munmap(ring_addr, PAGE_SIZE * ring_pages);
    close(unix_fd);
    return 0;
  }

  write_all_fd(unix_fd, (const char*)&ring_pages, sizeof(int));

  struct shmem_pipe_handle_conn* conn_handle = (struct shmem_pipe_handle_conn*)malloc(sizeof(struct shmem_pipe_handle_conn));
  memset(conn_handle, 0, sizeof(struct shmem_pipe_handle_conn));

  conn_handle->base.fd = unix_fd;
  conn_handle->base.type = SHMEMPIPE_HANDLE_CONN;
  conn_handle->ring = ring_addr;
  conn_handle->ring_pages = ring_pages;
  conn_handle->direction = direction;

  if(direction == FABLE_DIRECTION_SEND)
    shmem_pipe_init_send(conn_handle);
  // Otherwise memset-0 is enough

  return conn_handle;

}
Beispiel #3
0
int main(void)
{
	int fd,  get_fd, read_size;
	char buf[1024], s[]="hello china";
	ssize_t n;
	int send_fd;
	int len;

	if((fd = socket(AF_UNIX, SOCK_DGRAM, 0))<0)
	{
		perror("socket error");
		return -1;
	}

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sun_family = AF_LOCAL;
#define PATH "/var/tmp/foo1.sock"
#define PATH2 "/var/tmp/foo2.sock"
	strcpy(servaddr.sun_path, PATH);
	bzero(&localaddr, sizeof(localaddr));
	localaddr.sun_family = AF_LOCAL;
	strcpy(localaddr.sun_path, PATH2);
	len = offsetof(struct sockaddr_un, sun_path) + strlen(servaddr.sun_path);

	if(bind(fd,(struct sockaddr *)&localaddr, len) < 0)
		perror("bind error");

#if 1
	if(connect(fd, (struct sockaddr *)&servaddr, len)<0)
	{
		perror("connect error");
		return -1;
	}
#endif

#if 0
	get_fd = client_recv_fd(fd);
	memset(buf, 0, sizeof(buf));
	read_size = read(get_fd, buf, 100);
	printf("read_size = %d, %s\n", read_size, buf);
#endif
#if 0
	char recv_buff[1024];
	memset(recv_buff, 0, 1024);
	int ret = recvfrom(fd, recv_buff, 1024, 0, NULL, NULL);
	if(ret < 1)
	{
		perror("recvfrom");
	}
#endif

#if 1
		send_fd = open("hello.c", O_CREAT | O_RDWR, 0666);
		if( send_fd < 0 )
		{
			perror("open hello.c");
		}
		unix_send_fd(fd, send_fd);

		printf("press enter to exit\n");
		getchar();
		close(send_fd);
#endif

#if 0
	if(sendto(fd, s, strlen(s), 0, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)
	{
		perror("sendto");
	}
	//if(n = read(fd, buf, sizeof(buf)) == -1)
	socklen_t len = sizeof(servaddr);
	n = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&servaddr, &len);
	if(n == -1)
	{
		perror("read");
	}
	/*
	if(n = write(STDOUT_FILENO, buf, n) != n)
	{
		preeor("write");
	}
	 * */
#endif
	return 0;
}
Beispiel #4
0
int main(void)
{
	int listensock, connsock, send_fd, size;
 	
	struct sockaddr_un servaddr, cliaddr;
	int ret;
	char buf[1024];
	ssize_t n;
	socklen_t len = sizeof(cliaddr);
	int get_fd;
	int read_size;
//	while(1)
	{
#if 0
		send_fd = open("hello.c", O_CREAT | O_RDWR);
#else
		//bug
		send_fd = open("hello.c", O_CREAT | O_RDWR, 0666);
#endif
		listensock = socket(AF_LOCAL, SOCK_DGRAM, 0);
		if(listensock < 0)
		{
			perror("socket");
			return -1;
		}
		memset(&servaddr, 0, sizeof(servaddr));
#define PATH	"/var/tmp/foo1.sock"
		unlink(PATH);
		servaddr.sun_family = AF_LOCAL;
		strcpy(servaddr.sun_path, PATH);
		len = offsetof(struct sockaddr_un, sun_path) + strlen(servaddr.sun_path);
	
		if(bind(listensock,(struct sockaddr *)&servaddr, len) < 0)
			perror("bind error");
	
#if 0
		//test recv
		{
			char buf[1024];
			int ret = 0;

			memset(buf, 0, sizeof(buf));
			ret = recv(listensock, buf, 1024, 0);
			printf("ret = %d buf[0]=%d %c\n", ret, buf[0], buf[0]);
		}
#else
		while(1)
		{
			struct msghdr msg;
			struct iovec vec;
			char buf[1024];
			int ret;

			memset(&msg, 0, sizeof(msg));
			memset(&vec, 0, sizeof(vec));
			vec.iov_base = &buf;
			vec.iov_len = 1024;
			msg.msg_iovlen = 1;
			msg.msg_iov = &vec;
			msg.msg_name = &servaddr;
			msg.msg_namelen = sizeof(servaddr);
			printf("wait for msg:\n");
			ret = recvmsg(listensock, &msg, 0);
			printf("ret = %d\n", ret);
			if( ret > 0 )
			{
				printf("msg->iovlen: %d, vec.iov_base:%x\n", 
						msg.msg_iovlen, vec.iov_base);
				printf("msg->iovlen : %d iovbase[0].[0] = %d\n", msg.msg_iovlen,
						*(char*)(msg.msg_iov[0].iov_base));
			}

#define PATH2	"/var/tmp/foo2.sock"
			strcpy(servaddr.sun_path, PATH2);
			msg.msg_name = &servaddr;
			msg.msg_namelen = sizeof(servaddr);
			buf[0] = 'b';
			vec.iov_len = 1;
			ret = sendmsg(listensock, &msg, 0);
			if( ret < 0  )
			{
				perror("send msg error");
			}
			printf("send msg over: ret=%d\n", ret);

			{
				static int i = 0;
				i++;
				if( i == 3 )
				{
					printf("normal exit.\n");
					_exit(0);
				}
			}
		}
#endif
#if 0
		if(connect(listensock, (struct sockaddr *)&servaddr, len)<0)
		{
			perror("connect error");
		}
#endif
#if 0	
		listen(listensock, QLEN);
		len = sizeof(un);
		if((connsock = accept(listensock, (struct sockaddr *)&un, &len))<0)
		{
			perror("accept error");
		}
		else	
		{	
			unix_send_fd(connsock, send_fd);
		}	
#endif	
	#if 0
//		unix_send_fd(listensock, send_fd);
		len = strlen(un.sun_path) + sizeof(un.sun_family);
		memset(send_buff, 0, 1024);
		sprintf(send_buff, "hello world");
		ret = sendto(listensock, send_buff, strlen(send_buff), 0, (struct sockaddr*)&un, len);
	
		if(ret < 0)
		{
			perror("sendto");
		}
		
		//unix_send_fd(listensock, send_fd);
	
#endif
		get_fd = client_recv_fd(listensock);
		memset(buf, 0, sizeof(buf));
		read_size = read(get_fd, buf, 100);
		printf("read_size = %d, %s\n", read_size, buf);
#if 0
		n = recvfrom(listensock, buf, sizeof(buf), 0, (struct sockaddr *)&servaddr, &len);
		//n = recvfrom(listensock, buf, sizeof(buf), 0, (struct sockaddr *)&cliaddr, &len);
		if(n = -1)
		{
			perror("recvfrom");
		}
		printf("buf == %s\n", buf);
		//if(sendto(listensock, buf, n, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr) != n))
		if(sendto(listensock, buf, n, 0, (struct sockaddr *)&servaddr, sizeof(servaddr) != n))
		{
			perror("sendto");
		}
#endif
		close(send_fd);	
//		close(connsock);
		close(listensock);
	}
	return 0;
}