root/opal/util/opal_getcwd.c

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

DEFINITIONS

This source file includes following definitions.
  1. opal_getcwd

   1 /*
   2  * Copyright (c) 2007      Cisco Systems, Inc.  All rights reserved.
   3  * $COPYRIGHT$
   4  *
   5  * Additional copyrights may follow
   6  *
   7  * $HEADER$
   8  */
   9 
  10 #include "opal_config.h"
  11 
  12 #include <stdio.h>
  13 #include <stdlib.h>
  14 #ifdef HAVE_SYS_TYPES_H
  15 #include <sys/types.h>
  16 #endif
  17 #ifdef HAVE_SYS_STAT_H
  18 #include <sys/stat.h>
  19 #endif
  20 #ifdef HAVE_UNISTD_H
  21 #include <unistd.h>
  22 #endif
  23 #include <string.h>
  24 
  25 #include "opal/util/basename.h"
  26 #include "opal/util/opal_getcwd.h"
  27 #include "opal/util/string_copy.h"
  28 #include "opal/constants.h"
  29 
  30 
  31 /*
  32  * Use $PWD instead of getcwd() a) if $PWD exists and b) is a valid
  33  * synonym for the results from getcwd(). If both of these conditions
  34  * are not met, just fall back and use the results of getcwd().
  35  */
  36 int opal_getcwd(char *buf, size_t size)
  37 {
  38     char cwd[OPAL_PATH_MAX];
  39     char *pwd = getenv("PWD");
  40     struct stat a, b;
  41     char *shortened;
  42 
  43     /* Bozo checks (e.g., if someone accidentally passed -1 to the
  44        unsigned "size" param) */
  45     if (NULL == buf || size > INT_MAX) {
  46         return OPAL_ERR_BAD_PARAM;
  47     }
  48 
  49     /* Call getcwd() to get a baseline result */
  50     if (NULL == getcwd(cwd, sizeof(cwd))) {
  51         return OPAL_ERR_IN_ERRNO;
  52     }
  53 
  54 #if !defined(HAVE_SYS_STAT_H)
  55     /* If we don't have stat(), then we can't tell if the $PWD and cwd
  56        are the same, so just fall back to getcwd(). */
  57     pwd = cwd;
  58 #else
  59     if (NULL == pwd) {
  60         pwd = cwd;
  61     } else {
  62         /* If the two are not the same value, figure out if they are
  63            pointing to the same place */
  64         if (0 != strcmp(pwd, cwd)) {
  65             /* If we can't stat() what getcwd() gave us, give up */
  66             if (0 != stat(cwd, &a)) {
  67                 return OPAL_ERR_IN_ERRNO;
  68             }
  69             /* If we can't stat() $PWD, then $PWD could just be stale
  70                -- so ignore it. */
  71             else if (0 != stat(pwd, &b)) {
  72                 pwd = cwd;
  73             }
  74             /* Otherwise, we successfully stat()'ed them both, so
  75                compare.  If either the device or inode is not the
  76                same, then fallback to getcwd(). */
  77             else {
  78                 if (a.st_dev != b.st_dev || a.st_ino != b.st_ino) {
  79                     pwd = cwd;
  80                 }
  81             }
  82         }
  83     }
  84 #endif
  85 
  86     /* If we got here, pwd is pointing to the result that we want to
  87        give.  Ensure the user's buffer is long enough.  If it is, copy
  88        in the value and be done. */
  89     if (strlen(pwd) > size) {
  90         /* if it isn't big enough, give them as much
  91          * of the basename as possible
  92          */
  93         shortened = opal_basename(pwd);
  94         opal_string_copy(buf, shortened, size);
  95         free(shortened);
  96         /* indicate that it isn't the full path */
  97         return OPAL_ERR_TEMP_OUT_OF_RESOURCE;
  98     }
  99     opal_string_copy(buf, pwd, size);
 100     return OPAL_SUCCESS;
 101 }

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