00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00033 #include <ipc/ipc.h>
00034 #include <ipc/services.h>
00035 #include <adt/list.h>
00036 #include <bool.h>
00037 #include <errno.h>
00038 #include <assert.h>
00039 #include <stdio.h>
00040 #include <malloc.h>
00041 #include <loader/loader.h>
00042 #include "clonable.h"
00043 #include "ns.h"
00044
00046 typedef struct {
00047 link_t link;
00048 sysarg_t service;
00049 ipc_call_t call;
00050 ipc_callid_t callid;
00051 } cs_req_t;
00052
00054 static link_t cs_req;
00055
00056 int clonable_init(void)
00057 {
00058 list_initialize(&cs_req);
00059 return EOK;
00060 }
00061
00063 bool service_clonable(int service)
00064 {
00065 return (service == SERVICE_LOAD);
00066 }
00067
00075 void register_clonable(sysarg_t service, sysarg_t phone, ipc_call_t *call,
00076 ipc_callid_t callid)
00077 {
00078 if (list_empty(&cs_req)) {
00079
00080 printf("%s: Unexpected clonable server.\n", NAME);
00081 ipc_answer_0(callid, EBUSY);
00082 return;
00083 }
00084
00085 cs_req_t *csr = list_get_instance(cs_req.next, cs_req_t, link);
00086 list_remove(&csr->link);
00087
00088
00089 assert(csr->service == SERVICE_LOAD);
00090
00091 ipc_answer_0(callid, EOK);
00092
00093 ipc_forward_fast(csr->callid, phone, IPC_GET_ARG2(csr->call),
00094 IPC_GET_ARG3(csr->call), 0, IPC_FF_NONE);
00095
00096 free(csr);
00097 ipc_hangup(phone);
00098 }
00099
00109 void connect_to_clonable(sysarg_t service, ipc_call_t *call,
00110 ipc_callid_t callid)
00111 {
00112 assert(service == SERVICE_LOAD);
00113
00114 cs_req_t *csr = malloc(sizeof(cs_req_t));
00115 if (csr == NULL) {
00116 ipc_answer_0(callid, ENOMEM);
00117 return;
00118 }
00119
00120
00121 int rc = loader_spawn("loader");
00122
00123 if (rc < 0) {
00124 free(csr);
00125 ipc_answer_0(callid, rc);
00126 return;
00127 }
00128
00129 link_initialize(&csr->link);
00130 csr->service = service;
00131 csr->call = *call;
00132 csr->callid = callid;
00133
00134
00135
00136
00137
00138
00139 list_append(&csr->link, &cs_req);
00140 }
00141