Beispiel #1
0
def randombytes():
    """
  <Purpose>
    Return a string of random bytes with length 1024

  <Arguments>
    None.

  <Exceptions>
    None.

  <Side Effects>
    This function is metered because it may involve using a hardware source of randomness.

  <Resource Consumption>
    This operation consumes 1024 bytes of random data.

  <Returns>
    The string of bytes.
  """
    # Wait for random resources
    nanny.tattle_quantity('random', 0)

    # If an OS-specific source of randomness is not a found
    # a NotImplementedError would be raised.
    # Anthony - a NotImplementedError will be logged as an internal
    # error so that we will hopefully be able to identify the system,
    # the exception is not passed on because the problem was not
    # caused by the user. The exit code 217 was chosen to be
    # unique from all other exit calls in repy.
    try:
        randomdata = os.urandom(1024)
    except NotImplementedError, e:
        tracebackrepy.handle_internalerror("os.urandom is not implemented " + \
            "(Exception was: %s)" % e.message, 217)
Beispiel #2
0
def listfiles():
  """
   <Purpose>
      Allows the user program to get a list of files in their vessel.

   <Arguments>
      None

   <Exceptions>
      None

   <Side Effects>
      None

  <Resource Consumption>
    Consumes 4K of fileread.

   <Returns>
      A list of strings (file names)
  """
  # We will consume 4K of fileread
  nanny.tattle_quantity('fileread', 4096)

  # Get the list of files from the current directory
  files = os.listdir(repy_constants.REPY_CURRENT_DIR)


  # Return the files
  return files
Beispiel #3
0
def randombytes():
  """
  <Purpose>
    Return a string of random bytes with length 1024

  <Arguments>
    None.

  <Exceptions>
    None.

  <Side Effects>
    This function is metered because it may involve using a hardware source of randomness.

  <Resource Consumption>
    This operation consumes 1024 bytes of random data.

  <Returns>
    The string of bytes.
  """
  # Wait for random resources
  nanny.tattle_quantity('random', 0)

  # If an OS-specific source of randomness is not a found
  # a NotImplementedError would be raised. 
  # Anthony - a NotImplementedError will be logged as an internal
  # error so that we will hopefully be able to identify the system,
  # the exception is not passed on because the problem was not
  # caused by the user. The exit code 217 was chosen to be
  # unique from all other exit calls in repy.
  try:
    randomdata = os.urandom(1024)
  except NotImplementedError, e:
    tracebackrepy.handle_internalerror("os.urandom is not implemented " + \
        "(Exception was: %s)" % e.message, 217)
Beispiel #4
0
def listfiles():
    """
   <Purpose>
      Allows the user program to get a list of files in their vessel.

   <Arguments>
      None

   <Exceptions>
      None

   <Side Effects>
      None

  <Resource Consumption>
    Consumes 4K of fileread.

   <Returns>
      A list of strings (file names)
  """
    # We will consume 4K of fileread
    nanny.tattle_quantity('fileread', 4096)

    # Get the list of files from the current directory
    files = os.listdir(repy_constants.REPY_CURRENT_DIR)

    # Return the files
    return files
Beispiel #5
0
def _read(devs, timeout=None):
    ready = select.select(devs, [], [], timeout)[0]
    if ready:
        dev = ready[0]
        nanny.tattle_quantity("netrecv", 0)
        data = dev.read()
        nanny.tattle_quantity("netrecv", len(data))
        return (dev.alias, data)
    raise TimeoutError("No data read")
Beispiel #6
0
  def write(self, writeitem):
    # block if already over
    nanny.tattle_quantity('lograte', 0)

    # do the actual write
    loggingrepy_core.flush_logger_core.write(self, writeitem)

    # block if over after log write
    writeamt = len(str(writeitem))
    nanny.tattle_quantity('lograte', writeamt)
Beispiel #7
0
    def write(self, writeitem):
        # block if already over
        nanny.tattle_quantity('lograte', 0)

        # do the actual write
        loggingrepy_core.flush_logger_core.write(self, writeitem)

        # block if over after log write
        writeamt = len(str(writeitem))
        nanny.tattle_quantity('lograte', writeamt)
