mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Make escaping consistent for fish <-> fishd protocol
Fix fork guards to work in fishd https://github.com/fish-shell/fish-shell/issues/339
This commit is contained in:
parent
b67526aae8
commit
51de26960c
7 changed files with 69 additions and 27 deletions
5
env.cpp
5
env.cpp
|
@ -375,7 +375,7 @@ static void react_to_variable_change(const wcstring &key) {
|
|||
Universal variable callback function. This function makes sure the
|
||||
proper events are triggered when an event occurs.
|
||||
*/
|
||||
static void universal_callback( int type,
|
||||
static void universal_callback( fish_message_type_t type,
|
||||
const wchar_t *name,
|
||||
const wchar_t *val )
|
||||
{
|
||||
|
@ -395,6 +395,9 @@ static void universal_callback( int type,
|
|||
str=L"ERASE";
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( str )
|
||||
|
|
|
@ -61,7 +61,7 @@ static int get_socket_count = 0;
|
|||
static wchar_t * path;
|
||||
static wchar_t *user;
|
||||
static void (*start_fishd)();
|
||||
static void (*external_callback)( int type, const wchar_t *name, const wchar_t *val );
|
||||
static void (*external_callback)( fish_message_type_t type, const wchar_t *name, const wchar_t *val );
|
||||
|
||||
/**
|
||||
Flag set to 1 when a barrier reply is recieved
|
||||
|
@ -165,7 +165,7 @@ static int get_socket( int fork_ok )
|
|||
/**
|
||||
Callback function used whenever a new fishd message is recieved
|
||||
*/
|
||||
static void callback( int type, const wchar_t *name, const wchar_t *val )
|
||||
static void callback( fish_message_type_t type, const wchar_t *name, const wchar_t *val )
|
||||
{
|
||||
if( type == BARRIER_REPLY )
|
||||
{
|
||||
|
@ -250,7 +250,7 @@ static void reconnect()
|
|||
void env_universal_init( wchar_t * p,
|
||||
wchar_t *u,
|
||||
void (*sf)(),
|
||||
void (*cb)( int type, const wchar_t *name, const wchar_t *val ))
|
||||
void (*cb)( fish_message_type_t type, const wchar_t *name, const wchar_t *val ))
|
||||
{
|
||||
path=p;
|
||||
user=u;
|
||||
|
|
|
@ -20,7 +20,7 @@ extern connection_t env_universal_server;
|
|||
void env_universal_init( wchar_t * p,
|
||||
wchar_t *u,
|
||||
void (*sf)(),
|
||||
void (*cb)( int type, const wchar_t *name, const wchar_t *val ));
|
||||
void (*cb)( fish_message_type_t type, const wchar_t *name, const wchar_t *val ));
|
||||
/**
|
||||
Free memory used by envuni
|
||||
*/
|
||||
|
|
|
@ -112,7 +112,7 @@ env_var_table_t env_universal_var;
|
|||
/**
|
||||
Callback function, should be called on all events
|
||||
*/
|
||||
void (*callback)( int type,
|
||||
static void (*callback)( fish_message_type_t type,
|
||||
const wchar_t *key,
|
||||
const wchar_t *val );
|
||||
|
||||
|
@ -405,7 +405,7 @@ static char *wcs2utf( const wchar_t *in )
|
|||
|
||||
|
||||
|
||||
void env_universal_common_init( void (*cb)(int type, const wchar_t *key, const wchar_t *val ) )
|
||||
void env_universal_common_init( void (*cb)(fish_message_type_t type, const wchar_t *key, const wchar_t *val ) )
|
||||
{
|
||||
callback = cb;
|
||||
}
|
||||
|
@ -622,6 +622,7 @@ static void parse_message( wchar_t *msg,
|
|||
val = tmp+1;
|
||||
val = unescape( val, 0 );
|
||||
|
||||
if (key && val)
|
||||
env_universal_common_set( key, val, exportv );
|
||||
|
||||
free( val );
|
||||
|
@ -752,6 +753,15 @@ void try_send_all( connection_t *c )
|
|||
}
|
||||
}
|
||||
|
||||
/* The universal variable format has some funny escaping requirements; here we try to be safe */
|
||||
static bool is_universal_safe_to_encode_directly(wchar_t c)
|
||||
{
|
||||
if (c < 32 || c > 128)
|
||||
return false;
|
||||
|
||||
return iswalnum(c) || wcschr(L"/", c);
|
||||
}
|
||||
|
||||
/**
|
||||
Escape specified string
|
||||
*/
|
||||
|
@ -760,21 +770,22 @@ static wcstring full_escape( const wchar_t *in )
|
|||
wcstring out;
|
||||
for( ; *in; in++ )
|
||||
{
|
||||
if( *in < 32 )
|
||||
wchar_t c = *in;
|
||||
if (is_universal_safe_to_encode_directly(c))
|
||||
{
|
||||
append_format( out, L"\\x%.2x", *in );
|
||||
out.push_back(c);
|
||||
}
|
||||
else if( *in < 128 )
|
||||
else if (c < 256)
|
||||
{
|
||||
out.push_back(*in);
|
||||
append_format(out, L"\\x%.2x", c);
|
||||
}
|
||||
else if( *in < 65536 )
|
||||
else if (c < 65536)
|
||||
{
|
||||
append_format( out, L"\\u%.4x", *in );
|
||||
append_format(out, L"\\u%.4x", c);
|
||||
}
|
||||
else
|
||||
{
|
||||
append_format( out, L"\\U%.8x", *in );
|
||||
append_format(out, L"\\U%.8x", c);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
|
@ -803,7 +814,7 @@ void set_body(message_t *msg, ...)
|
|||
}
|
||||
|
||||
/* Returns an instance of message_t allocated via new */
|
||||
message_t *create_message( int type,
|
||||
message_t *create_message( fish_message_type_t type,
|
||||
const wchar_t *key_in,
|
||||
const wchar_t *val_in )
|
||||
{
|
||||
|
|
|
@ -40,15 +40,14 @@
|
|||
/**
|
||||
The different types of commands that can be sent between client/server
|
||||
*/
|
||||
enum
|
||||
typedef enum
|
||||
{
|
||||
SET,
|
||||
SET_EXPORT,
|
||||
ERASE,
|
||||
BARRIER,
|
||||
BARRIER_REPLY,
|
||||
}
|
||||
;
|
||||
} fish_message_type_t;
|
||||
|
||||
/**
|
||||
The size of the buffer used for reading from the socket
|
||||
|
@ -133,12 +132,12 @@ void try_send_all( connection_t *c );
|
|||
/**
|
||||
Create a messge with the specified properties
|
||||
*/
|
||||
message_t *create_message( int type, const wchar_t *key, const wchar_t *val );
|
||||
message_t *create_message( fish_message_type_t type, const wchar_t *key, const wchar_t *val );
|
||||
|
||||
/**
|
||||
Init the library
|
||||
*/
|
||||
void env_universal_common_init(void (*cb)(int type, const wchar_t *key, const wchar_t *val ) );
|
||||
void env_universal_common_init(void (*cb)(fish_message_type_t type, const wchar_t *key, const wchar_t *val ) );
|
||||
|
||||
/**
|
||||
Destroy library data
|
||||
|
|
29
fish.cpp
29
fish.cpp
|
@ -410,10 +410,34 @@ static int fish_parse_opt( int argc, char **argv, const char **cmd_ptr )
|
|||
parses commands from stdin or files, depending on arguments
|
||||
*/
|
||||
|
||||
static wcstring full_escape( const wchar_t *in )
|
||||
{
|
||||
wcstring out;
|
||||
for( ; *in; in++ )
|
||||
{
|
||||
if( *in < 32 )
|
||||
{
|
||||
append_format( out, L"\\x%.2x", *in );
|
||||
}
|
||||
else if( *in < 128 )
|
||||
{
|
||||
out.push_back(*in);
|
||||
}
|
||||
else if( *in < 65536 )
|
||||
{
|
||||
append_format( out, L"\\u%.4x", *in );
|
||||
}
|
||||
else
|
||||
{
|
||||
append_format( out, L"\\U%.8x", *in );
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
extern int g_fork_count;
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
struct stat tmp;
|
||||
int res=1;
|
||||
const char *cmd=0;
|
||||
int my_optind=0;
|
||||
|
@ -425,7 +449,8 @@ int main( int argc, char **argv )
|
|||
is_interactive_session=1;
|
||||
program_name=L"fish";
|
||||
|
||||
stat("----------FISH_HIT_MAIN----------", &tmp);
|
||||
//struct stat tmp;
|
||||
//stat("----------FISH_HIT_MAIN----------", &tmp);
|
||||
|
||||
my_optind = fish_parse_opt( argc, argv, &cmd );
|
||||
|
||||
|
|
|
@ -496,7 +496,7 @@ unlock:
|
|||
/**
|
||||
Event handler. Broadcasts updates to all clients.
|
||||
*/
|
||||
static void broadcast( int type, const wchar_t *key, const wchar_t *val )
|
||||
static void broadcast( fish_message_type_t type, const wchar_t *key, const wchar_t *val )
|
||||
{
|
||||
connection_t *c;
|
||||
message_t *msg;
|
||||
|
@ -540,6 +540,9 @@ static void daemonize()
|
|||
|
||||
case 0:
|
||||
{
|
||||
/* Ordinarily there's very limited things we will do after fork, due to multithreading. But fishd is safe because it's single threaded. So don't die in is_forked_child. */
|
||||
setup_fork_guards();
|
||||
|
||||
/*
|
||||
Make fishd ignore the HUP signal.
|
||||
*/
|
||||
|
@ -557,6 +560,7 @@ static void daemonize()
|
|||
act.sa_handler=&handle_term;
|
||||
sigaction( SIGTERM, &act, 0);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
default:
|
||||
|
|
Loading…
Reference in a new issue