00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #include "w_defines.h"
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 #if defined(linux) && !defined(_GNU_SOURCE)
00070
00071
00072
00073
00074
00075 #define _GNU_SOURCE
00076 #endif
00077
00078 #include <w.h>
00079 #include <sthread.h>
00080 #include <sdisk.h>
00081 #include <sdisk_unix.h>
00082 #include <sthread_stats.h>
00083 extern class sthread_stats SthreadStats;
00084
00085 #include "os_fcntl.h"
00086 #include <cerrno>
00087 #include <sys/stat.h>
00088
00089 #include <sys/uio.h>
00090
00091 #define HAVE_IO_VECTOR
00092
00093
00094
00095
00096 #include <os_interface.h>
00097
00098
00099 const int stBADFD = sthread_base_t::stBADFD;
00100
00101 int sdisk_unix_t::convert_flags(int sflags)
00102 {
00103 int flags = 0;
00104
00105
00106 switch (modeBits(sflags)) {
00107 case OPEN_RDWR:
00108 flags |= O_RDWR;
00109 break;
00110 case OPEN_WRONLY:
00111 flags |= O_WRONLY;
00112 break;
00113 case OPEN_RDONLY:
00114 flags |= O_RDONLY;
00115 break;
00116 }
00117
00118
00119
00120 if (hasOption(sflags, OPEN_CREATE))
00121 flags |= O_CREAT;
00122 if (hasOption(sflags, OPEN_TRUNC))
00123 flags |= O_TRUNC;
00124 if (hasOption(sflags, OPEN_EXCL))
00125 flags |= O_EXCL;
00126 #ifdef O_SYNC
00127 if (hasOption(sflags, OPEN_SYNC))
00128 flags |= O_SYNC;
00129 #endif
00130 if (hasOption(sflags, OPEN_APPEND))
00131 flags |= O_APPEND;
00132 #ifdef O_DIRECT
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 if (hasOption(sflags, OPEN_RAW))
00148 flags |= O_DIRECT;
00149 #endif
00150
00151 return flags;
00152 }
00153
00154
00155 sdisk_unix_t::~sdisk_unix_t()
00156 {
00157 if (_fd != FD_NONE)
00158 W_COERCE(close());
00159 }
00160
00161
00162 w_rc_t sdisk_unix_t::make(const char *name, int flags, int mode,
00163 sdisk_t *&disk)
00164 {
00165 sdisk_unix_t *ud;
00166 w_rc_t e;
00167
00168 disk = 0;
00169
00170 ud = new sdisk_unix_t(name);
00171 if (!ud)
00172 return RC(fcOUTOFMEMORY);
00173
00174 e = ud->open(name, flags, mode);
00175 if (e.is_error()) {
00176 delete ud;
00177 return e;
00178 }
00179
00180 disk = ud;
00181 return RCOK;
00182 }
00183
00184
00185 w_rc_t sdisk_unix_t::open(const char *name, int flags, int mode)
00186 {
00187 if (_fd != FD_NONE)
00188 return RC(stBADFD);
00189
00190 _fd = ::os_open(name, convert_flags(flags), mode);
00191 if (_fd == -1) {
00192 w_rc_t rc = RC(fcOS);
00193 RC_APPEND_MSG(rc, << "Offending file: " << name);
00194 return rc;
00195 }
00196
00197 return RCOK;
00198 }
00199
00200 w_rc_t sdisk_unix_t::close()
00201 {
00202 if (_fd == FD_NONE)
00203 return RC(stBADFD);
00204
00205 int n;
00206
00207 n = ::os_close(_fd);
00208 if (n == -1)
00209 return RC(fcOS);
00210
00211 _fd = FD_NONE;
00212 return RCOK;
00213 }
00214
00215
00216
00217
00218 w_rc_t sdisk_unix_t::read(void *buf, int count, int &done)
00219 {
00220 if (_fd == FD_NONE)
00221 return RC(stBADFD);
00222
00223 int n;
00224 n = ::os_read(_fd, buf, count);
00225 if (n == -1)
00226 return RC(fcOS);
00227
00228 done = n;
00229
00230 return RCOK;
00231 }
00232
00233 w_rc_t sdisk_unix_t::write(const void *buf, int count, int &done)
00234 {
00235 if (_fd == FD_NONE)
00236 return RC(stBADFD);
00237
00238 int n;
00239
00240 n = ::os_write(_fd, buf, count);
00241 if (n == -1)
00242 return RC(fcOS);
00243
00244 #if defined(USING_VALGRIND)
00245 if(RUNNING_ON_VALGRIND)
00246 {
00247 check_valgrind_errors(__LINE__, __FILE__);
00248 }
00249 #endif
00250
00251 done = n;
00252
00253 return RCOK;
00254 }
00255
00256 #ifdef HAVE_IO_VECTOR
00257 w_rc_t sdisk_unix_t::readv(const iovec_t *iov, int iovcnt, int &done)
00258 {
00259 if (_fd == FD_NONE)
00260 return RC(stBADFD);
00261
00262 int n;
00263
00264 n = ::os_readv(_fd, (const struct iovec *)iov, iovcnt);
00265 if (n == -1)
00266 return RC(fcOS);
00267
00268 done = n;
00269
00270 return RCOK;
00271 }
00272
00273 w_rc_t sdisk_unix_t::writev(const iovec_t *iov, int iovcnt, int &done)
00274 {
00275 if (_fd == FD_NONE)
00276 return RC(stBADFD);
00277
00278 int n;
00279
00280 n = ::os_writev(_fd, (const struct iovec *)iov, iovcnt);
00281 if (n == -1)
00282 return RC(fcOS);
00283
00284 #if defined(USING_VALGRIND)
00285 if(RUNNING_ON_VALGRIND)
00286 {
00287 check_valgrind_errors(__LINE__, __FILE__);
00288 }
00289 #endif
00290
00291 done = n;
00292
00293 return RCOK;
00294 }
00295 #endif
00296
00297 w_rc_t sdisk_unix_t::pread(void *buf, int count, fileoff_t pos, int &done)
00298 {
00299 if (_fd == FD_NONE)
00300 return RC(stBADFD);
00301
00302 int n;
00303
00304 n = ::os_pread(_fd, buf, count, pos);
00305 if (n == -1)
00306 return RC(fcOS);
00307
00308 done = n;
00309
00310 return RCOK;
00311 }
00312
00313
00314 w_rc_t sdisk_unix_t::pwrite(const void *buf, int count, fileoff_t pos,
00315 int &done)
00316 {
00317 if (_fd == FD_NONE)
00318 return RC(stBADFD);
00319
00320 int n;
00321
00322 n = ::os_pwrite(_fd, buf, count, pos);
00323 if (n == -1)
00324 return RC(fcOS);
00325 #if defined(USING_VALGRIND)
00326 if(RUNNING_ON_VALGRIND)
00327 {
00328 check_valgrind_errors(__LINE__, __FILE__);
00329 }
00330 #endif
00331
00332 done = n;
00333
00334 return RCOK;
00335 }
00336
00337 w_rc_t sdisk_unix_t::seek(fileoff_t pos, int origin, fileoff_t &newpos)
00338 {
00339 if (_fd == FD_NONE)
00340 return RC(stBADFD);
00341
00342 switch (origin) {
00343 case SEEK_AT_SET:
00344 origin = SEEK_SET;
00345 break;
00346 case SEEK_AT_CUR:
00347 origin = SEEK_CUR;
00348 break;
00349 case SEEK_AT_END:
00350 origin = SEEK_END;
00351 break;
00352 }
00353
00354 fileoff_t l=0;
00355 l = ::os_lseek(_fd, pos, origin);
00356 if (l == -1)
00357 return RC(fcOS);
00358
00359 newpos = l;
00360
00361 return RCOK;
00362 }
00363
00364 w_rc_t sdisk_unix_t::truncate(fileoff_t size)
00365 {
00366 if (_fd == FD_NONE)
00367 return RC(stBADFD);
00368 int n = ::os_ftruncate(_fd, size);
00369 return (n == -1) ? RC(fcOS) : RCOK;
00370 }
00371
00372 w_rc_t sdisk_unix_t::sync()
00373 {
00374 if (_fd == FD_NONE)
00375 return RC(stBADFD);
00376
00377 int n = os_fsync(_fd);
00378
00379
00380 if (n == -1 && (errno == EBADF || errno == EINVAL))
00381 n = 0;
00382
00383 return (n == -1) ? RC(fcOS) : RCOK;
00384 }
00385
00386
00387 w_rc_t sdisk_unix_t::stat(filestat_t &st)
00388 {
00389 if (_fd == FD_NONE)
00390 return RC(stBADFD);
00391
00392 os_stat_t sys;
00393 int n = os_fstat(_fd, &sys);
00394 if (n == -1)
00395 return RC(fcOS);
00396
00397 st.st_size = sys.st_size;
00398 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
00399 st.st_block_size = sys.st_blksize;
00400 #else
00401 st.st_block_size = 512;
00402 #endif
00403
00404 st.st_device_id = sys.st_dev;
00405 st.st_file_id = sys.st_ino;
00406
00407 int mode = (sys.st_mode & S_IFMT);
00408 st.is_file = (mode == S_IFREG);
00409 st.is_dir = (mode == S_IFDIR);
00410 #ifdef S_IFBLK
00411 st.is_device = (mode == S_IFBLK);
00412 #else
00413 st.is_device = false;
00414 #endif
00415 st.is_device = st.is_device || (mode == S_IFCHR);
00416
00417 return RCOK;
00418 }
00419
00420