1 #include "inc.h" 2 3 int identifier = 0x1234; 4 endpoint_t who_e; 5 int call_type; 6 7 static struct { 8 int type; 9 int (*func)(message *); 10 int reply; /* whether the reply action is passed through */ 11 } ipc_calls[] = { 12 { IPC_SHMGET, do_shmget, 0 }, 13 { IPC_SHMAT, do_shmat, 0 }, 14 { IPC_SHMDT, do_shmdt, 0 }, 15 { IPC_SHMCTL, do_shmctl, 0 }, 16 { IPC_SEMGET, do_semget, 0 }, 17 { IPC_SEMCTL, do_semctl, 0 }, 18 { IPC_SEMOP, do_semop, 1 }, 19 }; 20 21 #define SIZE(a) (sizeof(a)/sizeof(a[0])) 22 23 static int verbose = 0; 24 25 /* SEF functions and variables. */ 26 static void sef_local_startup(void); 27 static int sef_cb_init_fresh(int type, sef_init_info_t *info); 28 static void sef_cb_signal_handler(int signo); 29 30 int main(int argc, char *argv[]) 31 { 32 message m; 33 34 /* SEF local startup. */ 35 env_setargs(argc, argv); 36 sef_local_startup(); 37 38 while (TRUE) { 39 int r; 40 int ipc_number; 41 42 if ((r = sef_receive(ANY, &m)) != OK) 43 printf("sef_receive failed %d.\n", r); 44 who_e = m.m_source; 45 call_type = m.m_type; 46 47 if(verbose) 48 printf("IPC: get %d from %d\n", call_type, who_e); 49 50 if (call_type & NOTIFY_MESSAGE) { 51 switch (who_e) { 52 case VM_PROC_NR: 53 /* currently, only semaphore needs such information. */ 54 sem_process_vm_notify(); 55 break; 56 default: 57 printf("IPC: ignoring notify() from %d\n", 58 who_e); 59 break; 60 } 61 continue; 62 } 63 64 /* 65 * The ipc number in the table can be obtained 66 * with a simple equation because the values of 67 * IPC system calls are consecutive and begin 68 * at ( IPC_BASE + 1 ) 69 */ 70 71 ipc_number = call_type - (IPC_BASE + 1); 72 73 /* dispatch message */ 74 if (ipc_number >= 0 && ipc_number < SIZE(ipc_calls)) { 75 int result; 76 77 if (ipc_calls[ipc_number].type != call_type) 78 panic("IPC: call table order mismatch"); 79 80 /* If any process does an IPC call, 81 * we have to know about it exiting. 82 * Tell VM to watch it for us. 83 */ 84 if(vm_watch_exit(m.m_source) != OK) { 85 printf("IPC: watch failed on %d\n", m.m_source); 86 } 87 88 result = ipc_calls[ipc_number].func(&m); 89 90 /* 91 * The handler of the IPC call did not 92 * post a reply. 93 */ 94 if (!ipc_calls[ipc_number].reply) { 95 96 m.m_type = result; 97 98 if(verbose && result != OK) 99 printf("IPC: error for %d: %d\n", 100 call_type, result); 101 102 if ((r = ipc_sendnb(who_e, &m)) != OK) 103 printf("IPC send error %d.\n", r); 104 } 105 } else { 106 /* warn and then ignore */ 107 printf("IPC unknown call type: %d from %d.\n", 108 call_type, who_e); 109 } 110 update_refcount_and_destroy(); 111 } 112 113 /* no way to get here */ 114 return -1; 115 } 116 117 /*===========================================================================* 118 * sef_local_startup * 119 *===========================================================================*/ 120 static void sef_local_startup() 121 { 122 /* Register init callbacks. */ 123 sef_setcb_init_fresh(sef_cb_init_fresh); 124 sef_setcb_init_restart(sef_cb_init_fresh); 125 126 /* No live update support for now. */ 127 128 /* Register signal callbacks. */ 129 sef_setcb_signal_handler(sef_cb_signal_handler); 130 131 /* Let SEF perform startup. */ 132 sef_startup(); 133 } 134 135 /*===========================================================================* 136 * sef_cb_init_fresh * 137 *===========================================================================*/ 138 static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) 139 { 140 /* Initialize the ipc server. */ 141 142 if(verbose) 143 printf("IPC: self: %d\n", sef_self()); 144 145 return(OK); 146 } 147 148 /*===========================================================================* 149 * sef_cb_signal_handler * 150 *===========================================================================*/ 151 static void sef_cb_signal_handler(int signo) 152 { 153 /* Only check for termination signal, ignore anything else. */ 154 if (signo != SIGTERM) return; 155 156 /* Checkout if there are still IPC keys. Inform the user in that case. */ 157 if (!is_sem_nil() || !is_shm_nil()) 158 printf("IPC: exit with un-clean states.\n"); 159 } 160 161