root/plugin/pid/pid_filewrappers.cpp

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

DEFINITIONS

This source file includes following definitions.
  1. updateProcPathVirtualToReal
  2. updateProcPathRealToVirtual
  3. open
  4. open64
  5. fopen
  6. fopen64
  7. fclose
  8. __xstat
  9. __xstat64
  10. __fxstat
  11. __fxstat64
  12. __lxstat
  13. __lxstat64
  14. readlink
  15. realpath
  16. __realpath
  17. __realpath_chk
  18. canonicalize_file_name
  19. access
  20. ioctl

   1 /****************************************************************************
   2  *   Copyright (C) 2006-2013 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 /* realpath is defined with "always_inline" attribute. GCC>=4.7 disallows us
  23  * to define the realpath wrapper if compiled with -O0. Here we are renaming
  24  * realpath so that later code does not see the declaration of realpath as
  25  * inline. Normal user code from other files will continue to invoke realpath
  26  * as an inline function calling __ptsname_r_chk. Later in this file
  27  * we define __ptsname_r_chk to call the original realpath 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 open open_always_inline
  36 #define open64 open64_always_inline
  37 #define readlink readlink_always_inline
  38 #define realpath realpath_always_inline
  39 
  40 #include <stdio.h>
  41 #include <stdarg.h>
  42 #include <sys/ioctl.h>
  43 #include <string.h>
  44 
  45 #undef open
  46 #undef open64
  47 #undef readlink
  48 #undef realpath
  49 
  50 #include "jassert.h"
  51 #include "jfilesystem.h"
  52 #include "jconvert.h"
  53 #include "pidwrappers.h"
  54 #include "util.h"
  55 #include "virtualpidtable.h"
  56 #include "dmtcp.h"
  57 #include "pid.h"
  58 
  59 #define PROC_PREFIX "/proc/"
  60 
  61 using namespace dmtcp;
  62 
  63 // FIXME:  This function needs third argument newpathsize, or assume PATH_MAX
  64 static void updateProcPathVirtualToReal(const char *path, char **newpath)
  65 {
  66   if (Util::strStartsWith(path, PROC_PREFIX)) {
  67     int index = strlen(PROC_PREFIX);
  68     char *rest;
  69     pid_t virtualPid = strtol(&path[index], &rest, 0);
  70     if (virtualPid > 0 && *rest == '/') {
  71       pid_t realPid = VIRTUAL_TO_REAL_PID(virtualPid);
  72       sprintf(*newpath, "/proc/%d%s", realPid, rest);
  73       return;
  74     }
  75   }
  76   *newpath = (char *)path;
  77 }
  78 
  79 // FIXME:  This function needs third argument newpathsize, or assume PATH_MAX
  80 static void updateProcPathRealToVirtual(const char *path, char **newpath)
  81 {
  82   if (Util::strStartsWith(path, PROC_PREFIX)) {
  83     int index = strlen(PROC_PREFIX);
  84     char *rest;
  85     pid_t realPid = strtol(&path[index], &rest, 0);
  86     if (realPid > 0 && *rest == '/') {
  87       pid_t virtualPid = REAL_TO_VIRTUAL_PID(realPid);
  88       sprintf(*newpath, "/proc/%d%s", virtualPid, rest);
  89       return;
  90     }
  91   }
  92   *newpath = (char *)path;
  93   return;
  94 }
  95 
  96 /* Used by open() wrapper to do other tracking of open apart from
  97    synchronization stuff. */
  98 extern "C" int open (const char *path, int flags, ... )
  99 {
 100   mode_t mode = 0;
 101   // Handling the variable number of arguments
 102   if (flags & O_CREAT) {
 103     va_list arg;
 104     va_start (arg, flags);
 105     mode = va_arg (arg, int);
 106     va_end (arg);
 107   }
 108   char tmpbuf[PATH_MAX];
 109   char *newpath = tmpbuf;
 110   updateProcPathVirtualToReal(path, &newpath);
 111   return _real_open(newpath, flags, mode);
 112 }
 113 
 114 // FIXME: Add the 'fn64' wrapper test cases to dmtcp test suite.
 115 extern "C" int open64 (const char *path, int flags, ... )
 116 {
 117   mode_t mode = 0;
 118   // Handling the variable number of arguments
 119   if (flags & O_CREAT) {
 120     va_list arg;
 121     va_start (arg, flags);
 122     mode = va_arg (arg, int);
 123     va_end (arg);
 124   }
 125   char tmpbuf[PATH_MAX];
 126   char *newpath = tmpbuf;
 127   updateProcPathVirtualToReal(path, &newpath);
 128   return _real_open64(newpath, flags, mode);
 129 }
 130 
 131 extern "C" FILE *fopen (const char* path, const char* mode)
 132 {
 133   char tmpbuf[PATH_MAX];
 134   char *newpath = tmpbuf;
 135   updateProcPathVirtualToReal(path, &newpath);
 136   return _real_fopen(newpath, mode);
 137 }
 138 
 139 extern "C" FILE *fopen64 (const char* path, const char* mode)
 140 {
 141   char tmpbuf[PATH_MAX];
 142   char *newpath = tmpbuf;
 143   updateProcPathVirtualToReal(path, &newpath);
 144   return _real_fopen64(newpath, mode);
 145 }
 146 
 147 extern "C" int fclose(FILE *fp)
 148 {
 149   // This wrapper is needed to ensure that we call the "GLIBC_2.1" version in
 150   // 32-bit systems.  Ideally, this should be done only in the plugin that uses
 151   // fclose (e.g. File plugin), but doing it here will work as well.
 152   return _real_fclose(fp);
 153 }
 154 
 155 extern "C" int __xstat(int vers, const char *path, struct stat *buf)
 156 {
 157   char tmpbuf[PATH_MAX];
 158   char *newpath = tmpbuf;
 159   updateProcPathVirtualToReal(path, &newpath);
 160   int retval = _real_xstat( vers, newpath, buf );
 161   return retval;
 162 }
 163 
 164 extern "C" int __xstat64(int vers, const char *path, struct stat64 *buf)
 165 {
 166   char tmpbuf[PATH_MAX];
 167   char *newpath = tmpbuf;
 168   updateProcPathVirtualToReal(path, &newpath);
 169   int retval = _real_xstat64( vers, newpath, buf );
 170   return retval;
 171 }
 172 
 173 #if 0
 174 extern "C" int __fxstat(int vers, int fd, struct stat *buf)
 175 {
 176   int retval = _real_fxstat(vers, fd, buf);
 177   return retval;
 178 }
 179 
 180 extern "C" int __fxstat64(int vers, int fd, struct stat64 *buf)
 181 {
 182   int retval = _real_fxstat64(vers, fd, buf);
 183   return retval;
 184 }
 185 #endif
 186 
 187 extern "C" int __lxstat(int vers, const char *path, struct stat *buf)
 188 {
 189   char tmpbuf[PATH_MAX];
 190   char *newpath = tmpbuf;
 191   updateProcPathVirtualToReal(path, &newpath);
 192   int retval = _real_lxstat( vers, newpath, buf );
 193   return retval;
 194 }
 195 
 196 extern "C" int __lxstat64(int vers, const char *path, struct stat64 *buf)
 197 {
 198   char tmpbuf[PATH_MAX];
 199   char *newpath = tmpbuf;
 200   updateProcPathVirtualToReal(path, &newpath);
 201   int retval = _real_lxstat64( vers, newpath, buf );
 202   return retval;
 203 }
 204 
 205 extern "C" ssize_t readlink(const char *path, char *buf, size_t bufsiz)
 206 {
 207   char tmpbuf[PATH_MAX];
 208   char *newpath = tmpbuf;
 209   //FIXME:  Suppose the real path is longer than PATH_MAX.  Do we check?
 210   updateProcPathVirtualToReal(path, &newpath);
 211   return NEXT_FNC(readlink) (newpath, buf, bufsiz);
 212 #if 0
 213   if (ret != -1) {
 214     JASSERT(ret < bufsiz)(ret)(bufsiz)(buf)(newpath);
 215     buf[ret] = '\0'; // glibc-2.13: readlink doesn't terminate buf w/ null char
 216     updateProcPathRealToVirtual(buf, newpath);
 217     JASSERT(strlen(newpath) < bufsiz)(newpath)(bufsiz);
 218     strcpy(buf, newpath);
 219   }
 220   return ret;
 221 #endif
 222 }
 223 
 224 extern "C" char *realpath(const char *path, char *resolved_path)
 225 {
 226   char tmpbuf[PATH_MAX];
 227   char *newpath = tmpbuf;
 228   updateProcPathVirtualToReal(path, &newpath);
 229   // Required for matlab-2012 and later; realpath is a versioned symbol.
 230   char *retval = NEXT_FNC_DEFAULT(realpath) (newpath, resolved_path);
 231   if (retval != NULL) {
 232     updateProcPathRealToVirtual(retval, &newpath);
 233     strcpy(retval, newpath);
 234   }
 235   return retval;
 236 }
 237 
 238 extern "C" char *__realpath(const char *path, char *resolved_path)
 239 {
 240   return realpath(path, resolved_path);
 241 }
 242 
 243 extern "C" char *__realpath_chk(const char *path, char *resolved_path,
 244                                 size_t resolved_len)
 245 {
 246   return realpath(path, resolved_path);
 247 }
 248 
 249 extern "C" char *canonicalize_file_name(const char *path)
 250 {
 251   return realpath(path, NULL);
 252 }
 253 
 254 #include <unistd.h>
 255 extern "C" int access(const char *path, int mode)
 256 {
 257   char tmpbuf[PATH_MAX];
 258   char *newpath = tmpbuf;
 259   updateProcPathVirtualToReal(path, &newpath);
 260   return NEXT_FNC(access) (newpath, mode);
 261 }
 262 
 263 // TODO:  ioctl must use virtualized pids for request = TIOCGPGRP / TIOCSPGRP
 264 // These are synonyms for POSIX standard tcgetpgrp / tcsetpgrp
 265 extern "C" {
 266 int send_sigwinch = 0;
 267 }
 268 
 269 
 270 extern "C" int ioctl(int d,  unsigned long int request, ...)
 271 {
 272   va_list ap;
 273   int retval;
 274 
 275   if (send_sigwinch && request == TIOCGWINSZ) {
 276     send_sigwinch = 0;
 277     va_list local_ap;
 278     va_copy(local_ap, ap);
 279     va_start(local_ap, request);
 280     struct winsize * win = va_arg(local_ap, struct winsize *);
 281     va_end(local_ap);
 282     retval = _real_ioctl(d, request, win);  // This fills in win
 283     win->ws_col--; // Lie to application, and force it to resize window,
 284                    //  reset any scroll regions, etc.
 285     kill(getpid(), SIGWINCH); // Tell application to look up true winsize
 286                               // and resize again.
 287   } else {
 288     void * arg;
 289     va_start(ap, request);
 290     arg = va_arg(ap, void *);
 291     va_end(ap);
 292     retval = _real_ioctl(d, request, arg);
 293   }
 294   return retval;
 295 }

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