diff --git a/C/c_interface.c b/C/c_interface.c index b1f37202f..e5580deaa 100644 --- a/C/c_interface.c +++ b/C/c_interface.c @@ -80,7 +80,6 @@ X_API Int STD_PROTO(YapFastInit,(char *)); X_API Int STD_PROTO(YapCallProlog,(Term)); X_API void *STD_PROTO(YapAllocSpaceFromYap,(unsigned int)); X_API void STD_PROTO(YapFreeSpaceFromYap,(void *)); -X_API void STD_PROTO(YapFreeSpaceFromYap,(void *)); X_API int STD_PROTO(YapStringToBuffer, (Term, char *, unsigned int)); X_API Term STD_PROTO(YapBufferToString, (char *)); X_API Term STD_PROTO(YapBufferToAtomList, (char *)); diff --git a/library/system.yap b/library/system.yap index b40ea7d71..d62a0163a 100644 --- a/library/system.yap +++ b/library/system.yap @@ -347,23 +347,15 @@ shell :- shell(Command) :- G = shell(Command), check_command(Command, G), - get_shell(Shell), - atom_codes(Command, SC0), - protect_command(SC0,SC), - append(Shell, [0'"|SC], ShellCommand), - atom_codes(FullCommand, ShellCommand), - do_system(FullCommand, _, Error), + get_shell(Shell,Opt), + do_shell(Shell, Opt, Command, _, Error), handle_system_error(Error, off, G). shell(Command, Status) :- G = shell(Command, Status), check_command(Command, G), - get_shell(Shell), - atom_codes(Command, SC0), - protect_command(SC0,SC), - append(Shell, [0'"|SC], ShellCommand), - atom_codes(FullCommand, ShellCommand), - do_system(FullCommand, Status, Error), + get_shell(Shell,Opt), + do_shell(Shell, Opt, Command, Status, Error), handle_system_error(Error, off, G). protect_command([], [0'"]). @@ -377,16 +369,12 @@ get_shell0(Shell) :- getenv('COMSPEC', Shell). get_shell0('/bin/sh'). -get_shell(Shell) :- - getenv('SHELL', Shell0), !, - atom_codes(Shell0, Codes), - append(Codes," -c ", Shell). -get_shell(Shell) :- +get_shell(Shell, '-c') :- + getenv('SHELL', Shell), !. +get_shell(Shell, '/c') :- win, !, - getenv('COMSPEC', Shell0), - atom_codes(Shell0, Codes), - append(Codes," /c ", Shell). -get_shell("/bin/sh -c "). + getenv('COMSPEC', Shell). +get_shell('/bin/sh','-c'). system :- default_shell(Command), diff --git a/library/system/sys.c b/library/system/sys.c index a543e97ba..a474c203f 100644 --- a/library/system/sys.c +++ b/library/system/sys.c @@ -331,10 +331,10 @@ static int p_mktemp(void) { #if HAVE_MKTEMP - char *s, tmp[1024]; + char *s, tmp[BUF_SIZE]; s = AtomName(AtomOfTerm(ARG1)); #if HAVE_STRNCPY - strncpy(tmp, s, 1024); + strncpy(tmp, s, BUF_SIZE); #else strcpy(tmp, s); #endif @@ -585,12 +585,78 @@ static int do_system(void) { char *command = AtomName(AtomOfTerm(ARG1)); - int sys = system(command); #if HAVE_SYSTEM + int sys = system(command); if (sys < 0) { return(unify(ARG3,MkIntTerm(errno))); } return(unify(ARG2, MkIntTerm(sys))); +#else + YapError("system not available in this configuration"); + return(FALSE); +#endif +} + + + +/* execute a command as a detached process */ +static int +do_shell(void) +{ +#if defined(__MINGW32__) || _MSC_VER + char *buf = YapAllocSpaceFromYap(BUF_SIZE); + int sys; + + if (buf == NULL) { + YapError("No Temporary Space for Shell"); + return(FALSE); + } +#if HAVE_STRNCPY + strncpy(YapAtomName(AtomOfTerm(ARG1)), buf, BUF_SIZE); + strncpy(" ", buf, BUF_SIZE); + strncpy(YapAtomName(AtomOfTerm(ARG2)), buf, BUF_SIZE); + strncpy(" ", buf, BUF_SIZE); + strncpy(YapAtomName(AtomOfTerm(ARG3)), buf, BUF_SIZE); +#else + strcpy(YapAtomName(AtomOfTerm(ARG1)), buf); + strcpy(" ", buf); + strcpy(YapAtomName(AtomOfTerm(ARG2)), buf); + strcpy(" ", buf); + strcpy(YapAtomName(AtomOfTerm(ARG3)), buf); +#endif +#if HAVE_SYSTEM + sys = system(buf); + YapFreeSpaceFromYap(buf); + if (sys < 0) { + return(unify(ARG5,MkIntTerm(errno))); + } + return(unify(ARG4, MkIntTerm(sys))); +#else + YapError("system not available in this configuration"); + return(FALSE); +#endif +#else + char *cptr[4]; + int t; + int sys; + + cptr[0]= YapAtomName(AtomOfTerm(ARG1)); + cptr[1]= YapAtomName(AtomOfTerm(ARG2)); + cptr[2]= YapAtomName(AtomOfTerm(ARG3)); + cptr[3]= NULL; + t = fork(); + if (t < 0) { + return(unify(ARG5,MkIntTerm(errno))); + } else if (t == 0) { + t = execvp(YapAtomName(AtomOfTerm(ARG1)),cptr); + return(t); + } else { + t = wait(&sys); + if (t < 0) { + return(unify(ARG5,MkIntTerm(errno))); + } + } + return(unify(ARG4, MkIntTerm(sys))); #endif } @@ -802,6 +868,7 @@ init_sys(void) UserCPredicate("dir_separator", dir_separator, 1); UserCPredicate("p_environ", p_environ, 2); UserCPredicate("exec_command", execute_command, 6); + UserCPredicate("do_shell", do_shell, 5); UserCPredicate("do_system", do_system, 3); UserCPredicate("popen", p_popen, 4); UserCPredicate("wait", p_wait, 3);