Beispiel #8
0
def removefile(filename):
    """
   <Purpose>
      Allows the user program to remove a file in their area.

   <Arguments>
      filename: the name of the file to remove.   It must not contain 
      characters other than 'a-zA-Z0-9.-_' and cannot be '.', '..' or
      the empty string.

   <Exceptions>
      RepyArgumentError is raised if the filename is invalid.
      FileInUseError is raised if the file is already open.
      FileNotFoundError is raised if the file does not exist

   <Side Effects>
      None

  <Resource Consumption>
      Consumes 4K of fileread.   If successful, also consumes 4K of filewrite.

   <Returns>
      None
  """

    # Raise an RepyArgumentError if the filename isn't valid
    # If the filename is invalid, it will raise an FileNotFoundError, why do
    # an explicit check.
    # _assert_is_allowed_filename(filename)

    OPEN_FILES_LOCK.acquire()
    try:
        # Consume the filewrite resources
        nanny.tattle_quantity('filewrite', 4096)

        # Don't explicitly check for state of the file like os.isfile(), if the file is
        # opened or not when removing. Let python handle that stuff, we will catch exceptions.
        # This way if everything is good os.remove() is called immediatly.

        # Remove the file (failure is an internal error)
        os.remove(filename)

    # I need to catch two separate Errors, to maintain portability between windows and linux
    # even though these checks take a bit more time, these are only executed if there's an
    # error, and I think nobody will see a performance issue here.
    except OSError:
        raise FileNotFoundError('Cannot remove non-existent file "' +
                                filename + '".')
    except WindowsError, err:
        if err.winerror == 2:
            raise FileNotFoundError('Cannot remove non-existent file "' +
                                    filename + '".')
        elif err.winerror == 32:
            raise FileInUseError('Cannot remove file "' + filename +
                                 '" because it is in use!')
Beispiel #9
0
  def writelines(self, writelist):
    # block if already over
    nanny.tattle_quantity('lograte', 0)

    # do the actual writelines()
    loggingrepy_core.flush_logger_core.writelines(self, writelist)

    # block if over after log write
    writeamt = 0
    for writeitem in writelist:
      writeamt = writeamt + len(str(writeitem))
    nanny.tattle_quantity('lograte', writeamt)
Beispiel #10
0
    def writelines(self, writelist):
        # block if already over
        nanny.tattle_quantity('lograte', 0)

        # do the actual writelines()
        loggingrepy_core.flush_logger_core.writelines(self, writelist)

        # block if over after log write
        writeamt = 0
        for writeitem in writelist:
            writeamt = writeamt + len(str(writeitem))
        nanny.tattle_quantity('lograte', writeamt)
Beispiel #11
0
def removefile(filename):
    """
   <Purpose>
      Allows the user program to remove a file in their area.

   <Arguments>
      filename: the name of the file to remove.   It must not contain 
      characters other than 'a-zA-Z0-9.-_' and cannot be '.', '..' or
      the empty string.

   <Exceptions>
      RepyArgumentError is raised if the filename is invalid.
      FileInUseError is raised if the file is already open.
      FileNotFoundError is raised if the file does not exist

   <Side Effects>
      None

  <Resource Consumption>
      Consumes 4K of fileread.   If successful, also consumes 4K of filewrite.

   <Returns>
      None
  """

    # raise an RepyArgumentError if the filename isn't valid
    _assert_is_allowed_filename(filename)

    OPEN_FILES_LOCK.acquire()
    try:
        # Check if the file is in use
        if filename in OPEN_FILES:
            raise FileInUseError('Cannot remove file "' + filename +
                                 '" because it is in use!')

        # Get the absolute file name
        absolute_filename = os.path.abspath(
            os.path.join(repy_constants.REPY_CURRENT_DIR, filename))

        # Check if the file exists
        nanny.tattle_quantity('fileread', 4096)
        if not os.path.isfile(absolute_filename):
            raise FileNotFoundError('Cannot remove non-existent file "' +
                                    filename + '".')

        # Consume the filewrite resources
        nanny.tattle_quantity('filewrite', 4096)

        # Remove the file (failure is an internal error)
        os.remove(absolute_filename)

    finally:
        OPEN_FILES_LOCK.release()
Beispiel #12
0
def removefile(filename):
  """
   <Purpose>
      Allows the user program to remove a file in their area.

   <Arguments>
      filename: the name of the file to remove.   It must not contain 
      characters other than 'a-zA-Z0-9.-_' and cannot be '.', '..' or
      the empty string.

   <Exceptions>
      RepyArgumentError is raised if the filename is invalid.
      FileInUseError is raised if the file is already open.
      FileNotFoundError is raised if the file does not exist

   <Side Effects>
      None

  <Resource Consumption>
      Consumes 4K of fileread.   If successful, also consumes 4K of filewrite.

   <Returns>
      None
  """

  # Raise an RepyArgumentError if the filename isn't valid
  # If the filename is invalid, it will raise an FileNotFoundError, why do
  # an explicit check.
  # _assert_is_allowed_filename(filename)

  OPEN_FILES_LOCK.acquire()
  try:
    # Consume the filewrite resources
    nanny.tattle_quantity('filewrite',4096)
    
    # Don't explicitly check for state of the file like os.isfile(), if the file is
    # opened or not when removing. Let python handle that stuff, we will catch exceptions.
    # This way if everything is good os.remove() is called immediatly.

    # Remove the file (failure is an internal error)
    os.remove(filename)

  # I need to catch two separate Errors, to maintain portability between windows and linux
  # even though these checks take a bit more time, these are only executed if there's an
  # error, and I think nobody will see a performance issue here.
  except OSError:
    raise  FileNotFoundError('Cannot remove non-existent file "'+filename+'".')
  except WindowsError, err:
    if err.winerror == 2:
      raise  FileNotFoundError('Cannot remove non-existent file "'+filename+'".')
    elif err.winerror == 32:
      raise FileInUseError('Cannot remove file "'+filename+'" because it is in use!')
