shmctl.c 1005 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. #include <sys/shm.h>
  2. #include <endian.h>
  3. #include "syscall.h"
  4. #include "ipc.h"
  5. #if __BYTE_ORDER != __BIG_ENDIAN
  6. #undef SYSCALL_IPC_BROKEN_MODE
  7. #endif
  8. int shmctl(int id, int cmd, struct shmid_ds *buf)
  9. {
  10. #if IPC_TIME64
  11. struct shmid_ds out, *orig;
  12. if (cmd&IPC_TIME64) {
  13. out = (struct shmid_ds){0};
  14. orig = buf;
  15. buf = &out;
  16. }
  17. #endif
  18. #ifdef SYSCALL_IPC_BROKEN_MODE
  19. struct shmid_ds tmp;
  20. if (cmd == IPC_SET) {
  21. tmp = *buf;
  22. tmp.shm_perm.mode *= 0x10000U;
  23. buf = &tmp;
  24. }
  25. #endif
  26. #ifndef SYS_ipc
  27. int r = __syscall(SYS_shmctl, id, IPC_CMD(cmd), buf);
  28. #else
  29. int r = __syscall(SYS_ipc, IPCOP_shmctl, id, IPC_CMD(cmd), 0, buf, 0);
  30. #endif
  31. #ifdef SYSCALL_IPC_BROKEN_MODE
  32. if (r >= 0) switch (cmd | IPC_TIME64) {
  33. case IPC_STAT:
  34. case SHM_STAT:
  35. case SHM_STAT_ANY:
  36. buf->shm_perm.mode >>= 16;
  37. }
  38. #endif
  39. #if IPC_TIME64
  40. if (r >= 0 && (cmd&IPC_TIME64)) {
  41. buf = orig;
  42. *buf = out;
  43. IPC_HILO(buf, shm_atime);
  44. IPC_HILO(buf, shm_dtime);
  45. IPC_HILO(buf, shm_ctime);
  46. }
  47. #endif
  48. return __syscall_ret(r);
  49. }