3030#include <string.h>
3131#include <errno.h>
3232#include <debug.h>
33- #include <pthread.h>
3433#include <sched.h>
3534#include <unistd.h>
3635
126125 * Private Types
127126 ****************************************************************************/
128127
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-
142128/* This structure describes the allocation list */
143129
144130#ifdef HAVE_MEMLIST
@@ -174,13 +160,6 @@ static void nsh_alist_free(FAR struct nsh_vtbl_s *vtbl,
174160 FAR struct nsh_alist_s * alist );
175161#endif
176162
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-
184163static int nsh_saveresult (FAR struct nsh_vtbl_s * vtbl , bool result );
185164static int nsh_execute (FAR struct nsh_vtbl_s * vtbl ,
186165 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,
443422}
444423#endif
445424
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-
547425/****************************************************************************
548426 * Name: nsh_saveresult
549427 ****************************************************************************/
@@ -616,8 +494,6 @@ static int nsh_execute(FAR struct nsh_vtbl_s *vtbl,
616494 FAR const char * redirfile_in ,
617495 FAR const char * redirfile_out , int oflags )
618496{
619- int fd_in = STDIN_FILENO ;
620- int fd_out = STDOUT_FILENO ;
621497 int ret ;
622498
623499 /* DO NOT CHANGE THE ORDERING OF THE FOLLOWING STEPS
@@ -713,42 +589,6 @@ static int nsh_execute(FAR struct nsh_vtbl_s *vtbl,
713589
714590#endif
715591
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-
752592 /* Handle the case where the command is executed in background.
753593 * However is app is to be started as built-in new process will
754594 * be created anyway, so skip this step.
@@ -757,108 +597,79 @@ static int nsh_execute(FAR struct nsh_vtbl_s *vtbl,
757597#ifndef CONFIG_NSH_DISABLEBG
758598 if (vtbl -> np .np_bg )
759599 {
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 ;
770603
771- bkgvtbl = nsh_clone (vtbl );
772- if (!bkgvtbl )
773- {
774- goto errout_with_redirect ;
775- }
604+ DEBUGASSERT (strncmp (argv [0 ], sh_cmd , 3 ) != 0 );
776605
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 ++ )
781609 {
782- nsh_release (bkgvtbl );
783- goto errout_with_redirect ;
784- }
610+ FAR char * p_arg = argv [i ];
611+ size_t len = strlen (p_arg );
785612
786- /* Handle redirection of output via a file descriptor */
613+ /* Restore from split args to concat args. */
787614
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 ] = ' ' ;
791617 }
792618
793- /* Get the execution priority of this task */
619+ sh_argv [2 ] = argv [0 ];
620+ sh_argv [3 ] = NULL ;
794621
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+ */
800625
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 ];
802633
803- nsh_releaseargs (args );
804- goto errout ;
805- }
634+ int fd_in = STDIN_FILENO ;
635+ int fd_out = STDOUT_FILENO ;
806636
807- /* Determine the priority to execute the command */
637+ /* Redirected output? */
808638
809- if (vtbl -> np .np_nice != 0 )
639+ if (vtbl -> np .np_redir_out )
810640 {
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 )
821649 {
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);
827652 }
828-
829- param .sched_priority = priority ;
830653 }
831654
832- /* Set up the thread attributes */
655+ /* Redirected input? */
833656
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 )
844658 {
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+ */
849664
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+ }
852671 }
853672
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-
862673 /* Handle redirection of stdin/stdout file descriptor */
863674
864675 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,
890701
891702 if (ret < 0 )
892703 {
893- goto errout ;
704+ return nsh_saveresult ( vtbl , true) ;
894705 }
895706 }
896707
@@ -899,22 +710,6 @@ static int nsh_execute(FAR struct nsh_vtbl_s *vtbl,
899710 */
900711
901712 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);
918713}
919714
920715/****************************************************************************
0 commit comments