root/plugin/ipc/file/filewrappers.cpp

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. close
  2. fclose
  3. closedir
  4. dup
  5. dup2
  6. dup3
  7. ptsname_r_work
  8. ptsname_r
  9. ptsname
  10. __ptsname_r_chk
  11. ttyname_r
  12. ttyname
  13. __ttyname_r_chk
  14. getpt
  15. posix_openpt
  16. tmpfile
  17. mkstemp
  18. mkostemp
  19. mkstemps
  20. mkostemps
  21. _open_open64_work
  22. open
  23. __open_2
  24. open64
  25. __open64_2
  26. creat
  27. creat64
  28. _fopen_fopen64_work
  29. fopen
  30. fopen64
  31. freopen
  32. openat
  33. openat_2
  34. __openat_2
  35. openat64
  36. openat64_2
  37. __openat64_2
  38. opendir
  39. updateStatPath
  40. __xstat
  41. __xstat64
  42. __fxstat
  43. __fxstat64
  44. __lxstat
  45. __lxstat64
  46. readlink
  47. __readlink_chk
  48. fcntl
  49. realpath
  50. __realpath
  51. __realpath_chk
  52. canonicalize_file_name
  53. access
  54. ioctl

   1 /****************************************************************************
   2  *   Copyright (C) 2006-2010 by Jason Ansel, Kapil Arya, and Gene Cooperman *
   3  *   jansel@csail.mit.edu, kapil@ccs.neu.edu, gene@ccs.neu.edu              *
   4  *                                                                          *
   5  *   This file is part of the dmtcp/src module of DMTCP (DMTCP:dmtcp/src).  *
   6  *                                                                          *
   7  *  DMTCP:dmtcp/src is free software: you can redistribute it and/or        *
   8  *  modify it under the terms of the GNU Lesser General Public License as   *
   9  *  published by the Free Software Foundation, either version 3 of the      *
  10  *  License, or (at your option) any later version.                         *
  11  *                                                                          *
  12  *  DMTCP:dmtcp/src is distributed in the hope that it will be useful,      *
  13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of          *
  14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
  15  *  GNU Lesser General Public License for more details.                     *
  16  *                                                                          *
  17  *  You should have received a copy of the GNU Lesser General Public        *
  18  *  License along with DMTCP:dmtcp/src.  If not, see                        *
  19  *  <http://www.gnu.org/licenses/>.                                         *
  20  ****************************************************************************/
  21 
  22 /* ptsname_r is defined with "always_inline" attribute. GCC>=4.7 disallows us
  23  * to define the ptsname_r wrapper if compiled with -O0. Here we are renaming
  24  * ptsname_r so that later code does not see the declaration of ptsname_r as
  25  * inline. Normal user code from other files will continue to invoke ptsname_r
  26  * as inline as an inline function calling __ptsname_r_chk. Later in this file
  27  * we define __ptsname_r_chk to call the original ptsname_r symbol.
  28  * Similarly, for ttyname_r, etc.
  29  *
  30  * Also, on some machines (e.g. SLES 10), readlink has conflicting return types
  31  * (ssize_t and int).
  32  *     In general, we rename the functions below, since any type declarations
  33  * may vary on different systems, and so we ignore these type declarations.
  34 */
  35 #define ptsname_r ptsname_r_always_inline
  36 #define ttyname_r ttyname_r_always_inline
  37 #define open open_always_inline
  38 #define open64 open64_always_inline
  39 #define openat openat_always_inline
  40 #define openat64 openat64_always_inline
  41 #define readlink readlink_always_inline
  42 #define __readlink_chk _ret__readlink_chk
  43 #define realpath realpath_always_inline
  44 
  45 #include <stdarg.h>
  46 #include <stdlib.h>
  47 #include <vector>
  48 #include <list>
  49 #include <string>
  50 #include <fcntl.h>
  51 #include <signal.h>
  52 #include <sys/ipc.h>
  53 #include <sys/shm.h>
  54 #include <sys/types.h>
  55 #include <sys/socket.h>
  56 #include <sys/ioctl.h>
  57 #include <unistd.h>
  58 #include <dirent.h>
  59 #include <sys/syscall.h>
  60 #include <linux/version.h>
  61 #include <limits.h>
  62 
  63 #undef ptsname_r
  64 #undef ttyname_r
  65 #undef open
  66 #undef open64
  67 #undef openat
  68 #undef openat64
  69 #undef readlink
  70 #undef __readlink_chk
  71 #undef realpath
  72 
  73 #include "dmtcp.h"
  74 #include "shareddata.h"
  75 #include "util.h"
  76 #include "jassert.h"
  77 #include "jconvert.h"
  78 #include "jfilesystem.h"
  79 
  80 #include "fileconnlist.h"
  81 #include "fileconnection.h"
  82 #include "filewrappers.h"
  83 
  84 using namespace dmtcp;
  85 #if 0
  86 extern "C" int close(int fd)
  87 {
  88   if (dmtcp_is_protected_fd(fd)) {
  89     JTRACE("blocked attempt to close protected fd") (fd);
  90     errno = EBADF;
  91     return -1;
  92   }
  93 
  94   DMTCP_PLUGIN_DISABLE_CKPT();
  95   int rv = _real_close(fd);
  96   if (rv == 0 && dmtcp_is_running_state()) {
  97     FileConnList::instance().processClose(fd);
  98   }
  99   DMTCP_PLUGIN_ENABLE_CKPT();
 100   return rv;
 101 }
 102 
 103 extern "C" int fclose(FILE *fp)
 104 {
 105   int fd = fileno(fp);
 106   if (dmtcp_is_protected_fd(fd)) {
 107     JTRACE("blocked attempt to fclose protected fd") (fd);
 108     errno = EBADF;
 109     return -1;
 110   }
 111 
 112   DMTCP_PLUGIN_DISABLE_CKPT();
 113   int rv = _real_fclose(fp);
 114   if (rv == 0 && dmtcp_is_running_state()) {
 115     FileConnList::instance().processClose(fd);
 116   }
 117   DMTCP_PLUGIN_ENABLE_CKPT();
 118 
 119   return rv;
 120 }
 121 
 122 extern "C" int closedir(DIR *dir)
 123 {
 124   int fd = dirfd(dir);
 125   if (dmtcp_is_protected_fd(fd)) {
 126     JTRACE("blocked attempt to closedir protected fd") (fd);
 127     errno = EBADF;
 128     return -1;
 129   }
 130 
 131   DMTCP_PLUGIN_DISABLE_CKPT();
 132   int rv = _real_closedir(dir);
 133   if (rv == 0 && dmtcp_is_running_state()) {
 134     FileConnList::instance().processClose(fd);
 135   }
 136   DMTCP_PLUGIN_ENABLE_CKPT();
 137 
 138   return rv;
 139 }
 140 
 141 extern "C" int dup(int oldfd)
 142 {
 143   DMTCP_PLUGIN_DISABLE_CKPT();
 144   int newfd = _real_dup(oldfd);
 145   if (newfd != -1 && dmtcp_is_running_state()) {
 146     FileConnList::instance().processDup(oldfd, newfd);
 147   }
 148   DMTCP_PLUGIN_ENABLE_CKPT();
 149   return newfd;
 150 }
 151 
 152 extern "C" int dup2(int oldfd, int newfd)
 153 {
 154   DMTCP_PLUGIN_DISABLE_CKPT();
 155   int res = _real_dup2(oldfd, newfd);
 156   if (res != -1 && newfd != oldfd && dmtcp_is_running_state()) {
 157     FileConnList::instance().processDup(oldfd, newfd);
 158   }
 159   DMTCP_PLUGIN_ENABLE_CKPT();
 160   return newfd;
 161 }
 162 
 163 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) && __GLIBC_PREREQ(2,9)
 164 // dup3 appeared in Linux 2.6.27
 165 extern "C" int dup3(int oldfd, int newfd, int flags)
 166 {
 167   DMTCP_PLUGIN_DISABLE_CKPT();
 168   int res = _real_dup3(oldfd, newfd, flags);
 169   if (res != -1 && newfd != oldfd && dmtcp_is_running_state()) {
 170     FileConnList::instance().processDup(oldfd, newfd);
 171   }
 172   DMTCP_PLUGIN_ENABLE_CKPT();
 173   return newfd;
 174 }
 175 #endif
 176 #endif
 177 
 178 static int ptsname_r_work(int fd, char * buf, size_t buflen)
 179 {
 180   JTRACE("Calling ptsname_r");
 181 
 182   Connection* c = FileConnList::instance().getConnection(fd);
 183   PtyConnection* ptyCon =(PtyConnection*) c;
 184 
 185   string virtPtsName = ptyCon->virtPtsName();
 186 
 187   JTRACE("ptsname_r") (virtPtsName);
 188 
 189   if (virtPtsName.length() >= buflen)
 190   {
 191     JWARNING(false) (virtPtsName) (virtPtsName.length()) (buflen)
 192       .Text("fake ptsname() too long for user buffer");
 193     errno = ERANGE;
 194     return -1;
 195   }
 196 
 197   strcpy(buf, virtPtsName.c_str());
 198 
 199   return 0;
 200 }
 201 
 202 extern "C" int ptsname_r(int fd, char * buf, size_t buflen)
 203 {
 204   DMTCP_PLUGIN_DISABLE_CKPT();
 205 
 206   int retVal = ptsname_r_work(fd, buf, buflen);
 207 
 208   DMTCP_PLUGIN_ENABLE_CKPT();
 209 
 210   return retVal;
 211 }
 212 
 213 extern "C" char *ptsname(int fd)
 214 {
 215   /* No need to acquire Wrapper Protection lock since it will be done in ptsname_r */
 216   JTRACE("ptsname() promoted to ptsname_r()");
 217   static char tmpbuf[PATH_MAX];
 218 
 219   if (ptsname_r(fd, tmpbuf, sizeof(tmpbuf)) != 0)
 220   {
 221     return NULL;
 222   }
 223 
 224   return tmpbuf;
 225 }
 226 
 227 extern "C" int __ptsname_r_chk(int fd, char * buf, size_t buflen, size_t nreal)
 228 {
 229   DMTCP_PLUGIN_DISABLE_CKPT();
 230 
 231   JASSERT(buflen <= nreal) (buflen) (nreal) .Text("Buffer Overflow detected!");
 232 
 233   int retVal = ptsname_r_work(fd, buf, buflen);
 234 
 235   DMTCP_PLUGIN_ENABLE_CKPT();
 236 
 237   return retVal;
 238 }
 239 
 240 extern "C" int ttyname_r(int fd, char *buf, size_t buflen)
 241 {
 242   char tmpbuf[64];
 243   DMTCP_PLUGIN_DISABLE_CKPT();
 244   int ret = _real_ttyname_r(fd, tmpbuf, sizeof(tmpbuf));
 245 
 246   if (ret == 0 && strcmp(tmpbuf, "/dev/tty") != 0) {
 247     Connection* c = FileConnList::instance().getConnection(fd);
 248     JASSERT(c != NULL) (fd) (tmpbuf);
 249     PtyConnection* ptyCon =(PtyConnection*) c;
 250     string virtPtsName = ptyCon->virtPtsName();
 251 
 252     if (virtPtsName.length() >= buflen) {
 253       JWARNING(false) (virtPtsName) (virtPtsName.length()) (buflen)
 254         .Text("fake ptsname() too long for user buffer");
 255       errno = ERANGE;
 256       ret = -1;
 257     } else {
 258       strncpy(buf, virtPtsName.c_str(), buflen);
 259     }
 260   }
 261   DMTCP_PLUGIN_ENABLE_CKPT();
 262 
 263   return ret;
 264 }
 265 
 266 extern "C" char *ttyname(int fd)
 267 {
 268   static char tmpbuf[64];
 269 
 270   if (ttyname_r(fd, tmpbuf, sizeof(tmpbuf)) != 0) {
 271     return NULL;
 272   }
 273   return tmpbuf;
 274 }
 275 
 276 extern "C" int __ttyname_r_chk(int fd, char *buf, size_t buflen, size_t nreal)
 277 {
 278   return ttyname_r(fd, buf, buflen);
 279 }
 280 
 281 extern "C" int getpt()
 282 {
 283   DMTCP_PLUGIN_DISABLE_CKPT();
 284   int fd = _real_getpt();
 285   if (fd >= 0 && dmtcp_is_running_state()) {
 286     FileConnList::instance().processFileConnection(fd, "/dev/ptmx",
 287                                                      O_RDWR | O_NOCTTY, -1);
 288   }
 289   DMTCP_PLUGIN_ENABLE_CKPT();
 290   return fd;
 291 }
 292 
 293 extern "C" int posix_openpt(int flags)
 294 {
 295   DMTCP_PLUGIN_DISABLE_CKPT();
 296   int fd = _real_posix_openpt(flags);
 297   if (fd >= 0 && dmtcp_is_running_state()) {
 298     FileConnList::instance().processFileConnection(fd, "/dev/ptmx",
 299                                                      flags, -1);
 300   }
 301   DMTCP_PLUGIN_ENABLE_CKPT();
 302   return fd;
 303 }
 304 
 305 extern "C" FILE *tmpfile()
 306 {
 307   DMTCP_PLUGIN_DISABLE_CKPT();
 308   FILE *fp = _real_tmpfile();
 309   if (fp  != NULL && dmtcp_is_running_state()) {
 310     FileConnList::instance().processFileConnection(fileno(fp), NULL, O_RDWR, 0600);
 311   }
 312   DMTCP_PLUGIN_ENABLE_CKPT();
 313   return fp;
 314 }
 315 
 316 extern "C" int mkstemp(char *ttemplate)
 317 {
 318   DMTCP_PLUGIN_DISABLE_CKPT();
 319   int fd = _real_mkstemp(ttemplate);
 320   if (fd >= 0 && dmtcp_is_running_state()) {
 321     FileConnList::instance().processFileConnection(fd, NULL, O_RDWR, 0600);
 322   }
 323   DMTCP_PLUGIN_ENABLE_CKPT();
 324   return fd;
 325 }
 326 
 327 extern "C" int mkostemp(char *ttemplate, int flags)
 328 {
 329   DMTCP_PLUGIN_DISABLE_CKPT();
 330   int fd = _real_mkostemp(ttemplate, flags);
 331   if (fd >= 0 && dmtcp_is_running_state()) {
 332     FileConnList::instance().processFileConnection(fd, NULL, flags, 0600);
 333   }
 334   DMTCP_PLUGIN_ENABLE_CKPT();
 335   return fd;
 336 }
 337 
 338 extern "C" int mkstemps(char *ttemplate, int suffixlen)
 339 {
 340   DMTCP_PLUGIN_DISABLE_CKPT();
 341   int fd = _real_mkstemps(ttemplate, suffixlen);
 342   if (fd >= 0 && dmtcp_is_running_state()) {
 343     FileConnList::instance().processFileConnection(fd, NULL, O_RDWR, 0600);
 344   }
 345   DMTCP_PLUGIN_ENABLE_CKPT();
 346   return fd;
 347 }
 348 
 349 extern "C" int mkostemps(char *ttemplate, int suffixlen, int flags)
 350 {
 351   DMTCP_PLUGIN_DISABLE_CKPT();
 352   int fd = _real_mkostemps(ttemplate, suffixlen, flags);
 353   if (fd >= 0 && dmtcp_is_running_state()) {
 354     FileConnList::instance().processFileConnection(fd, NULL, flags, 0600);
 355   }
 356   DMTCP_PLUGIN_ENABLE_CKPT();
 357   return fd;
 358 }
 359 
 360 static int _open_open64_work(int(*fn) (const char *path, int flags, ...),
 361                              const char *path, int flags, mode_t mode)
 362 {
 363   char currPtsDevName[32];
 364   const char *newpath = path;
 365 
 366   DMTCP_PLUGIN_DISABLE_CKPT();
 367 
 368   if (Util::strStartsWith(path, VIRT_PTS_PREFIX_STR)) {
 369     SharedData::getRealPtyName(path, currPtsDevName,
 370                                       sizeof(currPtsDevName));
 371     newpath = currPtsDevName;
 372   }
 373 
 374   int fd = (*fn) (newpath, flags, mode);
 375 
 376   if (fd >= 0 && dmtcp_is_running_state()) {
 377     FileConnList::instance().processFileConnection(fd, newpath, flags, mode);
 378   }
 379 
 380   DMTCP_PLUGIN_ENABLE_CKPT();
 381 
 382   return fd;
 383 }
 384 
 385 /* Used by open() wrapper to do other tracking of open apart from
 386    synchronization stuff. */
 387 extern "C" int open(const char *path, int flags, ...)
 388 {
 389   mode_t mode = 0;
 390   // Handling the variable number of arguments
 391   if (flags & O_CREAT) {
 392     va_list arg;
 393     va_start(arg, flags);
 394     mode = va_arg(arg, int);
 395     va_end(arg);
 396   }
 397   return _open_open64_work(_real_open, path, flags, mode);
 398 }
 399 
 400 extern "C" int __open_2(const char *path, int flags)
 401 {
 402   return _open_open64_work(_real_open, path, flags, 0);
 403 }
 404 
 405 // FIXME: The 'fn64' version of functions is defined only when within
 406 // __USE_LARGEFILE64 is #defined. The wrappers in this file need to consider
 407 // this fact. The problem can occur, for example, when DMTCP is not compiled
 408 // with __USE_LARGEFILE64 whereas the user-binary is. In that case the open64()
 409 // call from user will come to DMTCP and DMTCP might fail to execute it
 410 // properly.
 411 
 412 // FIXME: Add the 'fn64' wrapper test cases to dmtcp test suite.
 413 extern "C" int open64(const char *path, int flags, ...)
 414 {
 415   mode_t mode = 0;
 416   // Handling the variable number of arguments
 417   if (flags & O_CREAT) {
 418     va_list arg;
 419     va_start(arg, flags);
 420     mode = va_arg(arg, int);
 421     va_end(arg);
 422   }
 423   return _open_open64_work(_real_open64, path, flags, mode);
 424 }
 425 
 426 extern "C" int __open64_2(const char *path, int flags)
 427 {
 428   return _open_open64_work(_real_open64, path, flags, 0);
 429 }
 430 
 431 extern "C" int creat(const char *path, mode_t mode)
 432 {
 433   //creat() is equivalent to open() with flags equal to O_CREAT|O_WRONLY|O_TRUNC
 434   return _open_open64_work(_real_open, path, O_CREAT|O_WRONLY|O_TRUNC, mode);
 435 }
 436 
 437 extern "C" int creat64(const char *path, mode_t mode)
 438 {
 439   //creat() is equivalent to open() with flags equal to O_CREAT|O_WRONLY|O_TRUNC
 440   return _open_open64_work(_real_open64, path, O_CREAT|O_WRONLY|O_TRUNC, mode);
 441 }
 442 
 443 static FILE *_fopen_fopen64_work(FILE*(*fn) (const char *path, const char *mode),
 444                                  const char *path, const char *mode)
 445 {
 446   char currPtsDevName[32];
 447   const char *newpath = path;
 448 
 449   DMTCP_PLUGIN_DISABLE_CKPT();
 450 
 451   if (Util::strStartsWith(path, VIRT_PTS_PREFIX_STR)) {
 452     SharedData::getRealPtyName(path, currPtsDevName,
 453                                       sizeof(currPtsDevName));
 454     newpath = currPtsDevName;
 455   }
 456 
 457   FILE *file =(*fn) (newpath, mode);
 458 
 459   if (file != NULL && dmtcp_is_running_state()) {
 460     FileConnList::instance().processFileConnection(fileno(file), newpath,
 461                                                      -1, -1);
 462   }
 463 
 464   DMTCP_PLUGIN_ENABLE_CKPT();
 465   return file;
 466 }
 467 
 468 extern "C" FILE *fopen(const char* path, const char* mode)
 469 {
 470   return _fopen_fopen64_work(_real_fopen, path, mode);
 471 }
 472 
 473 extern "C" FILE *fopen64(const char* path, const char* mode)
 474 {
 475   return _fopen_fopen64_work(_real_fopen64, path, mode);
 476 }
 477 
 478 extern "C" FILE *freopen(const char *path, const char *mode, FILE *stream)
 479 {
 480   char currPtsDevName[32];
 481   const char *newpath = path;
 482 
 483   DMTCP_PLUGIN_DISABLE_CKPT();
 484 
 485   if (Util::strStartsWith(path, VIRT_PTS_PREFIX_STR)) {
 486     SharedData::getRealPtyName(path, currPtsDevName,
 487                                       sizeof(currPtsDevName));
 488     newpath = currPtsDevName;
 489   }
 490 
 491   FILE *file = _real_freopen(newpath, mode, stream);
 492 
 493   if (file != NULL && dmtcp_is_running_state()) {
 494     FileConnList::instance().processFileConnection(fileno(file), newpath,
 495                                                    -1, -1);
 496   }
 497 
 498   DMTCP_PLUGIN_ENABLE_CKPT();
 499   return file;
 500 }
 501 
 502 extern "C" int openat(int dirfd, const char *path, int flags, ...)
 503 {
 504   va_list arg;
 505   va_start(arg, flags);
 506   mode_t mode = va_arg(arg, int);
 507   va_end(arg);
 508   DMTCP_PLUGIN_DISABLE_CKPT();
 509   int fd = _real_openat(dirfd, path, flags, mode);
 510   if (fd >= 0 && dmtcp_is_running_state()) {
 511     string procpath = "/proc/self/fd/" + jalib::XToString(fd);
 512     string device = jalib::Filesystem::ResolveSymlink(procpath);
 513     FileConnList::instance().processFileConnection(fd, device.c_str(),
 514                                                      flags, mode);
 515   }
 516   DMTCP_PLUGIN_ENABLE_CKPT();
 517   return fd;
 518 }
 519 
 520 extern "C" int openat_2(int dirfd, const char *path, int flags)
 521 {
 522   return openat(dirfd, path, flags, 0);
 523 }
 524 
 525 extern "C" int __openat_2(int dirfd, const char *path, int flags)
 526 {
 527   return openat(dirfd, path, flags, 0);
 528 }
 529 
 530 extern "C" int openat64(int dirfd, const char *path, int flags, ...)
 531 {
 532   va_list arg;
 533   va_start(arg, flags);
 534   mode_t mode = va_arg(arg, int);
 535   va_end(arg);
 536   DMTCP_PLUGIN_DISABLE_CKPT();
 537   int fd = _real_openat64(dirfd, path, flags, mode);
 538   if (fd >= 0 && dmtcp_is_running_state()) {
 539     string procpath = "/proc/self/fd/" + jalib::XToString(fd);
 540     string device = jalib::Filesystem::ResolveSymlink(procpath);
 541     FileConnList::instance().processFileConnection(fd, device.c_str(),
 542                                                      flags, mode);
 543   }
 544   DMTCP_PLUGIN_ENABLE_CKPT();
 545   return fd;
 546 }
 547 
 548 extern "C" int openat64_2(int dirfd, const char *path, int flags)
 549 {
 550   return openat64(dirfd, path, flags, 0);
 551 }
 552 
 553 extern "C" int __openat64_2(int dirfd, const char *path, int flags)
 554 {
 555   return openat64(dirfd, path, flags, 0);
 556 }
 557 
 558 extern "C" DIR *opendir(const char *name)
 559 {
 560   DMTCP_PLUGIN_DISABLE_CKPT();
 561   DIR *dir = _real_opendir(name);
 562   if (dir != NULL && dmtcp_is_running_state()) {
 563     FileConnList::instance().processFileConnection(dirfd(dir), name, -1, -1);
 564   }
 565   DMTCP_PLUGIN_ENABLE_CKPT();
 566   return dir;
 567 }
 568 
 569 static void updateStatPath(const char *path, char **newpath)
 570 {
 571   if (Util::strStartsWith(path, VIRT_PTS_PREFIX_STR)) {
 572     char currPtsDevName[32];
 573     SharedData::getRealPtyName(path, currPtsDevName,
 574                                       sizeof(currPtsDevName));
 575     strcpy(*newpath, currPtsDevName);
 576   } else {
 577     *newpath = (char*) path;
 578   }
 579 }
 580 
 581 extern "C" int __xstat(int vers, const char *path, struct stat *buf)
 582 {
 583   char tmpbuf [ PATH_MAX ] = {0} ;
 584   char *newpath = tmpbuf;
 585   DMTCP_PLUGIN_DISABLE_CKPT();
 586   updateStatPath(path, &newpath);
 587   int retval = _real_xstat(vers, newpath, buf);
 588   DMTCP_PLUGIN_ENABLE_CKPT();
 589   return retval;
 590 }
 591 
 592 extern "C" int __xstat64(int vers, const char *path, struct stat64 *buf)
 593 {
 594   char tmpbuf [ PATH_MAX ] = {0};
 595   char *newpath = tmpbuf;
 596   DMTCP_PLUGIN_DISABLE_CKPT();
 597   updateStatPath(path, &newpath);
 598   int retval = _real_xstat64(vers, newpath, buf);
 599   DMTCP_PLUGIN_ENABLE_CKPT();
 600   return retval;
 601 }
 602 
 603 #if 0
 604 extern "C" int __fxstat(int vers, int fd, struct stat *buf)
 605 {
 606   DMTCP_PLUGIN_DISABLE_CKPT();
 607   int retval = _real_fxstat(vers, fd, buf);
 608   DMTCP_PLUGIN_ENABLE_CKPT();
 609   return retval;
 610 }
 611 
 612 extern "C" int __fxstat64(int vers, int fd, struct stat64 *buf)
 613 {
 614   DMTCP_PLUGIN_DISABLE_CKPT();
 615   int retval = _real_fxstat64(vers, fd, buf);
 616   DMTCP_PLUGIN_ENABLE_CKPT();
 617   return retval;
 618 }
 619 #endif
 620 
 621 extern "C" int __lxstat(int vers, const char *path, struct stat *buf)
 622 {
 623   char tmpbuf [ PATH_MAX ] = {0} ;
 624   char *newpath = tmpbuf;
 625   DMTCP_PLUGIN_DISABLE_CKPT();
 626   updateStatPath(path, &newpath);
 627   int retval = _real_lxstat(vers, newpath, buf);
 628   DMTCP_PLUGIN_ENABLE_CKPT();
 629   return retval;
 630 }
 631 
 632 extern "C" int __lxstat64(int vers, const char *path, struct stat64 *buf)
 633 {
 634   char tmpbuf [ PATH_MAX ] = {0} ;
 635   char *newpath = tmpbuf;
 636   DMTCP_PLUGIN_DISABLE_CKPT();
 637   updateStatPath(path, &newpath);
 638   int retval = _real_lxstat64(vers, newpath, buf);
 639   DMTCP_PLUGIN_ENABLE_CKPT();
 640   return retval;
 641 }
 642 
 643 //FIXME: Add wrapper for readlinkat
 644 // NOTE:  If you see a compiler error: "declaration of C function ... conflicts
 645 //   with ... unistd.h", then consider changing ssize_t to int
 646 //   A user has reported this was needed for Linux SLES10.
 647 extern "C" ssize_t readlink(const char *path, char *buf, size_t bufsiz)
 648 {
 649   char tmpbuf [ PATH_MAX ] = {0} ;
 650   char *newpath = tmpbuf;
 651   DMTCP_PLUGIN_DISABLE_CKPT();
 652   ssize_t retval;
 653   if (path != NULL && strcmp(path, "/proc/self/exe") == 0) {
 654     const char *procSelfExe = dmtcp_get_executable_path();
 655     strncpy(buf, procSelfExe, bufsiz);
 656     retval = bufsiz > strlen(procSelfExe) ? strlen(procSelfExe) : bufsiz;
 657   } else {
 658     updateStatPath(path, &newpath);
 659     retval = _real_readlink(newpath, buf, bufsiz);
 660   }
 661   DMTCP_PLUGIN_ENABLE_CKPT();
 662   return retval;
 663 }
 664 
 665 extern "C" ssize_t __readlink_chk(const char *path, char *buf,
 666                                   size_t bufsiz, size_t buflen)
 667 {
 668   return readlink(path, buf, bufsiz);
 669 }
 670 
 671 extern "C" int fcntl(int fd, int cmd, ...)
 672 {
 673   void *arg = NULL;
 674   va_list ap;
 675   va_start(ap, cmd);
 676   arg = va_arg(ap, void *);
 677   va_end(ap);
 678 
 679   DMTCP_PLUGIN_DISABLE_CKPT();
 680 
 681   int res = _real_fcntl(fd, cmd, arg);
 682   if (res != -1 &&
 683 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
 684       (cmd == F_DUPFD || cmd == F_DUPFD_CLOEXEC) &&
 685 #else
 686       (cmd == F_DUPFD) &&
 687 #endif
 688       dmtcp_is_running_state()) {
 689     FileConnList::instance().processDup(fd, res);
 690   }
 691 
 692   DMTCP_PLUGIN_ENABLE_CKPT();
 693   return res;
 694 }
 695 
 696 extern "C" char *realpath(const char *path, char *resolved_path)
 697 {
 698   char *ret;
 699   if (Util::strStartsWith(path, "/dev/pts")) {
 700     JASSERT(strlen(path) < PATH_MAX);
 701     if (resolved_path == NULL) {
 702       ret = (char*) malloc(strlen(path) + 1);
 703     } else {
 704       ret = resolved_path;
 705     }
 706     strcpy(ret, path);
 707   } else {
 708     ret = _real_realpath(path, resolved_path);
 709   }
 710   return ret;
 711 }
 712 
 713 extern "C" char *__realpath(const char *path, char *resolved_path)
 714 {
 715   return realpath(path, resolved_path);
 716 }
 717 
 718 extern "C" char *__realpath_chk(const char *path, char *resolved_path,
 719                                 size_t resolved_len)
 720 {
 721   return realpath(path, resolved_path);
 722 }
 723 
 724 extern "C" char *canonicalize_file_name(const char *path)
 725 {
 726   return realpath(path, NULL);
 727 }
 728 
 729 extern "C" int access(const char *path, int mode)
 730 {
 731   if (Util::strStartsWith(path, "/dev/pts")) {
 732     char currPtsDevName[32];
 733     DMTCP_PLUGIN_DISABLE_CKPT();
 734     SharedData::getRealPtyName(path, currPtsDevName, sizeof(currPtsDevName));
 735     int ret = _real_access(currPtsDevName, mode);
 736     DMTCP_PLUGIN_ENABLE_CKPT();
 737     return ret;
 738   }
 739   return _real_access(path, mode);
 740 }
 741 
 742 #if 0
 743 // TODO:  ioctl must use virtualized pids for request = TIOCGPGRP / TIOCSPGRP
 744 // These are synonyms for POSIX standard tcgetpgrp / tcsetpgrp
 745 extern "C" {
 746 int send_sigwinch = 0;
 747 }
 748 
 749 extern "C" int ioctl(int d,  unsigned long int request, ...)
 750 {
 751   va_list ap;
 752   int retval;
 753 
 754   if (send_sigwinch && request == TIOCGWINSZ) {
 755     send_sigwinch = 0;
 756     va_list local_ap;
 757     va_copy(local_ap, ap);
 758     va_start(local_ap, request);
 759     struct winsize * win = va_arg(local_ap, struct winsize *);
 760     va_end(local_ap);
 761     retval = _real_ioctl(d, request, win);  // This fills in win
 762     win->ws_col--; // Lie to application, and force it to resize window,
 763                    //  reset any scroll regions, etc.
 764     kill(getpid(), SIGWINCH); // Tell application to look up true winsize
 765                               // and resize again.
 766   } else {
 767     void * arg;
 768     va_start(ap, request);
 769     arg = va_arg(ap, void *);
 770     va_end(ap);
 771     retval = _real_ioctl(d, request, arg);
 772   }
 773   return retval;
 774 }
 775 #endif

/* [<][>][^][v][top][bottom][index][help] */