2005-10-05 01:11:39 +10:00
# ifndef FISH_ENV_UNIVERSAL_COMMON_H
# define FISH_ENV_UNIVERSAL_COMMON_H
2005-09-20 23:26:39 +10:00
2005-10-05 01:11:39 +10:00
# include <wchar.h>
2011-12-26 21:39:08 -08:00
# include <queue>
2012-08-05 11:58:17 -07:00
# include <string>
2014-04-27 13:34:51 -07:00
# include <set>
2005-10-05 01:11:39 +10:00
# include "util.h"
2014-04-25 16:09:26 -07:00
# include "env.h"
2005-09-20 23:26:39 +10:00
/**
The set command
*/
# define SET_STR L"SET"
2005-09-23 06:16:52 +10:00
/**
The set_export command
*/
# define SET_EXPORT_STR L"SET_EXPORT"
2005-09-20 23:26:39 +10:00
/**
The erase command
*/
# define ERASE_STR L"ERASE"
2005-09-23 06:16:52 +10:00
/**
The barrier command
*/
2005-09-20 23:26:39 +10:00
# define BARRIER_STR L"BARRIER"
2005-09-23 06:16:52 +10:00
/**
The barrier_reply command
*/
2005-09-20 23:26:39 +10:00
# define BARRIER_REPLY_STR L"BARRIER_REPLY"
/**
The filename to use for univeral variables . The username is appended
*/
# define SOCK_FILENAME "fishd.socket."
/**
The different types of commands that can be sent between client / server
*/
2012-10-08 14:47:25 -07:00
typedef enum
2005-09-20 23:26:39 +10:00
{
2012-11-18 16:30:30 -08:00
SET ,
SET_EXPORT ,
ERASE ,
BARRIER ,
BARRIER_REPLY ,
2012-10-08 14:47:25 -07:00
} fish_message_type_t ;
2005-09-20 23:26:39 +10:00
2006-10-07 04:45:39 +10:00
/**
The size of the buffer used for reading from the socket
*/
# define ENV_UNIVERSAL_BUFFER_SIZE 1024
2011-12-26 21:39:08 -08:00
/**
A struct representing a message to be sent between client and server
*/
2012-11-18 11:23:22 +01:00
typedef struct
2011-12-26 21:39:08 -08:00
{
2012-11-18 16:30:30 -08:00
/**
Number of queues that contain this message . Once this reaches zero , the message should be deleted
*/
int count ;
2012-11-18 11:23:22 +01:00
2012-11-18 16:30:30 -08:00
/**
Message body . The message must be allocated using enough memory to actually contain the message .
*/
std : : string body ;
2012-11-18 11:23:22 +01:00
2012-08-05 11:58:17 -07:00
} message_t ;
2011-12-26 21:39:08 -08:00
typedef std : : queue < message_t * > message_queue_t ;
2005-09-20 23:26:39 +10:00
/**
This struct represents a connection between a universal variable server / client
*/
2013-02-16 00:32:15 -08:00
class connection_t
2005-09-20 23:26:39 +10:00
{
2013-02-19 17:48:51 -08:00
private :
2013-02-16 00:32:15 -08:00
/* No assignment */
connection_t & operator = ( const connection_t & ) ;
2013-02-19 17:48:51 -08:00
public :
2012-11-18 16:30:30 -08:00
/**
The file descriptor this socket lives on
*/
int fd ;
2013-02-19 17:48:51 -08:00
2012-11-18 16:30:30 -08:00
/**
2013-02-16 00:02:40 -08:00
Queue of unsent messages
2012-11-18 16:30:30 -08:00
*/
2013-02-16 00:02:40 -08:00
std : : queue < message_t * > unsent ;
2012-11-18 16:30:30 -08:00
/**
Set to one when this connection should be killed
*/
2013-02-16 00:02:40 -08:00
bool killme ;
2012-11-18 16:30:30 -08:00
/**
The input string . Input from the socket goes here . When a
newline is encountered , the buffer is parsed and cleared .
*/
std : : vector < char > input ;
/**
The read buffer .
*/
2013-02-16 01:28:46 -08:00
std : : vector < char > read_buffer ;
2012-11-18 16:30:30 -08:00
/**
Number of bytes that have already been consumed .
*/
size_t buffer_consumed ;
2013-02-19 17:48:51 -08:00
2013-02-16 00:02:40 -08:00
/* Constructor */
connection_t ( int input_fd ) ;
} ;
2005-09-20 23:26:39 +10:00
/**
Read all available messages on this connection
*/
2012-11-18 16:30:30 -08:00
void read_message ( connection_t * ) ;
2005-09-20 23:26:39 +10:00
/**
Send as many messages as possible without blocking to the connection
*/
2012-11-18 16:30:30 -08:00
void try_send_all ( connection_t * c ) ;
2005-09-20 23:26:39 +10:00
/**
Create a messge with the specified properties
*/
2012-11-18 16:30:30 -08:00
message_t * create_message ( fish_message_type_t type , const wchar_t * key , const wchar_t * val ) ;
2005-09-20 23:26:39 +10:00
/**
Init the library
*/
2012-11-18 16:30:30 -08:00
void env_universal_common_init ( void ( * cb ) ( fish_message_type_t type , const wchar_t * key , const wchar_t * val ) ) ;
2005-09-20 23:26:39 +10:00
2005-09-23 06:16:52 +10:00
/**
Add all variable names to the specified list
2006-11-15 22:34:47 +10:00
This function operate agains the local copy of all universal
variables , it does not communicate with any other process .
2005-09-23 06:16:52 +10:00
*/
2012-11-18 16:30:30 -08:00
void env_universal_common_get_names ( wcstring_list_t & lst ,
2013-01-19 13:16:21 -08:00
bool show_exported ,
bool show_unexported ) ;
2005-09-23 06:16:52 +10:00
2006-11-15 22:34:47 +10:00
/**
Perform the specified variable assignment .
This function operate agains the local copy of all universal
variables , it does not communicate with any other process .
Do not call this function . Create a message to do it . This function
is only to be used when fishd is dead .
*/
2013-01-19 13:16:21 -08:00
void env_universal_common_set ( const wchar_t * key , const wchar_t * val , bool exportv ) ;
2006-11-15 22:34:47 +10:00
/**
2012-11-18 11:23:22 +01:00
Remove the specified variable .
2006-11-15 22:34:47 +10:00
This function operate agains the local copy of all universal
variables , it does not communicate with any other process .
Do not call this function . Create a message to do it . This function
is only to be used when fishd is dead .
*/
2012-11-18 16:30:30 -08:00
void env_universal_common_remove ( const wcstring & key ) ;
2006-11-15 22:34:47 +10:00
2005-09-23 06:16:52 +10:00
/**
Get the value of the variable with the specified name
2006-11-15 22:34:47 +10:00
This function operate agains the local copy of all universal
variables , it does not communicate with any other process .
2005-09-23 06:16:52 +10:00
*/
2014-04-25 16:09:26 -07:00
env_var_t env_universal_common_get ( const wcstring & name ) ;
2005-09-23 06:16:52 +10:00
/**
Get the export flag of the variable with the specified
2013-01-19 13:16:21 -08:00
name . Returns false if the variable doesn ' t exist .
2006-11-15 22:34:47 +10:00
This function operate agains the local copy of all universal
variables , it does not communicate with any other process .
2005-09-23 06:16:52 +10:00
*/
2013-01-19 13:16:21 -08:00
bool env_universal_common_get_export ( const wcstring & name ) ;
2005-09-23 06:16:52 +10:00
2014-04-27 16:53:07 -07:00
/** Synchronizes all changse: writes everything out, reads stuff in */
void env_universal_common_sync ( ) ;
2005-10-25 01:26:25 +10:00
/**
Add messages about all existing variables to the specified connection
*/
2012-11-18 16:30:30 -08:00
void enqueue_all ( connection_t * c ) ;
2005-09-23 06:16:52 +10:00
2006-11-15 22:34:47 +10:00
/**
Close and destroy the specified connection struct . This frees
allstructures allocated by the connection , such as ques of unsent
messages .
*/
2012-11-18 16:30:30 -08:00
void connection_destroy ( connection_t * c ) ;
2005-09-23 06:16:52 +10:00
2014-04-29 11:28:00 -07:00
typedef std : : vector < struct callback_data_t > callback_data_list_t ;
2014-04-25 16:09:26 -07:00
/** Class representing universal variables */
class env_universal_t
{
2014-04-27 13:34:51 -07:00
/* Current values */
2014-04-25 16:09:26 -07:00
var_table_t vars ;
2014-04-27 13:34:51 -07:00
/* Keys that have been modified, and need to be written. A value here that is not present in vars indicates a deleted value. */
std : : set < wcstring > modified ;
/* Path that we save to. If empty, use the default */
const wcstring explicit_vars_path ;
2014-04-25 16:09:26 -07:00
mutable pthread_mutex_t lock ;
2014-04-26 11:41:34 -07:00
bool tried_renaming ;
2014-04-29 11:28:00 -07:00
bool load_from_path ( const wcstring & path , callback_data_list_t * callbacks ) ;
void load_from_fd ( int fd , callback_data_list_t * callbacks ) ;
2014-04-29 17:03:00 -07:00
void erase_unmodified_values ( ) ;
2014-04-26 11:41:34 -07:00
2014-04-29 11:28:00 -07:00
void parse_message_internal ( wchar_t * msg , connection_t * src , callback_data_list_t * callbacks ) ;
2014-04-26 11:41:34 -07:00
2014-04-27 13:34:51 -07:00
void set_internal ( const wcstring & key , const wcstring & val , bool exportv , bool overwrite ) ;
void remove_internal ( const wcstring & name , bool overwrite ) ;
/* Functions concerned with saving */
bool open_and_acquire_lock ( const wcstring & path , int * out_fd ) ;
bool open_temporary_file ( const wcstring & directory , wcstring * out_path , int * out_fd ) ;
void write_to_fd ( int fd ) ;
bool move_new_vars_file_into_place ( const wcstring & src , const wcstring & dst ) ;
/* File id from which we last read */
file_id_t last_read_file ;
2014-04-29 11:28:00 -07:00
void read_message_internal ( connection_t * src , callback_data_list_t * callbacks ) ;
2014-04-27 13:34:51 -07:00
void enqueue_all_internal ( connection_t * c ) const ;
2014-04-26 11:41:34 -07:00
2014-04-25 16:09:26 -07:00
public :
2014-04-27 13:34:51 -07:00
env_universal_t ( const wcstring & path ) ;
2014-04-25 16:09:26 -07:00
~ env_universal_t ( ) ;
/* Get the value of the variable with the specified name */
env_var_t get ( const wcstring & name ) const ;
/* Returns whether the variable with the given name is exported, or false if it does not exist */
bool get_export ( const wcstring & name ) const ;
/* Sets a variable */
void set ( const wcstring & key , const wcstring & val , bool exportv ) ;
/* Removes a variable */
void remove ( const wcstring & name ) ;
/* Gets variable names */
wcstring_list_t get_names ( bool show_exported , bool show_unexported ) const ;
/* Writes variables to the connection */
void enqueue_all ( connection_t * c ) const ;
2014-04-26 11:41:34 -07:00
/** Loads variables at the correct path */
bool load ( ) ;
2014-04-29 17:03:00 -07:00
/** Reads and writes variables at the correct path. Returns true if modified variables were written. */
2014-04-29 11:28:00 -07:00
bool sync ( callback_data_list_t * callbacks ) ;
2014-04-26 11:41:34 -07:00
/* Internal use */
2014-04-29 11:28:00 -07:00
void read_message ( connection_t * src , callback_data_list_t * callbacks ) ;
2014-04-25 16:09:26 -07:00
} ;
2014-04-29 14:14:50 -07:00
class universal_notifier_t
{
public :
enum notifier_strategy_t
{
strategy_default ,
strategy_shmem_polling ,
strategy_notifyd
} ;
protected :
universal_notifier_t ( ) ;
private :
/* No copying */
universal_notifier_t & operator = ( const universal_notifier_t & ) ;
universal_notifier_t ( const universal_notifier_t & x ) ;
static notifier_strategy_t resolve_default_strategy ( ) ;
public :
virtual ~ universal_notifier_t ( ) ;
/* Factory constructor. Free with delete */
static universal_notifier_t * new_notifier_for_strategy ( notifier_strategy_t strat ) ;
2014-04-29 17:03:00 -07:00
/* Default instance. Other instances are possible for testing. */
2014-04-29 14:14:50 -07:00
static universal_notifier_t & default_notifier ( ) ;
/* Returns the fd from which to watch for events, or -1 if none */
virtual int notification_fd ( ) ;
/* Does a fast poll(). Returns true if changed. */
virtual bool poll ( ) ;
/* Indicates whether this notifier requires polling. */
virtual bool needs_polling ( ) const ;
/* Triggers a notification */
virtual void post_notification ( ) ;
2014-04-29 17:03:00 -07:00
/* Recommended delay between polls. A value of 0 means no polling required (so no timeout) */
virtual unsigned long usec_delay_between_polls ( ) const ;
2014-04-30 15:50:03 -07:00
/* The notification_fd is readable; drain it */
virtual void drain_notification_fd ( int fd ) ;
2014-04-29 14:14:50 -07:00
} ;
2014-04-25 17:44:49 -07:00
std : : string get_machine_identifier ( ) ;
bool get_hostname_identifier ( std : : string * result ) ;
2005-09-20 23:26:39 +10:00
# endif