2 meinOS - A unix-like x86 microkernel operating system
3 Copyright (C) 2008 Janosch Gräf <janosch.graef@gmx.net>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include <interrupt.h>
31 rpc_functions
= llist_create();
33 if (syscall_create(SYSCALL_RPC_CREATE
,rpc_function_create
,4)==-1) return -1;
34 if (syscall_create(SYSCALL_RPC_DESTROY
,rpc_function_destroy
,1)==-1) return -1;
35 if (syscall_create(SYSCALL_RPC_GETINFO
,rpc_function_getinfo
,8)==-1) return -1;
36 if (syscall_create(SYSCALL_RPC_CALL
,rpc_function_call
,5)==-1) return -1;
37 if (syscall_create(SYSCALL_RPC_POLL
,rpc_call_poll
,4)==-1) return -1;
38 if (syscall_create(SYSCALL_RPC_RETURN
,rpc_call_return
,3)==-1) return -1;
39 if (syscall_create(SYSCALL_RPC_LIST
,rpc_list
,3)==-1) return -1;
44 * Creates a RPC function (Syscall)
45 * @param name Function name
46 * @param rpc_handler RPC handler
47 * @param func Function pointer
48 * @param synopsis Funtion synopsis
51 int rpc_function_create(char *name
,void *func
,char *synopsis
,size_t params_size
) {
52 rpc_function_t
*new = malloc(sizeof(rpc_function_t
));
53 new->id
= rpc_lastid
++;
54 new->name
= strdup(name
);
56 new->synopsis
= strdup(synopsis
);
57 new->owner
= proc_current
;
58 new->calls
= llist_create();
59 new->params_size
= params_size
;
60 llist_push(rpc_functions
,new);
65 * Destroys a RPC function (Syscall)
66 * @param id Function ID
69 int rpc_function_destroy(int id
) {
70 rpc_function_t
*func
= rpc_find(id
,NULL
,NULL
,0,0);
72 if (func
->owner
==proc_current
) {
76 while ((call
= llist_pop(func
->calls
))) rpc_call_destroy(call
);
85 * Gets information about RPC function (Syscall)
86 * @param id Function ID (or -1)
87 * @param name Function name (or NULL)
88 * @param pid Function owner's PID (or 0)
89 * @param has_calls Whether function must have calls
90 * @param params_size Reference for size of params
91 * @param synopsis Buffer for synopsis
92 * @param maxlen Maxlen for synopsis
93 * @param sleep Whether to sleep til next found (works only for owner)
96 int rpc_function_getinfo(int id
,char *name
,pid_t pid
,int has_calls
,size_t *params_size
,char *synopsis
,size_t maxlen
,int sleep
) {
97 rpc_function_t
*func
= rpc_find(id
,name
,NULL
,pid
,has_calls
);
99 strncpy(synopsis
,func
->synopsis
,maxlen
);
100 *params_size
= func
->params_size
;
103 else if (sleep
&& has_calls
&& pid
==proc_current
->pid
) {
104 *(interrupt_curregs
.eax
) = -1;
105 proc_sleep(proc_current
);
112 * Calls a RPC function (Syscall)
113 * @param id Function ID
114 * @param params Parameters
115 * @param ret Reference for return value
116 * @param ret_params Reference for return parameters (can be NULL)
117 * @param error Reference for RPC error
118 * @param sleep Sleep Reference
121 int rpc_function_call(int id
,void *params
,int *ret
,void *ret_params
,int *error
) {
122 rpc_function_t
*func
= rpc_find(id
,NULL
,NULL
,0,0);
124 rpc_call_t
*new = malloc(sizeof(rpc_call_t
));
125 new->caller
= proc_current
;
127 new->ret_params
= ret_params
;
128 new->params
= memcpy(malloc(func
->params_size
),params
,func
->params_size
);
130 llist_push(func
->calls
,new);
131 if (error
!=NULL
) *error
= 1;
132 proc_wake(func
->owner
);
133 *(interrupt_curregs
.eax
) = 0;
134 proc_sleep(proc_current
);
141 * Destroys a RPC Call
142 * @param call RPC Call
145 int rpc_call_destroy(rpc_call_t
*call
) {
152 * Checks for new calls (Syscall)
153 * @param id Function ID (or -1)
154 * @param func Reference for function pointer
155 * @param params Buffer for params
156 * @param caller Reference for caller PID
159 int rpc_call_poll(int id
,void **func_ptr
,void *params
,pid_t
*caller
) {
160 rpc_function_t
*func
= rpc_find(-1,NULL
,proc_current
,0,1);
162 rpc_call_t
*call
= llist_pop(func
->calls
);
163 func
->current
= call
;
164 *func_ptr
= func
->func
;
165 *caller
= call
->caller
->pid
;
166 memcpy(params
,call
->params
,func
->params_size
);
173 * Returns from a RPC functions (Syscall)
174 * @param id Function ID (or -1)
175 * @param ret Return value
176 * @param ret_params Return params
179 int rpc_call_return(int id
,int ret
,void *ret_params
) {
180 rpc_function_t
*func
= rpc_find(id
,NULL
,proc_current
,0,0);
182 rpc_call_t
*call
= func
->current
;
184 if (call
->ret_params
!=NULL
) {
185 void *buf
= memcpy(malloc(func
->params_size
),ret_params
,func
->params_size
);
186 memuser_load_addrspace(call
->caller
->addrspace
);
187 memcpy(call
->ret_params
,buf
,func
->params_size
);
189 else memuser_load_addrspace(call
->caller
->addrspace
);
190 if (call
->ret
!=NULL
) *(call
->ret
) = ret
;
191 if (call
->error
!=NULL
) *(call
->error
) = 0;
192 memuser_load_addrspace(proc_current
->addrspace
);
193 proc_wake(call
->caller
);
194 rpc_call_destroy(call
);
195 func
->current
= NULL
;
203 * Finds a RPC function
204 * @param id Function ID (or -1)
205 * @param name Function name (or NULL)
206 * @param owner Function owner (or NULL)
207 * @param pid Function owner's PID (or 0)
208 * @param has_calls Whether to check if functions is called
209 * @return RPC function
211 rpc_function_t
*rpc_find(int id
,char *name
,proc_t
*owner
,pid_t pid
,int has_calls
) {
212 rpc_function_t
*func
;
214 for (i
=0;(func
= llist_get(rpc_functions
,i
));i
++) {
215 if ((id
==-1 || id
==func
->id
) && (name
==NULL
|| strcmp(name
,func
->name
)==0) && (owner
==NULL
|| owner
==func
->owner
) && (pid
==0 || pid
==func
->owner
->pid
) && (has_calls
==0 || !llist_empty(func
->calls
))) return func
;
221 * "Lists" RPC function.
222 * @param i Index of current function
223 * @param buf Buffer for name
224 * @param bufsize Size of buffer
225 * @return Count of copied bytes
227 size_t rpc_list(size_t i
,char *buf
,size_t bufsize
) {
228 rpc_function_t
*func
;
229 func
= llist_get(rpc_functions
,i
);
231 if (buf
==NULL
|| bufsize
==0) { // only return size
232 return strlen(func
->name
)+1;
235 strncpy(buf
,func
->name
,bufsize
);
236 return strlen(buf
)+1;