Beispiel #13
0
def removefile(filename):
  """
   <Purpose>
      Allows the user program to remove a file in their area.

   <Arguments>
      filename: the name of the file to remove.   It must not contain 
      characters other than 'a-z0-9.-_' and cannot start with a period or
      the empty string.

   <Exceptions>
      RepyArgumentError is raised if the filename is invalid.
      FileInUseError is raised if the file is already open.
      FileNotFoundError is raised if the file does not exist

   <Side Effects>
      None

  <Resource Consumption>
      Consumes 4K of fileread.   If successful, also consumes 4K of filewrite.

   <Returns>
      None
  """

  # raise an RepyArgumentError if the filename isn't valid
  _assert_is_allowed_filename(filename)

  OPEN_FILES_LOCK.acquire()
  try:
    # Check if the file is in use
    if filename in OPEN_FILES:
      raise FileInUseError('Cannot remove file "'+filename+'" because it is in use!')

    # Get the absolute file name
    absolute_filename = os.path.abspath(os.path.join(repy_constants.REPY_CURRENT_DIR, filename))

    # Check if the file exists
    nanny.tattle_quantity('fileread', 4096)
    if not os.path.isfile(absolute_filename):
      raise FileNotFoundError('Cannot remove non-existent file "'+filename+'".')

    # Consume the filewrite resources
    nanny.tattle_quantity('filewrite',4096)

    # Remove the file (failure is an internal error)
    os.remove(absolute_filename)

  
  finally:
    OPEN_FILES_LOCK.release()
Beispiel #14
0
  def next(self):
    # prevent TOCTOU race with client changing my filehandle
    myfilehandle = self.filehandle
    restrictions.assertisallowed('file.next')

    if "w" in self.mode:
      raise IOError("file.next() is invalid for write-enabled files.")

    # wait if it's already over used
    nanny.tattle_quantity('fileread',0)

    readdata = fileinfo[myfilehandle]['fobj'].next()

    nanny.tattle_quantity('fileread', len(readdata))

    return readdata
Beispiel #15
0
    def readline(self, *args):
        # prevent TOCTOU race with client changing my filehandle
        myfilehandle = self.filehandle
        restrictions.assertisallowed("file.readline", *args)

        # wait if it's already over used
        nanny.tattle_quantity("fileread", 0)

        try:
            readdata = fileinfo[myfilehandle]["fobj"].readline(*args)
        except KeyError:
            raise ValueError("Invalid file object (probably closed).")

        nanny.tattle_quantity("fileread", len(readdata))

        return readdata
Beispiel #16
0
    def next(self):
        # prevent TOCTOU race with client changing my filehandle
        myfilehandle = self.filehandle
        restrictions.assertisallowed("file.next")

        if "w" in self.mode:
            raise IOError("file.next() is invalid for write-enabled files.")

        # wait if it's already over used
        nanny.tattle_quantity("fileread", 0)

        readdata = fileinfo[myfilehandle]["fobj"].next()

        nanny.tattle_quantity("fileread", len(readdata))

        return readdata
Beispiel #17
0
  def readline(self,*args):
    # prevent TOCTOU race with client changing my filehandle
    myfilehandle = self.filehandle
    restrictions.assertisallowed('file.readline',*args)

    # wait if it's already over used
    nanny.tattle_quantity('fileread',0)

    try:
      readdata =  fileinfo[myfilehandle]['fobj'].readline(*args)
    except KeyError:
      raise ValueError("Invalid file object (probably closed).")

    nanny.tattle_quantity('fileread',len(readdata))

    return readdata
