00001
00002
00003
00004
00005
00006
00007
00008 #include "unixFileDriver.h"
00009
00010 int
00011 unixFileCreate (rsComm_t *rsComm, char *fileName, int mode, rodsLong_t mySize)
00012 {
00013 int fd;
00014 mode_t myMask;
00015
00016 myMask = umask((mode_t) 0000);
00017 fd = open (fileName, O_RDWR|O_CREAT|O_EXCL, mode);
00018
00019 (void) umask((mode_t) myMask);
00020
00021 if (fd == 0) {
00022 close (fd);
00023 rodsLog (LOG_NOTICE, "unixFileCreate: 0 descriptor");
00024 open ("/dev/null", O_RDWR, 0);
00025 fd = open (fileName, O_RDWR|O_CREAT|O_EXCL, mode);
00026 }
00027
00028 if (fd < 0) {
00029 fd = UNIX_FILE_CREATE_ERR - errno;
00030 if (errno == EEXIST) {
00031 rodsLog (LOG_DEBUG,
00032 "unixFileCreate: open error for %s, status = %d",
00033 fileName, fd);
00034 } else {
00035 rodsLog (LOG_DEBUG,
00036 "unixFileCreate: open error for %s, status = %d",
00037 fileName, fd);
00038 }
00039 }
00040
00041 return (fd);
00042 }
00043
00044 int
00045 unixFileOpen (rsComm_t *rsComm, char *fileName, int flags, int mode)
00046 {
00047 int fd;
00048
00049 #if defined(osx_platform)
00050
00051 if (flags & 0x200) {
00052 flags = flags ^ 0x200;
00053 flags = flags | O_TRUNC;
00054 }
00055 #endif
00056
00057 fd = open (fileName, flags, mode);
00058
00059 if (fd == 0) {
00060 close (fd);
00061 rodsLog (LOG_NOTICE, "unixFileOpen: 0 descriptor");
00062 open ("/dev/null", O_RDWR, 0);
00063 fd = open (fileName, flags, mode);
00064 }
00065
00066 if (fd < 0) {
00067 fd = UNIX_FILE_OPEN_ERR - errno;
00068 rodsLog (LOG_NOTICE, "unixFileOpen: open error for %s, status = %d",
00069 fileName, fd);
00070 }
00071
00072 return (fd);
00073 }
00074
00075 int
00076 unixFileRead (rsComm_t *rsComm, int fd, void *buf, int len)
00077 {
00078 int status;
00079
00080 status = read (fd, buf, len);
00081
00082 if (status < 0) {
00083 status = UNIX_FILE_READ_ERR - errno;
00084 rodsLog (LOG_NOTICE, "unixFileRead: read error fd = %d, status = %d",
00085 fd, status);
00086 }
00087 return (status);
00088 }
00089
00090 int
00091 nbFileRead (rsComm_t *rsComm, int fd, void *buf, int len)
00092 {
00093 int status;
00094 struct timeval tv;
00095 int nbytes;
00096 int toRead;
00097 char *tmpPtr;
00098 fd_set set;
00099
00100 bzero (&tv, sizeof (tv));
00101 tv.tv_sec = NB_READ_TOUT_SEC;
00102
00103
00104 FD_ZERO (&set);
00105 FD_SET (fd, &set);
00106
00107 toRead = len;
00108 tmpPtr = (char *) buf;
00109
00110 while (toRead > 0) {
00111 #ifndef _WIN32
00112 status = select (fd + 1, &set, NULL, NULL, &tv);
00113 if (status == 0) {
00114
00115 if (len - toRead > 0) {
00116 return (len - toRead);
00117 } else {
00118 return UNIX_FILE_OPR_TIMEOUT_ERR - errno;
00119 }
00120 } else if (status < 0) {
00121 if ( errno == EINTR) {
00122 errno = 0;
00123 continue;
00124 } else {
00125 return UNIX_FILE_READ_ERR - errno;
00126 }
00127 }
00128 #endif
00129 nbytes = read (fd, (void *) tmpPtr, toRead);
00130 if (nbytes < 0) {
00131 if (errno == EINTR) {
00132
00133 errno = 0;
00134 nbytes = 0;
00135 } else if (toRead == len) {
00136 return UNIX_FILE_READ_ERR - errno;
00137 } else {
00138 nbytes = 0;
00139 break;
00140 }
00141 } else if (nbytes == 0) {
00142 break;
00143 }
00144 toRead -= nbytes;
00145 tmpPtr += nbytes;
00146 }
00147 return (len - toRead);
00148 }
00149
00150 int
00151 unixFileWrite (rsComm_t *rsComm, int fd, void *buf, int len)
00152 {
00153 int status;
00154
00155 status = write (fd, buf, len);
00156
00157 if (status < 0) {
00158 status = UNIX_FILE_WRITE_ERR - errno;
00159 rodsLog (LOG_NOTICE, "unixFileWrite: open write fd = %d, status = %d",
00160 fd, status);
00161 }
00162 return (status);
00163
00164 }
00165
00166 int
00167 nbFileWrite (rsComm_t *rsComm, int fd, void *buf, int len)
00168 {
00169 int nbytes;
00170 int toWrite;
00171 char *tmpPtr;
00172 fd_set set;
00173 struct timeval tv;
00174 int status;
00175
00176 bzero (&tv, sizeof (tv));
00177 tv.tv_sec = NB_WRITE_TOUT_SEC;
00178
00179
00180 FD_ZERO (&set);
00181 FD_SET (fd, &set);
00182
00183 toWrite = len;
00184 tmpPtr = (char *) buf;
00185
00186 while (toWrite > 0) {
00187 #ifndef _WIN32
00188 status = select (fd + 1, NULL, &set, NULL, &tv);
00189 if (status == 0) {
00190
00191 return UNIX_FILE_OPR_TIMEOUT_ERR - errno;
00192 } else if (status < 0) {
00193 if ( errno == EINTR) {
00194 errno = 0;
00195 continue;
00196 } else {
00197 return UNIX_FILE_WRITE_ERR - errno;
00198 }
00199 }
00200 #endif
00201 nbytes = write (fd, (void *) tmpPtr, len);
00202 if (nbytes < 0) {
00203 if (errno == EINTR) {
00204
00205 errno = 0;
00206 nbytes = 0;
00207 } else {
00208 return UNIX_FILE_WRITE_ERR - errno;
00209 }
00210 }
00211 toWrite -= nbytes;
00212 tmpPtr += nbytes;
00213 }
00214 return (len);
00215 }
00216
00217 int
00218 unixFileClose (rsComm_t *rsComm, int fd)
00219 {
00220 int status;
00221
00222 status = close (fd);
00223
00224 if (fd == 0) {
00225 rodsLog (LOG_NOTICE, "unixFileClose: 0 descriptor");
00226 open ("/dev/null", O_RDWR, 0);
00227 }
00228 if (status < 0) {
00229 status = UNIX_FILE_CLOSE_ERR - errno;
00230 rodsLog (LOG_NOTICE, "unixFileClose: open write fd = %d, status = %d",
00231 fd, status);
00232 }
00233 return (status);
00234 }
00235
00236 int
00237 unixFileUnlink (rsComm_t *rsComm, char *filename)
00238 {
00239 int status;
00240
00241 status = unlink (filename);
00242
00243 if (status < 0) {
00244 status = UNIX_FILE_UNLINK_ERR - errno;
00245 rodsLog (LOG_NOTICE, "unixFileUnlink: unlink of %s error, status = %d",
00246 filename, status);
00247 }
00248
00249 return (status);
00250 }
00251
00252 int
00253 unixFileStat (rsComm_t *rsComm, char *filename, struct stat *statbuf)
00254 {
00255 int status;
00256
00257 status = stat (filename, statbuf);
00258
00259 #ifdef RUN_SERVER_AS_ROOT
00260 if (status < 0 && errno == EACCES && isServiceUserSet()) {
00261
00262
00263 if (changeToRootUser() == 0) {
00264 status = stat (filename, statbuf);
00265 changeToServiceUser();
00266 }
00267 }
00268 #endif
00269
00270 if (status < 0) {
00271 status = UNIX_FILE_STAT_ERR - errno;
00272 rodsLog (LOG_DEBUG, "unixFileStat: stat of %s error, status = %d",
00273 filename, status);
00274 }
00275
00276 return (status);
00277 }
00278
00279 int
00280 unixFileFstat (rsComm_t *rsComm, int fd, struct stat *statbuf)
00281 {
00282 int status;
00283
00284 status = fstat (fd, statbuf);
00285
00286 #ifdef RUN_SERVER_AS_ROOT
00287 if (status < 0 && errno == EACCES && isServiceUserSet()) {
00288
00289
00290 if (changeToRootUser() == 0) {
00291 status = fstat (fd, statbuf);
00292 changeToServiceUser();
00293 }
00294 }
00295 #endif
00296
00297 if (status < 0) {
00298 status = UNIX_FILE_FSTAT_ERR - errno;
00299 rodsLog (LOG_DEBUG, "unixFileFstat: stat of fd %d error, status = %d",
00300 fd, status);
00301 }
00302
00303 return (status);
00304 }
00305
00306 rodsLong_t
00307 unixFileLseek (rsComm_t *rsComm, int fd, rodsLong_t offset, int whence)
00308 {
00309 rodsLong_t status;
00310
00311 status = lseek (fd, offset, whence);
00312
00313 if (status < 0) {
00314 status = UNIX_FILE_LSEEK_ERR - errno;
00315 rodsLog (LOG_NOTICE,
00316 "unixFileLseek: lseek of fd %d error, status = %d", fd, status);
00317 }
00318
00319 return (status);
00320 }
00321
00322 int
00323 unixFileFsync (rsComm_t *rsComm, int fd)
00324 {
00325 int status;
00326
00327 status = fsync (fd);
00328
00329 if (status < 0) {
00330 status = UNIX_FILE_FSYNC_ERR - errno;
00331 rodsLog (LOG_NOTICE,
00332 "unixFileFsync: fsync of fd %d error, status = %d", fd, status);
00333 }
00334 return (status);
00335 }
00336
00337 int
00338 unixFileMkdir (rsComm_t *rsComm, char *filename, int mode)
00339 {
00340 int status;
00341 mode_t myMask;
00342
00343 myMask = umask((mode_t) 0000);
00344
00345
00346 status = mkdir (filename, mode);
00347
00348 (void) umask((mode_t) myMask);
00349
00350
00351 if (status < 0) {
00352 status = UNIX_FILE_MKDIR_ERR - errno;
00353 if (errno != EEXIST)
00354 rodsLog (LOG_NOTICE,
00355 "unixFileMkdir: mkdir of %s error, status = %d",
00356 filename, status);
00357 }
00358
00359 return (status);
00360 }
00361
00362 int
00363 unixFileChmod (rsComm_t *rsComm, char *filename, int mode)
00364 {
00365 int status;
00366
00367 status = chmod (filename, mode);
00368
00369 if (status < 0) {
00370 status = UNIX_FILE_CHMOD_ERR - errno;
00371 rodsLog (LOG_NOTICE,
00372 "unixFileChmod: chmod of %s error, status = %d",
00373 filename, status);
00374 }
00375
00376 return (status);
00377 }
00378
00379 int
00380 unixFileRmdir (rsComm_t *rsComm, char *filename)
00381 {
00382 int status;
00383
00384 status = rmdir (filename);
00385
00386 if (status < 0) {
00387 status = UNIX_FILE_RMDIR_ERR - errno;
00388 rodsLog (LOG_DEBUG,
00389 "unixFileRmdir: rmdir of %s error, status = %d",
00390 filename, status);
00391 }
00392
00393 return (status);
00394 }
00395
00396 int
00397 unixFileOpendir (rsComm_t *rsComm, char *dirname, void **outDirPtr)
00398 {
00399 int status;
00400 DIR *dirPtr;
00401
00402
00403 dirPtr = opendir (dirname);
00404
00405 #ifdef RUN_SERVER_AS_ROOT
00406 if (dirPtr == NULL && errno == EACCES && isServiceUserSet()) {
00407
00408
00409 if (changeToRootUser() == 0) {
00410 dirPtr = opendir (dirname);
00411 changeToServiceUser();
00412 }
00413 }
00414 #endif
00415
00416 if (dirPtr != NULL) {
00417 *outDirPtr = (void *) dirPtr;
00418 status = 0;
00419 return (0);
00420 } else {
00421 status = UNIX_FILE_OPENDIR_ERR - errno;
00422 rodsLog (LOG_NOTICE,
00423 "unixFileOpendir: opendir of %s error, status = %d",
00424 dirname, status);
00425 }
00426 return (status);
00427 }
00428
00429 int
00430 unixFileClosedir (rsComm_t *rsComm, void *dirPtr)
00431 {
00432 int status;
00433
00434 status = closedir ((DIR *) dirPtr);
00435
00436 if (status < 0) {
00437 status = UNIX_FILE_CLOSEDIR_ERR - errno;
00438 rodsLog (LOG_NOTICE,
00439 "unixFileClosedir: closedir error, status = %d", status);
00440 }
00441 return (status);
00442 }
00443
00444 int
00445 unixFileReaddir (rsComm_t *rsComm, void *dirPtr, struct dirent *direntPtr)
00446 {
00447 int status;
00448 struct dirent *tmpDirentPtr;
00449
00450 errno = 0;
00451 tmpDirentPtr = readdir ((DIR*)dirPtr);
00452
00453 if (tmpDirentPtr == NULL) {
00454 if (errno == 0) {
00455
00456 status = -1;
00457 } else {
00458 status = UNIX_FILE_READDIR_ERR - errno;
00459 rodsLog (LOG_NOTICE,
00460 "unixFileReaddir: readdir error, status = %d", status);
00461 }
00462 } else {
00463 status = 0;
00464 *direntPtr = *tmpDirentPtr;
00465 #if defined(solaris_platform)
00466 rstrcpy (direntPtr->d_name, tmpDirentPtr->d_name, MAX_NAME_LEN);
00467 #endif
00468 }
00469 return (status);
00470 }
00471
00472 int
00473 unixFileStage (rsComm_t *rsComm, char *path, int flag)
00474 {
00475 #ifdef SAMFS_STAGE
00476 int status;
00477 status = sam_stage (path, "i");
00478
00479 if (status < 0) {
00480 status = UNIX_FILE_STAGE_ERR - errno;
00481 rodsLog (LOG_NOTICE,
00482 "unixFileStage: sam_stage error, status = %d\n",
00483 status);
00484 }
00485
00486 return (status);
00487 #else
00488 return (0);
00489 #endif
00490 }
00491
00492 int
00493 unixFileRename (rsComm_t *rsComm, char *oldFileName, char *newFileName)
00494 {
00495 int status;
00496 status = rename (oldFileName, newFileName);
00497
00498 if (status < 0) {
00499 status = UNIX_FILE_RENAME_ERR - errno;
00500 rodsLog (LOG_NOTICE,
00501 "unixFileRename: rename error, status = %d\n",
00502 status);
00503 }
00504
00505 return (status);
00506 }
00507
00508 int
00509 unixFileTruncate (rsComm_t *rsComm, char *filename, rodsLong_t dataSize)
00510 {
00511 int status;
00512
00513 status = truncate (filename, dataSize);
00514
00515 if (status < 0) {
00516 status = UNIX_FILE_TRUNCATE_ERR - errno;
00517 rodsLog (LOG_NOTICE,
00518 "unixFileTruncate: truncate of %s error, status = %d",
00519 filename, status);
00520 }
00521
00522 return (status);
00523 }
00524
00525 rodsLong_t
00526 unixFileGetFsFreeSpace (rsComm_t *rsComm, char *path, int flag)
00527 {
00528 int status;
00529 rodsLong_t fssize = USER_NO_SUPPORT_ERR;
00530 #if defined(solaris_platform)
00531 struct statvfs statbuf;
00532 #else
00533 struct statfs statbuf;
00534 #endif
00535 #if defined(solaris_platform) || defined(sgi_platform) || defined(aix_platform) || defined(linux_platform) || defined(osx_platform)
00536 #if defined(solaris_platform)
00537 status = statvfs (path, &statbuf);
00538 #else
00539 #if defined(sgi_platform)
00540 status = statfs (path, &statbuf, sizeof (struct statfs), 0);
00541 #else
00542 status = statfs (path, &statbuf);
00543 #endif
00544 #endif
00545 if (status < 0) {
00546 status = UNIX_FILE_GET_FS_FREESPACE_ERR - errno;
00547 rodsLog (LOG_NOTICE,
00548 "UNIX statfs error for %s. errorCode = %d", path, status);
00549 return (status);
00550 }
00551 #if defined(sgi_platform)
00552 if (statbuf.f_frsize > 0) {
00553 fssize = statbuf.f_frsize;
00554 } else {
00555 fssize = statbuf.f_bsize;
00556 }
00557 fssize *= statbuf.f_bavail;
00558 #endif
00559
00560 #if defined(aix_platform) || defined(osx_platform) || (linux_platform)
00561 fssize = statbuf.f_bavail * statbuf.f_bsize;
00562 #endif
00563 #if defined(sgi_platform)
00564 fssize = statbuf.f_bfree * statbuf.f_bsize;
00565 #endif
00566
00567 #endif
00568
00569 return (fssize);
00570 }
00571
00572
00573
00574
00575
00576
00577
00578 int
00579 unixStageToCache (rsComm_t *rsComm, fileDriverType_t cacheFileType,
00580 int mode, int flags, char *filename,
00581 char *cacheFilename, rodsLong_t dataSize,
00582 keyValPair_t *condInput)
00583 {
00584 int status;
00585
00586 status = unixFileCopy (mode, filename, cacheFilename);
00587 return status;
00588 }
00589
00590
00591
00592
00593
00594
00595
00596 int
00597 unixSyncToArch (rsComm_t *rsComm, fileDriverType_t cacheFileType,
00598 int mode, int flags, char *filename,
00599 char *cacheFilename, rodsLong_t dataSize,
00600 keyValPair_t *condInput)
00601 {
00602 int status;
00603
00604 status = unixFileCopy (mode, cacheFilename, filename);
00605 return status;
00606 }
00607
00608 int
00609 unixFileCopy (int mode, char *srcFileName, char *destFileName)
00610 {
00611 int inFd, outFd;
00612 char myBuf[TRANS_BUF_SZ];
00613 rodsLong_t bytesCopied = 0;
00614 int bytesRead;
00615 int bytesWritten;
00616 int status;
00617 struct stat statbuf;
00618
00619 status = stat (srcFileName, &statbuf);
00620
00621 if (status < 0) {
00622 status = UNIX_FILE_STAT_ERR - errno;
00623 rodsLog (LOG_ERROR, "unixFileCopy: stat of %s error, status = %d",
00624 srcFileName, status);
00625 return status;
00626 }
00627
00628 inFd = open (srcFileName, O_RDONLY, 0);
00629 if (inFd < 0 || (statbuf.st_mode & S_IFREG) == 0) {
00630 status = UNIX_FILE_OPEN_ERR - errno;
00631 rodsLog (LOG_ERROR,
00632 "unixFileCopy: open error for srcFileName %s, status = %d",
00633 srcFileName, status);
00634 close( inFd );
00635 return status;
00636 }
00637
00638 outFd = open (destFileName, O_WRONLY | O_CREAT | O_TRUNC, mode);
00639 if (outFd < 0) {
00640 status = UNIX_FILE_OPEN_ERR - errno;
00641 rodsLog (LOG_ERROR,
00642 "unixFileCopy: open error for destFileName %s, status = %d",
00643 destFileName, status);
00644 close (inFd);
00645 return status;
00646 }
00647
00648 while ((bytesRead = read (inFd, (void *) myBuf, TRANS_BUF_SZ)) > 0) {
00649 bytesWritten = write (outFd, (void *) myBuf, bytesRead);
00650 if (bytesWritten <= 0) {
00651 status = UNIX_FILE_WRITE_ERR - errno;
00652 rodsLog (LOG_ERROR,
00653 "unixFileCopy: write error for srcFileName %s, status = %d",
00654 destFileName, status);
00655 close (inFd);
00656 close (outFd);
00657 return status;
00658 }
00659 bytesCopied += bytesWritten;
00660 }
00661
00662 close (inFd);
00663 close (outFd);
00664
00665 if (bytesCopied != statbuf.st_size) {
00666 rodsLog (LOG_ERROR,
00667 "unixFileCopy: Copied size %lld does not match source size %lld of %s",
00668 bytesCopied, statbuf.st_size, srcFileName);
00669 return SYS_COPY_LEN_ERR;
00670 } else {
00671 return 0;
00672 }
00673 }
00674