voyeur-0.1.0.1: Haskell bindings for libvoyeur

Safe HaskellNone

System.Process.Voyeur

Contents

Description

This package provides bindings to libvoyeur, a library for observing the private activity of processes. Libvoyeur observes a child process and all of its descendants, so it works even when the child process calls out to other processes to do the actual work.

To observe a process, use withVoyeur to create an VoyeurContext, then register handlers for the events you want to observe using functions like observeExec. When you've set up all your handlers, use prepareEnvironment to create a special environment that will inject libvoyeur code into the child process, and pass that environment to a function like runProcess. Finally, pass the resulting ProcessHandle or ProcessID to startObserving, and your handlers will be called as events happen.

A simple program that prints a message every time a child process opened a file might look like this:

 import Control.Monad
 import Data.Maybe
 import System.Environment
 import System.Process
 import System.Process.Voyeur
 
 main = do
   (program : args) <- getArgs
   withVoyeur $ \ctx -> do
     -- Set up a handler.
     observeOpen ctx defaultOpenFlags $
       \path _ _ _ _ pid -> putStrLn $ show pid ++ " opened " ++ show path
 
     -- Set up the environment.
     curEnv <- getEnvironment
     newEnv <- prepareEnvironment ctx curEnv
     
     when (isJust newEnv) $ do
       -- Start the child process.
       handle <- runProcess program args Nothing newEnv Nothing Nothing Nothing
 
       -- Observe it! startObserving only returns when the child process
       -- exits, so we don't need to wait.
       void $ startObserving ctx handle

A larger example program is included with the source code to this package.

Synopsis

Observing a process

withVoyeur :: (VoyeurContext -> IO a) -> IO aSource

Creates a VoyeurContext and runs an IO action that observes a process using it.

prepareEnvironmentSource

Arguments

:: VoyeurContext

The context.

-> [(String, String)]

The environment you want to use.

-> IO (Maybe [(String, String)])

A modified version of that environment, or Nothing if something went wrong.

Prepares an environment for a child process you want to observe. prepareEnvironment starts the server component of libvoyeur and adds or modifies environment variables as necessary to inject code into the child process you're about to create and make sure it can connect to the server.

Generally after calling prepareEnvironment, you'll want to start the child process using the returned environment, and then call startObserving to begin receiving events.

If something goes wrong, prepareEnvironment will return Nothing.

startObservingSource

Arguments

:: HasPid a 
=> VoyeurContext

The context.

-> a

The child process to observe.

-> IO ExitCode

The exit status of the child process.

Start observing a child process. Your handlers will be called while the process runs. Note that no handlers will be called if you didn't start the process with an environment produced by prepareEnvironment.

When the child process exits, startObserving will terminate the server component of libvoyeur and return. This means that startObserving implicitly waits for the child process, so you don't need to do this on your own.

Observing 'exec' calls

data ObserveExecFlags Source

Flags for observing exec calls.

Constructors

ObserveExecFlags 

Fields

observeExecCWD :: !Bool

True if you want the current working directory.

observeExecEnv :: !Bool

True if you want the environment. (Potentially slow.)

observeExecPath :: !Bool

True if you want the value of PATH.

observeExecNoAccess :: !Bool

True if you want to see calls that fail due to access restrictions.

defaultExecFlags :: ObserveExecFlagsSource

Default flags which observe the minimum amount of information.

type ObserveExecHandlerSource

Arguments

 = ByteString

The file being executed.

-> [ByteString]

The arguments.

-> [(ByteString, ByteString)]

The environment (if requested).

-> ByteString

The value of PATH (if requested).

-> ByteString

The working directory (if requested).

-> ProcessID

The new process ID.

-> ProcessID

The parent process ID.

-> IO () 

A handler for exec calls.

observeExecSource

Arguments

:: VoyeurContext

The context.

-> ObserveExecFlags

Flags controlling what will be observed.

-> ObserveExecHandler

A handler for observed 'exec*' events.

-> IO () 

Observe calls to the exec and posix_spawn families of functions.

Observing 'exit' calls

type ObserveExitHandlerSource

Arguments

 = ExitCode

The exit status.

-> ProcessID

The process ID of the exiting process.

-> ProcessID

The parent process ID of the exiting process.

-> IO () 

A handler for 'exit' calls.

observeExitSource

Arguments

:: VoyeurContext

The context.

-> ObserveExitHandler

A handler for observed 'exit' events.

-> IO () 

Observe calls to the 'exit' family of functions.

Observing 'open' calls

data ObserveOpenFlags Source

Flags for observing 'open' calls.

Constructors

ObserveOpenFlags 

Fields

observeOpenCWD :: !Bool

True if you want the current working directory.

defaultOpenFlags :: ObserveOpenFlagsSource

Default flags which observe the minimum amount of information.

type ObserveOpenHandlerSource

Arguments

 = ByteString

The file being opened.

-> Int

The flags used to open the file.

-> FileMode

The mode. Only meaningful if O_CREAT was specified.

-> ByteString

The working directory (if requested).

-> Int

The return value of 'open'. May be a file descriptor or an error value.

-> ProcessID

The process ID of the observed process.

-> IO () 

A handler for 'open' calls.

observeOpenSource

Arguments

:: VoyeurContext

The context.

-> ObserveOpenFlags

Flags controlling what will be observed.

-> ObserveOpenHandler

A handler for observed 'open' events.

-> IO () 

Observe calls to 'open'.

Observing 'close' calls

type ObserveCloseHandlerSource

Arguments

 = Int

The file descriptor being closed.

-> Int

The return value of 'close'.

-> ProcessID

The process ID of the observed process.

-> IO () 

A handler for 'close' calls.

observeCloseSource

Arguments

:: VoyeurContext

The context.

-> ObserveCloseHandler

A handler for observed 'close' events.

-> IO () 

Observe calls to 'close'.

Types

data VoyeurContext Source

The context libvoyeur uses to store its state.

class HasPid a Source

The class of values that contain a ProcessID. This is used to abstract over the different representations of a process used by the various process libraries.