/* the main function only runs the server */ int main(int argc, char **argv) { struct minipc_ch *ch; if (argc != 2) { fprintf(stderr, "%s: use \"%s <shmid>\n", argv[0], argv[0]); exit(1); } ch = minipc_server_create(argv[1], 0); if (!ch) { fprintf(stderr, "%s: rpc_open(%s): %s\n", argv[0], argv[1], strerror(errno)); exit(1); } minipc_set_logfile(ch, stderr); /* Register your functions */ if (shm_export_functions(ch)) { fprintf(stderr, "%s: exporting RPC functions: %s\n", argv[0], strerror(errno)); exit(1); } /* Then just obey requests */ while (1) { minipc_server_action(ch, 1000); } }
void ptpd_init_exports(void) { ptp_ch = minipc_server_create("ptpd", 0); __rpcdef_get_sync_state.f = export_get_sync_state; __rpcdef_cmd.f = export_cmd; minipc_export(ptp_ch, &__rpcdef_get_sync_state); minipc_export(ptp_ch, &__rpcdef_cmd); }
int main(int argc, char **argv) { int fdm, fds, pid, exitval = 0; struct minipc_ch *ch; struct pty_counts counters = {0,}; /* First, open the pty */ if (openpty(&fdm, &fds, NULL, NULL, NULL) < 0) { fprintf(stderr, "%s: openpty(): %s\n", argv[0], strerror(errno)); exit(1); } /* Run a shell and let it go by itself before we open the rpc */ fprintf(stderr, "%s: Running a sub-shell in a new pty\n", argv[0]); if ((pid = fork()) < 0) { fprintf(stderr, "%s: fork(): %s\n", argv[0], strerror(errno)); exit(1); } if (!pid) { /* Child: become a shell and disappear... */ close(fdm); login_tty(fds); execl("/bin/sh", "sh", NULL); fprintf(stderr, "%s: exec(/bin/sh): %s\n", argv[0], strerror(errno)); exit(1); } /* Open the RPC server channel */ ch = minipc_server_create(PTY_RPC_NAME, 0); if (!ch) { fprintf(stderr, "%s: rpc_open(): %s\n", argv[0], strerror(errno)); exit(1); } /* Log file for diagnostics */ { char name[] = "/tmp/pty-server.XXXXXX"; int logfd; FILE *logf; logfd = mkstemp(name); if (logfd >= 0) { logf = fdopen(logfd, "w"); if (logf) minipc_set_logfile(ch, logf); } } /* Register your functions: all our RPC is split to another source */ if (pty_export_functions(ch, fdm, &counters)) { fprintf(stderr, "%s: exporting RPC functions: %s\n", argv[0], strerror(errno)); exit(1); } /* * Now, we must mirror stdin/stdout to the pty master, with RPC too. * The first step is horribly changing the termios of our tty */ close(fds); system("stty raw -echo"); while (waitpid(pid, NULL, WNOHANG) != pid) { fd_set set; int nfd, i; char buf[256]; /* ask the RPC engine its current fdset and augment it */ minipc_server_get_fdset(ch, &set); FD_SET(STDIN_FILENO, &set); FD_SET(fdm, &set); /* wait for any of the FD to be active */ nfd = select(64 /* Hmmm... */, &set, NULL, NULL, NULL); if (nfd < 0 && errno == EINTR) continue; if (nfd < 0) { fprintf(stderr, "%s: select(): %s\n", argv[0], strerror(errno)); exitval = 1; break; } /* Handle fdm and fds by just mirroring stuff and counting */ if (FD_ISSET(STDIN_FILENO, &set)) { i = read(0, buf, sizeof(buf)); if (i > 0) { write(fdm, buf, i); counters.in += i; } nfd--; } if (FD_ISSET(fdm, &set)) { i = read(fdm, buf, sizeof(buf)); if (i > 0) { write(1, buf, i); counters.out += i; } nfd--; } /* If there are no more active fd, loop over */ if (!nfd) continue; /* * If we are there, there has been an RPC call. * We tell the library to use a 0 timeout, since we know * for sure that at least one of its descriptors is pending. */ minipc_server_action(ch, 0); } /* The child shell exited, reset the tty and exit. Let RPC die out */ system("stty sane"); exit(exitval); }
/* No arguments */ int main(int argc, char **argv) { struct minipc_ch *server; struct minipc_ch *client; void *shmem; int ret; if (argc > 1) { fprintf(stderr, "%s: no arguments please\n", argv[0]); exit(1); } /* Create your shared memory and/or attach to it */ ret = shmget(MINIPC_SHM, sizeof(struct minipc_mbox_info), IPC_CREAT | 0666); if (ret < 0) { fprintf(stderr, "%s: shmget(): %s\n", argv[0], strerror(errno)); exit(1); } shmem = shmat(ret, NULL, SHM_RND); if (shmem == (void *)-1) { fprintf(stderr, "%s: shmat(): %s\n", argv[0], strerror(errno)); exit(1); } info = shmem; /* Create a server socket for mini-ipc */ server = minipc_server_create("mbox", 0); if (!server) { fprintf(stderr, "%s: server_create(): %s\n", argv[0], strerror(errno)); exit(1); } minipc_set_logfile(server, stderr); minipc_export(server, &mb_stat_struct); /* Connect as a client to the trivial-server */ client = minipc_client_create("trivial", 0); if (!client) { fprintf(stderr, "%s: client_create(): %s\n", argv[0], strerror(errno)); exit(1); } /* Loop serving both mini-ipc and the mailbox */ while (1) { fd_set set; struct timeval to = { MBOX_POLL_US / (1000*1000), MBOX_POLL_US % (1000*1000) }; minipc_server_get_fdset(server, &set); /* Wait for any server, with the defined timeout */ ret = select(16 /* hack */, &set, NULL, NULL, &to); if (ret > 0) { if (minipc_server_action(server, 0) < 0) { fprintf(stderr, "%s: server_action(): %s\n", argv[0], strerror(errno)); exit(1); } } /* No IPC request: if needed act as IPC client */ if (info->proc_req) { memset(&info->tv, 0, sizeof(info->tv)); minipc_call(client, 100 /* ms */, &mb_tod_struct, &info->tv, NULL); info->proc_req = 0; } } }