source: trunk/zoo-project/zoo-kernel/service_internal.c @ 800

Last change on this file since 800 was 788, checked in by knut, 8 years ago

Implemented support for PHP 7: The Zend API for PHP 7/PHPNG is substantially different from older versions. Therefore, an alternative implementation of zoo_php_support is provided in the new source file service_internal_php7.c. Presently the Zoo kernel can be built with support for either PHP 7 or older versions, see the makefiles (for Windows) nmake.opt and makefile.vc. Other makefiles have not been updated.

Fixed problem with ambiguous symbol in service_conf.y. Fixed problem with conversion of line endings yielding extra bytes in _getStatusFile on Windows platforms. Removed call to free() stack memory in zoo_service_loader.c. Fixed issue with size of structs in service.h.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 18.6 KB
Line 
1/*
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2009-2015 GeoLabs SARL
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#define _LARGEFILE64_SOURCE 1
26#ifdef USE_MS
27#include "service_internal_ms.h"
28#else
29#include "cpl_vsi.h"
30#endif
31#include "service_internal.h"
32
33#ifndef TRUE
34#define TRUE 1
35#endif
36#ifndef FALSE
37#define FALSE -1
38#endif
39
40#define ERROR_MSG_MAX_LENGTH 1024
41#ifndef RELY_ON_DB
42#include <dirent.h>
43
44/**
45 * Read the sid file attached of a service if any
46 *
47 * @param conf the maps containing the setting of the main.cfg file
48 * @param pid the service identifier (usid key from the [lenv] section)
49 * @return the reported status char* (temporary/final result)
50 */
51char* getStatusId(maps* conf,char* pid){
52  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
53  char* fbkpid =
54    (char *)
55    malloc ((strlen (r_inputs->value) + strlen (pid) + 7) * sizeof (char));
56  sprintf (fbkpid, "%s/%s.sid", r_inputs->value, pid);
57  FILE* f0 = fopen (fbkpid, "r");
58  if(f0!=NULL){
59    long flen;
60    char *fcontent;
61    fseek (f0, 0, SEEK_END);
62    flen = ftell (f0);
63    fseek (f0, 0, SEEK_SET);
64    fcontent = (char *) malloc ((flen + 1) * sizeof (char));
65    fread(fcontent,flen,1,f0);
66    fcontent[flen]=0;
67    fclose(f0);
68    return fcontent;
69  }else
70    return NULL;
71}
72
73/**
74 * Acquire the global lock
75 *
76 * @param conf the maps containing the setting of the main.cfg file
77 * @return a semid
78 */
79semid acquireLock(maps* conf){
80  semid lockid;
81  int itn=0;
82 toRetry1:
83  lockid=getShmLockId(conf,1);
84  if(
85#ifdef WIN32
86     lockid==NULL
87#else
88     lockid<0
89#endif
90     ){
91#ifdef WIN32
92    return NULL;
93#else
94    return -1;
95#endif
96  }
97  if(lockShm(lockid)<0){
98#ifdef WIN32
99      return NULL;
100#else
101    if(itn<ZOO_LOCK_MAX_RETRY){
102      itn++;
103      goto toRetry1;
104    }else
105      return -1;
106#endif
107  }else
108    return lockid;
109}
110
111/**
112 * Read the cache file of a running service
113 *
114 * @param conf the maps containing the setting of the main.cfg file
115 * @param pid the service identifier (usid key from the [lenv] section)
116 * @return the reported status char* (temporary/final result)
117 */
118char* _getStatusFile(maps* conf,char* pid){
119  map* tmpTmap = getMapFromMaps (conf, "main", "tmpPath");
120
121  struct dirent *dp;
122  DIR *dirp = opendir(tmpTmap->value);
123  char fileName[1024];
124  int hasFile=-1;
125  if(dirp!=NULL){
126    char tmp[128];
127    sprintf(tmp,"_%s.xml",pid);
128    while ((dp = readdir(dirp)) != NULL){
129#ifdef DEBUG
130      fprintf(stderr,"File : %s searched : %s\n",dp->d_name,tmp);
131#endif
132      if(strstr(dp->d_name,"final_")==0 && strstr(dp->d_name,tmp)!=0){
133        sprintf(fileName,"%s/%s",tmpTmap->value,dp->d_name);
134        hasFile=1;
135        break;
136      }
137    }
138  }
139  if(hasFile>0){
140    semid lockid;
141    char* stat=getStatusId(conf,pid);
142    if(stat!=NULL){
143      setMapInMaps(conf,"lenv","lid",stat);
144      lockid=acquireLock(conf);
145      if(lockid<0)
146        return NULL;
147    }
148
149    //FILE* f0 = fopen (fileName, "r");
150        // knut: open file in binary mode to avoid conversion of line endings (yielding extra bytes) on Windows platforms
151        FILE* f0 = fopen(fileName, "rb"); 
152    if(f0!=NULL){
153      fseek (f0, 0, SEEK_END);
154      long flen = ftell (f0);
155      fseek (f0, 0, SEEK_SET);
156      char *tmps1 = (char *) malloc ((flen + 1) * sizeof (char));
157      fread(tmps1,flen,1,f0);
158      tmps1[flen]=0;
159      fclose(f0);
160      if(stat!=NULL){
161        unlockShm(lockid);
162        free(stat);
163      }
164
165      return tmps1;
166    }
167    else{
168      if(stat!=NULL){
169        unlockShm(lockid);
170        free(stat);
171      }
172      return NULL;
173    }
174  }
175  else
176    return NULL;
177}
178
179/**
180 * Get the ongoing status of a running service
181 *
182 * @param conf the maps containing the setting of the main.cfg file
183 * @param pid the service identifier (usid key from the [lenv] section)
184 * @return the reported status char* (MESSAGE|POURCENTAGE)
185 */
186char* _getStatus(maps* conf,char* lid){
187  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
188  char* fbkpid =
189    (char *)
190    malloc ((strlen (r_inputs->value) + strlen (lid) + 9) * sizeof (char));
191  sprintf (fbkpid, "%s/%s.status", r_inputs->value, lid);
192  FILE* f0 = fopen (fbkpid, "r");
193  if(f0!=NULL){   
194    semid lockid = NULL;
195    char* stat;
196    long flen;
197    stat=getStatusId(conf,lid);
198    if(stat!=NULL){
199      setMapInMaps(conf,"lenv","lid",stat);
200      lockid=acquireLock(conf);
201      if(lockid<0)
202        return NULL;
203    }
204    fseek (f0, 0, SEEK_END);
205    flen = ftell (f0);
206    if(flen>0){
207      char *fcontent;
208      fseek (f0, 0, SEEK_SET);
209      fcontent = (char *) malloc ((flen + 1) * sizeof (char));
210      fread(fcontent,flen,1,f0);
211      fcontent[flen]=0;
212      fclose(f0);
213      free(fbkpid);
214      if(stat!=NULL){
215#ifndef WIN32
216        removeShmLock(conf,1);
217#else
218        unlockShm(lockid);
219#endif
220        free(stat);
221      }
222      return fcontent;
223    }
224    fclose(f0);
225    free(fbkpid);
226    if(stat!=NULL){
227      removeShmLock(conf,1);
228      free(stat);
229    }
230    return NULL;
231  }else{
232    free(fbkpid);
233    char* stat=getStatusId(conf,lid);
234    setMapInMaps(conf,"lenv","lid",stat);
235    removeShmLock(conf,1);
236    return NULL;
237  }
238}
239
240/**
241 * Stop handling status repport.
242 *
243 * @param conf the map containing the setting of the main.cfg file
244 */
245void unhandleStatus(maps *conf){
246  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
247  map* usid = getMapFromMaps (conf, "lenv", "usid");
248  char* fbkpid =
249    (char *) malloc ((strlen (r_inputs->value) + strlen (usid->value) + 9) 
250                     * sizeof (char));
251  sprintf (fbkpid, "%s/%s.status", r_inputs->value, usid->value);
252  unlink(fbkpid);
253  free(fbkpid);
254}
255
256/**
257 * Update the current status of the running service.
258 *
259 * @see acquireLock, lockShm
260 * @param conf the map containing the setting of the main.cfg file
261 * @return 0 on success, -2 if shmget failed, -1 if shmat failed
262 */
263int _updateStatus(maps *conf){
264       
265  map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
266  map* sid = getMapFromMaps (conf, "lenv", "usid");
267 
268  char* fbkpid =
269    (char *)
270    malloc ((strlen (r_inputs->value) + strlen (sid->value) + 9) * sizeof (char));
271  sprintf (fbkpid, "%s/%s.status", r_inputs->value, sid->value);
272  map* status=getMapFromMaps(conf,"lenv","status");
273  map* msg=getMapFromMaps(conf,"lenv","message");
274  if(status!=NULL && msg!=NULL &&
275     status->value!=NULL && msg->value!=NULL && 
276     strlen(status->value)>0 && strlen(msg->value)>1){   
277    semid lockid = NULL;
278       
279    char* stat=getStatusId(conf,sid->value);
280    if(stat!=NULL){
281      lockid=acquireLock(conf);
282      if(lockid<0){
283        dumpMap(status);
284        return ZOO_LOCK_ACQUIRE_FAILED;
285      }
286    }
287    FILE* fstatus=fopen(fbkpid,"w");
288    if(fstatus!=NULL){
289      fprintf(fstatus,"%s|%s",status->value,msg->value);
290      fflush(fstatus);
291      fclose(fstatus);
292    }
293    if(stat!=NULL){
294      unlockShm(lockid);
295      free(stat);
296    }
297  }
298
299  return 0;
300}
301
302#endif
303
304#ifdef WIN32
305
306#define SHMEMSIZE 4096
307
308size_t getKeyValue(maps* conf, char* key, size_t length){
309  if(conf==NULL) {
310    strncpy(key, "700666", length);
311    return strlen(key);
312  }
313 
314  map *tmpMap=getMapFromMaps(conf,"lenv","lid");
315  if(tmpMap==NULL)
316    tmpMap=getMapFromMaps(conf,"lenv","osid");
317
318  if(tmpMap!=NULL){
319    snprintf(key, length, "zoo_sem_%s", tmpMap->value);     
320  }
321  else {
322    strncpy(key, "-1", length);
323  }
324  return strlen(key);
325}
326
327
328semid getShmLockId(maps* conf, int nsems){
329  semid sem_id;
330  char key[MAX_PATH];
331  getKeyValue(conf, key, MAX_PATH);
332 
333  sem_id = CreateSemaphore( NULL, nsems, nsems+1, key);
334  if(sem_id==NULL){
335#ifdef DEBUG
336    fprintf(stderr,"Semaphore failed to create: %s\n", getLastErrorMessage());
337#endif
338    return NULL;
339  }
340#ifdef DEBUG
341  fprintf(stderr,"%s Accessed !\n",key);
342#endif
343  return sem_id;
344}
345
346int removeShmLock(maps* conf, int nsems){
347  semid sem_id=getShmLockId(conf,1);
348  if (CloseHandle(sem_id) == 0) {
349#ifdef DEBUG
350    fprintf(stderr,"Unable to remove semaphore: %s\n", getLastErrorMessage());
351#endif
352    return -1;
353  }
354#ifdef DEBUG
355  fprintf(stderr,"%d Removed !\n",sem_id);
356#endif
357  return 0;
358}
359
360int lockShm(semid id){
361  DWORD dwWaitResult=WaitForSingleObject(id,INFINITE);
362  switch (dwWaitResult){
363    case WAIT_OBJECT_0:
364      return 0;
365      break;
366    case WAIT_TIMEOUT:
367      return -1;
368      break;
369    default:
370      return -2;
371      break;
372  }
373  return 0;
374}
375
376int unlockShm(semid id){
377  if(!ReleaseSemaphore(id,1,NULL)){
378    return -1;
379  }
380  return 0;
381}
382
383static LPVOID lpvMemG = NULL;      // pointer to shared memory
384static HANDLE hMapObjectG = NULL;  // handle to file mapping
385
386
387char* getStatus(int pid){
388  char *lpszBuf=(char*) malloc(SHMEMSIZE*sizeof(char));
389  int i=0;
390  LPWSTR lpszTmp=NULL;
391  LPVOID lpvMem = NULL;
392  HANDLE hMapObject = NULL;
393  BOOL fIgnore,fInit;
394  char tmp[1024];
395  sprintf(tmp,"%d",pid);
396  if(hMapObject==NULL)
397    hMapObject = CreateFileMapping( 
398                                   INVALID_HANDLE_VALUE,   // use paging file
399                                   NULL,                   // default security attributes
400                                   PAGE_READWRITE,         // read/write access
401                                   0,                      // size: high 32-bits
402                                   4096,                   // size: low 32-bits
403                                   TEXT(tmp));   // name of map object
404  if (hMapObject == NULL){
405#ifdef DEBUG
406    fprintf(stderr,"ERROR on line %d\n",__LINE__);
407#endif
408    return "-1";
409  }
410  if((GetLastError() != ERROR_ALREADY_EXISTS)){
411#ifdef DEBUG
412    fprintf(stderr,"ERROR on line %d\n",__LINE__);
413    fprintf(stderr,"READING STRING S %s\n", getLastErrorMessage());
414#endif
415    fIgnore = UnmapViewOfFile(lpvMem); 
416    fIgnore = CloseHandle(hMapObject);
417    return "-1";
418  }
419  fInit=TRUE;
420  if(lpvMem==NULL)
421    lpvMem = MapViewOfFile( 
422                           hMapObject,     // object to map view of
423                           FILE_MAP_READ,  // read/write access
424                           0,              // high offset:  map from
425                           0,              // low offset:   beginning
426                           0);             // default: map entire file
427  if (lpvMem == NULL){
428#ifdef DEBUG
429    fprintf(stderr,"READING STRING S %d\n",__LINE__);
430    fprintf(stderr,"READING STRING S %s\n", getLastErrorMessage());
431#endif
432    return "-1"; 
433  }
434  lpszTmp = (LPWSTR) lpvMem;
435  while (*lpszTmp){
436    lpszBuf[i] = (char)*lpszTmp;
437    *lpszTmp++; 
438    lpszBuf[i+1] = '\0'; 
439    i++;
440  }
441  return (char*)lpszBuf;
442}
443
444#else
445/**
446 * Number of time to try to access a semaphores set
447 * @see getShmLockId
448 */
449#define MAX_RETRIES 10
450
451#ifndef __APPLE__
452/**
453 * arg for semctl system calls.
454 */
455union semun {
456  int val; //!< value for SETVAL
457  struct semid_ds *buf; //!< buffer for IPC_STAT & IPC_SET
458  ushort *array; //!< array for GETALL & SETALL
459};
460#endif
461
462/**
463 * Set in the pre-allocated key the zoo_sem_[OSID] string
464 * where [OSID] is the lid (if any) or osid value from the [lenv] section.
465 *
466 * @param conf the map containing the setting of the main.cfg file
467 */
468int getKeyValue(maps* conf){
469  if(conf==NULL)
470     return 700666;
471  map *tmpMap=getMapFromMaps(conf,"lenv","lid");
472  if(tmpMap==NULL)
473    tmpMap=getMapFromMaps(conf,"lenv","osid");
474  int key=-1;
475  if(tmpMap!=NULL)
476    key=atoi(tmpMap->value);
477  return key;
478}
479
480/**
481 * Try to create or access a semaphore set.
482 *
483 * @see getKeyValue
484 * @param conf the map containing the setting of the main.cfg file
485 * @param nsems number of semaphores
486 * @return a semaphores set indentifier on success, -1 in other case
487 */
488int getShmLockId(maps* conf, int nsems){
489    int i;
490    union semun arg;
491    struct semid_ds buf;
492    struct sembuf sb;
493    semid sem_id;
494    int key=getKeyValue(conf);
495   
496    sem_id = semget(key, nsems, IPC_CREAT | IPC_EXCL | 0666);
497
498    if (sem_id >= 0) { /* we got it first */
499        sb.sem_op = 1; 
500        sb.sem_flg = 0;
501        arg.val=1;
502        for(sb.sem_num = 0; sb.sem_num < nsems; sb.sem_num++) { 
503            /* do a semop() to "free" the semaphores. */
504            /* this sets the sem_otime field, as needed below. */
505            if (semop(sem_id, &sb, 1) == -1) {
506                int e = errno;
507                semctl(sem_id, 0, IPC_RMID); /* clean up */
508                errno = e;
509                return -1; /* error, check errno */
510            }
511        }
512    } else if (errno == EEXIST) { /* someone else got it first */
513        int ready = 0;
514
515        sem_id = semget(key, nsems, 0); /* get the id */
516        if (sem_id < 0) return sem_id; /* error, check errno */
517
518        /* wait for other process to initialize the semaphore: */
519        arg.buf = &buf;
520        for(i = 0; i < MAX_RETRIES && !ready; i++) {
521            semctl(sem_id, nsems-1, IPC_STAT, arg);
522            if (arg.buf->sem_otime != 0) {
523#ifdef DEBUG
524              fprintf(stderr,"Semaphore acquired ...\n");
525#endif
526              ready = 1;
527            } else {
528#ifdef DEBUG
529              fprintf(stderr,"Retry to access the semaphore later ...\n");
530#endif
531              zSleep(1);
532            }
533        }
534        errno = ZOO_LOCK_ACQUIRE_FAILED;
535        if (!ready) {
536#ifdef DEBUG
537          fprintf(stderr,"Unable to access the semaphore ...\n");
538#endif
539          errno = ETIME;
540          return -1;
541        }
542    } else {
543        return sem_id; /* error, check errno */
544    }
545#ifdef DEBUG
546    fprintf(stderr,"%d Created !\n",sem_id);
547#endif
548    return sem_id;
549}
550
551/**
552 * Try to remove a semaphore set.
553 *
554 * @param conf the map containing the setting of the main.cfg file
555 * @param nsems number of semaphores
556 * @return 0 if the semaphore can be removed, -1 in other case.
557 */
558int removeShmLock(maps* conf, int nsems){
559  union semun arg;
560  int sem_id=getShmLockId(conf,nsems);
561  if (semctl(sem_id, 0, IPC_RMID, arg) == -1) {
562#ifdef DEBUG
563    perror("semctl remove");
564#endif
565    return -1;
566  }
567#ifdef DEBUG
568  fprintf(stderr,"Semaphore removed!\n");
569#endif
570  return 0;
571}
572
573/**
574 * Lock a semaphore set.
575 *
576 * @param id the semaphores set indetifier
577 * @return 0 if the semaphore can be locked, -1 in other case.
578 */
579int lockShm(int id){
580  struct sembuf sb;
581  sb.sem_num = 0;
582  sb.sem_op = -1;  /* set to allocate resource */
583  sb.sem_flg = SEM_UNDO;
584  if (semop(id, &sb, 1) == -1){
585#ifdef DEBUG
586    perror("semop lock");
587#endif
588    return -1;
589  }
590  return 0;
591}
592
593/**
594 * unLock a semaphore set.
595 *
596 * @param id the semaphores set indetifier
597 * @return 0 if the semaphore can be locked, -1 in other case.
598 */
599int unlockShm(int id){
600  struct sembuf sb;
601  sb.sem_num = 0;
602  sb.sem_op = 1;  /* free resource */
603  sb.sem_flg = SEM_UNDO;
604  if (semop(id, &sb, 1) == -1) {
605#ifdef DEBUG
606    perror("semop unlock");
607#endif
608    return -1;
609  }
610  return 0;
611}
612
613/**
614 * Get the current status of the running service.
615 *
616 * @see getKeyValue, getShmLockId, lockShm
617 * @param pid the semaphores
618 * @return 0 on success, -2 if shmget failed, -1 if shmat failed
619 */
620char* getStatus(int pid){
621  int shmid;
622  key_t key;
623  void *shm;
624  key=pid;
625  if ((shmid = shmget(key, SHMSZ, 0666)) < 0) {
626#ifdef DEBUG
627    fprintf(stderr,"shmget failed in getStatus\n");
628#endif
629  }else{
630    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
631#ifdef DEBUG
632      fprintf(stderr,"shmat failed in getStatus\n");
633#endif
634    }else{
635      char *ret=strdup((char*)shm);
636      shmdt((void *)shm);
637      return ret;
638    }
639  }
640  return (char*)"-1";
641}
642
643#endif
644
645/**
646 * Update the status of an ongoing service
647 *
648 * @param conf the maps containing the settings of the main.cfg file
649 * @param percentCompleted percentage of completude of execution of the service
650 * @param message information about the current step executed
651 * @return the value of _updateStatus
652 * @see _updateStatus
653 */
654int updateStatus( maps* conf, const int percentCompleted, const char* message ){
655  char tmp[4];
656  snprintf(tmp,4,"%d",percentCompleted);
657  setMapInMaps( conf, "lenv", "status", tmp );
658  setMapInMaps( conf, "lenv", "message", message);
659  return _updateStatus( conf );
660}
661
662/**
663 * Access an input value
664 *
665 * @param inputs the maps to search for the input value
666 * @param parameterName the input name to fetch the value
667 * @param numberOfBytes the resulting size of the value to add (for binary
668 *  values), -1 for basic char* data
669 * @return a pointer to the input value if found, NULL in other case.
670 */
671char* getInputValue( maps* inputs, const char* parameterName, size_t* numberOfBytes){
672  map* res=getMapFromMaps(inputs,parameterName,"value");
673  if(res!=NULL){
674    map* size=getMapFromMaps(inputs,parameterName,"size");
675    if(size!=NULL){
676      *numberOfBytes=(size_t)atoi(size->value);
677      return res->value;
678    }else{
679      *numberOfBytes=strlen(res->value);
680      return res->value;
681    }
682  }
683  return NULL;
684}
685
686/**
687 * Read a file using the GDAL VSI API
688 *
689 * @param conf the maps containing the settings of the main.cfg file
690 * @param dataSource the datasource name to read
691 * @warning make sure to free resources returned by this function
692 */
693char *readVSIFile(maps* conf,const char* dataSource){
694    VSILFILE * fichier=VSIFOpenL(dataSource,"rb");
695    VSIStatBufL file_status;
696    VSIStatL(dataSource, &file_status);
697    if(fichier==NULL){
698      char tmp[1024];
699      sprintf(tmp,"Failed to open file %s for reading purpose. File seems empty %lld.",
700              dataSource,file_status.st_size);
701      setMapInMaps(conf,"lenv","message",tmp);
702      return NULL;
703    }
704    char *res1=(char *)malloc(file_status.st_size*sizeof(char));
705    VSIFReadL(res1,1,file_status.st_size*sizeof(char),fichier);
706    res1[file_status.st_size-1]=0;
707    VSIFCloseL(fichier);
708    VSIUnlink(dataSource);
709    return res1;
710}
711
712/**
713 * Set an output value
714 *
715 * @param outputs the maps to define the output value
716 * @param parameterName the output name to set the value
717 * @param data the value to set
718 * @param numberOfBytes size of the value to add (for binary values), -1 for
719 *  basic char* data
720 * @return 0
721 */
722int  setOutputValue( maps* outputs, const char* parameterName, char* data, size_t numberOfBytes ){
723  if(numberOfBytes==-1){
724    setMapInMaps(outputs,parameterName,"value",data);
725  }else{
726    char size[1024];
727    map* tmp=getMapFromMaps(outputs,parameterName,"value");
728    if(tmp==NULL){
729      setMapInMaps(outputs,parameterName,"value","");
730      tmp=getMapFromMaps(outputs,parameterName,"value");
731    }
732    free(tmp->value);
733    tmp->value=(char*) malloc((numberOfBytes+1)*sizeof(char));
734    memcpy(tmp->value,data,numberOfBytes);
735    sprintf(size,"%lu",numberOfBytes);
736    setMapInMaps(outputs,parameterName,"size",size);
737  }
738  return 0;
739}
740
Note: See TracBrowser for help on using the repository browser.

Search

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png