@@ -97,13 +97,14 @@ static gboolean terminal_vte_button_press_event(VteTerminal * vte, GdkEventButto
9797static void terminal_settings_apply_to_term (LXTerminal * terminal , Term * term );
9898static Term * terminal_new (LXTerminal * terminal , const gchar * label , const gchar * pwd , gchar * * env , gchar * * exec );
9999static void terminal_set_geometry_hints (Term * term , GdkGeometry * geometry );
100- static void terminal_new_tab (LXTerminal * terminal , const gchar * label );
100+ static void terminal_new_tab (LXTerminal * terminal , const gchar * label , const gchar * cmd );
101101static void terminal_free (Term * term );
102102static void terminal_menubar_initialize (LXTerminal * terminal );
103103static void terminal_menu_accelerator_update (LXTerminal * terminal );
104104static void terminal_settings_apply (LXTerminal * terminal );
105105static void terminal_update_menu_shortcuts (Setting * setting );
106106static void terminal_initialize_menu_shortcuts (Setting * setting );
107+ static void terminal_process_requested_command (gchar * * * const command , const gint cmd_len , const gboolean login_shell );
107108
108109/* Menu accelerator saved when the user disables it. */
109110static char * saved_menu_accelerator = NULL ;
@@ -113,8 +114,10 @@ static gchar usage_display[] = {
113114 "Usage:\n"
114115 " lxterminal [Options...] - LXTerminal is a terminal emulator\n\n"
115116 "Options:\n"
116- " -e, --command=STRING Execute the argument to this option inside the terminal\n"
117+ " --command=STRING [--command=STRING [...]],\n"
118+ " -e STRING, --command STRING Execute the argument to this option inside the terminal\n"
117119 " --geometry=COLUMNSxROWS Set the terminal's size\n"
120+ " -h, --help This help text\n"
118121 " -l, --loginshell Execute login shell\n"
119122 " -t, -T, --title=,\n"
120123 " --tabs=NAME[,NAME[,NAME[...]]] Set the terminal's title\n"
@@ -293,7 +296,8 @@ static void terminal_initialize_switch_tab_accelerator(Term * term)
293296 {
294297 /* Formulate the accelerator name. */
295298 char switch_tab_accel [1 + 3 + 1 + 1 + 1 ]; /* "<ALT>n" */
296- sprintf (switch_tab_accel , "<ALT>%d" , term -> index + 1 );
299+ /* Casting to unsigned, and %10, to shut off a compilation warning. */
300+ sprintf (switch_tab_accel , "<ALT>%d" , (guint )(term -> index + 1 )%10 );
297301
298302 /* Parse the accelerator name. */
299303 guint key ;
@@ -373,7 +377,7 @@ static void terminal_new_window_activate_event(GtkAction * action, LXTerminal *
373377 * Open a new tab. */
374378static void terminal_new_tab_activate_event (GtkAction * action , LXTerminal * terminal )
375379{
376- terminal_new_tab (terminal , NULL );
380+ terminal_new_tab (terminal , NULL , NULL );
377381}
378382
379383static void terminal_set_geometry_hints (Term * term , GdkGeometry * geometry )
@@ -410,7 +414,7 @@ static void terminal_save_size(LXTerminal * terminal)
410414 terminal -> row = vte_terminal_get_row_count (VTE_TERMINAL (term -> vte ));
411415}
412416
413- static void terminal_new_tab (LXTerminal * terminal , const gchar * label )
417+ static void terminal_new_tab (LXTerminal * terminal , const gchar * label , const gchar * cmd )
414418{
415419 Term * term ;
416420 gchar * proc_cwd = terminal_get_current_dir (terminal );
@@ -419,21 +423,14 @@ static void terminal_new_tab(LXTerminal * terminal, const gchar * label)
419423 * If the working directory was determined above, use it; otherwise default to the working directory of the process.
420424 * Create the new terminal. */
421425
422- if (terminal -> login_shell )
426+ gint cmd_len = 0 ;
427+ gchar * * exec = NULL ;
428+ if (cmd != NULL )
423429 {
424- /* Create a login shell, this should be cleaner. */
425- gchar * * exec = g_malloc (3 * sizeof (gchar * ));
426- exec [0 ] = g_strdup (terminal_get_preferred_shell ());
427- char * shellname = g_path_get_basename (exec [0 ]);
428- exec [1 ] = g_strdup_printf ("-%s" , shellname );
429- g_free (shellname );
430- exec [2 ] = NULL ;
431- term = terminal_new (terminal , label , proc_cwd , NULL , exec );
432- }
433- else
434- {
435- term = terminal_new (terminal , label , proc_cwd , NULL , NULL );
430+ g_shell_parse_argv (cmd , & cmd_len , & exec , NULL );
436431 }
432+ terminal_process_requested_command (& exec , cmd_len , terminal -> login_shell );
433+ term = terminal_new (terminal , label , proc_cwd , NULL , exec );
437434 g_free (proc_cwd );
438435
439436 /* Add a tab to the notebook and the "terms" array. */
@@ -1315,6 +1312,7 @@ static Term * terminal_new(LXTerminal * terminal, const gchar * label, const gch
13151312 exec [1 ] = g_path_get_basename (exec [0 ]);
13161313 exec [2 ] = NULL ;
13171314 }
1315+ term -> command = exec ;
13181316
13191317#if VTE_CHECK_VERSION (0 , 38 , 0 )
13201318 vte_terminal_spawn_sync (
@@ -1342,7 +1340,6 @@ static Term * terminal_new(LXTerminal * terminal, const gchar * label, const gch
13421340 & term -> pid ,
13431341 NULL );
13441342#endif
1345- g_strfreev (exec );
13461343
13471344 /* Connect signals. */
13481345 g_signal_connect (G_OBJECT (term -> tab ), "button-press-event" , G_CALLBACK (terminal_tab_button_press_event ), term );
@@ -1365,6 +1362,7 @@ static Term * terminal_new(LXTerminal * terminal, const gchar * label, const gch
13651362/* Deallocate a Term structure. */
13661363static void terminal_free (Term * term )
13671364{
1365+ g_strfreev (term -> command );
13681366 g_free (term -> matched_url );
13691367 if ((GTK_IS_ACCEL_GROUP (term -> parent -> accel_group )) && (term -> closure != NULL ))
13701368 {
@@ -1431,27 +1429,31 @@ gboolean lxterminal_process_arguments(gint argc, gchar * * argv, CommandArgument
14311429 arguments -> executable = argv [0 ];
14321430
14331431 char * * argv_cursor = argv ;
1434- gint cmd_len ;
1432+ gint num___commandEqual = 0 ; /* ___commandEqual for _--command= */
14351433
14361434 while (argc > 1 )
14371435 {
14381436 argc -- ;
14391437 argv_cursor ++ ;
14401438 char * argument = * argv_cursor ;
14411439
1442- /* --command=<command> */
1440+ /* --command= */
14431441 if (strncmp (argument , "--command=" , 10 ) == 0 )
14441442 {
1445- g_strfreev (arguments -> command );
1446- g_shell_parse_argv (& argument [10 ], & cmd_len , & arguments -> command , NULL );
1443+ arguments -> commands =
1444+ g_realloc (arguments -> commands ,
1445+ (num___commandEqual + 2 ) * sizeof (gchar * ));
1446+ arguments -> commands [num___commandEqual ] = & argument [10 ];
1447+ num___commandEqual ++ ;
1448+ arguments -> commands [num___commandEqual ] = NULL ;
14471449 }
14481450
14491451 /* -e <rest of arguments>, --command <rest of arguments>
14501452 * The <rest of arguments> behavior is demanded by distros who insist on this xterm feature. */
14511453 else if ((strcmp (argument , "--command" ) == 0 ) || (strcmp (argument , "-e" ) == 0 ))
14521454 {
1453- if ( arguments -> command != NULL ) g_strfreev (arguments -> command );
1454- cmd_len = 0 ;
1455+ g_strfreev (arguments -> command );
1456+ gint cmd_len = 0 ;
14551457 arguments -> command = g_malloc (argc * sizeof (gchar * ));
14561458
14571459 while (argc > 1 )
@@ -1521,7 +1523,7 @@ gboolean lxterminal_process_arguments(gint argc, gchar * * argv, CommandArgument
15211523 arguments -> working_directory = & argument [20 ];
15221524 }
15231525
1524- /* --no-remote: Do not accept or send remote commands */
1526+ /* --no-remote: Do not accept or send remote commands */
15251527 else if (strcmp (argument , "--no-remote" ) == 0 ) {
15261528 arguments -> no_remote = TRUE;
15271529 }
@@ -1536,55 +1538,61 @@ gboolean lxterminal_process_arguments(gint argc, gchar * * argv, CommandArgument
15361538 else {
15371539 printf ("%s\n" , usage_display );
15381540 return FALSE;
1541+ }
15391542 }
1540- }
1543+ return TRUE;
1544+ }
1545+
1546+ /* Furthere process a command before executing it. Handle out of path, and login shell.*/
1547+ static void terminal_process_requested_command (gchar * * * const command , const gint cmd_len , const gboolean login_shell )
1548+ {
1549+ gboolean force_login_shell = FALSE;
15411550 /* Handle --loginshell. */
1542- if (arguments -> command != NULL && cmd_len <= 2 ) {
1551+ if (* command != NULL && cmd_len <= 2 ) {
15431552 /* Force using login shell if it has only 1 command, and command is not
15441553 * in PATH. */
1545- gchar * program_path = g_find_program_in_path (arguments -> command [0 ]);
1554+ gchar * program_path = g_find_program_in_path (( * command ) [0 ]);
15461555 if (program_path == NULL ) {
1547- arguments -> login_shell = TRUE;
1556+ force_login_shell = TRUE;
15481557 }
15491558 g_free (program_path );
15501559 }
1551- if (arguments -> login_shell == TRUE)
1560+ if (login_shell == TRUE || force_login_shell == TRUE)
15521561 {
15531562 const gchar * shell = terminal_get_preferred_shell ();
15541563 gchar * shellname = g_path_get_basename (shell );
1555- if (arguments -> command == NULL )
1564+ if (* command == NULL )
15561565 {
1557- arguments -> command = g_malloc (3 * sizeof (gchar * ));
1558- arguments -> command [0 ] = g_strdup (shell );
1559- arguments -> command [1 ] = g_strdup_printf ("-%s" , shellname );
1560- arguments -> command [2 ] = NULL ;
1566+ * command = g_malloc (3 * sizeof (gchar * ));
1567+ ( * command ) [0 ] = g_strdup (shell );
1568+ ( * command ) [1 ] = g_strdup_printf ("-%s" , shellname );
1569+ ( * command ) [2 ] = NULL ;
15611570 }
15621571 else
15631572 {
15641573 gchar * * tmp = g_malloc ((cmd_len + 4 ) * sizeof (gchar * ));
15651574 tmp [0 ] = g_strdup (shell );
15661575 tmp [1 ] = g_strdup_printf ("-%s" , shellname );
15671576 tmp [2 ] = g_strdup ("-c" );
1568- memcpy ((tmp + 3 ), arguments -> command , cmd_len * sizeof (gchar * ));
1577+ memcpy ((tmp + 3 ), * command , cmd_len * sizeof (gchar * ));
15691578 tmp [cmd_len + 3 ] = NULL ;
1570- g_free (arguments -> command );
1571- arguments -> command = tmp ;
1579+ g_free (* command );
1580+ * command = tmp ;
15721581 }
15731582 g_free (shellname );
15741583 }
15751584 else
15761585 {
1577- if ( arguments -> command != NULL )
1586+ if ( * command != NULL )
15781587 {
15791588 gchar * * tmp = g_malloc ((cmd_len + 2 ) * sizeof (gchar * ));
1580- tmp [0 ] = g_strdup (arguments -> command [0 ]);
1581- memcpy ((tmp + 1 ), arguments -> command , cmd_len * sizeof (gchar * ));
1589+ tmp [0 ] = g_strdup (( * command ) [0 ]);
1590+ memcpy ((tmp + 1 ), * command , cmd_len * sizeof (gchar * ));
15821591 tmp [cmd_len + 1 ] = NULL ;
1583- g_free (arguments -> command );
1584- arguments -> command = tmp ;
1592+ g_free (* command );
1593+ * command = tmp ;
15851594 }
15861595 }
1587- return TRUE;
15881596}
15891597
15901598/* Initialize a new LXTerminal.
@@ -1670,12 +1678,27 @@ LXTerminal * lxterminal_initialize(LXTermWindow * lxtermwin, CommandArguments *
16701678 {
16711679 local_working_directory = g_get_current_dir ();
16721680 }
1681+ gchar * * command = NULL ;
1682+ gint cmd_len = 0 ;
1683+ if (arguments -> command != NULL )
1684+ {
1685+ command = g_strdupv (arguments -> command );
1686+ /* This duplication is meant to help unify the rest of the code.
1687+ * In particular, when freeing the memory of the --commands= options,
1688+ * there will be no need to differentiate the --command case. */
1689+ cmd_len = (gint )g_strv_length (arguments -> command );
1690+ }
1691+ else if (arguments -> commands != NULL )
1692+ {
1693+ g_shell_parse_argv (arguments -> commands [0 ], & cmd_len , & command , NULL );
1694+ }
1695+ terminal_process_requested_command (& command , cmd_len , arguments -> login_shell );
16731696 Term * term = terminal_new (
16741697 terminal ,
16751698 ((arguments -> title != NULL ) ? arguments -> title : NULL ),
16761699 ((arguments -> working_directory != NULL ) ? arguments -> working_directory : local_working_directory ),
16771700 NULL ,
1678- arguments -> command );
1701+ command );
16791702 g_free (local_working_directory );
16801703
16811704 /* Set window title. */
@@ -1761,18 +1784,37 @@ LXTerminal * lxterminal_initialize(LXTermWindow * lxtermwin, CommandArguments *
17611784 /* Update terminal settings. */
17621785 terminal_settings_apply (terminal );
17631786
1764- if (arguments -> tabs != NULL && arguments -> tabs [0 ] != '\0' )
1787+ if (arguments -> tabs != NULL && arguments -> tabs [0 ] != '\0'
1788+ || arguments -> commands != NULL )
17651789 {
1766- /* use token to destructively slice tabs to different tab names */
1767- char * token = strtok (arguments -> tabs , "," );
1768- term -> user_specified_label = TRUE;
1769- gtk_label_set_text (GTK_LABEL (term -> label ), token );
1770- token = strtok (NULL , "," );
1790+ gchar * tab = NULL ;
1791+ if (arguments -> tabs != NULL && arguments -> tabs [0 ] != '\0' )
1792+ {
1793+ /* Use tab to destructively slice tabs to different tab names */
1794+ tab = strtok (arguments -> tabs , "," );
1795+ term -> user_specified_label = TRUE;
1796+ gtk_label_set_text (GTK_LABEL (term -> label ), tab );
1797+ /* Initially, the 1st tab is hidden */
1798+ tab = strtok (NULL , "," );
1799+ }
1800+ gchar * * cmd = arguments -> commands ;
1801+ if (cmd != NULL )
1802+ {
1803+ if (arguments -> command == NULL )
1804+ {
1805+ cmd ++ ; /* Initialy, hidden tab runs 1st command from --command=. */
1806+ }
1807+ }
17711808
1772- while (token != NULL && token [0 ] != '\0' )
1809+ while (tab != NULL && tab [0 ] != '\0' || cmd != NULL && * cmd != NULL )
17731810 {
1774- terminal_new_tab (terminal , token );
1775- token = strtok (NULL , "," );
1811+ terminal_new_tab (terminal , tab , cmd != NULL ? * cmd : NULL );
1812+ if (tab != NULL && tab [0 ] != '\0' )
1813+ tab = strtok (NULL , "," );
1814+ if (cmd != NULL && * cmd != NULL )
1815+ {
1816+ cmd ++ ;
1817+ }
17761818 }
17771819 }
17781820
0 commit comments