Beispiel #18
0
def randomfloat():
    """
   <Purpose>
     Return a random number in the range [0.0, 1.0) using sources 
     provided by the operating system (such as /dev/urandom on Unix or
     CryptGenRandom on Windows).

   <Arguments>
     None

   <Exceptions>
     None

   <Side Effects>
     This function is metered because it may involve using a hardware
     source of randomness.
     
     If os.urandom raises a NotImplementedError then we will log the
     exception as interalerror and a harshexit will occur. A machine
     that raised this exception has not been observed but it is best
     that the problemed be logged. os.urandom will raise the exception
     if a source of OS-specific random numbers is not found.

   <Returns>
     The number (a float)

  """

    restrictions.assertisallowed('randomfloat')
    nanny.tattle_quantity('random', 1)

    # If an OS-specific source of randomness is not a found
    # a NotImplementedError would be raised.
    # Anthony - a NotImplementedError will be logged as an internal
    # error so that we will hopefully be able to identify the system,
    # the exception is not passed on because the problem was not
    # caused by the user. The exit code 217 was chosen to be
    # unique from all other exit calls in repy.
    # Get 56 bits of random data
    try:
        randombytes = os.urandom(7)
    except NotImplementedError, e:
        tracebackrepy.handle_internalerror("os.urandom is not implemented " + \
            "(Exception was: %s)" % e.message, 217)
Beispiel #19
0
def randomfloat():
  """
   <Purpose>
     Return a random number in the range [0.0, 1.0) using sources 
     provided by the operating system (such as /dev/urandom on Unix or
     CryptGenRandom on Windows).

   <Arguments>
     None

   <Exceptions>
     None

   <Side Effects>
     This function is metered because it may involve using a hardware
     source of randomness.
     
     If os.urandom raises a NotImplementedError then we will log the
     exception as interalerror and a harshexit will occur. A machine
     that raised this exception has not been observed but it is best
     that the problemed be logged. os.urandom will raise the exception
     if a source of OS-specific random numbers is not found.

   <Returns>
     The number (a float)

  """

  restrictions.assertisallowed('randomfloat')
  nanny.tattle_quantity('random',1)
  
  # If an OS-specific source of randomness is not a found
  # a NotImplementedError would be raised. 
  # Anthony - a NotImplementedError will be logged as an internal
  # error so that we will hopefully be able to identify the system,
  # the exception is not passed on because the problem was not
  # caused by the user. The exit code 217 was chosen to be
  # unique from all other exit calls in repy.
  # Get 56 bits of random data
  try:
    randombytes = os.urandom(7)
  except NotImplementedError, e:
    tracebackrepy.handle_internalerror("os.urandom is not implemented " + \
        "(Exception was: %s)" % e.message, 217)
Beispiel #20
0
  def write(self, writeitem):
    # they / we can always log info (or else what happens on exception?)

    # acquire (and release later no matter what)
    self.writelock.acquire()
    try:
      if self.should_nanny:
        # Only invoke the nanny if the should_nanny flag is set.
        # block if already over
        nanny.tattle_quantity('lograte',0)

      writeamt = self.writedata(writeitem)

      if self.should_nanny:
        # Only invoke the nanny if the should_nanny flag is set.
        nanny.tattle_quantity('lograte',writeamt)

    finally:
      self.writelock.release()
Beispiel #21
0
    def write(self, writeitem):
        # they / we can always log info (or else what happens on exception?)

        # acquire (and release later no matter what)
        self.writelock.acquire()
        try:
            if self.should_nanny:
                # Only invoke the nanny if the should_nanny flag is set.
                # block if already over
                nanny.tattle_quantity('lograte', 0)

            writeamt = self.writedata(writeitem)

            if self.should_nanny:
                # Only invoke the nanny if the should_nanny flag is set.
                nanny.tattle_quantity('lograte', writeamt)

        finally:
            self.writelock.release()
Beispiel #22
0
  def write(self,writeitem):
    # prevent TOCTOU race with client changing my filehandle
    myfilehandle = self.filehandle
    restrictions.assertisallowed('file.write',writeitem)

    # wait if it's already over used
    nanny.tattle_quantity('filewrite',0)

    if "w" in self.mode:
      try:
        retval = fileinfo[myfilehandle]['fobj'].write(writeitem)
      except KeyError:
        raise ValueError("Invalid file object (probably closed).")
    else:
      raise ValueError("write() isn't allowed on read-only file objects!")

    writeamt = len(str(writeitem))
    nanny.tattle_quantity('filewrite',writeamt)

    return retval
Beispiel #23
0
    def write(self, writeitem):
        # prevent TOCTOU race with client changing my filehandle
        myfilehandle = self.filehandle
        restrictions.assertisallowed("file.write", writeitem)

        # wait if it's already over used
        nanny.tattle_quantity("filewrite", 0)

        if "w" in self.mode:
            try:
                retval = fileinfo[myfilehandle]["fobj"].write(writeitem)
            except KeyError:
                raise ValueError("Invalid file object (probably closed).")
        else:
            raise ValueError("write() isn't allowed on read-only file objects!")

        writeamt = len(str(writeitem))
        nanny.tattle_quantity("filewrite", writeamt)

        return retval
