Choco OS  V.0.16.9.0
Join to the chocolate world
oc_program.c
Go to the documentation of this file.
1 
27 #include <oc_program.h>
28 #include <oc_stdlib.h>
29 #include <string.h>
30 #include <oc_streamman.h>
31 #include <oc_processman.h>
32 
38 #define _________________________________________TYPES_SECTION______________________________________________________________________________
39 
40 typedef struct
41 {
42  oC_Program_t Program;
43  oC_Process_t Process;
44  int Argc;
45  char ** Argv;
47 
48 #undef _________________________________________TYPES_SECTION______________________________________________________________________________
49 
50 
56 #define _________________________________________PROTOTYPES_SECTION_________________________________________________________________________
57 
58 void ProgramThread( void * UserPointer );
59 bool CloseProcess( oC_Thread_t Thread, void * Process, uint32_t Parameter );
60 
61 #undef _________________________________________PROTOTYPES_SECTION_________________________________________________________________________
62 
63 
69 #define _________________________________________VARIABLES_SECTION__________________________________________________________________________
70 
71 static const oC_Allocator_t Allocator = {
72  .Name = "program" ,
73  .EventFlags = 0 ,
74  .EventHandler = NULL
75 };
76 
77 #undef _________________________________________VARIABLES_SECTION__________________________________________________________________________
78 
84 #define _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
85 
86 
87 //==========================================================================================================================================
88 //==========================================================================================================================================
89 oC_Process_t oC_Program_NewProcess( oC_Program_t Program , oC_User_t User )
90 {
91  oC_Process_t process = NULL;
92 
93  if(oC_Program_IsCorrect(Program) && oC_User_IsCorrect(User))
94  {
95  oC_Stream_t _stdin = oC_StreamMan_GetStream(Program->StdInName);
96  oC_Stream_t _stdout = oC_StreamMan_GetStream(Program->StdOutName);
97  oC_Stream_t _stderr = oC_StreamMan_GetStream(Program->StdErrName);
98  process = oC_Process_New(Program->Priority,Program->Name,User,Program->HeapMapSize,_stdin,_stdout,_stderr);
99 
100  if(process != NULL)
101  {
102  oC_SaveIfFalse( "Program::NewProcess - cannot set memory limit " , oC_Process_SetAllocationLimit (process, Program->AllocationLimit ) , oC_ErrorCode_ObjectNotCorrect);
103  oC_SaveIfFalse( "Program::NewProcess - cannot set memory tracking " , oC_Process_SetAllocationTracking(process, Program->TrackAllocations) , oC_ErrorCode_ObjectNotCorrect);
104  }
105  }
106 
107  return process;
108 }
109 
110 //==========================================================================================================================================
111 //==========================================================================================================================================
112 oC_Program_t oC_Program_New( oC_Program_Priority_t Priority , char * Name , oC_Program_MainFunction_t MainFunction , char * StdInName , char * StdOutName , char * StdErrName , oC_UInt_t HeapMapSize )
113 {
114  oC_Program_Registration_t * program = NULL;
115 
116  if(
117  isaddresscorrect(Name) &&
118  isaddresscorrect(MainFunction) &&
119  isaddresscorrect(StdInName) &&
120  isaddresscorrect(StdOutName) &&
121  isaddresscorrect(StdOutName)
122  )
123  {
124  program = ksmartalloc(sizeof(oC_Program_Registration_t),&Allocator,AllocationFlags_NoWait);
125 
126  if(program)
127  {
128  program->Priority = Priority;
129  program->MainFunction = MainFunction;
130  program->HeapMapSize = HeapMapSize;
131  program->ThreadStackSize= 0;
132 
133  if(isrom(Name))
134  {
135  program->Name = Name;
136  }
137  else
138  {
139  program->Name = ksmartalloc(strlen(Name)+1 , &Allocator , AllocationFlags_NoWait);
140  strcpy(program->Name,Name);
141  }
142 
143  if(isrom(StdInName))
144  {
145  program->StdInName = StdInName;
146  }
147  else
148  {
149  program->StdInName = ksmartalloc(strlen(StdInName)+1 , &Allocator , AllocationFlags_NoWait);
150  strcpy(program->StdInName,StdInName);
151  }
152  if(isrom(StdOutName))
153  {
154  program->StdOutName = StdOutName;
155  }
156  else
157  {
158  program->StdOutName = ksmartalloc(strlen(StdOutName)+1 , &Allocator , AllocationFlags_NoWait);
159  strcpy(program->StdOutName,StdOutName);
160  }
161 
162  if(isrom(StdErrName))
163  {
164  program->StdErrName = StdErrName;
165  }
166  else
167  {
168  program->StdErrName = ksmartalloc(strlen(StdErrName)+1 , &Allocator , AllocationFlags_NoWait);
169  strcpy(program->StdErrName,StdErrName);
170  }
171 
172  }
173  }
174 
175  return program;
176 }
177 
178 //==========================================================================================================================================
179 //==========================================================================================================================================
180 bool oC_Program_Delete( oC_Program_Registration_t ** Program )
181 {
182  bool deleted = false;
183 
185  {
186  deleted = true;
187  if(oC_MemMan_IsDynamicAllocatedAddress((*Program)->Name))
188  {
189  if(!ksmartfree((*Program)->Name,strlen((*Program)->Name)+1,AllocationFlags_CanWaitForever))
190  {
191  deleted = false;
192  }
193  }
194 
195  if(oC_MemMan_IsDynamicAllocatedAddress((*Program)->StdInName))
196  {
197  if(!ksmartfree((*Program)->StdInName,strlen((*Program)->StdInName)+1,AllocationFlags_CanWaitForever))
198  {
199  deleted = false;
200  }
201  }
202 
203  if(oC_MemMan_IsDynamicAllocatedAddress((*Program)->StdOutName))
204  {
205  if(!ksmartfree((*Program)->StdOutName,strlen((*Program)->StdOutName)+1,AllocationFlags_CanWaitForever))
206  {
207  deleted = false;
208  }
209  }
210 
211  if(oC_MemMan_IsDynamicAllocatedAddress((*Program)->StdErrName))
212  {
213  if(!ksmartfree((*Program)->StdErrName,strlen((*Program)->StdErrName)+1,AllocationFlags_CanWaitForever))
214  {
215  deleted = false;
216  }
217  }
218 
219  if(!ksmartfree(*Program,sizeof(oC_Program_Registration_t),AllocationFlags_CanWaitForever))
220  {
221  deleted = false;
222  }
223  }
224 
225  return deleted;
226 }
227 //==========================================================================================================================================
228 //==========================================================================================================================================
229 bool oC_Program_IsCorrect( oC_Program_t Program )
230 {
231  return isaddresscorrect(Program);
232 }
233 //==========================================================================================================================================
234 //==========================================================================================================================================
235 oC_ErrorCode_t oC_Program_Exec( oC_Program_t Program , oC_Process_t Process , int Argc , const char ** Argv , oC_Thread_t * outMainThread )
236 {
237  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
238 
239  if(
240  oC_AssignErrorCodeIfFalse(&errorCode, oC_Program_IsCorrect(Program) , oC_ErrorCode_ObjectNotCorrect ) &&
241  oC_AssignErrorCodeIfFalse(&errorCode, isaddresscorrect(Argv) , oC_ErrorCode_WrongAddress ) &&
242  oC_AssignErrorCodeIfFalse(&errorCode, oC_Process_IsCorrect(Process) , oC_ErrorCode_ObjectNotCorrect ) &&
243  oC_AssignErrorCodeIfFalse(&errorCode, outMainThread == NULL || isram(outMainThread) , oC_ErrorCode_OutputAddressNotInRAM )
244  )
245  {
246  ProgramContext_t * programContext = kmalloc(sizeof(ProgramContext_t), oC_Process_GetAllocator(Process) ,AllocationFlags_CanWait1Second);
247  Allocator_t allocator = oC_Process_GetAllocator(Process);
248 
249  if(programContext)
250  {
251  programContext->Process = Process;
252  programContext->Program = Program;
253  programContext->Argv = kmalloc(Argc * sizeof(char*),allocator,AllocationFlags_CanWait1Second);
254  programContext->Argc = Argc;
255 
256  /*
257  * This is the loop without repeats - just for simply assignments of errors
258  */
259  do
260  {
261  errorCode = oC_ErrorCode_None;
262 
263  if(isram(programContext->Argv)==false)
264  {
265  errorCode = oC_ErrorCode_AllocationError;
266  break;
267  }
268 
269  for(int argumentIndex = 0; argumentIndex < Argc && !oC_ErrorOccur(errorCode) ; argumentIndex++ )
270  {
271  if(isaddresscorrect(Argv[argumentIndex]))
272  {
273  programContext->Argv[argumentIndex] = kmalloc(strlen(Argv[argumentIndex])+1,allocator,AllocationFlags_CanWait500Msecond);
274 
275  if(isram(programContext->Argv[argumentIndex]))
276  {
277  strcpy(programContext->Argv[argumentIndex],Argv[argumentIndex]);
278  }
279  else
280  {
281  errorCode = oC_ErrorCode_AllocationError;
282  }
283  }
284  else
285  {
286  errorCode = oC_ErrorCode_WrongAddress;
287  }
288  }
289 
290  if(oC_ErrorOccur(errorCode))
291  {
292  break;
293  }
294 
295  oC_Thread_t thread = oC_Thread_New( oC_Process_GetPriority(Process) ,Program->ThreadStackSize,Process,Program->Name,ProgramThread,programContext);
296 
297  if(thread==NULL)
298  {
299  kfree(programContext,AllocationFlags_CanWaitForever);
300  errorCode = oC_ErrorCode_AllocationError;
301  break;
302  }
303 
304  if(oC_ProcessMan_ContainsProcess(Process) == false)
305  {
306  errorCode = oC_ProcessMan_AddProcess(Process);
307  }
308 
309  if(oC_ProcessMan_ContainsProcess(Process))
310  {
311  if(oC_Thread_Run(thread))
312  {
313  if(outMainThread != NULL)
314  {
315  *outMainThread = thread;
316  }
317  oC_SaveIfFalse("Cannot save CloseProcess to revert", oC_Thread_SaveToRevert(thread,CloseProcess,Process,0), oC_ErrorCode_InternalDataAreDamaged);
318  errorCode = oC_ErrorCode_None;
319  }
320  else
321  {
322  errorCode = oC_ErrorCode_ImplementError;
323  }
324  }
325  else
326  {
327  oC_SaveIfFalse("Thread", oC_Thread_Delete(&thread) , oC_ErrorCode_ReleaseError);
328  }
329  } while(0);
330  }
331  else
332  {
333  errorCode = oC_ErrorCode_AllocationError;
334  }
335  }
336 
337  return errorCode;
338 }
339 //==========================================================================================================================================
340 //==========================================================================================================================================
341 const char * oC_Program_GetName( oC_Program_t Program )
342 {
343  const char * name = "program not correct";
344 
345  if(oC_Program_IsCorrect(Program))
346  {
347  name = Program->Name;
348  }
349 
350  return name;
351 }
352 //==========================================================================================================================================
353 //==========================================================================================================================================
354 const char * oC_Program_GetStdInName( oC_Program_t Program )
355 {
356  const char * name = "program not correct";
357 
358  if(oC_Program_IsCorrect(Program))
359  {
360  name = Program->StdInName;
361  }
362 
363  return name;
364 }
365 //==========================================================================================================================================
366 //==========================================================================================================================================
367 const char * oC_Program_GetStdOutName( oC_Program_t Program )
368 {
369  const char * name = "program not correct";
370 
371  if(oC_Program_IsCorrect(Program))
372  {
373  name = Program->StdOutName;
374  }
375 
376  return name;
377 }
378 //==========================================================================================================================================
379 //==========================================================================================================================================
380 const char * oC_Program_GetStdErrName( oC_Program_t Program )
381 {
382  const char * name = "program not correct";
383 
384  if(oC_Program_IsCorrect(Program))
385  {
386  name = Program->StdErrName;
387  }
388 
389  return name;
390 }
391 //==========================================================================================================================================
392 //==========================================================================================================================================
393 oC_Program_Priority_t oC_Program_GetPriority( oC_Program_t Program )
394 {
395  oC_Program_Priority_t priority = 0;
396 
397  if(oC_Program_IsCorrect(Program))
398  {
399  priority = Program->Priority;
400  }
401 
402  return priority;
403 }
404 
405 #undef _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
406 
412 #define _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
413 
414 //==========================================================================================================================================
415 //==========================================================================================================================================
416 void ProgramThread( void * UserPointer )
417 {
418  ProgramContext_t * programContext = UserPointer;
419 
420  if(isaddresscorrect(programContext) && isaddresscorrect(programContext->Program) && isaddresscorrect(programContext->Program->MainFunction))
421  {
422  int ret = programContext->Program->MainFunction(programContext->Argc,(const char **)programContext->Argv);
423 
424  if(ret != 0)
425  {
426  oC_SaveError(programContext->Program->Name,(oC_ErrorCode_t)ret);
427  }
428 
429  if(oC_Process_Kill(programContext->Process)==false)
430  {
431  oC_SaveError("Cannot kill process " , oC_ErrorCode_ReleaseError);
432  }
433  }
434 }
435 
436 //==========================================================================================================================================
437 //==========================================================================================================================================
438 bool CloseProcess( oC_Thread_t Thread, void * Process, uint32_t Parameter )
439 {
440  return oC_Process_Kill(Process);
441 }
442 
443 #undef _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
The file with interface for programs.
const char * Name
Definition: oc_stdlib.h:161
identifier for allocations
Definition: oc_stdlib.h:159
The file with interface for process manager.
Definition: oc_user.c:43
bool oC_MemMan_IsDynamicAllocatedAddress(const void *Address)
checks if address is in dynamic allocated section
Definition: oc_memman.c:1552
The file with interface for stream manager.
#define NULL
pointer to a zero
Definition: oc_null.h:37