server.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #include <stdio.h>
  2. #include <sys/mman.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <errno.h>
  7. #include "../graphene-ipc.h"
  8. #define PAGE_SIZE 4096
  9. #define MAX_PIDBUF 20
  10. int main () {
  11. volatile int * volatile x;
  12. int pid, pid2, fd0, fd1, rv;
  13. struct gipc_send gs;
  14. int p0[2];
  15. int p1[2];
  16. int p2[2];
  17. char pidbuf[MAX_PIDBUF];
  18. unsigned long addr[3];
  19. unsigned long len[3];
  20. int64_t token0, token1;
  21. int order = 0;
  22. if (pipe(p0) == -1) {
  23. printf("Pipe failed %d\n", errno);
  24. return -1;
  25. }
  26. if (pipe(p1) == -1) {
  27. printf("Pipe failed %d\n", errno);
  28. return -1;
  29. }
  30. if (pipe(p2) == -1) {
  31. printf("Pipe failed %d\n", errno);
  32. return -1;
  33. }
  34. /* Just fork the client as a convenient way to get the pid */
  35. pid = fork();
  36. if (pid == -1) {
  37. printf("Failed to FORK!, %d\n", errno);
  38. return -1;
  39. } else if (pid == 0) {
  40. // child reads the pipe
  41. close(p0[1]);
  42. dup2(p0[0], 0);
  43. dup2(p2[1], 3);
  44. execv("./client", NULL);
  45. printf("Failed to EXEC!, %d\n", errno);
  46. return -1;
  47. } else {
  48. close(p0[0]);
  49. }
  50. pid2 = fork();
  51. if (pid2 == -1) {
  52. printf("Failed to FORK!, %d\n", errno);
  53. return -1;
  54. } else if (pid2 == 0) {
  55. // child reads the pipe
  56. close(p1[1]);
  57. dup2(p1[0], 0);
  58. dup2(p2[0], 3);
  59. execv("./client", NULL);
  60. printf("Failed to EXEC!, %d\n", errno);
  61. return -1;
  62. } else {
  63. close(p1[0]);
  64. }
  65. printf("Server is %d, clients are %d %d\n", getpid(), pid, pid2);
  66. /* Map an anonymous page */
  67. addr[0] = (unsigned long) mmap(NULL, PAGE_SIZE * 6, PROT_READ|PROT_WRITE,
  68. MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
  69. x = (int *) addr[0];
  70. addr[1] = addr[0] + PAGE_SIZE;
  71. addr[2] = addr[1] + PAGE_SIZE;
  72. len[0] = PAGE_SIZE;
  73. len[1] = PAGE_SIZE;
  74. len[2] = PAGE_SIZE;
  75. /* Put a 42 in it */
  76. *x = pid2;
  77. x += PAGE_SIZE / sizeof(int);
  78. *x = 13;
  79. x += PAGE_SIZE / sizeof(int);
  80. *x = 407;
  81. x += PAGE_SIZE / sizeof(int);
  82. *x = pid;
  83. x += PAGE_SIZE / sizeof(int);
  84. *x = 155;
  85. x += PAGE_SIZE / sizeof(int);
  86. *x = 48;
  87. /* Open an IPC link */
  88. fd0 = open (GIPC_FILE, O_RDWR);
  89. if (fd0 < 0) {
  90. printf ("[server] Fd is %d %d\n", fd0, errno);
  91. return -1;
  92. }
  93. /* Create a new queue on the link, get the token*/
  94. token0 = ioctl(fd0, GIPC_CREATE, 0);
  95. if (token0 < 0) {
  96. printf ("[server] Failed to create a new token %ld\n", token0);
  97. return -1;
  98. }
  99. fd1 = open (GIPC_FILE, O_RDWR);
  100. if (fd1 < 0) {
  101. printf ("[server] Fd is %d %d\n", fd1, errno);
  102. return -1;
  103. }
  104. // parent writes the token to the pipe
  105. snprintf(pidbuf, MAX_PIDBUF, "%ld", token0);
  106. write(p0[1], &token0, sizeof(token0));
  107. // Tell the client whether it is 0 or 1
  108. write(p0[1], &order, sizeof(order));
  109. /* Create a new queue on the link, get the token*/
  110. token1 = ioctl(fd1, GIPC_CREATE, 0);
  111. if (token1 < 0) {
  112. printf ("[server] Failed to create a new token %ld\n", token0);
  113. return -1;
  114. }
  115. // parent writes the token to the pipe
  116. write(p1[1], &token1, sizeof(token1));
  117. // Tell the client whether it is 0 or 1
  118. order++;
  119. write(p1[1], &order, sizeof(order));
  120. /* Send the pages to client 1 */
  121. gs.entries = 3;
  122. gs.addr = addr;
  123. gs.len = len;
  124. rv = ioctl(fd0, GIPC_SEND, &gs);
  125. if (rv != 3)
  126. printf ("[server] Bad rv %d %d (1)\n", rv, errno);
  127. /* Send the pages to client 2 */
  128. addr[0] += PAGE_SIZE *3;
  129. addr[1] += PAGE_SIZE *3;
  130. addr[2] += PAGE_SIZE *3;
  131. rv = ioctl(fd1, GIPC_SEND, &gs);
  132. if (rv != 3)
  133. printf ("[server] Bad rv %d (2)\n", errno);
  134. /* Print the value */
  135. x = (int *) addr[0];
  136. *x = 384;
  137. printf("[server] X contains %d\n", *x);
  138. x += PAGE_SIZE / sizeof(int);
  139. printf("[server] X contains %d\n", *x);
  140. x += PAGE_SIZE / sizeof(int);
  141. printf("[server] X contains %d\n", *x);
  142. wait();
  143. wait();
  144. close(fd0);
  145. close(fd1);
  146. return 0;
  147. }