Beispiel #24
0
    def writelines(self, writelist):
        # prevent TOCTOU race with client changing my filehandle
        myfilehandle = self.filehandle
        restrictions.assertisallowed("file.writelines", writelist)

        # wait if it's already over used
        nanny.tattle_quantity("filewrite", 0)

        if "w" not in self.mode:
            raise ValueError("writelines() isn't allowed on read-only file objects!")

        try:
            fh = fileinfo[myfilehandle]["fobj"]
        except KeyError:
            raise ValueError("Invalid file object (probably closed).")

        for writeitem in writelist:
            strtowrite = str(writeitem)
            fileinfo[myfilehandle]["fobj"].write(strtowrite)
            nanny.tattle_quantity("filewrite", len(strtowrite))

        return None  # python documentation states there is no return value
Beispiel #25
0
  def writelines(self, writelist):
    # we / they can always log info (or else what happens on exception?)
    #restrictions.assertisallowed('log.writelines',writelist)

    # acquire (and release later no matter what)
    self.writelock.acquire()
    try:
      if self.should_nanny:
        # Only invoke the nanny if the should_nanny flag is set.
        # block if already over
        nanny.tattle_quantity('lograte',0)
  
      writeamt = 0
      for writeitem in writelist:
        writeamt = writeamt + self.writedata(writeitem)

      if self.should_nanny:
        # Only invoke the nanny if the should_nanny flag is set.
        nanny.tattle_quantity('lograte',writeamt)
  
    finally:
      self.writelock.release()
Beispiel #26
0
  def writelines(self,writelist):
    # prevent TOCTOU race with client changing my filehandle
    myfilehandle = self.filehandle
    restrictions.assertisallowed('file.writelines',writelist)

    # wait if it's already over used
    nanny.tattle_quantity('filewrite',0)

    if "w" not in self.mode:
      raise ValueError("writelines() isn't allowed on read-only file objects!")
    
    try:
      fh = fileinfo[myfilehandle]['fobj']
    except KeyError:
      raise ValueError("Invalid file object (probably closed).")

    for writeitem in writelist:
      strtowrite = str(writeitem)
      fileinfo[myfilehandle]['fobj'].write(strtowrite)
      nanny.tattle_quantity('filewrite', len(strtowrite))

    return None   # python documentation states there is no return value
Beispiel #27
0
    def read(self, *args):
        # prevent TOCTOU race with client changing my filehandle
        myfilehandle = self.filehandle
        restrictions.assertisallowed("file.read", *args)

        # basic sanity checking of input
        if len(args) > 1:
            raise TypeError("read() takes at most 1 argument")

        if len(args) == 1 and type(args[0]) != int:
            raise TypeError("file.read() expects an integer argument")

        # wait if it's already over used
        nanny.tattle_quantity("fileread", 0)

        try:
            readdata = fileinfo[myfilehandle]["fobj"].read(*args)
        except KeyError:
            raise ValueError("Invalid file object (probably closed).")

        nanny.tattle_quantity("fileread", len(readdata))

        return readdata
Beispiel #28
0
  def read(self,*args):
    # prevent TOCTOU race with client changing my filehandle
    myfilehandle = self.filehandle
    restrictions.assertisallowed('file.read',*args)

    # basic sanity checking of input
    if len(args) > 1:
      raise TypeError("read() takes at most 1 argument")

    if len(args) == 1 and type(args[0]) != int:
      raise TypeError("file.read() expects an integer argument")

    # wait if it's already over used
    nanny.tattle_quantity('fileread',0)

    try:
      readdata = fileinfo[myfilehandle]['fobj'].read(*args)
    except KeyError:
      raise ValueError("Invalid file object (probably closed).")

    nanny.tattle_quantity('fileread',len(readdata))

    return readdata
Beispiel #29
0
    # If an OS-specific source of randomness is not a found
    # a NotImplementedError would be raised.
    # Anthony - a NotImplementedError will be logged as an internal
    # error so that we will hopefully be able to identify the system,
    # the exception is not passed on because the problem was not
    # caused by the user. The exit code 217 was chosen to be
    # unique from all other exit calls in repy.
    try:
        randomdata = os.urandom(1024)
    except NotImplementedError, e:
        tracebackrepy.handle_internalerror("os.urandom is not implemented " + \
            "(Exception was: %s)" % e.message, 217)

    # Tattle all 1024 now
    nanny.tattle_quantity('random', 1024)

    return randomdata


