shm implemented as memfd syscall
cheliequan
2022-12-28 078d17014ed3bc3a00eafcd535095a03c64bea6c
修改CmakeList
3个文件已添加
3个文件已修改
280 ■■■■■ 已修改文件
include/ipc_msg.h 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sample/CMakeLists.txt 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sample/ipc_client.c 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sample/ipc_server.c 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/CMakeLists.txt 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Makefile 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
include/ipc_msg.h
New file
@@ -0,0 +1,62 @@
#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
sample/CMakeLists.txt
@@ -8,6 +8,8 @@
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 
@@ -29,4 +31,16 @@
                  memfd
              pthread
             )
target_link_libraries(ipc_server
                  PRIVATE
                  memfd
              pthread
                      libipc_server
             )
target_link_libraries(ipc_client
                  PRIVATE
                  memfd
              pthread
              libipc_client
             )
sample/ipc_client.c
New file
@@ -0,0 +1,54 @@
#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;
}
sample/ipc_server.c
New file
@@ -0,0 +1,138 @@
#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;
}
src/CMakeLists.txt
@@ -7,5 +7,7 @@
# 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)
src/Makefile
@@ -14,16 +14,16 @@
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