00001
00002 #ifndef __FILES_POSIX_PAL_HPP__
00003 #define __FILES_POSIX_PAL_HPP__
00004
00005 #include <sys/types.h>
00006 #include <sys/stat.h>
00007 #include <fcntl.h>
00008 #include <unistd.h>
00009 #include <errno.h>
00010 #include <assert.h>
00011
00012 namespace lfc
00013 {
00014 namespace posixPAL
00015 {
00016
00018
00021 namespace files
00022 {
00023
00024 const int MAX_ERROR_CODE = 3;
00025
00026 enum ErrorCodes
00027 {
00028 errOk,
00029 errGeneric,
00030 errNotSupported,
00031 errAlreadyExists,
00032 };
00033
00034 extern const char *messagesTable[MAX_ERROR_CODE + 1];
00035
00036
00038 typedef int Handle;
00039
00041 const Handle NULL_HANDLE = -1;
00042
00044 const int
00045 seekSet = 0x0001,
00046 seekCurrent = 0x0002,
00047 seekEnd = 0x0004;
00048
00050 const int
00051 flAppend = 0x0001,
00052 flRead = 0x0002,
00053 flWrite = 0x0004,
00054 flTruncate = 0x0008,
00055 flOpenExisting = 0x0010,
00056 flCreateNew = 0x0020,
00057 flTemp = 0x0040;
00058
00060 const int
00061 shRead = 0x0001,
00062 shWrite = 0x0002;
00063
00064
00066
00069 inline int init()
00070 {
00071 return errOk;
00072 }
00073
00075
00078 inline int cleanup()
00079 {
00080 return errOk;
00081 }
00082
00084
00094 inline int open(Handle &handle, const char *name, int flags, int shareFlags)
00095 {
00096 int accessFlag = 0;
00097
00098 if( (accessFlag & flRead) && (accessFlag & flWrite) )
00099 accessFlag |= O_RDWR;
00100 else
00101 {
00102 accessFlag |= (flags & flRead ? O_RDONLY : 0);
00103 accessFlag |= (flags & flWrite ? O_WRONLY : 0);
00104 }
00105
00106 accessFlag |= (flags & flAppend ? O_APPEND : 0);
00107 accessFlag |= O_CREAT;
00108
00109 if(flags & flOpenExisting)
00110 accessFlag &= ~O_CREAT;
00111 else if(flags & flCreateNew)
00112 accessFlag |= O_EXCL;
00113 else if(flags & flTruncate)
00114 accessFlag |= O_TRUNC;
00115
00116
00117
00118 int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
00119
00120 Handle h = ::open(name, accessFlag, mode);
00121
00122 if(h == -1)
00123 if(errno == EEXIST)
00124 return errAlreadyExists;
00125 else
00126 return errGeneric;
00127
00128
00129 struct flock fileLock;
00130 int tmpShFlag = 0;
00131
00132 if( shareFlags & shRead || shareFlags & shWrite )
00133 {
00134 tmpShFlag |= (shareFlags & shRead ? F_RDLCK : 0);
00135 tmpShFlag |= (shareFlags & shWrite ? F_WRLCK : 0);
00136 }
00137 else
00138 tmpShFlag |= F_UNLCK;
00139
00140 fileLock.l_type = tmpShFlag;
00141 fileLock.l_whence = SEEK_SET;
00142 fileLock.l_start = 0;
00143 fileLock.l_len = 0;
00144 fileLock.l_pid = ::getpid();
00145
00146 if( ::fcntl( h, F_SETLK, &fileLock) == -1)
00147 {
00148 ::close(h);
00149 return errGeneric;
00150 }
00151
00152
00153
00154 handle = h;
00155 return errOk;
00156 }
00157
00159
00164 inline int close(Handle handle)
00165 {
00166 assert(handle != NULL_HANDLE);
00167 return ::close(handle) == 0 ? errOk : errGeneric;
00168 }
00169
00171
00179 inline int seek(Handle handle, long offset, int mode, long &pos)
00180 {
00181 int tmpMode = 0;
00182 switch(mode)
00183 {
00184 case seekSet: tmpMode = SEEK_SET; break;
00185 case seekCurrent: tmpMode = SEEK_CUR; break;
00186 case seekEnd: tmpMode = SEEK_END; break;
00187 }
00188
00189 long newPos = ::lseek(handle, offset, tmpMode);
00190
00191 if( newPos != -1 )
00192 {
00193 pos = newPos;
00194 return errOk;
00195 }
00196 else
00197 return errGeneric;
00198 }
00199
00201
00206 inline int setEof(Handle handle)
00207 {
00208 off_t pos;
00209
00210
00211 if((pos = ::lseek(handle, 0, SEEK_CUR)) == -1)
00212 return errGeneric;
00213
00214 if( ::ftruncate(handle, pos) == -1)
00215 return errGeneric;
00216
00217 return errOk;
00218 }
00219
00221
00229 inline int write(Handle handle, const void *buff, long count, long &written)
00230 {
00231 long temp = ::write(handle, buff, count);
00232
00233 if(temp != -1)
00234 {
00235 written = temp;
00236 return errOk;
00237 }
00238 else
00239 return errGeneric;
00240 }
00241
00243
00251 inline int read(Handle handle, void *buff, long count, long &read)
00252 {
00253 long temp = ::read(handle, buff, count);
00254
00255 if(temp != -1)
00256 {
00257 read = temp;
00258 return errOk;
00259 }
00260 else
00261 return errGeneric;
00262 }
00263
00264
00266
00270 inline int flush(Handle handle)
00271 {
00272 return ::fsync(handle) == 0 ? errOk : errGeneric;
00273 }
00274
00275
00277
00280 inline const char *message(int index)
00281 {
00282 assert(index >= 0 && index <= MAX_ERROR_CODE);
00283 return messagesTable[index];
00284 }
00285
00286
00287 }
00288 }
00289
00290 namespace pal = posixPAL;
00291
00292 }
00293
00294
00295 #endif // __FILES_POSIX_PAL_HPP__
00296
00297