Changeset 917 for trunk/zoo-project/zoo-kernel/service_internal.c
- Timestamp:
- May 7, 2019, 2:17:08 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property
svn:mergeinfo
set to
False
/branches/prototype-v0 merged eligible
-
Property
svn:mergeinfo
set to
False
-
trunk/zoo-project/zoo-kernel/service_internal.c
r889 r917 2 2 * Author : Gérald FENOY 3 3 * 4 * Copyright (c) 2009-201 5GeoLabs SARL4 * Copyright (c) 2009-2018 GeoLabs SARL 5 5 * 6 6 * Permission is hereby granted, free of charge, to any person obtaining a copy … … 31 31 #include "service_internal.h" 32 32 33 #ifndef TRUE 34 #define TRUE 1 35 #endif 36 #ifndef FALSE 37 #define FALSE -1 38 #endif 39 33 #ifdef WIN32 34 // ref. https://docs.microsoft.com/en-us/windows/desktop/fileio/locking-and-unlocking-byte-ranges-in-files 35 __inline int fcntl(int fd, int cmd, ...) 36 { 37 va_list a; 38 va_start(a, cmd); 39 switch(cmd) 40 { 41 case F_SETLK: 42 { 43 HANDLE h = (HANDLE)_get_osfhandle(fd); 44 struct flock* l= va_arg(a, struct flock*); 45 OVERLAPPED sOverlapped; 46 sOverlapped.Offset = 0; 47 sOverlapped.OffsetHigh = 0; 48 switch(l->l_type) 49 { 50 case F_RDLCK: 51 { 52 if (!LockFileEx(h, LOCKFILE_FAIL_IMMEDIATELY, 0, l->l_len, 0, &sOverlapped)) 53 { 54 _set_errno(GetLastError() == ERROR_LOCK_VIOLATION ? EAGAIN : EBADF); 55 return -1; 56 } 57 } 58 break; 59 case F_WRLCK: 60 { 61 if (!LockFileEx(h, LOCKFILE_FAIL_IMMEDIATELY|LOCKFILE_EXCLUSIVE_LOCK, 0, l->l_len, 0, &sOverlapped)) 62 { 63 _set_errno(GetLastError() == ERROR_LOCK_VIOLATION ? EAGAIN : EBADF); 64 return -1; 65 } 66 } 67 break; 68 case F_UNLCK: 69 { 70 UnlockFileEx(h, 0, l->l_len, 0, &sOverlapped); 71 } 72 break; 73 default: 74 _set_errno(ENOTSUP); 75 return -1; 76 } 77 } 78 break; 79 default: 80 _set_errno(ENOTSUP); 81 return -1; 82 } 83 return 0; 84 } 85 #endif 40 86 #define ERROR_MSG_MAX_LENGTH 1024 87 88 /** 89 * Lock a file for read, write and upload. 90 * @param conf the main configuration maps 91 * @param filename the file to lock 92 * @param mode define access: 'r' for read, 'w' for write 93 * @return a new zooLock structure on sucess, NULL on failure 94 */ 95 struct zooLock* lockFile(maps* conf,const char* filename,const char mode){ 96 struct stat f_status; 97 int itn=0; 98 int s; 99 struct zooLock* myLock=(struct zooLock*)malloc(sizeof(struct flock)+sizeof(FILE*)+sizeof(char*)); 100 int len=6; 101 char *myTemplate="%s.lock"; 102 int res=-1; 103 retryLockFile: 104 myLock->filename=(char*)malloc((strlen(filename)+len)*sizeof(char)); 105 sprintf(myLock->filename,myTemplate,filename); 106 s=stat(myLock->filename, &f_status); 107 if(s==0 && mode!='r'){ 108 if(itn<ZOO_LOCK_MAX_RETRY){ 109 itn++; 110 #ifdef DEBUG 111 fprintf(stderr,"(%d) Wait for write lock on %s, tried %d times (sleep) ... \n",zGetpid(),myLock->filename,itn); 112 fflush(stderr); 113 #endif 114 zSleep(5); 115 free(myLock->filename); 116 goto retryLockFile; 117 }else{ 118 free(myLock->filename); 119 free(myLock); 120 return NULL; 121 } 122 }else{ 123 char local_mode[3]; 124 memset(local_mode,0,3); 125 if(mode=='w') 126 sprintf(local_mode,"%c+",mode); 127 else 128 sprintf(local_mode,"%c",mode); 129 myLock->lockfile=fopen(myLock->filename,local_mode); 130 char tmp[512]; 131 sprintf(tmp,"%d",zGetpid()); 132 if(myLock->lockfile==NULL){ 133 myLock->lockfile=fopen(myLock->filename,"w+"); 134 fwrite(tmp,sizeof(char),strlen(tmp),myLock->lockfile); 135 fflush(myLock->lockfile); 136 fclose(myLock->lockfile); 137 myLock->lockfile=fopen(myLock->filename,local_mode); 138 }/*else 139 fprintf(stderr,"%s %d %d\n",__FILE__,__LINE__,(myLock->lockfile==NULL));*/ 140 if(mode!='r'){ 141 fwrite(tmp,sizeof(char),strlen(tmp),myLock->lockfile); 142 fflush(myLock->lockfile); 143 } 144 int cnt=0; 145 if(mode=='r'){ 146 myLock->lock.l_type = F_RDLCK; 147 }else 148 myLock->lock.l_type = F_WRLCK; 149 myLock->lock.l_whence = 0; 150 myLock->lock.l_start = 0; 151 myLock->lock.l_len = strlen(tmp)*sizeof(char); 152 while (true) { 153 if((res=fcntl(fileno(myLock->lockfile), F_SETLK, &(myLock->lock)))==-1 && 154 (errno==EAGAIN || errno==EACCES)){ 155 if(cnt >= ZOO_LOCK_MAX_RETRY){ 156 char message[51]; 157 sprintf(message,"Unable to get the lock after %d attempts.\n",cnt); 158 setMapInMaps(conf,"lenv","message",message); 159 fclose(myLock->lockfile); 160 free(myLock->filename); 161 free(myLock); 162 return NULL; 163 } 164 #ifdef DEBUG 165 fprintf(stderr,"(%d) Wait for lock on %s, tried %d times ... \n",zGetpid(),myLock->filename,cnt); 166 fflush(stderr); 167 #endif 168 zSleep(1); 169 cnt++; 170 }else 171 break; 172 } 173 if(res<0){ 174 char *tmp; 175 if(errno==EBADF) 176 tmp="Either: the filedes argument is invalid; you requested a read lock but the filedes is not open for read access; or, you requested a write lock but the filedes is not open for write access."; 177 else 178 if(errno==EINVAL) 179 tmp="Either the lockp argument doesn’t specify valid lock information, or the file associated with filedes doesn’t support locks."; 180 else 181 tmp="The system has run out of file lock resources; there are already too many file locks in place."; 182 #ifdef DEBUG 183 fprintf(stderr,"Unable to get the lock on %s due to the following error: %s\n",myLock->filename,tmp); 184 #endif 185 return NULL; 186 } 187 return myLock; 188 } 189 } 190 191 /** 192 * Remove a lock. 193 * @param conf the main configuration maps 194 * @param s the zooLock structure 195 * @return 0 on success, -1 on failure. 196 */ 197 int unlockFile(maps* conf,struct zooLock* s){ 198 int res=-1; 199 if(s!=NULL){ 200 s->lock.l_type = F_UNLCK; 201 res=fcntl(fileno(s->lockfile), F_SETLK, &s->lock); 202 if(res==-1) 203 return res; 204 fclose(s->lockfile); 205 #ifndef WIN32 206 // Check if there is any process locking a file and delete the lock if not. 207 s->lock.l_type = F_WRLCK; 208 if(fcntl(fileno(s->lockfile), F_GETLK, &s->lock)!=-1 && s->lock.l_type == F_UNLCK){ 209 #endif 210 zUnlink(s->filename); 211 #ifndef WIN32 212 } 213 #endif 214 free(s->filename); 215 free(s); 216 } 217 return res; 218 } 219 41 220 #ifndef RELY_ON_DB 42 #include <dirent.h>221 #include "dirent.h" 43 222 44 223 /** … … 148 327 149 328 //FILE* f0 = fopen (fileName, "r"); 150 151 329 // knut: open file in binary mode to avoid conversion of line endings (yielding extra bytes) on Windows platforms 330 FILE* f0 = fopen(fileName, "rb"); 152 331 if(f0!=NULL){ 153 332 fseek (f0, 0, SEEK_END); … … 162 341 free(stat); 163 342 } 164 165 343 return tmps1; 166 344 } … … 250 428 * sizeof (char)); 251 429 sprintf (fbkpid, "%s/%s.status", r_inputs->value, usid->value); 252 unlink(fbkpid);430 zUnlink(fbkpid); 253 431 free(fbkpid); 254 432 } … … 510 688 } 511 689 } 690 setMapInMaps(conf,"lenv","semaphore","Created"); 512 691 } else if (errno == EEXIST) { /* someone else got it first */ 513 692 int ready = 0; … … 529 708 fprintf(stderr,"Retry to access the semaphore later ...\n"); 530 709 #endif 531 zSleep(1 );710 zSleep(1000); 532 711 } 533 712 } … … 540 719 return -1; 541 720 } 721 setMapInMaps(conf,"lenv","semaphore","Acquired"); 542 722 } else { 543 723 return sem_id; /* error, check errno */ … … 739 919 } 740 920 921 /** 922 * Check if file exists in specified folder 923 * 924 * @param dir the folder in which to search for file 925 * @param name the name of the file (not full path) 926 * @return a character string with the full path [dir/name], or NULL if the file does not exist 927 * 928 * @attention Caller is responsible for applying free() to the returned pointer 929 */ 930 char* file_exists(const char* dir, const char* name) { 931 const char* d = (dir != NULL ? dir : "."); 932 if (name != NULL) { 933 size_t length = strlen(d) + strlen(name) + 2; // including file separator and \0 character 934 char* path = (char*)calloc(length, sizeof(char)); 935 snprintf(path, length, "%s/%s", d, name); 936 937 struct stat buffer; 938 if (stat(path, &buffer) != 0) { 939 free(path); 940 path = NULL; 941 } 942 return path; 943 } 944 else { 945 return NULL; 946 } 947 }
Note: See TracChangeset
for help on using the changeset viewer.