コード例 #1
0
/// Setup our environment (e.g., tty modes), process key strokes, then reset the environment.
void setup_and_process_keys(bool continuous_mode) {
    is_interactive_session = 1;  // by definition this is interactive
    set_main_thread();
    setup_fork_guards();
    wsetlocale(LC_ALL, L"POSIX");
    program_name = L"fish_key_reader";
    env_init();
    reader_init();
    input_init();

    // Installing our handler for every signal (e.g., SIGSEGV) is dubious because it means that
    // signals that might generate a core dump will not do so. On the other hand this allows us
    // to restore the tty modes so the terminal is still usable when we die.
    for (int signo = 1; signo < 32; signo++) {
        signal(signo, signal_handler);
    }

    if (continuous_mode) {
        printf("\n");
        printf("Type 'exit' or 'quit' to terminate this program.\n");
        printf("\n");
        printf("Characters such as [ctrl-D] (EOF) and [ctrl-C] (interrupt)\n");
        printf("have no special meaning and will not terminate this program.\n");
        printf("\n");
    } else {
        set_wait_on_escape_ms(500);
    }

    // TODO: We really should enable keypad mode but see issue #838.
    process_input(continuous_mode);
    restore_term_mode();
}
コード例 #2
0
double C_STRTOD(wchar_t const *nptr, wchar_t **endptr)
{
    double r;

    const wcstring saved_locale = wsetlocale(LC_NUMERIC, NULL);

    if (!saved_locale.empty())
    {
        wsetlocale(LC_NUMERIC, L"C");
    }

    r = wcstod(nptr, endptr);

    if (!saved_locale.empty())
    {
        wsetlocale(LC_NUMERIC, saved_locale.c_str());
    }

    return r;
}
コード例 #3
0
ファイル: fishd.cpp プロジェクト: Soares/fish-shell
/**
   Main function for fishd
*/
int main( int argc, char ** argv )
{
	int child_socket;
	struct sockaddr_un remote;
	socklen_t t;
	int max_fd;
	int update_count=0;
	
	fd_set read_fd, write_fd;

	set_main_thread();
    setup_fork_guards();
	
	program_name=L"fishd";
	wsetlocale( LC_ALL, L"" );	

	/*
	  Parse options
	*/
	while( 1 )
	{
		static struct option
			long_options[] =
			{
				{
					"help", no_argument, 0, 'h' 
				}
				,
				{
					"version", no_argument, 0, 'v' 
				}
				,
				{ 
					0, 0, 0, 0 
				}
			}
		;
		
		int opt_index = 0;
		
		int opt = getopt_long( argc,
							   argv, 
							   GETOPT_STRING,
							   long_options, 
							   &opt_index );
		
		if( opt == -1 )
			break;
		
		switch( opt )
		{
			case 0:
				break;				

			case 'h':
				print_help( argv[0], 1 );
				exit(0);				
								
			case 'v':
				debug( 0, L"%ls, version %s\n", program_name, PACKAGE_VERSION );
				exit( 0 );				
				
			case '?':
				return 1;
				
		}		
	}
	
	init();
	while(1) 
	{
		connection_t *c;
		int res;

		t = sizeof( remote );		
		
		FD_ZERO( &read_fd );
		FD_ZERO( &write_fd );
		FD_SET( sock, &read_fd );
		max_fd = sock+1;
		for( c=conn; c; c=c->next )
		{
			FD_SET( c->fd, &read_fd );
			max_fd = maxi( max_fd, c->fd+1);
			
			if( ! c->unsent->empty() )
			{
				FD_SET( c->fd, &write_fd );
			}
		}

		while( 1 )
		{
			res=select( max_fd, &read_fd, &write_fd, 0, 0 );

			if( quit )
			{
				save();
				exit(0);
			}
			
			if( res != -1 )
				break;
			
			if( errno != EINTR )
			{
				wperror( L"select" );
				exit(1);
			}
		}
				
		if( FD_ISSET( sock, &read_fd ) )
		{
			if( (child_socket = 
				 accept( sock, 
						 (struct sockaddr *)&remote, 
						 &t) ) == -1) {
				wperror( L"accept" );
				exit(1);
			}
			else
			{
				debug( 4, L"Connected with new child on fd %d", child_socket );

				if( fcntl( child_socket, F_SETFL, O_NONBLOCK ) != 0 )
				{
					wperror( L"fcntl" );
					close( child_socket );		
				}
				else
				{
					connection_t *newc = (connection_t *)malloc( sizeof(connection_t));
					connection_init( newc, child_socket );					
					newc->next = conn;
					send( newc->fd, GREETING, strlen(GREETING), MSG_DONTWAIT );
					enqueue_all( newc );				
					conn=newc;
				}
			}
		}
		
		for( c=conn; c; c=c->next )
		{
			if( FD_ISSET( c->fd, &write_fd ) )
			{
				try_send_all( c );
			}
		}
		
		for( c=conn; c; c=c->next )
		{
			if( FD_ISSET( c->fd, &read_fd ) )
			{
				read_message( c );

				/*
				  Occasionally we save during normal use, so that we
				  won't lose everything on a system crash
				*/
				update_count++;
				if( update_count >= 64 )
				{
					save();
					update_count = 0;
				}
			}
		}
		
		connection_t *prev=0;
		c=conn;
		
		while( c )
		{
			if( c->killme )
			{
				debug( 4, L"Close connection %d", c->fd );

				while( ! c->unsent->empty() )
				{
					message_t *msg = c->unsent->front();
                    c->unsent->pop();
					msg->count--;
					if( !msg->count )
						free( msg );
				}
				
				connection_destroy( c );
				if( prev )
				{
					prev->next=c->next;
				}
				else
				{
					conn=c->next;
				}
				
				free(c);
				
				c=(prev?prev->next:conn);
				
			}
			else
			{
				prev=c;
				c=c->next;
			}
		}

		if( !conn )
		{
			debug( 0, L"No more clients. Quitting" );
			save();			
			env_universal_common_destroy();
			break;
		}		

	}
}
コード例 #4
0
ファイル: fish.cpp プロジェクト: fimmtiu/fish-shell
int main( int argc, char **argv )
{    
    struct stat tmp;
	int res=1;
	const char *cmd=0;
	int my_optind=0;

	set_main_thread();
    setup_fork_guards();
    
	wsetlocale( LC_ALL, L"" );
	is_interactive_session=1;
	program_name=L"fish";

    stat("----------FISH_HIT_MAIN----------", &tmp);

	my_optind = fish_parse_opt( argc, argv, &cmd );

	/*
	  No-exec is prohibited when in interactive mode
	*/
	if( is_interactive_session && no_exec)
	{
		debug( 1, _(L"Can not use the no-execute mode when running an interactive session") );
		no_exec = 0;
	}
    
	const struct config_paths_t paths = determine_config_directory_paths(argv[0]);
    	
	proc_init();	
	event_init();	
	wutil_init();
	//parser_init();
	builtin_init();
	function_init();
	env_init(&paths);
	reader_init();
	history_init();

    parser_t &parser = parser_t::principal_parser();

    if (g_log_forks)
        printf("%d: g_fork_count: %d\n", __LINE__, g_fork_count);

	if( read_init(paths) )
	{
		if( cmd != 0 )
		{
			wchar_t *cmd_wcs = str2wcs( cmd );
			res = parser.eval( cmd_wcs, 0, TOP );
			free(cmd_wcs);
			reader_exit(0, 0);
		}
		else
		{
			if( my_optind == argc )
			{
				res = reader_read( STDIN_FILENO, 0 );
			}
			else
			{
				char **ptr; 
				char *file = *(argv+(my_optind++));
				int i; 
				int fd;
				wchar_t *rel_filename, *abs_filename;

                
				if( ( fd = open(file, O_RDONLY) ) == -1 )
				{
					wperror( L"open" );
					return 1;
				}
                
                // OK to not do this atomically since we cannot have gone multithreaded yet
                set_cloexec(fd);
                
				if( *(argv+my_optind))
				{
                    wcstring sb;
					for( i=1,ptr = argv+my_optind; *ptr; i++, ptr++ )
					{
						if( i != 1 )
                            sb.append( ARRAY_SEP_STR );
                        sb.append( str2wcstring( *ptr ));
					}
				
					env_set( L"argv", sb.c_str(), 0 );
				}

				rel_filename = str2wcs( file );
				abs_filename = wrealpath( rel_filename, 0 );

				if( !abs_filename )
				{
					abs_filename = wcsdup(rel_filename);
				}

				reader_push_current_filename( intern( abs_filename ) );
				free( rel_filename );
				free( abs_filename );

				res = reader_read( fd, 0 );

				if( res )
				{
					debug( 1, 
					       _(L"Error while reading file %ls\n"), 
					       reader_current_filename()?reader_current_filename(): _(L"Standard input") );
				}				
				reader_pop_current_filename();
			}
		}
	}
	
	proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, getpid(), res );
	
	history_destroy();
	proc_destroy();
	builtin_destroy();
	reader_destroy();
	parser.destroy();
	wutil_destroy();
	event_destroy();
	
	env_destroy();
	
    if (g_log_forks)
        printf("%d: g_fork_count: %d\n", __LINE__, g_fork_count);
    
	return res?STATUS_UNKNOWN_COMMAND:proc_get_last_status();	
}
コード例 #5
0
ファイル: fish_indent.cpp プロジェクト: ixjlyons/fish-shell
int main(int argc, char *argv[])
{
    set_main_thread();
    setup_fork_guards();

    wsetlocale(LC_ALL, L"");
    program_name=L"fish_indent";

    env_init();
    input_init();

    /* Types of output we support */
    enum
    {
        output_type_plain_text,
        output_type_ansi,
        output_type_html
    } output_type = output_type_plain_text;

    /* Whether to indent (true) or just reformat to one job per line (false) */
    bool do_indent = true;

    while (1)
    {
        const struct option long_options[] =
        {
            { "no-indent", no_argument, 0, 'i' },
            { "help", no_argument, 0, 'h' },
            { "version", no_argument, 0, 'v' },
            { "html", no_argument, 0, 1 },
            { "ansi", no_argument, 0, 2 },
            { 0, 0, 0, 0 }
        };

        int opt_index = 0;
        int opt = getopt_long(argc, argv, "hvi", long_options, &opt_index);
        if (opt == -1)
            break;

        switch (opt)
        {
            case 0:
            {
                break;
            }

            case 'h':
            {
                print_help("fish_indent", 1);
                exit(0);
                assert(0 && "Unreachable code reached");
                break;
            }

            case 'v':
            {
                fwprintf(stderr, _(L"%ls, version %s\n"), program_name, get_fish_version());
                exit(0);
                assert(0 && "Unreachable code reached");
                break;
            }

            case 'i':
            {
                do_indent = false;
                break;
            }

            case 1:
            {
                output_type = output_type_html;
                break;
            }

            case 2:
            {
                output_type = output_type_ansi;
                break;
            }

            case '?':
            {
                exit(1);
            }
        }
    }

    const wcstring src = read_file(stdin);
    const wcstring output_wtext = prettify(src, do_indent);

    /* Maybe colorize */
    std::vector<highlight_spec_t> colors;
    if (output_type != output_type_plain_text)
    {
        highlight_shell_no_io(output_wtext, colors, output_wtext.size(), NULL, env_vars_snapshot_t::current());
    }

    std::string colored_output;
    switch (output_type)
    {
        case output_type_plain_text:
            colored_output = no_colorize(output_wtext);
            break;

        case output_type_ansi:
            colored_output = ansi_colorize(output_wtext, colors);
            break;

        case output_type_html:
            colored_output = html_colorize(output_wtext, colors);
            break;
    }

    fputs(colored_output.c_str(), stdout);
    return 0;
}
コード例 #6
0
ファイル: env.cpp プロジェクト: lnsoso/fish-shell
/**
  Properly sets all locale information
*/
static void handle_locale()
{
    const env_var_t lc_all = env_get_string(L"LC_ALL");
    const wcstring old_locale = wsetlocale(LC_MESSAGES, NULL);

    /*
      Array of locale constants corresponding to the local variable names defined in locale_variable
    */
    static const int cat[] =
    {
        0,
        LC_ALL,
        LC_COLLATE,
        LC_CTYPE,
        LC_MESSAGES,
        LC_MONETARY,
        LC_NUMERIC,
        LC_TIME
    }
    ;

    if (!lc_all.missing())
    {
        wsetlocale(LC_ALL, lc_all.c_str());
    }
    else
    {
        const env_var_t lang = env_get_string(L"LANG");
        if (!lang.missing())
        {
            wsetlocale(LC_ALL, lang.c_str());
        }

        for (int i=2; locale_variable[i]; i++)
        {
            const env_var_t val = env_get_string(locale_variable[i]);

            if (!val.missing())
            {
                wsetlocale(cat[i], val.c_str());
            }
        }
    }

    const wcstring new_locale = wsetlocale(LC_MESSAGES, NULL);
    if (old_locale != new_locale)
    {

        /*
           Try to make change known to gettext. Both changing
           _nl_msg_cat_cntr and calling dcgettext might potentially
           tell some gettext implementation that the translation
           strings should be reloaded. We do both and hope for the
           best.
        */

        extern int _nl_msg_cat_cntr;
        _nl_msg_cat_cntr++;

        fish_dcgettext("fish", "Changing language to English", LC_MESSAGES);

        if (get_is_interactive())
        {
            debug(2, _(L"Changing language to English"));
        }
    }
}
コード例 #7
0
ファイル: fish_pager.cpp プロジェクト: anbotero/fish-shell
int main( int argc, char **argv )
{
	int i;
	int is_quoted=0;	
	wcstring_list_t comp;
	wchar_t *prefix = 0;

	int mangle_descriptors = 0;
	int result_fd = -1;
	set_main_thread();
    setup_fork_guards();
    
	/*
	  This initialization is made early, so that the other init code
	  can use global_context for memory managment
	*/
	program_name = L"fish_pager";


	wsetlocale( LC_ALL, L"" );

	/*
	  The call signature for fish_pager is a mess. Because we want
	  to be able to upgrade fish without breaking running
	  instances, we need to support all previous
	  modes. Unfortunatly, the two previous ones are a mess. The
	  third one is designed to be extensible, so hopefully it will
	  be the last.
	*/

	if( argc > 1 && argv[1][0] == '-' )
	{
		/*
		  Third mode
		*/
			
		int completion_fd = -1;
		FILE *completion_file;
			
		while( 1 )
		{
			static struct option
				long_options[] =
				{
					{
						"result-fd", required_argument, 0, 'r' 
					}
					,
					{
						"completion-fd", required_argument, 0, 'c' 
					}
					,
					{
						"prefix", required_argument, 0, 'p' 
					}
					,
					{
						"is-quoted", no_argument, 0, 'q' 
					}
					,
					{
						"help", no_argument, 0, 'h' 
					}
					,
					{
						"version", no_argument, 0, 'v' 
					}
					,
					{ 
						0, 0, 0, 0 
					}
				}
			;
		
			int opt_index = 0;
		
			int opt = getopt_long( argc,
					       argv, 
					       GETOPT_STRING,
					       long_options, 
					       &opt_index );
		
			if( opt == -1 )
				break;
		
			switch( opt )
			{
				case 0:
				{
					break;
				}
			
				case 'r':
				{
					result_fd = get_fd( optarg );
					break;
				}
			
				case 'c':
				{
					completion_fd = get_fd( optarg );
					break;
				}

				case 'p':
				{
					prefix = str2wcs(optarg);
					break;
				}

				case 'h':
				{
					print_help( argv[0], 1 );
					exit(0);						
				}

				case 'v':
				{
					debug( 0, L"%ls, version %s\n", program_name, PACKAGE_VERSION );
					exit( 0 );				
				}
					
				case 'q':
				{
					is_quoted = 1;
				}
			
			}
		}

		if( completion_fd == -1 || result_fd == -1 )
		{
			debug( 0, _(L"Unspecified file descriptors") );
			exit( 1 );
		}
			

		if( (completion_file = fdopen( completion_fd, "r" ) ) )
		{
			read_array( completion_file, comp );
			fclose( completion_file );
		}
		else
		{
			debug( 0, _(L"Could not read completions") );
			wperror( L"fdopen" );
			exit( 1 );
		}

		if( !prefix )
		{
			prefix = wcsdup( L"" );
		}
			
			
	}
	else
	{
		/*
		  Second or first mode. These suck, but we need to support
		  them for backwards compatibility. At least for some
		  time.

		  Third mode was implemented in January 2007, and previous
		  modes should be considered deprecated from that point
		  forward. A reasonable time frame for removal of the code
		  below has yet to be determined.
		*/
			
		if( argc < 3 )
		{
			print_help( argv[0], 1 );
			exit( 0 );
		}
		else
		{
			mangle_descriptors = 1;
			
			prefix = str2wcs( argv[2] );
			is_quoted = strcmp( "1", argv[1] )==0;
			
			if( argc > 3 )
			{
				/*
				  First mode
				*/
				for( i=3; i<argc; i++ )
				{
					wcstring wcs = str2wcstring( argv[i] );
                    comp.push_back(wcs);
				}
			}
			else
			{
				/*
				  Second mode
				*/
				read_array( stdin, comp );
			}
		}
			
	}
		
//		debug( 3, L"prefix is '%ls'", prefix );
		
	init( mangle_descriptors, result_fd );

	mangle_descriptions( comp );

	if( wcscmp( prefix, L"-" ) == 0 )
		join_completions( comp );

	std::vector<comp_t *> completions = mangle_completions( comp, prefix );

	/**
	   Try to print the completions. Start by trying to print the
	   list in PAGER_MAX_COLS columns, if the completions won't
	   fit, reduce the number of columns by one. Printing a single
	   column never fails.
	*/
	for( i = PAGER_MAX_COLS; i>0; i-- )
	{
		switch( completion_try_print( i, prefix, is_quoted, completions ) )
		{

			case PAGER_RETRY:
				break;

			case PAGER_DONE:
				i=0;
				break;

			case PAGER_RESIZE:
				/*
				  This means we got a resize event, so we start
				  over from the beginning. Since it the screen got
				  bigger, we might be able to fit all completions
				  on-screen.
				*/
				i=PAGER_MAX_COLS+1;
				break;

		}		
	}
	
	free(prefix );

	fwprintf( out_file, L"%ls", out_buff.c_str() );
	if( is_ca_mode )
	{
		writembs(exit_ca_mode);
		pager_flush();
	}
	destroy();

}
コード例 #8
0
ファイル: fish.cpp プロジェクト: GarethLewin/fish-shell
int main(int argc, char **argv)
{
    int res=1;
    int my_optind=0;

    set_main_thread();
    setup_fork_guards();

    wsetlocale(LC_ALL, L"");
    is_interactive_session=1;
    program_name=L"fish";

    //struct stat tmp;
    //stat("----------FISH_HIT_MAIN----------", &tmp);

    std::vector<std::string> cmds;
    my_optind = fish_parse_opt(argc, argv, &cmds);

    /*
      No-exec is prohibited when in interactive mode
    */
    if (is_interactive_session && no_exec)
    {
        debug(1, _(L"Can not use the no-execute mode when running an interactive session"));
        no_exec = 0;
    }

    /* Only save (and therefore restore) the fg process group if we are interactive. See #197, #1002 */
    if (is_interactive_session)
    {
        save_term_foreground_process_group();
    }

    const struct config_paths_t paths = determine_config_directory_paths(argv[0]);

    proc_init();
    event_init();
    wutil_init();
    builtin_init();
    function_init();
    env_init(&paths);
    reader_init();
    history_init();
    /* For setcolor to support term256 in config.fish (#1022) */
    update_fish_term256();

    parser_t &parser = parser_t::principal_parser();

    if (g_log_forks)
        printf("%d: g_fork_count: %d\n", __LINE__, g_fork_count);

    const io_chain_t empty_ios;
    if (read_init(paths))
    {
        /* Stop the exit status of any initialization commands (#635) */
        proc_set_last_status(STATUS_BUILTIN_OK);

        /* Run the commands specified as arguments, if any */
        if (! cmds.empty())
        {
            /* Do something nasty to support OpenSUSE assuming we're bash. This may modify cmds. */
            if (is_login)
            {
                fish_xdm_login_hack_hack_hack_hack(&cmds, argc - my_optind, argv + my_optind);
            }
            for (size_t i=0; i < cmds.size(); i++)
            {
                const wcstring cmd_wcs = str2wcstring(cmds.at(i));
                res = parser.eval(cmd_wcs, empty_ios, TOP);
            }
            reader_exit(0, 0);
        }
        else
        {
            if (my_optind == argc)
            {
                res = reader_read(STDIN_FILENO, empty_ios);
            }
            else
            {
                char **ptr;
                char *file = *(argv+(my_optind++));
                int i;
                int fd;


                if ((fd = open(file, O_RDONLY)) == -1)
                {
                    wperror(L"open");
                    return 1;
                }

                // OK to not do this atomically since we cannot have gone multithreaded yet
                set_cloexec(fd);

                if (*(argv+my_optind))
                {
                    wcstring sb;
                    for (i=1,ptr = argv+my_optind; *ptr; i++, ptr++)
                    {
                        if (i != 1)
                            sb.append(ARRAY_SEP_STR);
                        sb.append(str2wcstring(*ptr));
                    }

                    env_set(L"argv", sb.c_str(), 0);
                }

                const wcstring rel_filename = str2wcstring(file);
                const wchar_t *abs_filename = wrealpath(rel_filename, NULL);

                if (!abs_filename)
                {
                    abs_filename = wcsdup(rel_filename.c_str());
                }

                reader_push_current_filename(intern(abs_filename));
                free((void *)abs_filename);

                res = reader_read(fd, empty_ios);

                if (res)
                {
                    debug(1,
                          _(L"Error while reading file %ls\n"),
                          reader_current_filename()?reader_current_filename(): _(L"Standard input"));
                }
                reader_pop_current_filename();
            }
        }
    }

    proc_fire_event(L"PROCESS_EXIT", EVENT_EXIT, getpid(), res);

    restore_term_mode();
    restore_term_foreground_process_group();
    history_destroy();
    proc_destroy();
    builtin_destroy();
    reader_destroy();
    parser.destroy();
    wutil_destroy();
    event_destroy();

    env_destroy();

    if (g_log_forks)
        printf("%d: g_fork_count: %d\n", __LINE__, g_fork_count);

    exit_without_destructors(res ? STATUS_UNKNOWN_COMMAND : proc_get_last_status());
    return EXIT_FAILURE; //above line should always exit
}
コード例 #9
0
ファイル: fishd.cpp プロジェクト: jay2013/fish-shell
/**
   Main function for fishd
*/
int main(int argc, char ** argv)
{
    int child_socket;
    struct sockaddr_un remote;
    socklen_t t;
    uid_t sock_euid;
    gid_t sock_egid;
    int max_fd;
    int update_count=0;

    fd_set read_fd, write_fd;

    set_main_thread();
    setup_fork_guards();

    program_name=L"fishd";
    wsetlocale(LC_ALL, L"");

    /*
      Parse options
    */
    while (1)
    {
        static struct option
                long_options[] =
        {
            {
                "help", no_argument, 0, 'h'
            }
            ,
            {
                "version", no_argument, 0, 'v'
            }
            ,
            {
                0, 0, 0, 0
            }
        }
        ;

        int opt_index = 0;

        int opt = getopt_long(argc,
                              argv,
                              GETOPT_STRING,
                              long_options,
                              &opt_index);

        if (opt == -1)
            break;

        switch (opt)
        {
            case 0:
                break;

            case 'h':
                print_help(argv[0], 1);
                exit(0);

            case 'v':
                debug(0, L"%ls, version %s\n", program_name, FISH_BUILD_VERSION);
                exit(0);

            case '?':
                return 1;

        }
    }

    init();
    while (1)
    {
        int res;

        t = sizeof(remote);

        FD_ZERO(&read_fd);
        FD_ZERO(&write_fd);
        FD_SET(sock, &read_fd);
        max_fd = sock+1;
        for (connection_list_t::const_iterator iter = connections.begin(); iter != connections.end(); ++iter)
        {
            const connection_t &c = *iter;
            FD_SET(c.fd, &read_fd);
            max_fd = maxi(max_fd, c.fd+1);

            if (! c.unsent.empty())
            {
                FD_SET(c.fd, &write_fd);
            }
        }

        while (1)
        {
            res=select(max_fd, &read_fd, &write_fd, 0, 0);

            if (quit)
            {
                save();
                exit(0);
            }

            if (res != -1)
                break;

            if (errno != EINTR)
            {
                wperror(L"select");
                exit(1);
            }
        }

        if (FD_ISSET(sock, &read_fd))
        {
            if ((child_socket =
                        accept(sock,
                               (struct sockaddr *)&remote,
                               &t)) == -1)
            {
                wperror(L"accept");
                exit(1);
            }
            else
            {
                debug(4, L"Connected with new child on fd %d", child_socket);

                if (((getpeereid(child_socket, &sock_euid, &sock_egid) != 0) || sock_euid != geteuid()))
                {
                    debug(1, L"Wrong credentials for child on fd %d", child_socket);
                    close(child_socket);
                }
                else if (make_fd_nonblocking(child_socket) != 0)
                {
                    wperror(L"fcntl");
                    close(child_socket);
                }
                else
                {
                    connections.push_front(connection_t(child_socket));
                    connection_t &newc = connections.front();
                    send(newc.fd, GREETING, strlen(GREETING), MSG_DONTWAIT);
                    enqueue_all(&newc);
                }
            }
        }

        for (connection_list_t::iterator iter = connections.begin(); iter != connections.end(); ++iter)
        {
            if (FD_ISSET(iter->fd, &write_fd))
            {
                try_send_all(&*iter);
            }
        }

        for (connection_list_t::iterator iter = connections.begin(); iter != connections.end(); ++iter)
        {
            if (FD_ISSET(iter->fd, &read_fd))
            {
                read_message(&*iter);

                /*
                  Occasionally we save during normal use, so that we
                  won't lose everything on a system crash
                */
                update_count++;
                if (update_count >= 64)
                {
                    save();
                    update_count = 0;
                }
            }
        }

        for (connection_list_t::iterator iter = connections.begin(); iter != connections.end();)
        {
            if (iter->killme)
            {
                debug(4, L"Close connection %d", iter->fd);

                while (! iter->unsent.empty())
                {
                    message_t *msg = iter->unsent.front();
                    iter->unsent.pop();
                    msg->count--;
                    if (! msg->count)
                        free(msg);
                }

                connection_destroy(&*iter);
                iter = connections.erase(iter);
            }
            else
            {
                ++iter;
            }
        }

        if (connections.empty())
        {
            debug(0, L"No more clients. Quitting");
            save();
            break;
        }

    }
}
コード例 #10
0
ファイル: fish_indent.cpp プロジェクト: jayschwa/fish-shell
/**
   The main mathod. Run the program.
 */
