30
30
#include <string.h>
31
31
#include <errno.h>
32
32
#include <debug.h>
33
- #include <pthread.h>
34
33
#include <sched.h>
35
34
#include <unistd.h>
36
35
126
125
* Private Types
127
126
****************************************************************************/
128
127
129
- /* These structure describes the parsed command line */
130
-
131
- #ifndef CONFIG_NSH_DISABLEBG
132
- struct cmdarg_s
133
- {
134
- FAR struct nsh_vtbl_s * vtbl ; /* For front-end interaction */
135
- int fd_in ; /* FD for output redirection */
136
- int fd_out ; /* FD for output redirection */
137
- int argc ; /* Number of arguments in argv */
138
- FAR char * argv [MAX_ARGV_ENTRIES ]; /* Argument list */
139
- };
140
- #endif
141
-
142
128
/* This structure describes the allocation list */
143
129
144
130
#ifdef HAVE_MEMLIST
@@ -174,13 +160,6 @@ static void nsh_alist_free(FAR struct nsh_vtbl_s *vtbl,
174
160
FAR struct nsh_alist_s * alist );
175
161
#endif
176
162
177
- #ifndef CONFIG_NSH_DISABLEBG
178
- static void nsh_releaseargs (struct cmdarg_s * arg );
179
- static pthread_addr_t nsh_child (pthread_addr_t arg );
180
- static struct cmdarg_s * nsh_cloneargs (FAR struct nsh_vtbl_s * vtbl ,
181
- int fd_in , int fd_out , int argc , FAR char * argv []);
182
- #endif
183
-
184
163
static int nsh_saveresult (FAR struct nsh_vtbl_s * vtbl , bool result );
185
164
static int nsh_execute (FAR struct nsh_vtbl_s * vtbl ,
186
165
int argc , FAR char * argv [], FAR const char * redirfile_in ,
@@ -443,107 +422,6 @@ static void nsh_alist_free(FAR struct nsh_vtbl_s *vtbl,
443
422
}
444
423
#endif
445
424
446
- /****************************************************************************
447
- * Name: nsh_releaseargs
448
- ****************************************************************************/
449
-
450
- #ifndef CONFIG_NSH_DISABLEBG
451
- static void nsh_releaseargs (struct cmdarg_s * arg )
452
- {
453
- FAR struct nsh_vtbl_s * vtbl = arg -> vtbl ;
454
- int i ;
455
-
456
- /* If the output was redirected, then file descriptor should
457
- * be closed. The created task has its one, independent copy of
458
- * the file descriptor
459
- */
460
-
461
- if (vtbl -> np .np_redir_out )
462
- {
463
- close (arg -> fd_out );
464
- }
465
-
466
- /* Same for the input */
467
-
468
- if (vtbl -> np .np_redir_in )
469
- {
470
- close (arg -> fd_in );
471
- }
472
-
473
- /* Released the cloned vtbl instance */
474
-
475
- nsh_release (vtbl );
476
-
477
- /* Release the cloned args */
478
-
479
- for (i = 0 ; i < arg -> argc ; i ++ )
480
- {
481
- free (arg -> argv [i ]);
482
- }
483
-
484
- free (arg );
485
- }
486
- #endif
487
-
488
- /****************************************************************************
489
- * Name: nsh_child
490
- ****************************************************************************/
491
-
492
- #ifndef CONFIG_NSH_DISABLEBG
493
- static pthread_addr_t nsh_child (pthread_addr_t arg )
494
- {
495
- struct cmdarg_s * carg = (struct cmdarg_s * )arg ;
496
- int ret ;
497
-
498
- _info ("BG %s\n" , carg -> argv [0 ]);
499
-
500
- /* Execute the specified command on the child thread */
501
-
502
- ret = nsh_command (carg -> vtbl , carg -> argc , carg -> argv );
503
-
504
- /* Released the cloned arguments */
505
-
506
- _info ("BG %s complete\n" , carg -> argv [0 ]);
507
- nsh_releaseargs (carg );
508
-
509
- /* Detach from the pthread since we are not going to join with it.
510
- * Otherwise, we would have a memory leak.
511
- */
512
-
513
- pthread_detach (pthread_self ());
514
- return (pthread_addr_t )((uintptr_t )ret );
515
- }
516
- #endif
517
-
518
- /****************************************************************************
519
- * Name: nsh_cloneargs
520
- ****************************************************************************/
521
-
522
- #ifndef CONFIG_NSH_DISABLEBG
523
- static struct cmdarg_s * nsh_cloneargs (FAR struct nsh_vtbl_s * vtbl ,
524
- int fd_in , int fd_out , int argc ,
525
- FAR char * argv [])
526
- {
527
- struct cmdarg_s * ret = (struct cmdarg_s * )zalloc (sizeof (struct cmdarg_s ));
528
- int i ;
529
-
530
- if (ret )
531
- {
532
- ret -> vtbl = vtbl ;
533
- ret -> fd_in = fd_in ;
534
- ret -> fd_out = fd_out ;
535
- ret -> argc = argc ;
536
-
537
- for (i = 0 ; i < argc ; i ++ )
538
- {
539
- ret -> argv [i ] = strdup (argv [i ]);
540
- }
541
- }
542
-
543
- return ret ;
544
- }
545
- #endif
546
-
547
425
/****************************************************************************
548
426
* Name: nsh_saveresult
549
427
****************************************************************************/
@@ -616,8 +494,6 @@ static int nsh_execute(FAR struct nsh_vtbl_s *vtbl,
616
494
FAR const char * redirfile_in ,
617
495
FAR const char * redirfile_out , int oflags )
618
496
{
619
- int fd_in = STDIN_FILENO ;
620
- int fd_out = STDOUT_FILENO ;
621
497
int ret ;
622
498
623
499
/* DO NOT CHANGE THE ORDERING OF THE FOLLOWING STEPS
@@ -713,42 +589,6 @@ static int nsh_execute(FAR struct nsh_vtbl_s *vtbl,
713
589
714
590
#endif
715
591
716
- /* Redirected output? */
717
-
718
- if (vtbl -> np .np_redir_out )
719
- {
720
- /* Open the redirection file. This file will eventually
721
- * be closed by a call to either nsh_release (if the command
722
- * is executed in the background) or by nsh_undirect if the
723
- * command is executed in the foreground.
724
- */
725
-
726
- fd_out = open (redirfile_out , oflags , 0666 );
727
- if (fd_out < 0 )
728
- {
729
- nsh_error (vtbl , g_fmtcmdfailed , argv [0 ], "open" , NSH_ERRNO );
730
- goto errout ;
731
- }
732
- }
733
-
734
- /* Redirected input? */
735
-
736
- if (vtbl -> np .np_redir_in )
737
- {
738
- /* Open the redirection file. This file will eventually
739
- * be closed by a call to either nsh_release (if the command
740
- * is executed in the background) or by nsh_undirect if the
741
- * command is executed in the foreground.
742
- */
743
-
744
- fd_in = open (redirfile_in , O_RDONLY , 0 );
745
- if (fd_in < 0 )
746
- {
747
- nsh_error (vtbl , g_fmtcmdfailed , argv [0 ], "open" , NSH_ERRNO );
748
- goto errout ;
749
- }
750
- }
751
-
752
592
/* Handle the case where the command is executed in background.
753
593
* However is app is to be started as built-in new process will
754
594
* be created anyway, so skip this step.
@@ -757,108 +597,79 @@ static int nsh_execute(FAR struct nsh_vtbl_s *vtbl,
757
597
#ifndef CONFIG_NSH_DISABLEBG
758
598
if (vtbl -> np .np_bg )
759
599
{
760
- struct sched_param param ;
761
- struct nsh_vtbl_s * bkgvtbl ;
762
- struct cmdarg_s * args ;
763
- pthread_attr_t attr ;
764
- pthread_t thread ;
765
-
766
- /* Get a cloned copy of the vtbl with reference count=1.
767
- * after the command has been processed, the nsh_release() call
768
- * at the end of nsh_child() will destroy the clone.
769
- */
600
+ FAR char * sh_argv [4 ];
601
+ FAR char * sh_cmd = "sh" ;
602
+ int i ;
770
603
771
- bkgvtbl = nsh_clone (vtbl );
772
- if (!bkgvtbl )
773
- {
774
- goto errout_with_redirect ;
775
- }
604
+ DEBUGASSERT (strncmp (argv [0 ], sh_cmd , 3 ) != 0 );
776
605
777
- /* Create a container for the command arguments */
778
-
779
- args = nsh_cloneargs (bkgvtbl , fd_in , fd_out , argc , argv );
780
- if (!args )
606
+ sh_argv [0 ] = sh_cmd ;
607
+ sh_argv [1 ] = "-c" ;
608
+ for (i = 0 ; i < argc - 1 ; i ++ )
781
609
{
782
- nsh_release (bkgvtbl );
783
- goto errout_with_redirect ;
784
- }
610
+ FAR char * p_arg = argv [i ];
611
+ size_t len = strlen (p_arg );
785
612
786
- /* Handle redirection of output via a file descriptor */
613
+ /* Restore from split args to concat args. */
787
614
788
- if (vtbl -> np .np_redir_out || vtbl -> np .np_redir_in )
789
- {
790
- nsh_redirect (bkgvtbl , fd_in , fd_out , NULL );
615
+ DEBUGASSERT (& p_arg [len + 1 ] == argv [i + 1 ]);
616
+ p_arg [len ] = ' ' ;
791
617
}
792
618
793
- /* Get the execution priority of this task */
619
+ sh_argv [2 ] = argv [0 ];
620
+ sh_argv [3 ] = NULL ;
794
621
795
- ret = sched_getparam (0 , & param );
796
- if (ret != 0 )
797
- {
798
- nsh_error (vtbl , g_fmtcmdfailed , argv [0 ], "sched_getparm" ,
799
- NSH_ERRNO );
622
+ /* np.np_bg still there, try use nsh_builtin or nsh_fileapp to
623
+ * dispatch the backgroud by sh -c ""
624
+ */
800
625
801
- /* NOTE: bkgvtbl is released in nsh_relaseargs() */
626
+ return nsh_execute (vtbl , 4 , sh_argv ,
627
+ redirfile_in , redirfile_out , oflags );
628
+ }
629
+ else
630
+ #endif
631
+ {
632
+ uint8_t save [SAVE_SIZE ];
802
633
803
- nsh_releaseargs (args );
804
- goto errout ;
805
- }
634
+ int fd_in = STDIN_FILENO ;
635
+ int fd_out = STDOUT_FILENO ;
806
636
807
- /* Determine the priority to execute the command */
637
+ /* Redirected output? */
808
638
809
- if (vtbl -> np .np_nice != 0 )
639
+ if (vtbl -> np .np_redir_out )
810
640
{
811
- int priority = param .sched_priority - vtbl -> np .np_nice ;
812
- if (vtbl -> np .np_nice < 0 )
813
- {
814
- int max_priority = sched_get_priority_max (SCHED_NSH );
815
- if (priority > max_priority )
816
- {
817
- priority = max_priority ;
818
- }
819
- }
820
- else
641
+ /* Open the redirection file. This file will eventually
642
+ * be closed by a call to either nsh_release (if the command
643
+ * is executed in the background) or by nsh_undirect if the
644
+ * command is executed in the foreground.
645
+ */
646
+
647
+ fd_out = open (redirfile_out , oflags , 0666 );
648
+ if (fd_out < 0 )
821
649
{
822
- int min_priority = sched_get_priority_min (SCHED_NSH );
823
- if (priority < min_priority )
824
- {
825
- priority = min_priority ;
826
- }
650
+ nsh_error (vtbl , g_fmtcmdfailed , argv [0 ], "open" , NSH_ERRNO );
651
+ return nsh_saveresult (vtbl , true);
827
652
}
828
-
829
- param .sched_priority = priority ;
830
653
}
831
654
832
- /* Set up the thread attributes */
655
+ /* Redirected input? */
833
656
834
- pthread_attr_init (& attr );
835
- pthread_attr_setschedpolicy (& attr , SCHED_NSH );
836
- pthread_attr_setschedparam (& attr , & param );
837
-
838
- /* Execute the command as a separate thread at the appropriate
839
- * priority.
840
- */
841
-
842
- ret = pthread_create (& thread , & attr , nsh_child , (pthread_addr_t )args );
843
- if (ret != 0 )
657
+ if (vtbl -> np .np_redir_in )
844
658
{
845
- nsh_error (vtbl , g_fmtcmdfailed , argv [0 ], "pthread_create" ,
846
- NSH_ERRNO_OF (ret ));
847
-
848
- /* NOTE: bkgvtbl is released in nsh_relaseargs() */
659
+ /* Open the redirection file. This file will eventually
660
+ * be closed by a call to either nsh_release (if the command
661
+ * is executed in the background) or by nsh_undirect if the
662
+ * command is executed in the foreground.
663
+ */
849
664
850
- nsh_releaseargs (args );
851
- goto errout ;
665
+ fd_in = open (redirfile_in , O_RDONLY , 0 );
666
+ if (fd_in < 0 )
667
+ {
668
+ nsh_error (vtbl , g_fmtcmdfailed , argv [0 ], "open" , NSH_ERRNO );
669
+ return nsh_saveresult (vtbl , true);
670
+ }
852
671
}
853
672
854
- nsh_output (vtbl , "%s [%d:%d]\n" , argv [0 ], thread ,
855
- param .sched_priority );
856
- }
857
- else
858
- #endif
859
- {
860
- uint8_t save [SAVE_SIZE ];
861
-
862
673
/* Handle redirection of stdin/stdout file descriptor */
863
674
864
675
if (vtbl -> np .np_redir_out || vtbl -> np .np_redir_in )
@@ -890,7 +701,7 @@ static int nsh_execute(FAR struct nsh_vtbl_s *vtbl,
890
701
891
702
if (ret < 0 )
892
703
{
893
- goto errout ;
704
+ return nsh_saveresult ( vtbl , true) ;
894
705
}
895
706
}
896
707
@@ -899,22 +710,6 @@ static int nsh_execute(FAR struct nsh_vtbl_s *vtbl,
899
710
*/
900
711
901
712
return nsh_saveresult (vtbl , false);
902
-
903
- #ifndef CONFIG_NSH_DISABLEBG
904
- errout_with_redirect :
905
- if (vtbl -> np .np_redir_out )
906
- {
907
- close (fd_out );
908
- }
909
-
910
- if (vtbl -> np .np_redir_in )
911
- {
912
- close (fd_in );
913
- }
914
- #endif
915
-
916
- errout :
917
- return nsh_saveresult (vtbl , true);
918
713
}
919
714
920
715
/****************************************************************************
0 commit comments