def getruntime():
    """
   <Purpose>
      Return the amount of time the program has been running.   This is in
      wall clock time. This is guaranteed to be monotonic.

   <Arguments>
      None

   <Exceptions>
      None.
Beispiel #30
0
  # If an OS-specific source of randomness is not a found
  # a NotImplementedError would be raised. 
  # Anthony - a NotImplementedError will be logged as an internal
  # error so that we will hopefully be able to identify the system,
  # the exception is not passed on because the problem was not
  # caused by the user. The exit code 217 was chosen to be
  # unique from all other exit calls in repy.
  try:
    randomdata = os.urandom(1024)
  except NotImplementedError, e:
    tracebackrepy.handle_internalerror("os.urandom is not implemented " + \
        "(Exception was: %s)" % e.message, 217)

  # Tattle all 1024 now
  nanny.tattle_quantity('random',1024)
 
  return randomdata


def getruntime():
  """
   <Purpose>
      Return the amount of time the program has been running.   This is in
      wall clock time. This is guaranteed to be monotonic.

   <Arguments>
      None

   <Exceptions>
      None.
Beispiel #31
0
  def readat(self,sizelimit,offset):
    """
    <Purpose>
      Reads from a file handle. Reading 0 bytes informs you if you have read
      past the end-of-file, but returns no data.

    <Arguments>
      sizelimit: 
        The maximum number of bytes to read from the file. Reading EOF will 
        read less.   By setting this value to None, the entire file is read.
      offset:
        Seek to a specific absolute offset before reading.

    <Exceptions>
      RepyArgumentError is raised if the offset or size is negative.
      FileClosedError is raised if the file is already closed.
      SeekPastEndOfFileError is raised if trying to read past the end of the file.

    <Resource Consumption>
      Consumes 4K of fileread for each 4K aligned-block of the file read.
      All reads will consume at least 4K.

    <Returns>
      The data that was read. This may be the empty string if we have reached the
      end of the file, or if the sizelimit was 0.
    """
    # Check the arguments
    if sizelimit < 0 and sizelimit != None:
      raise RepyArgumentError("Negative sizelimit specified!")
    if offset < 0:
      raise RepyArgumentError("Negative read offset speficied!")

    # Get the seek lock
    self.seek_lock.acquire()

    try:
      # Get the underlying file object
      fobj = self.fobj
      if fobj is None:
        raise FileClosedError("File '"+self.filename+"' is already closed!")

      # Check the provided offset
      if offset > self.filesize:
        raise SeekPastEndOfFileError("Seek offset extends past the EOF!")
      
      # Seek to the correct location
      fobj.seek(offset)

      # Wait for available file read resources
      nanny.tattle_quantity('fileread',0)

      if sizelimit != None:
        # Read the data
        data = fobj.read(sizelimit)
      else:
        # read all the data...
        data = fobj.read()

    finally:
      # Release the seek lock
      self.seek_lock.release()

    # Check how much we've read, in terms of 4K "blocks"
    end_offset = len(data) + offset
    disk_blocks_read = end_offset / 4096 - offset / 4096
    if end_offset % 4096 > 0:
      disk_blocks_read += 1

    # Charge 4K per block
    nanny.tattle_quantity('fileread', disk_blocks_read*4096)

    # Return the data
    return data
Beispiel #32
0
  def __init__(self, filename, create):
    """
      This is an internal initializer.   See emulated_open for details.
    """
    # Initialize the fields, otherwise __del__ gets confused
    # when we throw an exception. This was not a problem when the
    # logic was in emulated_open, since we would never throw an
    # exception
    self.filename = filename
    self.abs_filename = None
    self.fobj = None
    self.seek_lock = threading.Lock()
    self.filesize = 0

    # raise an RepyArgumentError if the filename isn't valid
    _assert_is_allowed_filename(filename)

    # Check the  type of create
    if type(create) is not bool:
      raise RepyArgumentError("Create argument type is invalid! Must be a Boolean!")

    OPEN_FILES_LOCK.acquire()
    try:
      # Check if the file is in use
      if filename in OPEN_FILES:
        raise FileInUseError('Cannot open file "'+filename+'" because it is already open!')

      # Get the absolute file name
      self.abs_filename = os.path.abspath(os.path.join(repy_constants.REPY_CURRENT_DIR, filename))
      

      # Here is where we try to allocate a "file" resource from the
      # nanny system.   We will restore this below if there is an exception
      # This may raise a ResourceExhautedError
      nanny.tattle_add_item('filesopened', self.abs_filename)

      
      # charge for checking if the file exists.
      nanny.tattle_quantity('fileread', 4096)
      exists = os.path.isfile(self.abs_filename)

      # if there isn't a file already...
      if not exists:
        # if we shouldn't create it, it's an error
        if not create:
          raise FileNotFoundError('Cannot openfile non-existent file "'+filename+'" without creating it!')

        # okay, we should create it...
        nanny.tattle_quantity('filewrite', 4096)
        safe_open(self.abs_filename, "w").close() # Forces file creation

      # Store a file handle
      # Always open in mode r+b, this avoids Windows text-mode
      # quirks, and allows reading and writing
      self.fobj = safe_open(self.abs_filename, "r+b")

      # Add the filename to the open files
      OPEN_FILES.add(filename)

      # Get the file's size
      self.filesize = os.path.getsize(self.abs_filename)

    except RepyException:
      # Restore the file handle we tattled
      nanny.tattle_remove_item('filesopened', self.abs_filename)
      raise

    finally:
      OPEN_FILES_LOCK.release()
