@@ -97,13 +97,14 @@ static gboolean terminal_vte_button_press_event(VteTerminal * vte, GdkEventButto
97
97
static void terminal_settings_apply_to_term (LXTerminal * terminal , Term * term );
98
98
static Term * terminal_new (LXTerminal * terminal , const gchar * label , const gchar * pwd , gchar * * env , gchar * * exec );
99
99
static 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 );
101
101
static void terminal_free (Term * term );
102
102
static void terminal_menubar_initialize (LXTerminal * terminal );
103
103
static void terminal_menu_accelerator_update (LXTerminal * terminal );
104
104
static void terminal_settings_apply (LXTerminal * terminal );
105
105
static void terminal_update_menu_shortcuts (Setting * setting );
106
106
static 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 );
107
108
108
109
/* Menu accelerator saved when the user disables it. */
109
110
static char * saved_menu_accelerator = NULL ;
@@ -113,8 +114,10 @@ static gchar usage_display[] = {
113
114
"Usage:\n"
114
115
" lxterminal [Options...] - LXTerminal is a terminal emulator\n\n"
115
116
"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"
117
119
" --geometry=COLUMNSxROWS Set the terminal's size\n"
120
+ " -h, --help This help text\n"
118
121
" -l, --loginshell Execute login shell\n"
119
122
" -t, -T, --title=,\n"
120
123
" --tabs=NAME[,NAME[,NAME[...]]] Set the terminal's title\n"
@@ -293,7 +296,8 @@ static void terminal_initialize_switch_tab_accelerator(Term * term)
293
296
{
294
297
/* Formulate the accelerator name. */
295
298
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 );
297
301
298
302
/* Parse the accelerator name. */
299
303
guint key ;
@@ -373,7 +377,7 @@ static void terminal_new_window_activate_event(GtkAction * action, LXTerminal *
373
377
* Open a new tab. */
374
378
static void terminal_new_tab_activate_event (GtkAction * action , LXTerminal * terminal )
375
379
{
376
- terminal_new_tab (terminal , NULL );
380
+ terminal_new_tab (terminal , NULL , NULL );
377
381
}
378
382
379
383
static void terminal_set_geometry_hints (Term * term , GdkGeometry * geometry )
@@ -410,7 +414,7 @@ static void terminal_save_size(LXTerminal * terminal)
410
414
terminal -> row = vte_terminal_get_row_count (VTE_TERMINAL (term -> vte ));
411
415
}
412
416
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 )
414
418
{
415
419
Term * term ;
416
420
gchar * proc_cwd = terminal_get_current_dir (terminal );
@@ -419,21 +423,14 @@ static void terminal_new_tab(LXTerminal * terminal, const gchar * label)
419
423
* If the working directory was determined above, use it; otherwise default to the working directory of the process.
420
424
* Create the new terminal. */
421
425
422
- if (terminal -> login_shell )
426
+ gint cmd_len = 0 ;
427
+ gchar * * exec = NULL ;
428
+ if (cmd != NULL )
423
429
{
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 );
436
431
}
432
+ terminal_process_requested_command (& exec , cmd_len , terminal -> login_shell );
433
+ term = terminal_new (terminal , label , proc_cwd , NULL , exec );
437
434
g_free (proc_cwd );
438
435
439
436
/* 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
1315
1312
exec [1 ] = g_path_get_basename (exec [0 ]);
1316
1313
exec [2 ] = NULL ;
1317
1314
}
1315
+ term -> command = exec ;
1318
1316
1319
1317
#if VTE_CHECK_VERSION (0 , 38 , 0 )
1320
1318
vte_terminal_spawn_sync (
@@ -1342,7 +1340,6 @@ static Term * terminal_new(LXTerminal * terminal, const gchar * label, const gch
1342
1340
& term -> pid ,
1343
1341
NULL );
1344
1342
#endif
1345
- g_strfreev (exec );
1346
1343
1347
1344
/* Connect signals. */
1348
1345
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
1365
1362
/* Deallocate a Term structure. */
1366
1363
static void terminal_free (Term * term )
1367
1364
{
1365
+ g_strfreev (term -> command );
1368
1366
g_free (term -> matched_url );
1369
1367
if ((GTK_IS_ACCEL_GROUP (term -> parent -> accel_group )) && (term -> closure != NULL ))
1370
1368
{
@@ -1431,27 +1429,31 @@ gboolean lxterminal_process_arguments(gint argc, gchar * * argv, CommandArgument
1431
1429
arguments -> executable = argv [0 ];
1432
1430
1433
1431
char * * argv_cursor = argv ;
1434
- gint cmd_len ;
1432
+ gint num___commandEqual = 0 ; /* ___commandEqual for _--command= */
1435
1433
1436
1434
while (argc > 1 )
1437
1435
{
1438
1436
argc -- ;
1439
1437
argv_cursor ++ ;
1440
1438
char * argument = * argv_cursor ;
1441
1439
1442
- /* --command=<command> */
1440
+ /* --command= */
1443
1441
if (strncmp (argument , "--command=" , 10 ) == 0 )
1444
1442
{
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 ;
1447
1449
}
1448
1450
1449
1451
/* -e <rest of arguments>, --command <rest of arguments>
1450
1452
* The <rest of arguments> behavior is demanded by distros who insist on this xterm feature. */
1451
1453
else if ((strcmp (argument , "--command" ) == 0 ) || (strcmp (argument , "-e" ) == 0 ))
1452
1454
{
1453
- if ( arguments -> command != NULL ) g_strfreev (arguments -> command );
1454
- cmd_len = 0 ;
1455
+ g_strfreev (arguments -> command );
1456
+ gint cmd_len = 0 ;
1455
1457
arguments -> command = g_malloc (argc * sizeof (gchar * ));
1456
1458
1457
1459
while (argc > 1 )
@@ -1521,7 +1523,7 @@ gboolean lxterminal_process_arguments(gint argc, gchar * * argv, CommandArgument
1521
1523
arguments -> working_directory = & argument [20 ];
1522
1524
}
1523
1525
1524
- /* --no-remote: Do not accept or send remote commands */
1526
+ /* --no-remote: Do not accept or send remote commands */
1525
1527
else if (strcmp (argument , "--no-remote" ) == 0 ) {
1526
1528
arguments -> no_remote = TRUE;
1527
1529
}
@@ -1536,55 +1538,61 @@ gboolean lxterminal_process_arguments(gint argc, gchar * * argv, CommandArgument
1536
1538
else {
1537
1539
printf ("%s\n" , usage_display );
1538
1540
return FALSE;
1541
+ }
1539
1542
}
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;
1541
1550
/* Handle --loginshell. */
1542
- if (arguments -> command != NULL && cmd_len <= 2 ) {
1551
+ if (* command != NULL && cmd_len <= 2 ) {
1543
1552
/* Force using login shell if it has only 1 command, and command is not
1544
1553
* 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 ]);
1546
1555
if (program_path == NULL ) {
1547
- arguments -> login_shell = TRUE;
1556
+ force_login_shell = TRUE;
1548
1557
}
1549
1558
g_free (program_path );
1550
1559
}
1551
- if (arguments -> login_shell == TRUE)
1560
+ if (login_shell == TRUE || force_login_shell == TRUE)
1552
1561
{
1553
1562
const gchar * shell = terminal_get_preferred_shell ();
1554
1563
gchar * shellname = g_path_get_basename (shell );
1555
- if (arguments -> command == NULL )
1564
+ if (* command == NULL )
1556
1565
{
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 ;
1561
1570
}
1562
1571
else
1563
1572
{
1564
1573
gchar * * tmp = g_malloc ((cmd_len + 4 ) * sizeof (gchar * ));
1565
1574
tmp [0 ] = g_strdup (shell );
1566
1575
tmp [1 ] = g_strdup_printf ("-%s" , shellname );
1567
1576
tmp [2 ] = g_strdup ("-c" );
1568
- memcpy ((tmp + 3 ), arguments -> command , cmd_len * sizeof (gchar * ));
1577
+ memcpy ((tmp + 3 ), * command , cmd_len * sizeof (gchar * ));
1569
1578
tmp [cmd_len + 3 ] = NULL ;
1570
- g_free (arguments -> command );
1571
- arguments -> command = tmp ;
1579
+ g_free (* command );
1580
+ * command = tmp ;
1572
1581
}
1573
1582
g_free (shellname );
1574
1583
}
1575
1584
else
1576
1585
{
1577
- if ( arguments -> command != NULL )
1586
+ if ( * command != NULL )
1578
1587
{
1579
1588
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 * ));
1582
1591
tmp [cmd_len + 1 ] = NULL ;
1583
- g_free (arguments -> command );
1584
- arguments -> command = tmp ;
1592
+ g_free (* command );
1593
+ * command = tmp ;
1585
1594
}
1586
1595
}
1587
- return TRUE;
1588
1596
}
1589
1597
1590
1598
/* Initialize a new LXTerminal.
@@ -1670,12 +1678,27 @@ LXTerminal * lxterminal_initialize(LXTermWindow * lxtermwin, CommandArguments *
1670
1678
{
1671
1679
local_working_directory = g_get_current_dir ();
1672
1680
}
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 );
1673
1696
Term * term = terminal_new (
1674
1697
terminal ,
1675
1698
((arguments -> title != NULL ) ? arguments -> title : NULL ),
1676
1699
((arguments -> working_directory != NULL ) ? arguments -> working_directory : local_working_directory ),
1677
1700
NULL ,
1678
- arguments -> command );
1701
+ command );
1679
1702
g_free (local_working_directory );
1680
1703
1681
1704
/* Set window title. */
@@ -1761,18 +1784,37 @@ LXTerminal * lxterminal_initialize(LXTermWindow * lxtermwin, CommandArguments *
1761
1784
/* Update terminal settings. */
1762
1785
terminal_settings_apply (terminal );
1763
1786
1764
- if (arguments -> tabs != NULL && arguments -> tabs [0 ] != '\0' )
1787
+ if (arguments -> tabs != NULL && arguments -> tabs [0 ] != '\0'
1788
+ || arguments -> commands != NULL )
1765
1789
{
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
+ }
1771
1808
1772
- while (token != NULL && token [0 ] != '\0' )
1809
+ while (tab != NULL && tab [0 ] != '\0' || cmd != NULL && * cmd != NULL )
1773
1810
{
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
+ }
1776
1818
}
1777
1819
}
1778
1820
0 commit comments