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; }
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; }
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; }