Пример #1
0
err_t sys_getnameinfo(const sys_sockaddr_t* addr, char** host_out, char** serv_out, int flags)
{
  char* host_buf=0;
  char* new_host_buf;
  char* serv_buf=0;
  char* new_serv_buf;
  int host_buf_sz = NI_MAXHOST;
  int serv_buf_sz = NI_MAXSERV;
  int got;
  err_t err_out;

  STARTING_SLOW_SYSCALL;

  while( 1 ) {
    new_host_buf = (char*) qio_realloc(host_buf, host_buf_sz);
    new_serv_buf = (char*) qio_realloc(serv_buf, serv_buf_sz);
    if( ! new_host_buf || ! new_serv_buf ) {
      qio_free(host_buf);
      qio_free(serv_buf);
      err_out = ENOMEM;
      goto error;
    }
    host_buf = new_host_buf;
    serv_buf = new_serv_buf;

    got = getnameinfo((const struct sockaddr*) & addr->addr, addr->len, 
                      host_buf, host_buf_sz,
                      serv_buf, serv_buf_sz,
                      flags);

#ifndef EAI_OVERFLOW
    break; // oddly enough... old Mac OS X does not have EAI_OVERFLOW.
#else
    if( got != EAI_OVERFLOW ) break;
    host_buf_sz *= 2;
    serv_buf_sz *= 2;
#endif
  }

  if( got == 0 ) {
    *host_out = NULL;
    *serv_out = NULL;
    err_out = 0;
  } else {
    *host_out = host_buf;
    *serv_out = serv_buf;
    if( got == EAI_SYSTEM ) err_out = errno;
    else err_out = GAI_ERROR_OFFSET + got;
  }

error:

  DONE_SLOW_SYSCALL;

  return err_out;
}
Пример #2
0
// returns an allocated string in string_out, which must be freed.
err_t sys_readlink(const char* path, const char** string_out)
{
  ssize_t got;
  char* buf = NULL;
  char* newbuf;
  int buf_sz = 248;
  err_t ret = EINVAL;

  while( 1 ) {
    newbuf = (char*) qio_realloc(buf, buf_sz);
    if( ! newbuf ) {
      qio_free(buf);
      return ENOMEM;
    }
    buf = newbuf;
    got = readlink(path, buf, buf_sz);
    if( got == -1 ) {
      qio_free(buf);
      *string_out = NULL;
      return errno;
    }
    if( got+1 < buf_sz ) {
      buf[got] = '\0';
      // OK!
      *string_out = buf;
      ret = 0;
      break;
    }
    // otherwise, buffer is too small.
    buf_sz *= 2;
  }

  return ret;
}
Пример #3
0
// This routine returns a malloc'd string through its path_out pointer.
// The caller is responsible for freeing that memory.
err_t sys_getcwd(const char** path_out)
{
  int sz = 128;
  char* buf;
  char* got;
  err_t err = 0;

  buf = (char*) qio_malloc(sz);
  if( !buf ) return ENOMEM;
  while( 1 ) {
    got = getcwd(buf, sz);
    if( got != NULL ) break;
    else if( errno == ERANGE ) {
      // keep looping but with bigger buffer.
      sz = 2*sz;
      got = (char*) qio_realloc(buf, sz);
      if( ! got ) {
        qio_free(buf);
        return ENOMEM;
      }
    } else {
      // Other error, stop.
      err = errno;
    }
  }

  *path_out = buf;
  return err;
}
Пример #4
0
// Write from curl to a string. Note that userdata is a str_t, since nuch as we have
// to keep track of how much we read in  buf_writer, we have to keep track of how
// long our string is so that we cann lengthen it via realloc as we need to.
static
size_t chpl_curl_write_string(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct str_t *str = (struct str_t *)userp;

  str->mem = (char*)qio_realloc(str->mem, str->size + realsize + 1);
  if(str->mem == NULL) {
    return 0;
  }

  chpl_memcpy(&(str->mem[str->size]), contents, realsize);
  str->size += realsize;
  str->mem[str->size] = 0;

  return realsize;
}
Пример #5
0
qioerr hdfs_getcwd(void* file, const char** path_out, void* fs)
{
  int    sz   = 128;
  char*  buf  = (char*) qio_malloc(sz);
  qioerr err = 0;

  if ( !buf )
    QIO_GET_CONSTANT_ERROR(err, ENOMEM, "Out of memory in hdfs_getcwd");

  // hdfsGetWorkingDirectory will return 0 if buf[] is not large enough
  // If this happens, grow the buffer and try again
  while (err == 0 && hdfsGetWorkingDirectory(to_hdfs_fs(fs)->hfs, buf, sz) == 0) {
    if (errno == ERANGE) {
      int   newSz  = 2 * sz;
      char* newBuf = (char*) qio_realloc(buf, newSz);

      if (newBuf == 0) {
        QIO_GET_CONSTANT_ERROR(err, ENOMEM, "Out of memory in hdfs_getcwd");
      } else {
        sz  = newSz;
        buf = newBuf;
      }

    } else {
      // Other error, stop.
      QIO_GET_CONSTANT_ERROR(err, EREMOTEIO, "Unable to get path to file in HDFS");
    }
  }

  if (err != 0) {
    qio_free(buf);
    buf = 0;
  }

  *path_out = buf;

  return err;
}
Пример #6
0
// This routine returns a malloc'd string through its path_out pointer.
// The caller is responsible for freeing that memory.
err_t sys_getcwd(const char** path_out)
{
  int   sz  = 128;
  char* buf = (char*) qio_malloc(sz);
  err_t err = (buf == 0) ? ENOMEM : 0;

  // getcwd() returns 0 if the provided buffer is too small
  // If this happens, grow the buffer and try again
  while (err == 0 && getcwd(buf, sz) == 0) {
    if (errno == ERANGE) {
      int   newSz  = 2 * sz;
      char* newBuf = (char*) qio_realloc(buf, newSz);

      if (newBuf == 0) {
        qio_free(buf);
        err = ENOMEM;
      } else {
        sz  = newSz;
        buf = newBuf;
      }

    } else {
      err = errno;
    }
  }

  if (err != 0) {
    qio_free(buf);
    sz  = 0;
    buf = 0;
  }

  *path_out = buf;

  return err;
}
Пример #7
0
qioerr hdfs_getpath(void* file, const char** string_out, void* fs)  {
  // Speculatively allocate 128 bytes for the string
  int sz = 128;
  int left = 0;
  char* buf;
  char* got;
  qioerr err = 0;

  const char* host = to_hdfs_fs(fs)->fs_name;
  int port = to_hdfs_fs(fs)->fs_port;
  const char* path = to_hdfs_file(file)->pathnm;

  buf = (char*) qio_malloc(sz);

  if( !buf )
    QIO_GET_CONSTANT_ERROR(err, ENOMEM, "Out of memory in hdfs_getpath");

  while (1) {
    left = snprintf(buf, sz, "hdfs://%s:%d/%s", host, port, path);
    if (left > -1 && left < sz) {
      break;
    } else {
      // keep looping but with bigger buffer.
      // We know the size that we need now if n > -1
      sz = left > -1 ? left + 1 : 2*sz;
      got = (char*) qio_realloc(buf, sz);
      if( ! got ) {
        qio_free(buf);
        QIO_GET_CONSTANT_ERROR(err, ENOMEM, "Out of memory in hdfs_getpath");
      }
    }
  }

  *string_out = buf;
  return err;
}
Пример #8
0
// allocates and returns an error string in *string_out
// which must be freed.
static
err_t sys_strerror_internal(err_t error, char** string_out, size_t extra_space)
{
  // normal errors are in normal places.
  // EAI_AGAIN... etc are at 10000 + num.
  int buf_sz = 248 + extra_space;
  char* buf = NULL;
  char* newbuf;
  const char* errmsg;
  int got;
  err_t err_out;

  err_out = 0;

  if( error == 0 ||
      (EXTEND_ERROR_OFFSET <= error
                           && error < EXTEND_ERROR_OFFSET+EXTEND_ERROR_NUM) ) {
    if( error == 0 ) errmsg = error_string_no_error;
    else errmsg = extended_errors[error - EXTEND_ERROR_OFFSET];
    buf_sz = strlen(errmsg) + 1;
    buf = (char*) qio_malloc(buf_sz + extra_space);
    if( ! buf ) return ENOMEM;
    strcpy(buf, errmsg);
    *string_out = buf;
    return 0;
  }

  while( 1 ) {
    newbuf = (char*) qio_realloc(buf, buf_sz + extra_space);
    if( ! newbuf ) {
      qio_free(buf);
      return ENOMEM;
    }
    buf = newbuf;
    got = sys_xsi_strerror_r(error, buf, buf_sz);
    if( got == 0 ) break;
    if( got == -1 && errno != ERANGE ) {
      err_out = errno;
      break;
    }
    buf_sz *= 2; // try again with a bigger buffer.
  }

  // maybe it's a EAI/gai error, which we add GAI_ERROR_OFFSET to.
#ifdef HAS_GETADDRINFO
  if( got == -1 && err_out == EINVAL ) {
    const char* gai_str;
    int len;
    gai_str = gai_strerror(error - GAI_ERROR_OFFSET);

    if( ! gai_str ) {
      err_out = errno;
    } else {
      len = strlen(gai_str);
      if( len + 1 > buf_sz ) {
        newbuf = (char*) qio_realloc(buf, len + 1 + extra_space);
        if( ! newbuf ) {
          qio_free(buf);
          return ENOMEM;
        }
        buf = newbuf;
      }
      strcpy(buf, gai_str);
    }
  }
#endif

  *string_out = buf;
  return err_out;
}