int main(int argc, char **argv)
{
    int do_indent=1;
    set_main_thread();
    setup_fork_guards();

    wsetlocale(LC_ALL, L"");
    program_name=L"fish_indent";

    while (1)
    {
        static struct option
                long_options[] =
        {
            {
                "no-indent", no_argument, 0, 'i'
            }
            ,
            {
                "help", no_argument, 0, 'h'
            }
            ,
            {
                "version", no_argument, 0, 'v'
            }
            ,
            {
                0, 0, 0, 0
            }
        }
        ;

        int opt_index = 0;

        int opt = getopt_long(argc,
                              argv,
                              GETOPT_STRING,
                              long_options,
                              &opt_index);

        if (opt == -1)
            break;

        switch (opt)
        {
            case 0:
            {
                break;
            }

            case 'h':
            {
                print_help("fish_indent", 1);
                exit(0);
                break;
            }

            case 'v':
            {
                fwprintf(stderr,
                         _(L"%ls, version %s\n"),
                         program_name,
                         FISH_BUILD_VERSION);
                exit(0);
            }

            case 'i':
            {
                do_indent = 0;
                break;
            }


            case '?':
            {
                exit(1);
            }

        }
    }

    wcstring sb_in, sb_out;
    read_file(stdin, sb_in);

    wutil_init();

    if (!indent(sb_out, sb_in, do_indent))
    {
        trim(sb_out);
        fwprintf(stdout, L"%ls", sb_out.c_str());
    }
    else
    {
        /*
          Indenting failed - print original input
        */
        fwprintf(stdout, L"%ls", sb_in.c_str());
    }


    wutil_destroy();

    return 0;
}
コード例 #11
0
ファイル: fish_indent.cpp プロジェクト: actionless/fish-shell
int main(int argc, char *argv[])
{
    set_main_thread();
    setup_fork_guards();

    wsetlocale(LC_ALL, L"");
    program_name=L"fish_indent";

    env_init();
    input_init();

    /* Types of output we support */
    enum
    {
        output_type_plain_text,
        output_type_ansi,
        output_type_html
    } output_type = output_type_plain_text;
    bool do_indent = true;

    const char *short_opts = "+dhvi";
    const struct option long_opts[] =
    {
        { "dump", no_argument, NULL, 'd' },
        { "no-indent", no_argument, NULL, 'i' },
        { "help", no_argument, NULL, 'h' },
        { "version", no_argument, NULL, 'v' },
        { "html", no_argument, NULL, 1 },
        { "ansi", no_argument, NULL, 2 },
        { NULL, 0, NULL, 0 }
    };

    int opt;
    while ((opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1)
    {
        switch (opt)
        {
            case 0:
            {
                fwprintf(stderr, _(L"getopt_long() unexpectedly returned zero\n"));
                exit_without_destructors(127);
            }

            case 'd':
            {
                dump_parse_tree = true;
                break;
            }

            case 'h':
            {
                print_help("fish_indent", 1);
                exit_without_destructors(0);
            }

            case 'v':
            {
                fwprintf(stderr, _(L"%ls, version %s\n"), program_name, get_fish_version());
                exit(0);
                assert(0 && "Unreachable code reached");
                break;
            }

            case 'i':
            {
                do_indent = false;
                break;
            }

            case 1:
            {
                output_type = output_type_html;
                break;
            }

            case 2:
            {
                output_type = output_type_ansi;
                break;
            }

            default:
            {
                // We assume getopt_long() has already emitted a diagnostic msg.
                exit_without_destructors(1);
            }
        }
    }

    const wcstring src = read_file(stdin);
    const wcstring output_wtext = prettify(src, do_indent);

    /* Maybe colorize */
    std::vector<highlight_spec_t> colors;
    if (output_type != output_type_plain_text)
    {
        highlight_shell_no_io(output_wtext, colors, output_wtext.size(), NULL, env_vars_snapshot_t::current());
    }

    std::string colored_output;
    switch (output_type)
    {
        case output_type_plain_text:
            colored_output = no_colorize(output_wtext);
            break;

        case output_type_ansi:
            colored_output = ansi_colorize(output_wtext, colors);
            break;

        case output_type_html:
            colored_output = html_colorize(output_wtext, colors);
            break;
    }

    fputs(colored_output.c_str(), stdout);
    return 0;
}