| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | /*  Part of SWI-Prolog
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Author:        Jan Wielemaker | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  |     E-mail:        J.Wielemaker@vu.nl | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |     WWW:           http://www.swi-prolog.org
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  |     Copyright (C): 1985-2013, University of Amsterdam | 
					
						
							|  |  |  | 			      VU University Amsterdam | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     This library is free software; you can redistribute it and/or | 
					
						
							|  |  |  |     modify it under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  |     License as published by the Free Software Foundation; either | 
					
						
							|  |  |  |     version 2.1 of the License, or (at your option) any later version. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     This library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |     but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |     Lesser General Public License for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     You should have received a copy of the GNU Lesser General Public | 
					
						
							|  |  |  |     License along with this library; if not, write to the Free Software | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  |     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*  Modified (M) 1993 Dave Sherratt  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*#define O_DEBUG 1*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if OS2 && EMX
 | 
					
						
							|  |  |  | #include <os2.h>                /* this has to appear before pl-incl.h */
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-04 23:58:23 +00:00
										 |  |  | //@{
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
					
						
							|  |  |  | Solaris has asctime_r() with 3 arguments. Using _POSIX_PTHREAD_SEMANTICS | 
					
						
							|  |  |  | is supposed to give the POSIX standard one. | 
					
						
							|  |  |  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(__sun__) || defined(__sun)
 | 
					
						
							|  |  |  | #define _POSIX_PTHREAD_SEMANTICS 1
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define __MINGW_USE_VC2005_COMPAT		/* Get Windows time_t as 64-bit */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #include "pl-incl.h"
 | 
					
						
							|  |  |  | #include "pl-ctype.h"
 | 
					
						
							|  |  |  | #include "pl-utf8.h"
 | 
					
						
							| 
									
										
										
										
											2014-11-28 02:34:26 +00:00
										 |  |  | #include <stdlib.h>
 | 
					
						
							| 
									
										
										
										
											2013-11-15 01:10:25 +00:00
										 |  |  | #include <math.h>
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #include <stdio.h>		/* rename() and remove() prototypes */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  | #if TIME_WITH_SYS_TIME
 | 
					
						
							|  |  |  | # include <sys/time.h>
 | 
					
						
							|  |  |  | # include <time.h>
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | # if HAVE_SYS_TIME_H
 | 
					
						
							|  |  |  | #  include <sys/time.h>
 | 
					
						
							|  |  |  | # else
 | 
					
						
							|  |  |  | #  include <time.h>
 | 
					
						
							|  |  |  | # endif
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #if HAVE_SYS_STAT_H
 | 
					
						
							|  |  |  | #include <sys/stat.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-11-28 02:34:26 +00:00
										 |  |  | #if HAVE_ALLOCA_H
 | 
					
						
							|  |  |  | #include <alloca.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  | #ifdef O_XOS
 | 
					
						
							|  |  |  | #define statstruct struct _stati64
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #define statstruct struct stat
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #define statfunc stat
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if HAVE_PWD_H
 | 
					
						
							|  |  |  | #include <pwd.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if HAVE_VFORK_H
 | 
					
						
							|  |  |  | #include <vfork.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef HAVE_UNISTD_H
 | 
					
						
							|  |  |  | #include <unistd.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef HAVE_SYS_FILE_H
 | 
					
						
							|  |  |  | #include <sys/file.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if defined(HAVE_SYS_RESOURCE_H)
 | 
					
						
							|  |  |  | #include <sys/resource.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef HAVE_FTIME
 | 
					
						
							|  |  |  | #include <sys/timeb.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #include <time.h>
 | 
					
						
							|  |  |  | #include <fcntl.h>
 | 
					
						
							|  |  |  | #ifndef __WATCOMC__			/* appears a conflict */
 | 
					
						
							|  |  |  | #include <errno.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(__WATCOMC__)
 | 
					
						
							|  |  |  | #include <io.h>
 | 
					
						
							|  |  |  | #include <dos.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if OS2 && EMX
 | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | static double initial_time; | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #endif /* OS2 */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define LOCK()   PL_LOCK(L_OS)
 | 
					
						
							|  |  |  | #define UNLOCK() PL_UNLOCK(L_OS)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void	initEnviron(void); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef DEFAULT_PATH
 | 
					
						
							|  |  |  | #define DEFAULT_PATH "/bin:/usr/bin"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  | /** shell(+Command:text, -Status:integer) is det.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Run an external command and wait for its completion. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static | 
					
						
							|  |  |  | PRED_IMPL("shell", 2, shell, 0) | 
					
						
							|  |  |  | { GET_LD | 
					
						
							|  |  |  |   char *cmd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( PL_get_chars(A1, &cmd, CVT_ALL|REP_FN|CVT_EXCEPTION) ) | 
					
						
							|  |  |  |   { int rval = System(cmd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return PL_unify_integer(A2, rval); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   fail; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 		/********************************
 | 
					
						
							|  |  |  | 		*         INITIALISATION        * | 
					
						
							|  |  |  | 		*********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
					
						
							|  |  |  |     bool initOs() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Initialise the OS dependant functions. | 
					
						
							|  |  |  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool | 
					
						
							|  |  |  | initOs(void) | 
					
						
							| 
									
										
										
										
											2010-02-22 09:35:47 +00:00
										 |  |  | { GET_LD | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-28 19:41:12 +00:00
										 |  |  |     GD->statistics.start_time = WallTime(); | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |   initEnviron(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef __WINDOWS__
 | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  |   setPrologFlagMask(PLFLAG_FILE_CASE_PRESERVING); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  |   setPrologFlagMask(PLFLAG_FILE_CASE); | 
					
						
							|  |  |  |   setPrologFlagMask(PLFLAG_FILE_CASE_PRESERVING); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   DEBUG(1, Sdprintf("OS:done\n")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   succeed; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | cleanupOs(void) | 
					
						
							| 
									
										
										
										
											2015-03-28 19:41:12 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/********************************
 | 
					
						
							|  |  |  | 		*            OS ERRORS          * | 
					
						
							|  |  |  | 		*********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
					
						
							|  |  |  |     char *OsError() | 
					
						
							|  |  |  | 	Return a char *, holding a description of the last OS call error. | 
					
						
							|  |  |  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char * | 
					
						
							|  |  |  | OsError(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef HAVE_STRERROR
 | 
					
						
							|  |  |  | #ifdef __WINDOWS__
 | 
					
						
							|  |  |  |   return strerror(_xos_errno()); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   return strerror(errno); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #else /*HAVE_STRERROR*/
 | 
					
						
							|  |  |  | static char errmsg[64]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-04 19:48:11 +02:00
										 |  |  | #ifdef __unix__
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |   extern int sys_nerr; | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | #if !EMX
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |   extern char *sys_errlist[]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   extern int errno; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( errno < sys_nerr ) | 
					
						
							|  |  |  |     return sys_errlist[errno]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Ssprintf(errmsg, "Unknown Error (%d)", errno); | 
					
						
							|  |  |  |   return errmsg; | 
					
						
							|  |  |  | #endif /*HAVE_STRERROR*/
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/********************************
 | 
					
						
							|  |  |  | 		*    PROCESS CHARACTERISTICS    * | 
					
						
							|  |  |  | 		*********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
					
						
							|  |  |  |     double CpuTime(cputime_kind) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Returns a floating point number, representing the amount  of  (user) | 
					
						
							|  |  |  |     CPU-seconds  used  by the process Prolog is in.  For systems that do | 
					
						
							|  |  |  |     not allow you to obtain this information  you  may  wish  to  return | 
					
						
							|  |  |  |     elapsed  time  since Prolog was started, as this function is used to | 
					
						
							|  |  |  |     by consult/1 and time/1 to determine the amount of CPU time used  to | 
					
						
							|  |  |  |     consult a file or to execute a query. | 
					
						
							|  |  |  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-15 18:25:33 +00:00
										 |  |  | #ifdef HAVE_CLOCK_GETTIME
 | 
					
						
							|  |  |  | #define timespec_to_double(ts) \
 | 
					
						
							|  |  |  | 	((double)(ts).tv_sec + (double)(ts).tv_nsec/(double)1000000000.0) | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #ifndef __WINDOWS__			/* defined in pl-nt.c */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_TIMES
 | 
					
						
							|  |  |  | #include <sys/times.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(_SC_CLK_TCK)
 | 
					
						
							|  |  |  | #define Hz ((int)sysconf(_SC_CLK_TCK))
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #ifdef HZ
 | 
					
						
							|  |  |  | #  define Hz HZ
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #  define Hz 60				/* if nothing better: guess */
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #endif /*_SC_CLK_TCK*/
 | 
					
						
							|  |  |  | #endif /*HAVE_TIMES*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-15 01:10:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | double | 
					
						
							|  |  |  | CpuTime(cputime_kind which) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID)
 | 
					
						
							|  |  |  | #define CPU_TIME_DONE
 | 
					
						
							|  |  |  |   struct timespec ts; | 
					
						
							|  |  |  |   (void)which; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) == 0 ) | 
					
						
							|  |  |  |     return timespec_to_double(ts); | 
					
						
							|  |  |  |   return 0.0; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined(CPU_TIME_DONE) && defined(HAVE_TIMES)
 | 
					
						
							|  |  |  | #define CPU_TIME_DONE
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |   struct tms t; | 
					
						
							|  |  |  |   double used; | 
					
						
							|  |  |  |   static int MTOK_got_hz = FALSE; | 
					
						
							|  |  |  |   static double MTOK_hz; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( !MTOK_got_hz ) | 
					
						
							|  |  |  |   { MTOK_hz = (double) Hz; | 
					
						
							|  |  |  |     MTOK_got_hz++; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   times(&t); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch( which ) | 
					
						
							|  |  |  |   { case CPU_USER: | 
					
						
							|  |  |  |       used = (double) t.tms_utime / MTOK_hz; | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2015-03-28 19:41:12 +00:00
										 |  |  |   case CPU_SYSTEM: | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |     default:				/* make compiler happy */ | 
					
						
							|  |  |  |       used = (double) t.tms_stime / MTOK_hz; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( isnan(used) )			/* very dubious, but this */ | 
					
						
							|  |  |  |     used = 0.0;				/* happens when running under GDB */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return used; | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | #if !defined(CPU_TIME_DONE)
 | 
					
						
							|  |  |  |   (void)which; | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return 0.0; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /*__WINDOWS__*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | double | 
					
						
							|  |  |  | WallTime(void) | 
					
						
							|  |  |  | { double stime; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if HAVE_CLOCK_GETTIME
 | 
					
						
							|  |  |  |   struct timespec tp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   clock_gettime(CLOCK_REALTIME, &tp); | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  |   stime = timespec_to_double(tp); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | #ifdef HAVE_GETTIMEOFDAY
 | 
					
						
							|  |  |  |   struct timeval tp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   gettimeofday(&tp, NULL); | 
					
						
							|  |  |  |   stime = (double)tp.tv_sec + (double)tp.tv_usec/1000000.0; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #ifdef HAVE_FTIME
 | 
					
						
							|  |  |  |   struct timeb tb; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ftime(&tb); | 
					
						
							|  |  |  |   stime = (double)tb.time + (double)tb.millitm/1000.0; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   stime = (double)time((time_t *)NULL); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return stime; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		 /*******************************
 | 
					
						
							|  |  |  | 		 *	      FEATURES		* | 
					
						
							|  |  |  | 		 *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef __WINDOWS__			/* Windows version in pl-nt.c */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_SC_NPROCESSORS_CONF
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | CpuCount() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return sysconf(_SC_NPROCESSORS_CONF); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef PROCFS_CPUINFO
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | CpuCount() | 
					
						
							|  |  |  | { FILE *fd = fopen("/proc/cpuinfo", "r"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( fd ) | 
					
						
							|  |  |  |   { char buf[256]; | 
					
						
							|  |  |  |     int count = 0; | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |     while(fgets(buf, sizeof(buf)-1, fd)) | 
					
						
							|  |  |  |     { char *vp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if ( (vp = strchr(buf, ':')) ) | 
					
						
							|  |  |  |       { char *en; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for(en=vp; en > buf && en[-1] <= ' '; en--) | 
					
						
							|  |  |  | 	  ; | 
					
						
							|  |  |  | 	*en = EOS; | 
					
						
							|  |  |  | 	DEBUG(2, Sdprintf("Got %s = %s\n", buf, vp+2)); | 
					
						
							|  |  |  | 	if ( streq("processor", buf) && isDigit(vp[2]) ) | 
					
						
							|  |  |  | 	{ int cpu = atoi(vp+2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	  if ( cpu+1 > count ) | 
					
						
							|  |  |  | 	    count = cpu+1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fclose(fd); | 
					
						
							|  |  |  |     return count; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else /*PROCFS_CPUINFO*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_SYSCTLBYNAME	/* MacOS X */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <sys/param.h>
 | 
					
						
							|  |  |  | #include <sys/sysctl.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | CpuCount(void) | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | { int     count ; | 
					
						
							|  |  |  |   size_t  size=sizeof(count) ; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( sysctlbyname("hw.ncpu", &count, &size, NULL, 0) ) | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return count; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define CpuCount() 0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /*sysctlbyname*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /*PROCFS_CPUINFO*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /*HAVE_SC_NPROCESSORS_CONF*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | setOSPrologFlags(void) | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | { int cpu_count = CpuCount(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( cpu_count > 0 ) | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  |     PL_set_prolog_flag("cpu_count", PL_INTEGER, cpu_count); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		 /*******************************
 | 
					
						
							|  |  |  | 		 *	       MEMORY		* | 
					
						
							|  |  |  | 		 *******************************/ | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | uintptr_t | 
					
						
							|  |  |  | UsedMemory(void) | 
					
						
							| 
									
										
										
										
											2013-11-15 01:10:25 +00:00
										 |  |  | { //GET_LD
 | 
					
						
							| 
									
										
										
										
											2010-02-22 09:35:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #if defined(HAVE_GETRUSAGE) && defined(HAVE_RU_IDRSS)
 | 
					
						
							|  |  |  |   struct rusage usage; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( getrusage(RUSAGE_SELF, &usage) == 0 && | 
					
						
							|  |  |  |        usage.ru_idrss ) | 
					
						
							|  |  |  |   { return usage.ru_idrss;		/* total unshared data */ | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  |   return (usedStack(global) + | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 	  usedStack(local) + | 
					
						
							|  |  |  | 	  usedStack(trail)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | uintptr_t | 
					
						
							|  |  |  | FreeMemory(void) | 
					
						
							| 
									
										
										
										
											2011-03-02 23:19:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  | #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_DATA)
 | 
					
						
							| 
									
										
										
										
											2011-03-02 23:19:39 +00:00
										 |  |  |   uintptr_t used = UsedMemory(); | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  |   struct rlimit limit; | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if ( getrlimit(RLIMIT_DATA, &limit) == 0 ) | 
					
						
							|  |  |  |     return limit.rlim_cur - used; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return 0L; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/********************************
 | 
					
						
							|  |  |  | 		*           ARITHMETIC          * | 
					
						
							|  |  |  | 		*********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
					
						
							|  |  |  |     uint64_t _PL_Random() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Return a random number. Used for arithmetic only. More trouble. On | 
					
						
							|  |  |  |     some systems (__WINDOWS__) the seed of rand() is thread-local, while on | 
					
						
							|  |  |  |     others it is global.  We appear to have the choice between | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | 	# srand()/rand()
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 	Differ in MT handling, often bad distribution | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# srandom()/random()
 | 
					
						
							|  |  |  | 	Not portable, not MT-Safe but much better distribution | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 	# drand48() and friends
 | 
					
						
							|  |  |  | 	Depreciated according to Linux manpage, suggested by Solaris | 
					
						
							|  |  |  | 	manpage. | 
					
						
							|  |  |  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 
					
						
							| 
									
										
										
										
											2009-07-20 20:56:16 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | void | 
					
						
							|  |  |  | setRandom(unsigned int *seedp) | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | { unsigned int seed; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  |   if ( seedp ) | 
					
						
							|  |  |  |   { seed = *seedp; | 
					
						
							|  |  |  |   } else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  | #ifdef __WINDOWS__
 | 
					
						
							| 
									
										
										
										
											2015-03-28 19:41:12 +00:00
										 |  |  |     seed = (unsigned int)GetTickCount(); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | #ifdef HAVE_GETTIMEOFDAY
 | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  |      struct timeval tp; | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  |      gettimeofday(&tp, NULL); | 
					
						
							|  |  |  |      seed = (unsigned int)(tp.tv_sec + tp.tv_usec); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  |      seed = (unsigned int)time((time_t *) NULL); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-06-19 15:09:44 +01:00
										 |  |  | #if HAVE_SRANDOM
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |   srandom(seed); | 
					
						
							| 
									
										
										
										
											2014-06-19 15:09:44 +01:00
										 |  |  | #elif HAVE_SRAND
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |   srand(seed); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | uint64_t | 
					
						
							|  |  |  | _PL_Random(void) | 
					
						
							| 
									
										
										
										
											2010-02-22 09:35:47 +00:00
										 |  |  | { GET_LD | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( !LD->os.rand_initialised ) | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  |   { setRandom(NULL); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |     LD->os.rand_initialised = TRUE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_RANDOM
 | 
					
						
							|  |  |  |   { uint64_t l = random(); | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  |     l ^= (uint64_t)random()<<15; | 
					
						
							|  |  |  |     l ^= (uint64_t)random()<<30; | 
					
						
							|  |  |  |     l ^= (uint64_t)random()<<45; | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return l; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   { uint64_t l = rand();			/* 0<n<2^15-1 */ | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-22 09:35:47 +00:00
										 |  |  |     l ^= (uint64_t)rand()<<15; | 
					
						
							|  |  |  |     l ^= (uint64_t)rand()<<30; | 
					
						
							|  |  |  |     l ^= (uint64_t)rand()<<45; | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return l; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-28 19:41:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/********************************
 | 
					
						
							|  |  |  | 		*        TIME CONVERSION        * | 
					
						
							|  |  |  | 		*********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  |     struct tm *PL_localtime_r(time_t time, struct tm *r) | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-12 01:49:03 +01:00
										 |  |  |     Convert tunlime in Unix internal form (seconds since Jan 1 1970) into a | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |     structure providing easier access to the time. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     For non-Unix systems: struct time is supposed  to  look  like  this. | 
					
						
							|  |  |  |     Move  This  definition to pl-os.h and write the conversion functions | 
					
						
							|  |  |  |     here. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct tm { | 
					
						
							|  |  |  | 	int	tm_sec;		/ * second in the minute (0-59)* / | 
					
						
							|  |  |  | 	int	tm_min;		/ * minute in the hour (0-59) * / | 
					
						
							|  |  |  | 	int	tm_hour;	/ * hour of the day (0-23) * / | 
					
						
							|  |  |  | 	int	tm_mday;	/ * day of the month (1-31) * / | 
					
						
							|  |  |  | 	int	tm_mon;		/ * month of the year (1-12) * / | 
					
						
							|  |  |  | 	int	tm_year;	/ * year (0 = 1900) * / | 
					
						
							|  |  |  | 	int	tm_wday;	/ * day in the week (1-7, 1 = sunday) * / | 
					
						
							|  |  |  | 	int	tm_yday;	/ * day in the year (0-365) * / | 
					
						
							|  |  |  | 	int	tm_isdst;	/ * daylight saving time info * / | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  |     time_t Time() | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Return time in seconds after Jan 1 1970 (Unix' time notion). | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Note: MinGW has localtime_r(),  but  it  is   not  locked  and  thus not | 
					
						
							|  |  |  | thread-safe. MinGW does not have localtime_s(), but   we  test for it in | 
					
						
							|  |  |  | configure. | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct tm * | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | PL_localtime_r(const time_t *t, struct tm *r) | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | #ifdef HAVE_LOCALTIME_R
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |   return localtime_r(t, r); | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | #ifdef HAVE_LOCALTIME_S
 | 
					
						
							|  |  |  |   return localtime_s(r, t) == EINVAL ? NULL : t; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   struct tm *rc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   LOCK(); | 
					
						
							|  |  |  |   if ( (rc = localtime(t)) ) | 
					
						
							|  |  |  |     *r = *rc; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     r = NULL; | 
					
						
							|  |  |  |   UNLOCK(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |   return r; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char * | 
					
						
							|  |  |  | PL_asctime_r(const struct tm *tm, char *buf) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef HAVE_ASCTIME_R
 | 
					
						
							|  |  |  |   return asctime_r(tm, buf); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   char *rc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   LOCK(); | 
					
						
							|  |  |  |   if ( (rc = asctime(tm)) ) | 
					
						
							|  |  |  |     strcpy(buf, rc); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     buf = NULL; | 
					
						
							|  |  |  |   UNLOCK(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return buf; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  | 		 /*******************************
 | 
					
						
							|  |  |  | 		 *	      TERMINAL		* | 
					
						
							|  |  |  | 		 *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_TCSETATTR
 | 
					
						
							|  |  |  | #include <termios.h>
 | 
					
						
							|  |  |  | #include <unistd.h>
 | 
					
						
							|  |  |  | #define O_HAVE_TERMIO 1
 | 
					
						
							|  |  |  | #else /*HAVE_TCSETATTR*/
 | 
					
						
							|  |  |  | #ifdef HAVE_SYS_TERMIO_H
 | 
					
						
							|  |  |  | #include <sys/termio.h>
 | 
					
						
							|  |  |  | #define termios termio
 | 
					
						
							|  |  |  | #define O_HAVE_TERMIO 1
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #ifdef HAVE_SYS_TERMIOS_H
 | 
					
						
							|  |  |  | #include <sys/termios.h>
 | 
					
						
							|  |  |  | #define O_HAVE_TERMIO 1
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #endif /*HAVE_TCSETATTR*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct tty_state | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if defined(O_HAVE_TERMIO)
 | 
					
						
							|  |  |  |   struct termios tab; | 
					
						
							|  |  |  | #elif defined(HAVE_SGTTYB)
 | 
					
						
							|  |  |  |   struct sgttyb tab; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   int tab;				/* empty is not allowed */ | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } tty_state; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define TTY_STATE(buf) (((tty_state*)(buf->state))->tab)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
					
						
							|  |  |  | 			TERMINAL IO MANIPULATION | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ResetStdin() | 
					
						
							|  |  |  |     Clear the Sinput buffer after a saved state.  Only necessary | 
					
						
							|  |  |  |     if O_SAVE is defined. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PushTty(IOSTREAM *s, ttybuf *buf, int state) | 
					
						
							|  |  |  |     Push the tty to the specified state and save the old state in | 
					
						
							|  |  |  |     buf. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PopTty(IOSTREAM *s, ttybuf *buf) | 
					
						
							|  |  |  |     Restore the tty state. | 
					
						
							|  |  |  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2011-02-10 00:02:05 +00:00
										 |  |  | ResetStdin(void) | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | { Sinput->limitp = Sinput->bufp = Sinput->buffer; | 
					
						
							|  |  |  |   if ( !GD->os.org_terminal.read ) | 
					
						
							|  |  |  |     GD->os.org_terminal = *Sinput->functions; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static ssize_t | 
					
						
							|  |  |  | Sread_terminal(void *handle, char *buf, size_t size) | 
					
						
							| 
									
										
										
										
											2010-02-22 09:35:47 +00:00
										 |  |  | { GET_LD | 
					
						
							|  |  |  |   intptr_t h = (intptr_t)handle; | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |   int fd = (int)h; | 
					
						
							|  |  |  |   source_location oldsrc = LD->read_source; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-09 23:53:10 -05:00
										 |  |  |   if ( Soutput && True(Soutput, SIO_ISATTY) ) | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  |   { if ( LD->prompt.next && ttymode != TTY_RAW ) | 
					
						
							|  |  |  |       PL_write_prompt(TRUE); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       Sflush(Suser_output); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   PL_dispatch(fd, PL_DISPATCH_WAIT); | 
					
						
							|  |  |  |   size = (*GD->os.org_terminal.read)(handle, buf, size); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( size == 0 )			/* end-of-file */ | 
					
						
							|  |  |  |   { if ( fd == 0 ) | 
					
						
							|  |  |  |     { Sclearerr(Suser_input); | 
					
						
							|  |  |  |       LD->prompt.next = TRUE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else if ( size > 0 && buf[size-1] == '\n' ) | 
					
						
							|  |  |  |     LD->prompt.next = TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   LD->read_source = oldsrc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return size; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  | ResetTty(void) | 
					
						
							| 
									
										
										
										
											2010-02-22 09:35:47 +00:00
										 |  |  | { GET_LD | 
					
						
							|  |  |  |   startCritical; | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |   ResetStdin(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( !GD->os.iofunctions.read ) | 
					
						
							|  |  |  |   { GD->os.iofunctions       = *Sinput->functions; | 
					
						
							|  |  |  |     GD->os.iofunctions.read  = Sread_terminal; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  |     Sinput->functions  = | 
					
						
							|  |  |  |     Soutput->functions = | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |     Serror->functions  = &GD->os.iofunctions; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   LD->prompt.next = TRUE; | 
					
						
							|  |  |  |   endCritical; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef O_HAVE_TERMIO			/* sys/termios.h or sys/termio.h */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef HAVE_TCSETATTR
 | 
					
						
							|  |  |  | #ifndef NO_SYS_IOCTL_H_WITH_SYS_TERMIOS_H
 | 
					
						
							|  |  |  | #include <sys/ioctl.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifndef TIOCGETA
 | 
					
						
							|  |  |  | #define TIOCGETA TCGETA
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool | 
					
						
							|  |  |  | PushTty(IOSTREAM *s, ttybuf *buf, int mode) | 
					
						
							| 
									
										
										
										
											2010-02-22 09:35:47 +00:00
										 |  |  | { GET_LD | 
					
						
							|  |  |  |   struct termios tio; | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |   int fd; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  |   buf->mode  = ttymode; | 
					
						
							|  |  |  |   buf->state = NULL; | 
					
						
							|  |  |  |   ttymode    = mode; | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if ( (fd = Sfileno(s)) < 0 || !isatty(fd) ) | 
					
						
							|  |  |  |     succeed;				/* not a terminal */ | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  |   if ( !truePrologFlag(PLFLAG_TTY_CONTROL) ) | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |     succeed; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  |   buf->state = allocHeapOrHalt(sizeof(tty_state)); | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | #ifdef HAVE_TCSETATTR
 | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  |   if ( tcgetattr(fd, &TTY_STATE(buf)) )	/* save the old one */ | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |     fail; | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  |   if ( ioctl(fd, TIOCGETA, &TTY_STATE(buf)) )	/* save the old one */ | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |     fail; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  |   tio = TTY_STATE(buf); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   switch( mode ) | 
					
						
							|  |  |  |   { case TTY_RAW: | 
					
						
							|  |  |  | #if defined(HAVE_TCSETATTR) && defined(HAVE_CFMAKERAW)
 | 
					
						
							|  |  |  | 	cfmakeraw(&tio); | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  | 	tio.c_oflag = TTY_STATE(buf).c_oflag;	/* donot change output modes */ | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 	tio.c_lflag |= ISIG; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	tio.c_lflag &= ~(ECHO|ICANON); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 					/* OpenBSD requires this anyhow!? */ | 
					
						
							|  |  |  | 					/* Bug in OpenBSD or must we? */ | 
					
						
							|  |  |  | 					/* Could this do any harm? */ | 
					
						
							|  |  |  | 	tio.c_cc[VTIME] = 0, tio.c_cc[VMIN] = 1; | 
					
						
							|  |  |  | 	break; | 
					
						
							|  |  |  |     case TTY_OUTPUT: | 
					
						
							|  |  |  | 	tio.c_oflag |= (OPOST|ONLCR); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case TTY_SAVE: | 
					
						
							|  |  |  |         succeed; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  | 	sysError("Unknown PushTty() mode: %d", mode); | 
					
						
							|  |  |  | 	/*NOTREACHED*/ | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_TCSETATTR
 | 
					
						
							|  |  |  |   if ( tcsetattr(fd, TCSANOW, &tio) != 0 ) | 
					
						
							|  |  |  |   { static int MTOK_warned;			/* MT-OK */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ( !MTOK_warned++ ) | 
					
						
							|  |  |  |       warning("Failed to set terminal: %s", OsError()); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #ifdef TIOCSETAW
 | 
					
						
							|  |  |  |   ioctl(fd, TIOCSETAW, &tio); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   ioctl(fd, TCSETAW, &tio); | 
					
						
							|  |  |  |   ioctl(fd, TCXONC, (void *)1); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   succeed; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  | PopTty(IOSTREAM *s, ttybuf *buf, int do_free) | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | { ttymode = buf->mode; | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  |   if ( buf->state ) | 
					
						
							|  |  |  |   { int fd = Sfileno(s); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  |     if ( fd >= 0 ) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #ifdef HAVE_TCSETATTR
 | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  |       tcsetattr(fd, TCSANOW, &TTY_STATE(buf)); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | #ifdef TIOCSETA
 | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  |       ioctl(fd, TIOCSETA, &TTY_STATE(buf)); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  |       ioctl(fd, TCSETA, &TTY_STATE(buf)); | 
					
						
							|  |  |  |       ioctl(fd, TCXONC, (void *)1); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ( do_free ) | 
					
						
							|  |  |  |     { freeHeap(buf->state, sizeof(tty_state)); | 
					
						
							|  |  |  |       buf->state = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   succeed; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else /* O_HAVE_TERMIO */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_SGTTYB
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool | 
					
						
							|  |  |  | PushTty(IOSTREAM *s, ttybuf *buf, int mode) | 
					
						
							|  |  |  | { struct sgttyb tio; | 
					
						
							|  |  |  |   int fd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   buf->mode = ttymode; | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  |   buf->state = NULL; | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |   ttymode = mode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( (fd = Sfileno(s)) < 0 || !isatty(fd) ) | 
					
						
							|  |  |  |     succeed;				/* not a terminal */ | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  |   if ( !truePrologFlag(PLFLAG_TTY_CONTROL) ) | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |     succeed; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  |   buf->state = allocHeapOrHalt(sizeof(tty_state)); | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if ( ioctl(fd, TIOCGETP, &TTY_STATE(buf)) )  /* save the old one */ | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |     fail; | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  |   tio = TTY_STATE(buf); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   switch( mode ) | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  |   { case TTY_RAW: | 
					
						
							|  |  |  |       tio.sg_flags |= CBREAK; | 
					
						
							|  |  |  |       tio.sg_flags &= ~ECHO; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case TTY_OUTPUT: | 
					
						
							|  |  |  |       tio.sg_flags |= (CRMOD); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case TTY_SAVE: | 
					
						
							|  |  |  |       succeed; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       sysError("Unknown PushTty() mode: %d", mode); | 
					
						
							|  |  |  |       /*NOTREACHED*/ | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |   ioctl(fd, TIOCSETP,  &tio); | 
					
						
							|  |  |  |   ioctl(fd, TIOCSTART, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   succeed; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  | PopTty(IOSTREAM *s, ttybuf *buf, int do_free) | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | { ttymode = buf->mode; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  |   if ( buf->state ) | 
					
						
							|  |  |  |   { int fd = Sfileno(s); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  |     if ( fd >= 0 ) | 
					
						
							|  |  |  |     { ioctl(fd, TIOCSETP,  &buf->tab); | 
					
						
							|  |  |  |       ioctl(fd, TIOCSTART, NULL); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ( do_free ) | 
					
						
							|  |  |  |     { freeHeap(buf->state, sizeof(tty_state)); | 
					
						
							|  |  |  |       buf->state = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   succeed; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else /*HAVE_SGTTYB*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool | 
					
						
							|  |  |  | PushTty(IOSTREAM *s, ttybuf *buf, int mode) | 
					
						
							|  |  |  | { buf->mode = ttymode; | 
					
						
							|  |  |  |   ttymode = mode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   succeed; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  | PopTty(IOSTREAM *s, ttybuf *buf, int do_free) | 
					
						
							| 
									
										
										
										
											2010-02-22 09:35:47 +00:00
										 |  |  | { GET_LD | 
					
						
							|  |  |  |   ttymode = buf->mode; | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |   if ( ttymode != TTY_RAW ) | 
					
						
							|  |  |  |     LD->prompt.next = TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   succeed; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /*HAVE_SGTTYB*/
 | 
					
						
							|  |  |  | #endif /*O_HAVE_TERMIO*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/********************************
 | 
					
						
							|  |  |  | 		*      ENVIRONMENT CONTROL      * | 
					
						
							|  |  |  | 		*********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
					
						
							|  |  |  | Simple  library  to  manipulate  the    OS   environment.  The  modified | 
					
						
							|  |  |  | environment will be passed to  child  processes   and  the  can  also be | 
					
						
							|  |  |  | requested via getenv/2 from Prolog. Functions | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int Setenv(name, value) | 
					
						
							|  |  |  |          char *name, *value; | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |     Set the OS environment variable with name `name'.   If  it  exists | 
					
						
							|  |  |  |     its  value  is  changed, otherwise a new entry in the environment is | 
					
						
							|  |  |  |     created.  The return value is a pointer to the old value, or NULL if | 
					
						
							|  |  |  |     the variable is new. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int Unsetenv(name) | 
					
						
							|  |  |  |          char *name; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Delete a variable from the environment.  Return  value  is  the  old | 
					
						
							|  |  |  |     value, or NULL if the variable did not exist. | 
					
						
							|  |  |  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | size_t | 
					
						
							|  |  |  | getenv3(const char *name, char *buf, size_t len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if O_XOS
 | 
					
						
							|  |  |  |   return _xos_getenv(name, buf, len); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   char *s = getenv(name); | 
					
						
							|  |  |  |   size_t l; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( s ) | 
					
						
							|  |  |  |   { if ( (l=strlen(s)) < len ) | 
					
						
							|  |  |  |       memcpy(buf, s, l+1); | 
					
						
							|  |  |  |     else if ( len > 0 ) | 
					
						
							|  |  |  |       buf[0] = EOS;                     /* empty string if not fit */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return l; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (size_t)-1; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char * | 
					
						
							|  |  |  | Getenv(const char *name, char *buf, size_t len) | 
					
						
							|  |  |  | { size_t l = getenv3(name, buf, len); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( l != (size_t)-1 && l < len ) | 
					
						
							|  |  |  |     return buf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(HAVE_PUTENV) || defined(HAVE_SETENV)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | Setenv(char *name, char *value) | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #ifdef HAVE_SETENV
 | 
					
						
							|  |  |  |   if ( setenv(name, value, TRUE) != 0 ) | 
					
						
							|  |  |  |     return PL_error(NULL, 0, MSG_ERRNO, ERR_SYSCALL, "setenv"); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   char *buf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( *name == '\0' || strchr(name, '=') != NULL ) | 
					
						
							|  |  |  |   { errno = EINVAL; | 
					
						
							|  |  |  |     return PL_error(NULL, 0, MSG_ERRNO, ERR_SYSCALL, "setenv"); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   buf = alloca(strlen(name) + strlen(value) + 2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( buf ) | 
					
						
							|  |  |  |   { Ssprintf(buf, "%s=%s", name, value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ( putenv(store_string(buf)) < 0 ) | 
					
						
							|  |  |  |       return PL_error(NULL, 0, MSG_ERRNO, ERR_SYSCALL, "setenv"); | 
					
						
							|  |  |  |   } else | 
					
						
							|  |  |  |     return PL_error(NULL, 0, NULL, ERR_NOMEM); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   succeed; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | Unsetenv(char *name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef HAVE_UNSETENV
 | 
					
						
							|  |  |  | #ifdef VOID_UNSETENV
 | 
					
						
							|  |  |  |   unsetenv(name); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   if ( unsetenv(name) < 0 ) | 
					
						
							|  |  |  |     return PL_error(NULL, 0, MSG_ERRNO, ERR_SYSCALL, "unsetenv"); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   succeed; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   if ( !getenv(name) ) | 
					
						
							|  |  |  |     succeed; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return Setenv(name, ""); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | initEnviron() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else /*HAVE_PUTENV*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern char **environ;		/* Unix predefined environment */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
					
						
							|  |  |  | Grow the environment array by one and return the (possibly  moved)  base | 
					
						
							|  |  |  | pointer to the new environment. | 
					
						
							|  |  |  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | forwards char	**growEnviron(char**, int); | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | forwards char	*matchName(char *, char *); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | forwards void	setEntry(char **, char *, char *); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char ** | 
					
						
							|  |  |  | growEnviron(char **e, int amount) | 
					
						
							|  |  |  | { static int filled; | 
					
						
							|  |  |  |   static int size = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( amount == 0 )			/* reset after a dump */ | 
					
						
							|  |  |  |   { size = -1; | 
					
						
							|  |  |  |     return e; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( size < 0 ) | 
					
						
							|  |  |  |   { char **env, **e1, **e2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for(e1=e, filled=0; *e1; e1++, filled++) | 
					
						
							|  |  |  |       ; | 
					
						
							|  |  |  |     size = ROUND(filled+10+amount, 32); | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  |     env = (char **)PL_malloc(size * sizeof(char *)); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |     for ( e1=e, e2=env; *e1; *e2++ = *e1++ ) | 
					
						
							|  |  |  |       ; | 
					
						
							|  |  |  |     *e2 = (char *) NULL; | 
					
						
							|  |  |  |     filled += amount; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return env; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   filled += amount; | 
					
						
							|  |  |  |   if ( filled + 1 > size ) | 
					
						
							|  |  |  |   { char **env, **e1, **e2; | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |     size += 32; | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  |     env = (char **)PL_realloc(e, size * sizeof(char *)); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |     for ( e1=e, e2=env; *e1; *e2++ = *e1++ ) | 
					
						
							|  |  |  |       ; | 
					
						
							|  |  |  |     *e2 = (char *) NULL; | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |     return env; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return e; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | initEnviron(void) | 
					
						
							|  |  |  | { growEnviron(environ, 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char * | 
					
						
							|  |  |  | matchName(const char *e, const char *name) | 
					
						
							|  |  |  | { while( *name && *e == *name ) | 
					
						
							|  |  |  |     e++, name++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( (*e == '=' || *e == EOS) && *name == EOS ) | 
					
						
							|  |  |  |     return (*e == '=' ? e+1 : e); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (char *) NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | setEntry(char **e, char *name, char *value) | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | { size_t l = strlen(name); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  |   *e = PL_malloc_atomic(l + strlen(value) + 2); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |   strcpy(*e, name); | 
					
						
							|  |  |  |   e[0][l++] = '='; | 
					
						
							|  |  |  |   strcpy(&e[0][l], value); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | char * | 
					
						
							|  |  |  | Setenv(char *name, char *value) | 
					
						
							|  |  |  | { char **e; | 
					
						
							|  |  |  |   char *v; | 
					
						
							|  |  |  |   int n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for(n=0, e=environ; *e; e++, n++) | 
					
						
							|  |  |  |   { if ( (v=matchName(*e, name)) != NULL ) | 
					
						
							|  |  |  |     { if ( !streq(v, value) ) | 
					
						
							|  |  |  |         setEntry(e, name, value); | 
					
						
							|  |  |  |       return v; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   environ = growEnviron(environ, 1); | 
					
						
							|  |  |  |   setEntry(&environ[n], name, value); | 
					
						
							|  |  |  |   environ[n+1] = (char *) NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (char *) NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char * | 
					
						
							|  |  |  | Unsetenv(char *name) | 
					
						
							|  |  |  | { char **e; | 
					
						
							|  |  |  |   char *v; | 
					
						
							|  |  |  |   int n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for(n=0, e=environ; *e; e++, n++) | 
					
						
							|  |  |  |   { if ( (v=matchName(*e, name)) != NULL ) | 
					
						
							|  |  |  |     { environ = growEnviron(environ, -1); | 
					
						
							|  |  |  |       e = &environ[n]; | 
					
						
							|  |  |  |       do | 
					
						
							|  |  |  |       { e[0] = e[1]; | 
					
						
							|  |  |  |         e++; | 
					
						
							|  |  |  |       } while(*e); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return v; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (char *) NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /*HAVE_PUTENV*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/********************************
 | 
					
						
							|  |  |  | 		*       SYSTEM PROCESSES        * | 
					
						
							|  |  |  | 		*********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
					
						
							|  |  |  |     int System(command) | 
					
						
							|  |  |  | 	char *command; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Invoke a command on the operating system.  The return value  is  the | 
					
						
							|  |  |  |     exit  status  of  the  command.   Return  value  0 implies succesful | 
					
						
							|  |  |  |     completion. If you are not running Unix your C-library might provide | 
					
						
							|  |  |  |     an alternative. | 
					
						
							|  |  |  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | #ifdef __unix__
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #define SPECIFIC_SYSTEM 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
					
						
							|  |  |  | According to the autoconf docs HAVE_SYS_WAIT_H   is set if sys/wait.h is | 
					
						
							|  |  |  | defined *and* is POSIX.1 compliant,  which   implies  it uses int status | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | argument to wait() | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_SYS_WAIT_H
 | 
					
						
							|  |  |  | #undef UNION_WAIT
 | 
					
						
							|  |  |  | #include <sys/wait.h>
 | 
					
						
							|  |  |  | #define wait_t int
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef WEXITSTATUS
 | 
					
						
							|  |  |  | # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifndef WIFEXITED
 | 
					
						
							|  |  |  | # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else /*HAVE_SYS_WAIT_H*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef UNION_WAIT			/* Old BSD style wait */
 | 
					
						
							|  |  |  | #include <sys/wait.h>
 | 
					
						
							|  |  |  | #define wait_t union wait
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef WEXITSTATUS
 | 
					
						
							|  |  |  | #define WEXITSTATUS(s) ((s).w_status)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifndef WTERMSIG
 | 
					
						
							|  |  |  | #define WTERMSIG(s) ((s).w_status)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #endif /*UNION_WAIT*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /*HAVE_SYS_WAIT_H*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-26 09:47:05 +00:00
										 |  |  | typedef void (*sigf_t)(int sig); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | System(char *cmd) | 
					
						
							| 
									
										
										
										
											2010-02-22 09:35:47 +00:00
										 |  |  | { GET_LD | 
					
						
							|  |  |  |   int pid; | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |   char *shell = "/bin/sh"; | 
					
						
							|  |  |  |   int rval; | 
					
						
							| 
									
										
										
										
											2014-11-25 19:52:51 +00:00
										 |  |  |   sigf_t old_int, old_stop; | 
					
						
							| 
									
										
										
										
											2015-04-13 13:28:17 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |   if ( (pid = fork()) == -1 ) | 
					
						
							|  |  |  |   { return PL_error("shell", 2, OsError(), ERR_SYSCALL, "fork"); | 
					
						
							|  |  |  |   } else if ( pid == 0 )		/* The child */ | 
					
						
							|  |  |  |   { Setenv("PROLOGCHILD", "yes"); | 
					
						
							|  |  |  |     PL_cleanup_fork(); | 
					
						
							|  |  |  |     execl(shell, BaseName(shell), "-c", cmd, (char *)0); | 
					
						
							|  |  |  |     fatalError("Failed to execute %s: %s", shell, OsError()); | 
					
						
							|  |  |  |     fail; | 
					
						
							|  |  |  |     /*NOTREACHED*/ | 
					
						
							|  |  |  |   } else | 
					
						
							|  |  |  |   { wait_t status;			/* the parent */ | 
					
						
							|  |  |  |     int n; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-25 19:52:51 +00:00
										 |  |  |     old_int  = (sigf_t)signal(SIGINT,  SIG_IGN); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #ifdef SIGTSTP
 | 
					
						
							| 
									
										
										
										
											2014-11-25 19:52:51 +00:00
										 |  |  |     old_stop = (sigf_t)signal(SIGTSTP, SIG_DFL); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #endif /* SIGTSTP */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for(;;) | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #ifdef HAVE_WAITPID
 | 
					
						
							|  |  |  |       n = waitpid(pid, &status, 0); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |       n = wait(&status); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |       if ( n == -1 && errno == EINTR ) | 
					
						
							|  |  |  | 	continue; | 
					
						
							|  |  |  |       if ( n != pid ) | 
					
						
							|  |  |  | 	continue; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ( n == -1 ) | 
					
						
							|  |  |  |     { term_t tmp = PL_new_term_ref(); | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |       PL_put_atom_chars(tmp, cmd); | 
					
						
							|  |  |  |       PL_error("shell", 2, MSG_ERRNO, ERR_SHELL_FAILED, tmp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       rval = 1; | 
					
						
							|  |  |  |     } else if (WIFEXITED(status)) | 
					
						
							|  |  |  |     { rval = WEXITSTATUS(status); | 
					
						
							|  |  |  | #ifdef WIFSIGNALED
 | 
					
						
							|  |  |  |     } else if (WIFSIGNALED(status)) | 
					
						
							|  |  |  |     { term_t tmp = PL_new_term_ref(); | 
					
						
							|  |  |  |       int sig = WTERMSIG(status); | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |       PL_put_atom_chars(tmp, cmd); | 
					
						
							|  |  |  |       PL_error("shell", 2, NULL, ERR_SHELL_SIGNALLED, tmp, sig); | 
					
						
							|  |  |  |       rval = 1; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     } else | 
					
						
							|  |  |  |     { rval = 1;				/* make gcc happy */ | 
					
						
							|  |  |  |       fatalError("Unknown return code from wait(3)"); | 
					
						
							|  |  |  |       /*NOTREACHED*/ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   signal(SIGINT,  old_int);		/* restore signal handlers */ | 
					
						
							|  |  |  | #ifdef SIGTSTP
 | 
					
						
							|  |  |  |   signal(SIGTSTP, old_stop); | 
					
						
							|  |  |  | #endif /* SIGTSTP */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return rval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif /* __unix__ */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_WINEXEC			/* Windows 3.1 */
 | 
					
						
							|  |  |  | #define SPECIFIC_SYSTEM 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | System(char *command) | 
					
						
							|  |  |  | { char *msg; | 
					
						
							|  |  |  |   int rval = WinExec(command, SW_SHOWNORMAL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( rval < 32 ) | 
					
						
							|  |  |  |   { switch( rval ) | 
					
						
							|  |  |  |     { case 0:	msg = "Not enough memory"; break; | 
					
						
							|  |  |  |       case 2:	msg = "File not found"; break; | 
					
						
							|  |  |  |       case 3:	msg = "No path"; break; | 
					
						
							|  |  |  |       case 5:	msg = "Unknown error"; break; | 
					
						
							|  |  |  |       case 6:	msg = "Lib requires separate data segment"; break; | 
					
						
							|  |  |  |       case 8:	msg = "Not enough memory"; break; | 
					
						
							|  |  |  |       case 10:	msg = "Incompatible Windows version"; break; | 
					
						
							|  |  |  |       case 11:	msg = "Bad executable file"; break; | 
					
						
							|  |  |  |       case 12:	msg = "Incompatible operating system"; break; | 
					
						
							|  |  |  |       case 13:	msg = "MS-DOS 4.0 executable"; break; | 
					
						
							|  |  |  |       case 14:	msg = "Unknown executable file type"; break; | 
					
						
							|  |  |  |       case 15:	msg = "Real-mode application"; break; | 
					
						
							|  |  |  |       case 16:	msg = "Cannot start multiple copies"; break; | 
					
						
							|  |  |  |       case 19:	msg = "Executable is compressed"; break; | 
					
						
							|  |  |  |       case 20:	msg = "Invalid DLL"; break; | 
					
						
							|  |  |  |       case 21:	msg = "Application is 32-bits"; break; | 
					
						
							|  |  |  |       default:	msg = "Unknown error"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     warning("Could not start %s: error %d (%s)", | 
					
						
							|  |  |  | 	    command, rval, msg); | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef __WINDOWS__
 | 
					
						
							|  |  |  | #define SPECIFIC_SYSTEM 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					/* definition in pl-nt.c */ | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
					
						
							|  |  |  | Nothing special is needed.  Just hope the C-library defines system(). | 
					
						
							|  |  |  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef SPECIFIC_SYSTEM
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | System(command) | 
					
						
							|  |  |  | char *command; | 
					
						
							|  |  |  | { return system(command); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-28 19:41:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-13 13:28:17 +01:00
										 |  |  | #ifndef _YAP_NOT_INSTALLED_
 | 
					
						
							| 
									
										
										
										
											2015-03-28 19:41:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  |     char *findExecutable(char *buf) | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Return the path name of the executable of SWI-Prolog. | 
					
						
							|  |  |  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef __WINDOWS__			/* Win32 version in pl-nt.c */
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | static char *	Which(const char *program, char *fullname); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | char * | 
					
						
							|  |  |  | findExecutable(const char *av0, char *buffer) | 
					
						
							|  |  |  | { char *file; | 
					
						
							|  |  |  |   char buf[MAXPATHLEN]; | 
					
						
							|  |  |  |   char tmp[MAXPATHLEN]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( !av0 || !PrologPath(av0, buf, sizeof(buf)) ) | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   file = Which(buf, tmp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | #if __unix__				/* argv[0] can be an #! script! */
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |   if ( file ) | 
					
						
							|  |  |  |   { int n, fd; | 
					
						
							|  |  |  |     char buf[MAXPATHLEN]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					/* Fails if mode is x-only, but */ | 
					
						
							|  |  |  | 					/* then it can't be a script! */ | 
					
						
							|  |  |  |     if ( (fd = open(file, O_RDONLY)) < 0 ) | 
					
						
							|  |  |  |       return strcpy(buffer, file); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ( (n=read(fd, buf, sizeof(buf)-1)) > 0 ) | 
					
						
							|  |  |  |     { close(fd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       buf[n] = EOS; | 
					
						
							|  |  |  |       if ( strncmp(buf, "#!", 2) == 0 ) | 
					
						
							|  |  |  |       { char *s = &buf[2], *q; | 
					
						
							|  |  |  | 	while(*s && isBlank(*s)) | 
					
						
							|  |  |  | 	  s++; | 
					
						
							|  |  |  | 	for(q=s; *q && !isBlank(*q); q++) | 
					
						
							|  |  |  | 	  ; | 
					
						
							|  |  |  | 	*q = EOS; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return strcpy(buffer, s); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     close(fd); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /*__unix__*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return strcpy(buffer, file ? file : buf); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | #ifdef __unix__
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | static char * | 
					
						
							|  |  |  | okToExec(const char *s) | 
					
						
							| 
									
										
										
										
											2011-02-10 00:01:19 +00:00
										 |  |  | { statstruct stbuff; | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (statfunc(s, &stbuff) == 0 &&	/* stat it */ | 
					
						
							|  |  |  |      S_ISREG(stbuff.st_mode) &&		/* check for file */ | 
					
						
							|  |  |  |      access(s, X_OK) == 0)		/* can be executed? */ | 
					
						
							|  |  |  |     return (char *)s; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     return (char *) NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #define PATHSEP	':'
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | #endif /* __unix__ */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(OS2) || defined(__DOS__) || defined(__WINDOWS__)
 | 
					
						
							|  |  |  | #define EXEC_EXTENSIONS { ".exe", ".com", ".bat", ".cmd", NULL }
 | 
					
						
							|  |  |  | #define PATHSEP ';'
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef EXEC_EXTENSIONS
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char * | 
					
						
							|  |  |  | okToExec(const char *s) | 
					
						
							|  |  |  | { static char *extensions[] = EXEC_EXTENSIONS; | 
					
						
							|  |  |  |   static char **ext; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   DEBUG(2, Sdprintf("Checking %s\n", s)); | 
					
						
							|  |  |  |   for(ext = extensions; *ext; ext++) | 
					
						
							|  |  |  |     if ( stripostfix(s, *ext) ) | 
					
						
							|  |  |  |       return ExistsFile(s) ? (char *)s : (char *) NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for(ext = extensions; *ext; ext++) | 
					
						
							|  |  |  |   { static char path[MAXPATHLEN]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     strcpy(path, s); | 
					
						
							|  |  |  |     strcat(path, *ext); | 
					
						
							|  |  |  |     if ( ExistsFile(path) ) | 
					
						
							|  |  |  |       return path; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (char *) NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif /*EXEC_EXTENSIONS*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-28 19:41:12 +00:00
										 |  |  | #define isRelativePath(p) ( p[0] == '.' )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | static char * | 
					
						
							|  |  |  | Which(const char *program, char *fullname) | 
					
						
							|  |  |  | { char *path, *dir; | 
					
						
							|  |  |  |   char *e; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( IsAbsolutePath(program) || | 
					
						
							|  |  |  | #if OS2 && EMX
 | 
					
						
							|  |  |  |        isDriveRelativePath(program) || | 
					
						
							|  |  |  | #endif /* OS2 */
 | 
					
						
							| 
									
										
										
										
											2015-03-28 19:41:12 +00:00
										 |  |  |         isRelativePath(program) || | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |        strchr(program, '/') ) | 
					
						
							|  |  |  |   { if ( (e = okToExec(program)) != NULL ) | 
					
						
							| 
									
										
										
										
											2015-03-28 19:41:12 +00:00
										 |  |  |     { strcpy(fullname, e);1 | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |       return fullname; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if OS2 && EMX
 | 
					
						
							|  |  |  |   if ((e = okToExec(program)) != NULL) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     getcwd(fullname, MAXPATHLEN); | 
					
						
							|  |  |  |     strcat(fullname, "/"); | 
					
						
							|  |  |  |     strcat(fullname, e); | 
					
						
							|  |  |  |     return fullname; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* OS2 */
 | 
					
						
							|  |  |  |   if  ((path = getenv("PATH") ) == 0) | 
					
						
							|  |  |  |     path = DEFAULT_PATH; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   while(*path) | 
					
						
							|  |  |  |   { if ( *path == PATHSEP ) | 
					
						
							|  |  |  |     { if ( (e = okToExec(program)) ) | 
					
						
							|  |  |  | 	return strcpy(fullname, e); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         path++;				/* fix by Ron Hess (hess@sco.com) */ | 
					
						
							|  |  |  |     } else | 
					
						
							|  |  |  |     { char tmp[MAXPATHLEN]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       for(dir = fullname; *path && *path != PATHSEP; *dir++ = *path++) | 
					
						
							|  |  |  | 	; | 
					
						
							|  |  |  |       if (*path) | 
					
						
							|  |  |  | 	path++;				/* skip : */ | 
					
						
							|  |  |  |       if ((dir-fullname) + strlen(program)+2 > MAXPATHLEN) | 
					
						
							|  |  |  |         continue; | 
					
						
							|  |  |  |       *dir++ = '/'; | 
					
						
							|  |  |  |       strcpy(dir, program); | 
					
						
							|  |  |  |       if ( (e = okToExec(OsPath(fullname, tmp))) ) | 
					
						
							|  |  |  | 	return strcpy(fullname, e); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 00:19:07 +00:00
										 |  |  | #endif /*__WINDOWS__*/
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-28 19:41:12 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | /** int Pause(double time)
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | Suspend execution `time' seconds. Time  is   given  as  a floating point | 
					
						
							|  |  |  | number, expressing the time  to  sleep   in  seconds.  Just  about every | 
					
						
							|  |  |  | platform requires it own implementation. We provide them in the order of | 
					
						
							|  |  |  | preference. The implementations differ on  their granularity and whether | 
					
						
							|  |  |  | or not they can  be  interrupted   savely  restarted.  The  recent POSIX | 
					
						
							|  |  |  | nanosleep() is just about the  only   function  that  really works well: | 
					
						
							|  |  |  | accurate, interruptable and restartable. | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef __WINDOWS__
 | 
					
						
							|  |  |  | #define PAUSE_DONE 1			/* see pl-nt.c */
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined(PAUSE_DONE) && defined(HAVE_NANOSLEEP)
 | 
					
						
							|  |  |  | #define PAUSE_DONE 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | Pause(double t) | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | { struct timespec req; | 
					
						
							|  |  |  |   int rc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( t < 0.0 ) | 
					
						
							|  |  |  |     succeed; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   req.tv_sec = (time_t) t; | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  |   req.tv_nsec = (long)((t - floor(t)) * 1000000000); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   for(;;) | 
					
						
							|  |  |  |   { rc = nanosleep(&req, &req); | 
					
						
							|  |  |  |     if ( rc == -1 && errno == EINTR ) | 
					
						
							|  |  |  |     { if ( PL_handle_signals() < 0 ) | 
					
						
							|  |  |  | 	return FALSE; | 
					
						
							|  |  |  |     } else | 
					
						
							|  |  |  |       return TRUE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /*HAVE_NANOSLEEP*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined(PAUSE_DONE) && defined(HAVE_USLEEP)
 | 
					
						
							|  |  |  | #define PAUSE_DONE 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | Pause(double t) | 
					
						
							|  |  |  | { if ( t <= 0.0 ) | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  |   usleep((unsigned long)(t * 1000000.0)); | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /*HAVE_USLEEP*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined(PAUSE_DONE) && defined(HAVE_SELECT)
 | 
					
						
							|  |  |  | #define PAUSE_DONE 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | Pause(double time) | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | { struct timeval timeout; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( time <= 0.0 ) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( time < 60.0 )		/* select() is expensive. Does it make sense */ | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  |   { timeout.tv_sec = (long)time; | 
					
						
							|  |  |  |     timeout.tv_usec = (long)(time * 1000000) % 1000000; | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |     select(32, NULL, NULL, NULL, &timeout); | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  |     return TRUE; | 
					
						
							|  |  |  |   } else | 
					
						
							|  |  |  |   { int rc; | 
					
						
							|  |  |  |     int left = (int)(time+0.5); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     do | 
					
						
							|  |  |  |     { rc = sleep(left); | 
					
						
							|  |  |  |       if ( rc == -1 && errno == EINTR ) | 
					
						
							|  |  |  |       { if ( PL_handle_signals() < 0 ) | 
					
						
							|  |  |  | 	  return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return TRUE; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       left -= rc; | 
					
						
							|  |  |  |     } while ( rc != 0 ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /*HAVE_SELECT*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined(PAUSE_DONE) && defined(HAVE_DOSSLEEP)
 | 
					
						
							|  |  |  | #define PAUSE_DONE 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | int					/* a millisecond granualrity. */ | 
					
						
							|  |  |  | Pause(double time)			/* the EMX function sleep uses seconds */ | 
					
						
							|  |  |  | { if ( time <= 0.0 )			/* the select() trick does not work at all. */ | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   DosSleep((ULONG)(time * 1000)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /*HAVE_DOSSLEEP*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined(PAUSE_DONE) && defined(HAVE_SLEEP)
 | 
					
						
							|  |  |  | #define PAUSE_DONE 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | Pause(double t) | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | { if ( t <= 0.5 ) | 
					
						
							|  |  |  |     succeed; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   sleep((int)(t + 0.5)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   succeed; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /*HAVE_SLEEP*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined(PAUSE_DONE) && defined(HAVE_DELAY)
 | 
					
						
							|  |  |  | #define PAUSE_DONE 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | Pause(double t) | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | { delay((int)(t * 1000)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /*HAVE_DELAY*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef PAUSE_DONE
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2009-06-01 17:30:08 -05:00
										 |  |  | Pause(double t) | 
					
						
							| 
									
										
										
										
											2008-12-22 12:02:22 +00:00
										 |  |  | { return notImplemented("sleep", 1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  | BeginPredDefs(system) | 
					
						
							|  |  |  |   PRED_DEF("shell", 2, shell, 0) | 
					
						
							|  |  |  | EndPredDefs | 
					
						
							| 
									
										
										
										
											2015-01-04 23:58:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // @}
 |