New file |
| | |
| | | #ifndef IPC_MSG_H |
| | | #define IPC_MSG_H |
| | | #include <sys/socket.h> |
| | | #include <sys/types.h> |
| | | #include <netinet/in.h> |
| | | #include <unistd.h> |
| | | |
| | | #ifdef __cplusplus |
| | | extern "C" { |
| | | #endif |
| | | |
| | | |
| | | #define UNIX_DOMAIN "/tmp/UNIX.domain" |
| | | #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \ |
| | | } while (0) |
| | | |
| | | #define MAX_LEN 4096 |
| | | #define HELLO_MSG "hello_basic" |
| | | #define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER) |
| | | #define container_of(ptr, type, member) ({\ |
| | | const typeof(((type *)0)->member) * __mptr = (ptr);\ |
| | | (type *)((char *)__mptr - offsetof(type, member)); } |
| | | |
| | | typedef struct memfd_data { |
| | | pid_t pid; |
| | | int memfd; |
| | | void * data; |
| | | int len; |
| | | } memfd_data_st; |
| | | |
| | | struct user_data |
| | | { |
| | | int fd; |
| | | unsigned int n_size; |
| | | char line[MAX_LEN]; |
| | | }; |
| | | |
| | | #define READ_THREAD_NUM 2 |
| | | #define WRITE_THREAD_NUM 2 |
| | | |
| | | int proc_memfd(struct user_data* rdata); |
| | | int basic_create_ipc_server(char * unix_domain_path); |
| | | |
| | | int send_fd_sendmsg(int fd, memfd_data_st** ppmemfd_data); |
| | | |
| | | /** |
| | | * @brief 发送目标文件描述符 |
| | | * @param fd 传递信息的 UNIX 域 文件描述符 |
| | | * @param fd_to_send 待发送的文件描述符 |
| | | */ |
| | | int send_fd_args_sendmsg(int fd, int fd_to_send, pid_t pid, void **ppdata, int len); |
| | | |
| | | /** |
| | | * @brief 接受文件描述符 |
| | | * @param fd 传递信息的 UNIX 域 文件描述符 |
| | | */ |
| | | int recv_fd_recvmsg(int fd, memfd_data_st** ppmemfd_data); |
| | | |
| | | #ifdef __cplusplus |
| | | } |
| | | #endif |
| | | #endif |
| | |
| | | add_executable(sample_open sample_open.c) |
| | | add_executable(test_list_in_shm test_list_in_shm.c) |
| | | add_executable(shmht_mytests shmht_mytests.c) |
| | | add_executable(ipc_server ipc_server.c) |
| | | add_executable(ipc_client ipc_client.c) |
| | | |
| | | target_link_libraries(sample_create |
| | | PRIVATE |
| | |
| | | memfd |
| | | pthread |
| | | ) |
| | | target_link_libraries(ipc_server |
| | | PRIVATE |
| | | memfd |
| | | pthread |
| | | libipc_server |
| | | ) |
| | | target_link_libraries(ipc_client |
| | | PRIVATE |
| | | memfd |
| | | pthread |
| | | libipc_client |
| | | ) |
| | | |
New file |
| | |
| | | #include <stdio.h> |
| | | #include "memfd.h" |
| | | #include "ipc_msg.h" |
| | | |
| | | |
| | | int memfd_read(int fd) |
| | | { |
| | | unsigned char* addr; |
| | | ssize_t i, len; |
| | | len = basic_shm_mmap(fd, &addr); |
| | | if(len < 0) |
| | | { |
| | | return -1; |
| | | } |
| | | printf ("start: "); |
| | | for (i = 0; i < 32; ++i) |
| | | printf ("%i ", addr[i]); |
| | | printf ("\nend: "); |
| | | for (i = 0; i < 32; ++i) |
| | | printf ("%i ", addr[len-32+i]); |
| | | printf ("\ndone\n"); |
| | | return len; |
| | | } |
| | | |
| | | |
| | | int main(int argc, char **argv) |
| | | { |
| | | int fd = 0; |
| | | int ret; |
| | | int i; |
| | | char *fd_path; |
| | | memfd_data_st memfd_data = {0}; |
| | | int rcv_num = 0; |
| | | |
| | | ret = basic_create_ipc_client(UNIX_DOMAIN, &memfd_data); |
| | | if(ret < 0) |
| | | { |
| | | return ret; |
| | | } |
| | | |
| | | printf("receive message from server,pid:%d, memfd:%d\n", memfd_data.pid, memfd_data.memfd); |
| | | if ((memfd_data.pid != 0) && (memfd_data.memfd != 0)) |
| | | { |
| | | char fd_path[256] = {0}; |
| | | snprintf(fd_path, sizeof(fd_path), "/proc/%d/fd/%d", memfd_data.pid, memfd_data.memfd); |
| | | fprintf(stderr,"fd_path:%s\n", fd_path); |
| | | fd = basic_shm_open(memfd_data.memfd, memfd_data.pid , 1); |
| | | ret = memfd_read(fd); |
| | | } |
| | | |
| | | basic_shm_close(fd); |
| | | return 0; |
| | | |
| | | } |
New file |
| | |
| | | #include <signal.h> |
| | | #include <sys/types.h> |
| | | #include <sys/stat.h> |
| | | #include <unistd.h> |
| | | #include <stdlib.h> |
| | | #include <stdio.h> |
| | | #include <errno.h> |
| | | |
| | | #include "memfd.h" |
| | | #include "ipc_msg.h" |
| | | |
| | | int g_memfd = 0; |
| | | |
| | | void handler(){ |
| | | |
| | | printf("clean program start\n"); |
| | | //unlink(UNIX_DOMAIN); |
| | | remove(UNIX_DOMAIN); |
| | | printf("clean end.\n"); |
| | | } |
| | | |
| | | int shm_write(int fd) |
| | | { |
| | | struct stat st; |
| | | ssize_t len; |
| | | int ret = 0; |
| | | unsigned char* paddr; |
| | | |
| | | if (fstat (fd, &st)) |
| | | errExit ("fstat"); |
| | | len = st.st_size; |
| | | |
| | | char *content = "hello world!\n"; |
| | | ret = basic_shm_mmap (fd, &paddr); |
| | | if (ret < 0) |
| | | errExit("basic_shm_mmap"); |
| | | |
| | | memcpy(paddr, content, strlen(content)); |
| | | |
| | | printf("length: %zu, atime: %lu.%lu\n", len, st.st_atim.tv_sec, st.st_atim.tv_nsec); |
| | | return len; |
| | | } |
| | | |
| | | |
| | | |
| | | int proc_memfd(struct user_data* rdata) |
| | | { |
| | | int fd = rdata->fd; |
| | | unsigned int n_size; |
| | | char line[MAX_LEN]= {0}; |
| | | int n = 0; |
| | | int nwrite = 0; |
| | | int data_size = 0; |
| | | memfd_data_st memfd_data = {0}; |
| | | |
| | | if(rdata->n_size <= 0 || fd < 0) |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | if(0 == strncmp(rdata->line, HELLO_MSG, strlen(HELLO_MSG))) |
| | | { |
| | | memfd_data.memfd = g_memfd; |
| | | memfd_data.pid = getpid(); |
| | | memfd_data.data = NULL; |
| | | memfd_data.len = 0; |
| | | data_size = sizeof(memfd_data_st) + memfd_data.len; |
| | | memcpy(line, &memfd_data, data_size); |
| | | } |
| | | else |
| | | { |
| | | return -1; |
| | | } |
| | | |
| | | n = data_size; |
| | | while(n>0) |
| | | { |
| | | nwrite = write(rdata->fd, line+data_size-n,n);////ET |
| | | if( nwrite < n ) |
| | | { |
| | | if((nwrite==-1) && (errno != EAGAIN)) |
| | | { |
| | | perror("write error"); |
| | | } |
| | | if (errno == ECONNRESET) |
| | | { |
| | | close(rdata->fd); |
| | | printf("[SERVER] Error: send responce failed: %s\n", strerror(errno)); |
| | | } |
| | | else if (nwrite == 0) |
| | | { |
| | | close(rdata->fd); |
| | | printf("[SERVER] Error: client closed connection."); |
| | | } |
| | | break; |
| | | } |
| | | n -= nwrite; |
| | | } |
| | | |
| | | return nwrite; |
| | | |
| | | } |
| | | |
| | | /*define you our proc_memfd funtion to send your message to other processes,or just put it in shm, |
| | | notice the file description fd and the pid of creator to other*/ |
| | | int main(int argc, char **argv) |
| | | { |
| | | char *name; |
| | | ssize_t len; |
| | | char * unixdomain = NULL; |
| | | int ret = 0; |
| | | |
| | | if (argc < 3) { |
| | | fprintf(stderr, "%s name size [unix domain path]\n", argv[0]); |
| | | exit(EXIT_FAILURE); |
| | | } |
| | | |
| | | name = argv[1]; |
| | | len = atoi(argv[2]) * 1024LU * 1024LU * 1024LU; |
| | | unixdomain = argv[3]; |
| | | |
| | | signal(SIGTERM,handler); |
| | | signal(SIGABRT,handler); |
| | | signal(SIGSEGV,handler); |
| | | |
| | | |
| | | g_memfd = basic_shm_create(name, len); |
| | | ret = shm_write(g_memfd); |
| | | |
| | | ret = basic_create_ipc_server(unixdomain); |
| | | if(ret < 0) |
| | | { |
| | | printf("failed to create ipc_server\n"); |
| | | } |
| | | |
| | | // basic_shm_close(g_memfd); |
| | | return 0; |
| | | } |
| | |
| | | # add library |
| | | add_library(memfd SHARED memfd.c list_in_shm.c shmht.c) |
| | | target_link_libraries(memfd PRIVATE pthread) |
| | | add_library(libipc_server SHARED ipc_msg.c ipc_server_lib.c) |
| | | add_library(libipc_client SHARED ipc_msg.c ipc_client_lib.c) |
| | | |
| | | |
| | |
| | | shmht_mytests: shmht_mytests.o shmht.o memfd.o |
| | | $(CC) $(CFLAGS) $(INCLUDE) -L . -pthread -o $@ $^ |
| | | shmht_mytests.o: |
| | | $(CC) $(CFLAGS) $(INCLUDE) -fPIC -c shmht_mytests.c |
| | | $(CC) $(CFLAGS) $(INCLUDE) -fPIC -c ../sample/shmht_mytests.c |
| | | memfd.o: |
| | | $(CC) $(CFLAGS) $(INCLUDE) -fPIC -c memfd.c |
| | | ipc_server:libipc_server.so |
| | | $(CC) $(CFLAGS) $(INCLUDE) -fPIC -pthread -o $@ ipc_server.c -lipc_server -L . |
| | | $(CC) $(CFLAGS) $(INCLUDE) -fPIC -pthread -o $@ ../sample/ipc_server.c -lipc_server -L . |
| | | libipc_server.so: |
| | | $(CC) -shared -fPIC -o $@ ipc_server_lib.c ipc_msg.c memfd.c |
| | | $(CC) -shared -fPIC $(INCLUDE) -o $@ ipc_server_lib.c ipc_msg.c memfd.c |
| | | ipc_client:libipc_client.so |
| | | $(CC) $(CFLAGS) $(INCLUDE) -fPIC -o $@ ipc_client.c ipc_msg.c memfd.c -lipc_client -L . |
| | | $(CC) $(CFLAGS) $(INCLUDE) -fPIC -o $@ ../sample/ipc_client.c ipc_msg.c memfd.c -lipc_client -L . |
| | | libipc_client.so: |
| | | $(CC) -shared -fPIC -o $@ ipc_client_lib.c ipc_msg.c memfd.c |
| | | $(CC) -shared -fPIC $(INCLUDE) -o $@ ipc_client_lib.c ipc_msg.c memfd.c |
| | | clean: |
| | | rm -rf *.so *.o a.out shmht_mytests *.a ipc_client ipc_server |