@@ -259,6 +259,9 @@ static const char g_arg_separator[] = "`$";
259
259
static const char g_redirect_out1 [] = ">" ;
260
260
static const char g_redirect_out2 [] = ">>" ;
261
261
static const char g_redirect_in1 [] = "<" ;
262
+ #ifdef CONFIG_NSH_PIPELINE
263
+ static const char g_pipeline1 [] = "|" ;
264
+ #endif
262
265
#ifdef NSH_HAVE_VARS
263
266
static const char g_exitstatus [] = "?" ;
264
267
static const char g_lastpid [] = "!" ;
@@ -1601,6 +1604,16 @@ static FAR char *nsh_argument(FAR struct nsh_vtbl_s *vtbl,
1601
1604
argument = (FAR char * )g_redirect_in1 ;
1602
1605
}
1603
1606
1607
+ #ifdef CONFIG_NSH_PIPELINE
1608
+ /* Does the token begin with '|' -- pipeline? */
1609
+
1610
+ if (* pbegin == '|' )
1611
+ {
1612
+ * saveptr = pbegin + 1 ;
1613
+ argument = (FAR char * )g_pipeline1 ;
1614
+ }
1615
+ #endif
1616
+
1604
1617
/* Does the token begin with '#' -- comment */
1605
1618
1606
1619
else if (* pbegin == '#')
@@ -2415,6 +2428,13 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
2415
2428
.file_out = NULL
2416
2429
};
2417
2430
2431
+ #ifdef CONFIG_NSH_PIPELINE
2432
+ int pipefd [2 ] =
2433
+ {
2434
+ -1 , -1
2435
+ };
2436
+ #endif
2437
+
2418
2438
NSH_MEMLIST_TYPE memlist ;
2419
2439
NSH_ALIASLIST_TYPE alist ;
2420
2440
FAR char * argv [MAX_ARGV_ENTRIES ];
@@ -2424,9 +2444,15 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
2424
2444
int ret ;
2425
2445
bool redirect_out_save = false;
2426
2446
bool redirect_in_save = false;
2447
+ #ifdef CONFIG_NSH_PIPELINE
2448
+ bool bg_save = false;
2449
+ #endif
2427
2450
size_t redirect_out1_len = strlen (g_redirect_out1 );
2428
2451
size_t redirect_out2_len = strlen (g_redirect_out2 );
2429
2452
size_t redirect_in1_len = strlen (g_redirect_in1 );
2453
+ #ifdef CONFIG_NSH_PIPELINE
2454
+ size_t pipeline1_len = strlen (g_pipeline1 );
2455
+ #endif
2430
2456
2431
2457
#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
2432
2458
char tracebuf [CONFIG_NSH_LINELEN + 1 ];
@@ -2647,6 +2673,89 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
2647
2673
param .oflags_in = O_RDONLY ;
2648
2674
param .file_in = nsh_getfullpath (vtbl , arg );
2649
2675
}
2676
+ #ifdef CONFIG_NSH_PIPELINE
2677
+ else if (!strncmp (argv [argc ], g_pipeline1 , pipeline1_len ))
2678
+ {
2679
+ FAR char * arg ;
2680
+ FAR char * sh_argv [4 ];
2681
+
2682
+ if (argv [argc ][pipeline1_len ])
2683
+ {
2684
+ arg = & argv [argc ][pipeline1_len ];
2685
+ }
2686
+ else
2687
+ {
2688
+ arg = nsh_argument (vtbl , & saveptr , & memlist , NULL , & isenvvar );
2689
+ }
2690
+
2691
+ if (!arg )
2692
+ {
2693
+ nsh_error (vtbl , g_fmtarginvalid , cmd );
2694
+ ret = ERROR ;
2695
+ goto dynlist_free ;
2696
+ }
2697
+
2698
+ for (ret = 0 ; ret < argc - 1 ; ret ++ )
2699
+ {
2700
+ FAR char * p_arg = argv [ret ];
2701
+ size_t len = strlen (p_arg );
2702
+
2703
+ /* Restore from split args to concat args. */
2704
+
2705
+ DEBUGASSERT (& p_arg [len + 1 ] == argv [ret + 1 ]);
2706
+ p_arg [len ] = ' ' ;
2707
+ }
2708
+
2709
+ sh_argv [0 ] = "sh" ;
2710
+ sh_argv [1 ] = "-c" ;
2711
+ sh_argv [2 ] = argv [0 ];
2712
+ sh_argv [3 ] = NULL ;
2713
+
2714
+ ret = pipe2 (pipefd , 0 );
2715
+ if (ret < 0 )
2716
+ {
2717
+ ret = - errno ;
2718
+ goto dynlist_free ;
2719
+ }
2720
+
2721
+ redirect_out_save = vtbl -> np .np_redir_out ;
2722
+ vtbl -> np .np_redir_out = true;
2723
+ param .fd_out = pipefd [1 ];
2724
+
2725
+ bg_save = vtbl -> np .np_bg ;
2726
+ vtbl -> np .np_bg = true;
2727
+
2728
+ ret = nsh_execute (vtbl , 4 , sh_argv , & param );
2729
+
2730
+ vtbl -> np .np_bg = bg_save ;
2731
+
2732
+ if (param .fd_in != -1 )
2733
+ {
2734
+ close (param .fd_in );
2735
+ param .fd_in = -1 ;
2736
+ vtbl -> np .np_redir_in = redirect_in_save ;
2737
+ }
2738
+
2739
+ if (param .fd_out != -1 )
2740
+ {
2741
+ close (param .fd_out );
2742
+ param .fd_out = -1 ;
2743
+ vtbl -> np .np_redir_out = redirect_out_save ;
2744
+ }
2745
+
2746
+ redirect_in_save = vtbl -> np .np_redir_in ;
2747
+ vtbl -> np .np_redir_in = true;
2748
+ param .fd_in = pipefd [0 ];
2749
+
2750
+ argv [0 ] = arg ;
2751
+ argc = 1 ;
2752
+
2753
+ if (ret == -1 )
2754
+ {
2755
+ goto dynlist_free ;
2756
+ }
2757
+ }
2758
+ #endif
2650
2759
else
2651
2760
{
2652
2761
argc ++ ;
@@ -2678,6 +2787,8 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
2678
2787
2679
2788
ret = nsh_execute (vtbl , argc , argv , & param );
2680
2789
2790
+ dynlist_free :
2791
+
2681
2792
/* Free any allocated resources */
2682
2793
2683
2794
/* Free the redirected output file path */
@@ -2687,6 +2798,13 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
2687
2798
nsh_freefullpath ((char * )param .file_out );
2688
2799
vtbl -> np .np_redir_out = redirect_out_save ;
2689
2800
}
2801
+ #ifdef CONFIG_NSH_PIPELINE
2802
+ else if (param .fd_out != -1 )
2803
+ {
2804
+ close (param .fd_out );
2805
+ vtbl -> np .np_redir_out = redirect_out_save ;
2806
+ }
2807
+ #endif
2690
2808
2691
2809
/* Free the redirected input file path */
2692
2810
@@ -2695,8 +2813,14 @@ static int nsh_parse_command(FAR struct nsh_vtbl_s *vtbl, FAR char *cmdline)
2695
2813
nsh_freefullpath ((char * )param .file_in );
2696
2814
vtbl -> np .np_redir_in = redirect_in_save ;
2697
2815
}
2816
+ #ifdef CONFIG_NSH_PIPELINE
2817
+ else if (param .fd_in != -1 )
2818
+ {
2819
+ close (param .fd_in );
2820
+ vtbl -> np .np_redir_in = redirect_in_save ;
2821
+ }
2822
+ #endif
2698
2823
2699
- dynlist_free :
2700
2824
NSH_ALIASLIST_FREE (vtbl , & alist );
2701
2825
NSH_MEMLIST_FREE (& memlist );
2702
2826
#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
0 commit comments