Beispiel #33
0
    def __init__(self, filename, create):
        """
      This is an internal initializer.   See emulated_open for details.
    """
        # Initialize the fields, otherwise __del__ gets confused
        # when we throw an exception. This was not a problem when the
        # logic was in emulated_open, since we would never throw an
        # exception
        self.filename = filename
        self.abs_filename = None
        self.fobj = None
        self.seek_lock = threading.Lock()
        self.filesize = 0

        # raise an RepyArgumentError if the filename isn't valid
        _assert_is_allowed_filename(filename)

        # Check the  type of create
        if type(create) is not bool:
            raise RepyArgumentError(
                "Create argument type is invalid! Must be a Boolean!")

        OPEN_FILES_LOCK.acquire()
        try:
            # Check if the file is in use
            if filename in OPEN_FILES:
                raise FileInUseError('Cannot open file "' + filename +
                                     '" because it is already open!')

            # Get the absolute file name
            self.abs_filename = os.path.abspath(
                os.path.join(repy_constants.REPY_CURRENT_DIR, filename))

            # Here is where we try to allocate a "file" resource from the
            # nanny system.   We will restore this below if there is an exception
            # This may raise a ResourceExhautedError
            nanny.tattle_add_item('filesopened', self.abs_filename)

            # charge for checking if the file exists.
            nanny.tattle_quantity('fileread', 4096)
            exists = os.path.isfile(self.abs_filename)

            # if there isn't a file already...
            if not exists:
                # if we shouldn't create it, it's an error
                if not create:
                    raise FileNotFoundError(
                        'Cannot openfile non-existent file "' + filename +
                        '" without creating it!')

                # okay, we should create it...
                nanny.tattle_quantity('filewrite', 4096)
                safe_open(self.abs_filename,
                          "w").close()  # Forces file creation

            # Store a file handle
            # Always open in mode r+b, this avoids Windows text-mode
            # quirks, and allows reading and writing
            self.fobj = safe_open(self.abs_filename, "r+b")

            # Add the filename to the open files
            OPEN_FILES.add(filename)

            # Get the file's size
            self.filesize = os.path.getsize(self.abs_filename)

        except RepyException:
            # Restore the file handle we tattled
            nanny.tattle_remove_item('filesopened', self.abs_filename)
            raise

        finally:
            OPEN_FILES_LOCK.release()
Beispiel #34
0
  def writeat(self,data,offset):
    """
    <Purpose>
      Allows the user program to write data to a file.

    <Arguments>
      data: The data to write
      offset: An absolute offset into the file to write

    <Exceptions>
      RepyArgumentError is raised if the offset is negative or the data is not
      a string.
      FileClosedError is raised if the file is already closed.
      SeekPastEndOfFileError is raised if trying to write past the EOF.

    <Side Effects>
      Writes to persistent storage.

    <Resource Consumption>
      Consumes 4K of filewrite for each 4K aligned-block of the file written.
      All writes consume at least 4K.

    <Returns>
      Nothing
    """
    # Check the arguments
    if offset < 0:
      raise RepyArgumentError("Negative read offset speficied!")
    if type(data) is not str:
      raise RepyArgumentError("Data must be specified as a string!")

    # Get the seek lock
    self.seek_lock.acquire()

    try:
      # Get the underlying file object
      fobj = self.fobj
      if fobj is None:
        raise FileClosedError("File '"+self.filename+"' is already closed!")
 
      # Check the provided offset
      if offset > self.filesize:
        raise SeekPastEndOfFileError("Seek offset extends past the EOF!")
      
      # Seek to the correct location
      fobj.seek(offset)

      # Wait for available file write resources
      nanny.tattle_quantity('filewrite',0)

      # Write the data and flush to disk
      fobj.write(data)
      fobj.flush()

      # Check if we expanded the file size
      if offset + len(data) > self.filesize:
        self.filesize = offset + len(data)

    finally:
      # Release the seek lock
      self.seek_lock.release()

    # Check how much we've written, in terms of 4K "blocks"
    end_offset = len(data) + offset
    disk_blocks_written = end_offset / 4096 - offset / 4096
    if end_offset % 4096 > 0:
      disk_blocks_written += 1

    # Charge 4K per block
    nanny.tattle_quantity('filewrite', disk_blocks_written*4096)
