blob: 500378a2a135e3e585a353bb7cf7f2d5cdf5e1f9 [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
//
/// \file api.cpp
/// \brief The top-level API entry points for STFS Lib
///
/// This file contains the STFS API interface shell implementation. It contains
/// the interface only; actual function is in different files. The functional
/// STFS API is modeled after the POSIX API. It is POSIX-like, not POSIX
/// compliant in its behavior. For detailed information please refer to Scratch
/// & Temporary File System(STFS) External Specification.
//
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
///////////////////////////////////////////////////////////////////////////////
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <iostream>
#include <ctype.h>
#include "stfs/stfslib.h"
#include "stfs_metadata.h"
#include "stfs_defs.h"
#include "stfs_util.h"
#include "stfs_message.h"
#include "stfslibcalls.h"
#include "stfsinfocalls.h"
#include "send.h"
using namespace STFS;
// -------------------------
// STFS Utilities
// -------------------------
/// For now, stubs are used here for the utilities
/// \brief STFS_openers()
int STFS_openers(stfs_nodeid_t pv_nid,
char *pp_path,
long *pp_previndex,
stfs_nodeid_t &pv_openernid,
pid_t &pv_openerpid,
char *pp_openername)
{
const char *WHERE = "STFS_openers";
STFS_ScopeTrace lv_st(WHERE);
if((!pp_path) || (!pp_previndex) || (!pp_openername)) {
errno = EINVAL;
return -1;
}
STFS_util::Init(false);
return STFSINFO_openers(pv_nid,
pp_path,
pp_previndex,
pv_openernid,
pv_openerpid,
pp_openername);
}
int STFS_fopeners(stfs_fhndl_t pv_Fhandle,
long *pp_PrevIndex,
stfs_nodeid_t &pv_OpenerNid,
pid_t &pv_OpenerPid,
char *pp_OpenerName,
char *pp_OpenPath)
{
const char *WHERE = "STFS_fopeners";
STFS_ScopeTrace lv_st(WHERE,2);
if((!pp_PrevIndex) || (!pp_OpenerName) || (!pp_OpenPath)) {
errno = EINVAL;
return -1;
}
STFS_util::Init(false);
return STFSINFO_fopeners(pv_Fhandle,
pp_PrevIndex,
pv_OpenerNid,
pv_OpenerPid,
pp_OpenerName,
pp_OpenPath);
}
int STFS_stat(stfs_nodeid_t pv_Nid,
char *pp_Path,
long *pp_PrevIndex,
stfs_statmask_t pv_Mask,
struct stfs_stat *pp_Buf)
{
const char *WHERE = "STFS_stat";
STFS_ScopeTrace lv_st(WHERE,2);
if((!pp_Path) || (!pp_PrevIndex) || (!pp_Buf)) {
errno = EINVAL;
return -1;
}
STFS_util::Init(false);
return STFSINFO_stat(pv_Nid,
pp_Path,
pp_PrevIndex,
pv_Mask,
pp_Buf);
}
int STFS_fstat(stfs_fhndl_t pv_Fhandle,
stfs_statmask_t pv_Mask,
struct stfs_stat *pp_Buf)
{
const char *WHERE = "STFS_fstat";
STFS_ScopeTrace lv_st(WHERE,2);
if(!pp_Buf) {
errno = EINVAL;
return -1;
}
STFS_util::Init(false);
return STFSINFO_fstat(pv_Fhandle,
pv_Mask,
pp_Buf);
}
// -------------------------
// STFS_FH_* Set Manipulators
// -------------------------
/// \brief Removes a file handle from the set
void STFS_FH_CLR( stfs_fhndl_t pv_fhandle
, fh_set *pp_set)
{
const char *WHERE = "STFS_FH_CLR";
STFS_ScopeTrace lv_st(WHERE,2);
try {
std::vector<stfs_fhndl_t>::iterator it;
for (it = pp_set->FhArray.begin();
it != pp_set->FhArray.end();
it++) {
if(pv_fhandle == *it) {
pp_set->FhArray.erase(it);
break;
}
}
}
catch(...) {
TRACE_PRINTF1(1,"In the catch-all exception handler\n");
STFS_util::SoftwareFailureHandler(WHERE);
errno=EFAULT;
}
}
/// \brief Tests for existence of file handle in a set
int STFS_FH_ISSET( stfs_fhndl_t pv_fhandle
, fh_set *pp_set)
{
const char *WHERE = "STFS_FH_ISSET";
STFS_ScopeTrace lv_st(WHERE,2);
try {
int lv_RetVal = 0;
std::vector<stfs_fhndl_t>::iterator it;
for (it = pp_set->FhArray.begin();
it != pp_set->FhArray.end();
it++) {
if(pv_fhandle == *it) {
lv_RetVal = 1;
break;
}
}
return lv_RetVal;
}
catch (...) {
TRACE_PRINTF1(1,"In the catch-all exception handler\n");
STFS_util::SoftwareFailureHandler(WHERE);
errno=EFAULT;
return -1;
}
}
/// \brief Adds a file handle to the set
void STFS_FH_SET( stfs_fhndl_t pv_fhandle
, fh_set *pp_set)
{
const char *WHERE = "STFS_FH_SET";
STFS_ScopeTrace lv_st(WHERE,2);
try {
pp_set->FhArray.push_back(pv_fhandle);
}
catch (...) {
TRACE_PRINTF1(1,"In the catch-all exception handler\n");
STFS_util::SoftwareFailureHandler(WHERE);
errno=EFAULT;
}
}
/// \brief Clears all file handles from the set
void STFS_FH_ZERO(fh_set *pp_set)
{
const char *WHERE = "STFS_FH_ZERO";
try {
STFS_ScopeTrace lv_st(WHERE,2);
pp_set->FhArray.clear();
}
catch (...) {
TRACE_PRINTF1(1,"In the catch-all exception handler\n");
STFS_util::SoftwareFailureHandler(WHERE);
errno=EFAULT;
}
}
// ----------------
// Functions
// ----------------
/// \brief Close a file handle
int STFS_close(stfs_fhndl_t fhandle)
{
const char *WHERE = "STFS_close";
STFS_ScopeTrace lv_st(WHERE,2);
try {
return STFSLIB_close(fhandle);
}
catch(...) {
TRACE_PRINTF1(1,"In the catch-all exception handler\n");
STFS_util::SoftwareFailureHandler(WHERE);
errno=EFAULT;
return -1;
}
}
/// \brief Get error information from a file handle
int STFS_error ( stfs_fhndl_t pv_fhandle,
int *pp_error,
int *pp_addlError,
char *pp_context,
size_t pv_contextMaxLen,
size_t *pp_contextLen ) {
const char *WHERE = "STFS_error";
STFS_ScopeTrace lv_st (WHERE,2);
try {
return STFSLIB_error (pv_fhandle, pp_error, pp_addlError,
pp_context, pv_contextMaxLen, pp_contextLen );
}
catch (...) {
TRACE_PRINTF1 (1, "In the catch-all exception handler \n");
STFS_util::SoftwareFailureHandler (WHERE);
errno=EFAULT;
return -1;
}
}
/// \brief Manipulate a file handle
int STFS_fcntl( stfs_fhndl_t fhandle
, int cmd
, ...)
{
const char *WHERE = "STFS_fcntl";
STFS_ScopeTrace lv_st(WHERE,2);
if(cmd==F_SETFL)
{
//if F_SETFL is used for second argument,
// then third argument must also be set
long arglong,
bitmask;
va_list l_arg;
va_start(l_arg, cmd);
arglong = va_arg(l_arg, long);
//Checking to ensure only allowed bits are set
bitmask=(O_RDONLY|O_WRONLY|O_RDWR|O_APPEND|O_EXCL|O_NONBLOCK|O_TRUNC);
ASSERT((arglong&(~bitmask))==0);
arglong &= bitmask;
try {
return STFSLIB_fcntl(fhandle, cmd, arglong);
}
catch(...) {
TRACE_PRINTF1(1,"In the catch-all exception handler\n");
STFS_util::SoftwareFailureHandler(WHERE);
errno=EFAULT;
return -1;
}
}
else
{
try {
return STFSLIB_fcntl(fhandle, cmd);
}
catch(...) {
TRACE_PRINTF1(1,"In the catch-all exception handler\n");
STFS_util::SoftwareFailureHandler(WHERE);
errno=EFAULT;
return -1;
}
}
}
/// \brief Reposition read/write file offset
off_t STFS_lseek( stfs_fhndl_t fhandle
, off_t offset
, int whence)
{
const char *WHERE = "STFS_lseek";
STFS_ScopeTrace lv_st(WHERE,2);
try {
return STFSLIB_lseek(fhandle, offset, whence);
}
catch(...) {
TRACE_PRINTF1(1,"In the catch-all exception handler\n");
STFS_util::SoftwareFailureHandler(WHERE);
errno=EFAULT;
return -1;
}
}
/// \brief Create and open a unique file name
stfs_fhndl_t STFS_mkstemp (char *ctemplate)
{
const char *WHERE = "STFS_mkstemp";
STFS_ScopeTrace lv_st(WHERE,2);
if(ctemplate == NULL)
{
errno=EFAULT;
return -1;
}
for (unsigned int i = 0; i < strlen(ctemplate); i++)
{
if(ctemplate[i] == '/')
{
errno = EINVAL;
return -1;
}
}
if(strlen(ctemplate) > (STFS_PATH_MAX-STFS_NAME_SUFFIX_MAX))
{
errno=ENAMETOOLONG;
return -1;
}
STFS_util::Init(false);
try {
// Rev: Check the STFS_Session to set the errno if the return value (!= 0)
return STFSLIB_mkstemp(ctemplate);
}
catch(...) {
TRACE_PRINTF1(1,"In the catch-all exception handler\n");
STFS_util::SoftwareFailureHandler(WHERE);
// Rev: Check for any standard errno for an unhandled exception
errno=EFAULT;
return -1;
}
}
/// \brief Open a temporary file
stfs_fhndl_t STFS_open( const char *path
, int oflag
, ...)
{
const char *WHERE = "STFS_open";
STFS_ScopeTrace lv_st(WHERE,2);
//Check that the pathname passed is not longer than our MAX
ASSERT(strlen(path) <= STFS_PATH_MAX);
//Checking to ensure only allowed bits are set
int bitmask;
bitmask=(O_RDONLY|O_WRONLY|O_RDWR|O_APPEND|O_EXCL|O_NONBLOCK|O_TRUNC);
ASSERT((oflag&(~bitmask))==0);
//O_CREAT is not supported in initial version of STFS
if((oflag&O_CREAT)==O_CREAT)
{
errno=EINVAL;
return -1;
}
oflag &= bitmask;
STFS_util::Init(false);
try {
return STFSLIB_open(path, oflag);
}
catch(...) {
TRACE_PRINTF1(1,"In the catch-all exception handler\n");
STFS_util::SoftwareFailureHandler(WHERE);
errno=EFAULT;
return -1;
}
}
/// \brief Read from a file handle
long STFS_read( stfs_fhndl_t fhandle
, void *buf
, size_t count)
{
const char *WHERE = "STFS_read";
STFS_ScopeTrace lv_st(WHERE,2);
try {
return STFSLIB_read(fhandle, buf, count);
}
catch(...) {
TRACE_PRINTF1(1,"In the catch-all exception handler\n");
STFS_util::SoftwareFailureHandler(WHERE);
errno=EFAULT;
return -1;
}
}
/// \brief Synchronous I/O multiplexing
int STFS_select( stfs_fhndl_t nfhs
, fh_set *readfhs
, fh_set *writefhs
, fh_set *exceptfhs
, struct timeval *timeout)
{
const char *WHERE = "STFS_select";
STFS_ScopeTrace lv_st(WHERE,2);
try {
return STFSLIB_select(nfhs, readfhs, writefhs, exceptfhs, timeout);
}
catch(...) {
TRACE_PRINTF1(1,"In the catch-all exception handler\n");
STFS_util::SoftwareFailureHandler(WHERE);
errno=EFAULT;
return -1;
}
}
/// \brief Delete a name and possibly the file that it refers to
int STFS_unlink (const char *path)
{
const char *WHERE = "STFS_unlink";
STFS_ScopeTrace lv_st(WHERE,2);
//Check that the pathname passed is not longer than our MAX
ASSERT(strlen(path) <= STFS_PATH_MAX);
STFS_util::Init(false);
try {
return STFSLIB_unlink(path);
}
catch(...) {
TRACE_PRINTF1(1,"In the catch-all exception handler\n");
STFS_util::SoftwareFailureHandler(WHERE);
errno=EFAULT;
return -1;
}
}
/// \brief Write to a file handle
ssize_t STFS_write( stfs_fhndl_t fhandle
, const void *buf
, size_t count)
{
const char *WHERE = "STFS_write";
STFS_ScopeTrace lv_st(WHERE,2);
try {
return STFSLIB_write(fhandle, buf, count);
}
catch(...) {
TRACE_PRINTF1(1,"In the catch-all exception handler\n");
STFS_util::SoftwareFailureHandler(WHERE);
errno=EFAULT;
return -1;
}
}