Beispiel #35
0
    def readat(self, sizelimit, offset):
        """
    <Purpose>
      Reads from a file handle. Reading 0 bytes informs you if you have read
      past the end-of-file, but returns no data.

    <Arguments>
      sizelimit: 
        The maximum number of bytes to read from the file. Reading EOF will 
        read less.   By setting this value to None, the entire file is read.
      offset:
        Seek to a specific absolute offset before reading.

    <Exceptions>
      RepyArgumentError is raised if the offset or size is negative.
      FileClosedError is raised if the file is already closed.
      SeekPastEndOfFileError is raised if trying to read past the end of the file.

    <Resource Consumption>
      Consumes 4K of fileread for each 4K aligned-block of the file read.
      All reads will consume at least 4K.

    <Returns>
      The data that was read. This may be the empty string if we have reached the
      end of the file, or if the sizelimit was 0.
    """
        # Check the arguments
        if sizelimit < 0 and sizelimit != None:
            raise RepyArgumentError("Negative sizelimit specified!")
        if offset < 0:
            raise RepyArgumentError("Negative read offset speficied!")

        # Get the seek lock
        self.seek_lock.acquire()

        try:
            # Get the underlying file object
            fobj = self.fobj
            if fobj is None:
                raise FileClosedError("File '" + self.filename +
                                      "' is already closed!")

            # Check the provided offset
            if offset > self.filesize:
                raise SeekPastEndOfFileError(
                    "Seek offset extends past the EOF!")

            # Seek to the correct location
            fobj.seek(offset)

            # Wait for available file read resources
            nanny.tattle_quantity('fileread', 0)

            if sizelimit != None:
                # Read the data
                data = fobj.read(sizelimit)
            else:
                # read all the data...
                data = fobj.read()

        finally:
            # Release the seek lock
            self.seek_lock.release()

        # Check how much we've read, in terms of 4K "blocks"
        end_offset = len(data) + offset
        disk_blocks_read = end_offset / 4096 - offset / 4096
        if end_offset % 4096 > 0:
            disk_blocks_read += 1

        # Charge 4K per block
        nanny.tattle_quantity('fileread', disk_blocks_read * 4096)

        # Return the data
        return data
Beispiel #36
0
    def writeat(self, data, offset):
        """
    <Purpose>
      Allows the user program to write data to a file.

    <Arguments>
      data: The data to write
      offset: An absolute offset into the file to write

    <Exceptions>
      RepyArgumentError is raised if the offset is negative or the data is not
      a string.
      FileClosedError is raised if the file is already closed.
      SeekPastEndOfFileError is raised if trying to write past the EOF.

    <Side Effects>
      Writes to persistent storage.

    <Resource Consumption>
      Consumes 4K of filewrite for each 4K aligned-block of the file written.
      All writes consume at least 4K.

    <Returns>
      Nothing
    """
        # Check the arguments
        if offset < 0:
            raise RepyArgumentError("Negative read offset speficied!")
        if type(data) is not str:
            raise RepyArgumentError("Data must be specified as a string!")

        # Get the seek lock
        self.seek_lock.acquire()

        try:
            # Get the underlying file object
            fobj = self.fobj
            if fobj is None:
                raise FileClosedError("File '" + self.filename +
                                      "' is already closed!")

            # Check the provided offset
            if offset > self.filesize:
                raise SeekPastEndOfFileError(
                    "Seek offset extends past the EOF!")

            # Seek to the correct location
            fobj.seek(offset)

            # Wait for available file write resources
            nanny.tattle_quantity('filewrite', 0)

            # Write the data and flush to disk
            fobj.write(data)
            fobj.flush()

            # Check if we expanded the file size
            if offset + len(data) > self.filesize:
                self.filesize = offset + len(data)

        finally:
            # Release the seek lock
            self.seek_lock.release()

        # Check how much we've written, in terms of 4K "blocks"
        end_offset = len(data) + offset
        disk_blocks_written = end_offset / 4096 - offset / 4096
        if end_offset % 4096 > 0:
            disk_blocks_written += 1

        # Charge 4K per block
        nanny.tattle_quantity('filewrite', disk_blocks_written * 4096)
Beispiel #37
0
def device_send(name, data):
    nanny.tattle_quantity("netsend", len(data))
    _get_device(name).send(data)