1 /* luatex.c: Hand-coded routines for TeX or Metafont in C. Originally
2 written by Tim Morgan, drawing from other Unix ports of TeX. This is
3 a collection of miscellany, everything that's easier (or only
6 This file is public domain. */
8 /* This file is used to create texextra.c etc., with this line
9 changed to include texd.h or mfd.h. The ?d.h file is what
10 #defines TeX or MF, which avoids the need for a special
13 /* We |#define DLLPROC| in order to build LuaTeX and LuajitTeX as DLL
16 #define DLLPROC dllluajittexmain
18 #define DLLPROC dllluatexmain
23 #include "lua/luatex-api.h"
24 #include "luatex_svnversion.h"
29 int luatex_svn
= luatex_svn_revision
;
30 int luatex_version
= 81; /* \.{\\luatexversion} */
31 int luatex_revision
= '1'; /* \.{\\luatexrevision} */
32 int luatex_date_info
= 2015042200; /* the compile date is now hardwired */
33 const char *luatex_version_string
= "beta-0.81.1";
34 const char *engine_name
= my_name
; /* the name of this engine */
36 #include <kpathsea/c-ctype.h>
37 #include <kpathsea/line.h>
38 #include <kpathsea/readable.h>
39 #include <kpathsea/variable.h>
40 #include <kpathsea/absolute.h>
42 #include <kpathsea/concatn.h>
49 #include <time.h> /* For `struct tm'. */
50 #if defined (HAVE_SYS_TIME_H)
51 # include <sys/time.h>
52 #elif defined (HAVE_SYS_TIMEB_H)
53 # include <sys/timeb.h>
60 #include <signal.h> /* Catch interrupts. */
63 /* {tex,mf}d.h defines TeX, MF, INI, and other such symbols.
64 Unfortunately there's no way to get the banner into this code, so
65 just repeat the text. */
66 #define edit_var "TEXEDIT"
70 If shellenabledp == 0, all shell escapes are forbidden.
71 If (shellenabledp == 1 && restrictedshell == 0), any command
72 is allowed for a shell escape.
73 If (shellenabledp == 1 && restrictedshell == 1), only commands
74 given in the configuration file as
75 shell_escape_commands = kpsewhich,ebb,extractbb,mpost,metafun,...
76 (no spaces between commands) in texmf.cnf are allowed for a shell
77 escape in a restricted form: command name and arguments should be
78 separated by a white space. The first word should be a command
79 name. The quotation character for an argument with spaces,
80 including a pathname, should be ". ' should not be used.
82 Internally, all arguments are quoted by ' (Unix) or " (Windows)
83 before calling the system() function in order to forbid execution
84 of any embedded command. In addition, on Windows, special
85 characters of cmd.exe are escaped by using (^).
87 If the --shell-escape option is given, we set
88 shellenabledp = 1 and restrictedshell = 0, i.e., any command is allowed.
89 If the --shell-restricted option is given, we set
90 shellenabledp = 1 and restrictedshell = 1, i.e., only given cmds allowed.
91 If the --no-shell-escape option is given, we set
92 shellenabledp = -1 (and restrictedshell is irrelevant).
93 If none of these option are given, there are three cases:
98 it becomes shellenabledp = 1 and restrictedshell = 0,
99 that is, any command is allowed.
100 (2) In the case where
102 it becomes shellenabledp = 1 and restrictedshell = 1,
103 that is, restricted shell escape is allowed.
104 (3) In all other cases, shellenabledp = 0, that is, shell
105 escape is forbidden. The value of restrictedshell is
106 irrelevant if shellenabledp == 0.
111 /* cmdlist is a list of allowed commands which are given like this:
112 shell_escape_commands = kpsewhich,ebb,extractbb,mpost,metafun
115 static char **cmdlist
= NULL
;
117 void mk_shellcmdlist(char *v
)
126 /* analyze the variable shell_escape_commands = foo,bar,...
127 spaces before and after (,) are not allowed. */
129 while ((r
= strchr(q
, ',')) != 0) {
135 cmdlist
= (char **) xmalloc(n
* sizeof (char *));
138 while ((r
= strchr(q
, ',')) != 0) {
148 /* Called from maininit. Not static because also called from
149 luatexdir/lua/luainit.c. */
151 void init_shell_escape(void)
153 if (shellenabledp
< 0) { /* --no-shell-escape on cmd line */
157 if (shellenabledp
== 0) { /* no shell options on cmd line, check cnf */
158 char *v1
= kpse_var_value("shell_escape");
160 if (*v1
== 't' || *v1
== 'y' || *v1
== '1') {
162 } else if (*v1
== 'p') {
170 /* If shell escapes are restricted, get allowed cmds from cnf. */
171 if (shellenabledp
&& restrictedshell
== 1) {
172 char *v2
= kpse_var_value("shell_escape_commands");
188 static int char_needs_quote(int c
)
190 /* special characters of cmd.exe */
192 return (c
== '&' || c
== '|' || c
== '%' || c
== '<' ||
193 c
== '>' || c
== ';' || c
== ',' || c
== '(' || c
== ')');
197 static int Isspace(char c
)
199 return (c
== ' ' || c
== '\t');
203 -1 : invalid quotation of an argument
204 0 : command is not allowed
205 2 : restricted shell escape, CMD is allowed.
207 We set *SAFECMD to a safely-quoted version of *CMD; this is what
208 should get executed. And we set CMDNAME to its first word; this is
209 what is checked against the shell_escape_commands list. */
211 int shell_cmd_is_allowed(const char *cmd
, char **safecmd
, char **cmdname
)
221 /* pre == 1 means that the previous character is a white space
222 pre == 0 means that the previous character is not a white space */
223 buf
= xmalloc(strlen(cmd
) + 1);
229 while (!Isspace(*d
) && *d
)
233 /* *cmdname is the first word of the command line. For example,
234 *cmdname == "kpsewhich" for
235 \write18{kpsewhich --progname=dvipdfm --format="other text files" config}
237 *cmdname
= xstrdup(c
);
240 /* Is *cmdname listed in a texmf.cnf vriable as
241 shell_escape_commands = foo,bar,... ? */
245 if (strcmp(*p
, *cmdname
) == 0) {
246 /* *cmdname is found in the list, so restricted shell escape
256 for (s
= cmd
; *s
; s
++) {
261 /* allocate enough memory (too much?) */
263 *safecmd
= xmalloc(2 * strlen(cmd
) + 3 + 2 * spaces
);
265 *safecmd
= xmalloc(strlen(cmd
) + 3 + 2 * spaces
);
268 /* make a safe command line *safecmd */
273 while (!Isspace(*s
) && *s
)
278 /* Quotation given by a user. " should always be used; we
279 transform it below. On Unix, if ' is used, simply immediately
280 return a quotation error. */
286 /* All arguments are quoted as 'foo' (Unix) or "foo" (Windows)
287 before calling system(). Therefore closing QUOTE is necessary
288 if the previous character is not a white space.
290 --format="other text files" becomes
291 '--format=''other text files' (Unix)
292 "--format=""other test files" (Windows) */
298 /* output the quotation mark for the quoted argument */
303 /* Illegal use of ', or closing quotation mark is missing */
304 if (*s
== '\'' || *s
== '\0')
307 if (char_needs_quote(*s
))
313 /* Closing quotation mark will be output afterwards, so
314 we do nothing here */
317 /* The character after the closing quotation mark
318 should be a white space or NULL */
319 if (!Isspace(*s
) && *s
)
322 /* Beginning of a usual argument */
323 } else if (pre
== 1 && !Isspace(*s
)) {
327 if (char_needs_quote(*s
))
331 /* Ending of a usual argument */
333 } else if (pre
== 0 && Isspace(*s
)) {
335 /* Closing quotation mark */
339 /* Copy a character from cmd to *safecmd. */
341 if (char_needs_quote(*s
))
347 /* End of the command line */
356 if (strlen (p
) > 2 && p
[1] == ':' && !IS_DIR_SEP (p
[2])) {
357 q
= xmalloc (strlen (p
) + 2);
365 } else if (!IS_DIR_SEP (p
[0]) && !(p
[1] == ':' && IS_DIR_SEP (p
[2]))) {
366 p
= kpse_var_value ("SELFAUTOLOC");
369 while (*r
&& !Isspace(*r
))
372 q
= concatn ("\"", p
, "/", *safecmd
, "\"", NULL
);
376 while (*r
&& Isspace(*r
))
379 q
= concatn ("\"", p
, "/", *safecmd
, "\" ", r
, NULL
);
381 q
= concatn ("\"", p
, "/", *safecmd
, "\"", NULL
);
395 /* We should only be called with shellenabledp == 1.
397 -1 if a quotation syntax error.
398 0 if CMD is not allowed; given shellenabledp==1, this is because
399 shell escapes are restricted and CMD is not allowed.
400 1 if shell escapes are not restricted, hence any command is allowed.
401 2 if shell escapes are restricted and CMD is allowed. */
403 int runsystem(const char *cmd
)
406 char *safecmd
= NULL
;
407 char *cmdname
= NULL
;
409 if (shellenabledp
<= 0) {
413 /* If restrictedshell == 0, any command is allowed. */
414 if (restrictedshell
== 0)
417 allow
= shell_cmd_is_allowed(cmd
, &safecmd
, &cmdname
);
422 (void) system(safecmd
);
435 /* What we were invoked as and with. */
439 /* The C version of what might wind up in |TEX_format_default|. */
442 /* The C version of the jobname, if given. */
443 const_string c_job_name
;
445 const char *luatex_banner
;
448 /* Invalid parameter handler */
449 static void myInvalidParameterHandler(const wchar_t * expression
,
450 const wchar_t * function
,
451 const wchar_t * file
,
456 printf(L"Invalid parameter detected in function %s."
457 L" File: %s Line: %d\n", function, file, line);
458 printf(L"Expression: %s\n", expression);
461 I return silently to avoid an exit with the error 0xc0000417
462 (invalid parameter) when we use non-embedded fonts in luatex-ja,
463 which works without any problem on Unix systems.
464 I hope it is not dangerous.
470 /* The entry point: set up for reading the command line, which will
471 happen in `topenin', then call the main body. */
475 DLLPROC (int ac
, string
*av
)
477 main (int ac
, string
*av
)
487 _set_invalid_parameter_handler(myInvalidParameterHandler
);
489 av
[0] = kpse_program_basename (av
[0]);
491 SetErrorMode (SEM_FAILCRITICALERRORS
| SEM_NOGPFAULTERRORBOX
| SEM_NOOPENFILEERRORBOX
);
492 setmode(fileno(stdin
), _O_BINARY
);
495 lua_initialize(ac
, av
);
500 if ((strlen(av
[ac
-1]) > 2) &&
501 isalpha(av
[ac
-1][0]) &&
502 (av
[ac
-1][1] == ':') &&
503 (av
[ac
-1][2] == '\\')) {
504 for (pp
=av
[ac
-1]+2; *pp
; pp
++) {
516 /* Call the real main program. */
523 /* This is supposed to ``open the terminal for input'', but what we
524 really do is copy command line arguments into TeX's or Metafont's
525 buffer, so they can handle them. If nothing is available, or we've
526 been called already (and hence, argc==0), we return with
534 buffer
[first
] = 0; /* In case there are no arguments. */
536 if (optind
< argc
) { /* We have command line arguments. */
538 for (i
= optind
; i
< argc
; i
++) {
539 char *ptr
= &(argv
[i
][0]);
540 /* Don't use strcat, since in Aleph the buffer elements aren't
543 buffer
[k
++] = (packed_ASCII_code
) * (ptr
++);
547 argc
= 0; /* Don't do this again. */
551 /* Find the end of the buffer. */
552 for (last
= first
; buffer
[last
]; ++last
);
554 /* Make `last' be one past the last non-blank character in `buffer'. */
555 /* ??? The test for '\r' should not be necessary. */
556 for (--last
; last
>= first
557 && ISBLANK(buffer
[last
]) && buffer
[last
] != '\r'; --last
);
560 /* One more time, this time converting to TeX's internal character
564 /* IPC for TeX. By Tom Rokicki for the NeXT; it makes TeX ship out the
565 DVI file in a pipe to TeXView so that the output can be displayed
566 incrementally. Shamim Mohamed adapted it for Web2c. */
567 #if defined (TeX) && defined (IPC)
571 #include <winsock2.h>
573 #include <sys/socket.h>
575 #ifndef O_NONBLOCK /* POSIX */
576 #ifdef O_NDELAY /* BSD */
577 #define O_NONBLOCK O_NDELAY
578 #elif defined(O_FNDELAY) /* NeXT */
579 #define O_NONBLOCK O_FNDELAY
581 what the fcntl
? cannot implement IPC without equivalent
for O_NONBLOCK
.
583 #endif /* no O_NONBLOCK */
587 # define IPC_AF AF_INET
588 # ifndef IPC_LOCAL_HOST
589 # define IPC_LOCAL_HOST "127.0.0.1"
590 # define FIXED_PORT (unsigned short)4242
593 # define IPC_AF AF_UNIX
594 # ifndef IPC_PIPE_NAME /* $HOME is prepended to this. */
595 # define IPC_PIPE_NAME "/.TeXview_Pipe"
598 #ifndef IPC_SERVER_CMD /* Command to run to start the server. */
600 # define IPC_SERVER_CMD "texview.exe"
602 # define IPC_SERVER_CMD "open `which TeXview`"
608 int namelength
; /* length of auxiliary data */
609 int eof
; /* new eof for dvi file */
610 #if 0 /* see usage of struct msg below */
611 char more_data
[0]; /* where the rest of the stuff goes */
615 static struct sockaddr
*ipc_addr
;
616 static int ipc_addr_len
;
621 if (ipc_addr_len
== 0) {
623 unsigned long remote_addr
= inet_addr(IPC_LOCAL_HOST
);
624 if (remote_addr
!= INADDR_NONE
) {
625 struct sockaddr_in
*ipc_sin_addr
= xmalloc (sizeof (struct sockaddr_in
));
626 ipc_sin_addr
->sin_family
= AF_INET
;
627 ipc_sin_addr
->sin_addr
.s_addr
= remote_addr
;
628 ipc_sin_addr
->sin_port
= htons (FIXED_PORT
);
629 ipc_addr
= ((struct sockaddr
*) ipc_sin_addr
);
630 ipc_addr_len
= sizeof(struct sockaddr_in
);
633 string s
= getenv ("HOME");
636 ipc_addr
= xmalloc (strlen (s
) + 40);
637 ipc_addr
->sa_family
= 0;
638 ipc_name
= ipc_addr
->sa_data
;
639 strcpy (ipc_name
, s
);
640 strcat (ipc_name
, IPC_PIPE_NAME
);
641 ipc_addr_len
= strlen (ipc_name
) + 3;
648 static int sock
= -1;
651 # define CLOSE_SOCKET(s) closesocket (s); WSACleanup ()
653 # define CLOSE_SOCKET(s) close (s)
663 ipc_open_out (void) {
665 struct WSAData wsaData
;
667 unsigned long mode
= 1;
670 fputs ("tex: Opening socket for IPC output ...\n", stderr
);
677 if ((nCode
= WSAStartup(MAKEWORD(1, 1), &wsaData
)) != 0) {
678 fprintf(stderr
,"WSAStartup() returned error code %d.\n", nCode
);
683 if (ipc_make_name () <= 0)
686 sock
= socket (IPC_AF
, SOCK_STREAM
, 0);
689 fprintf(stderr
, "tex: Socket handle is %d\n", sock
);
691 fprintf(stderr
, "tex: Socket is invalid.\n");
695 if (connect (sock
, ipc_addr
, ipc_addr_len
) != 0 ||
697 ioctlsocket (sock
, FIONBIO
, &mode
) < 0
699 fcntl (sock
, F_SETFL
, O_NONBLOCK
) < 0
705 fputs ("tex: IPC socket cannot be connected.\n", stderr
);
706 fputs ("tex: Socket is closed.\n", stderr
);
711 fputs ("tex: Successfully opened IPC socket.\n", stderr
);
720 fputs ("tex: Closing output socket ...\n", stderr
);
722 if (ipc_is_open ()) {
729 ipc_snd (int n
, int is_eof
, char *data
)
734 char more_data
[1024];
737 if (!ipc_is_open ()) {
742 fprintf(stderr
, "%d\t%d\n", ourmsg
.msg
.namelength
, ourmsg
.msg
.eof
);
743 fputs ("tex: Sending message to socket ...\n", stderr
);
745 ourmsg
.msg
.namelength
= n
;
746 ourmsg
.msg
.eof
= is_eof
;
748 strcpy (ourmsg
.more_data
, data
);
750 n
+= sizeof (struct msg
);
752 fprintf(stderr
, "%d\t%d\n", ourmsg
.msg
.namelength
, ourmsg
.msg
.eof
);
753 fputs ("tex: Writing to socket...\n", stderr
);
756 if (send (sock
, (char *)&ourmsg
, n
, 0) != n
) {
758 if (write (sock
, &ourmsg
, n
) != n
) {
763 fputs ("tex: IPC message sent.\n", stderr
);
767 /* This routine notifies the server if there is an eof, or the filename
768 if a new DVI file is starting. This is the routine called by TeX.
769 Aleph defines str_start(#) as str_start_ar[# - too_big_char], with
770 too_big_char = biggest_char + 1 = 65536 (omstr.ch). */
775 static boolean begun
= false;
780 string name
; /* Just the filename. */
781 string cwd
= xgetcwd ();
785 /* Have to pass whole filename to the other end, since it may have
786 been started up and running as a daemon, e.g., as with the NeXT
788 name
= static_pdf
->file_name
;
789 p
= concat3 (cwd
, DIR_SEP_STRING
, name
);
795 for (q
= p
; *q
; q
++) {
798 else if (IS_KANJI(q
))
806 ipc_snd (len
, is_eof
, p
);
811 #endif /* TeX && IPC */
813 /* Normalize quoting of filename -- that is, only quote if there is a space,
814 and always use the quote-name-quote style. */
815 string
normalize_quotes(const_string name
, const_string mesg
)
817 boolean quoted
= false;
818 boolean must_quote
= (strchr(name
, ' ') != NULL
);
819 /* Leave room for quotes and NUL. */
820 string ret
= (string
) xmalloc((unsigned) strlen(name
) + 3);
826 for (q
= name
; *q
; q
++) {
836 fprintf(stderr
, "! Unbalanced quotes in %s %s\n", mesg
, name
);
843 /* All our interrupt handler has to do is set TeX's or Metafont's global
844 variable `interrupt'; then they will do everything needed. */
846 /* Win32 doesn't set SIGINT ... */
847 static BOOL WINAPI
catch_interrupt(DWORD arg
)
851 case CTRL_BREAK_EVENT
:
855 /* No need to set interrupt as we are exiting anyway */
859 #else /* not WIN32 */
860 static RETSIGTYPE
catch_interrupt(int arg
)
865 (void) signal(SIGINT
, SIG_ACK
);
867 (void) signal(SIGINT
, catch_interrupt
);
868 # endif /* not OS2 */
870 #endif /* not WIN32 */
872 /* Besides getting the date and time here, we also set up the interrupt
873 handler, for no particularly good reason. It's just that since the
874 `fix_date_and_time' routine is called early on (section 1337 in TeX,
875 ``Get the first line of input and prepare to start''), this is as
876 good a place as any. */
878 void get_date_and_time(int *minutes
, int *day
, int *month
, int *year
)
880 time_t myclock
= time((time_t *) 0);
881 struct tm
*tmptr
= localtime(&myclock
);
883 *minutes
= tmptr
->tm_hour
* 60 + tmptr
->tm_min
;
884 *day
= tmptr
->tm_mday
;
885 *month
= tmptr
->tm_mon
+ 1;
886 *year
= tmptr
->tm_year
+ 1900;
890 /* Under SunOS 4.1.x, the default action after return from the
891 signal handler is to restart the I/O if nothing has been
892 transferred. The effect on TeX is that interrupts are ignored if
893 we are waiting for input. The following tells the system to
894 return EINTR from read() in this case. From ken@cs.toronto.edu. */
896 struct sigaction a
, oa
;
898 a
.sa_handler
= catch_interrupt
;
899 sigemptyset(&a
.sa_mask
);
900 sigaddset(&a
.sa_mask
, SIGINT
);
901 a
.sa_flags
= SA_INTERRUPT
;
902 sigaction(SIGINT
, &a
, &oa
);
903 if (oa
.sa_handler
!= SIG_DFL
)
904 sigaction(SIGINT
, &oa
, (struct sigaction
*) 0);
905 #else /* no SA_INTERRUPT */
907 SetConsoleCtrlHandler(catch_interrupt
, TRUE
);
908 # else /* not WIN32 */
909 RETSIGTYPE(*old_handler
) (int);
911 old_handler
= signal(SIGINT
, catch_interrupt
);
912 if (old_handler
!= SIG_DFL
)
913 signal(SIGINT
, old_handler
);
914 # endif /* not WIN32 */
915 #endif /* no SA_INTERRUPT */
920 Getting a high resolution time.
922 void get_seconds_and_micros(int *seconds
, int *micros
)
924 #if defined (HAVE_GETTIMEOFDAY)
926 gettimeofday(&tv
, NULL
);
927 *seconds
= (int)tv
.tv_sec
;
928 *micros
= (int)tv
.tv_usec
;
929 #elif defined (HAVE_FTIME)
933 *micros
= tb
.millitm
* 1000;
935 time_t myclock
= time((time_t *) NULL
);
936 *seconds
= (int) myclock
;
942 Generating a better seed numbers
944 int getrandomseed(void)
946 #if defined (HAVE_GETTIMEOFDAY)
948 gettimeofday(&tv
, NULL
);
949 return (int)(tv
.tv_usec
+ 1000000 * tv
.tv_usec
);
950 #elif defined (HAVE_FTIME)
953 return (tb
.millitm
+ 1000 * tb
.time
);
955 time_t myclock
= time((time_t *) NULL
);
956 struct tm
*tmptr
= localtime(&myclock
);
957 return (tmptr
->tm_sec
+ 60 * (tmptr
->tm_min
+ 60 * tmptr
->tm_hour
));
961 /* Read a line of input as efficiently as possible while still looking
962 like Pascal. We set `last' to `first' and return `false' if we get
963 to eof. Otherwise, we return `true' and set last = first +
964 length(line except trailing whitespace). */
966 boolean
input_line(FILE * f
)
971 if (f
!= Poptr
&& fileno (f
) != fileno (stdin
)) {
972 long position
= ftell (f
);
974 if (position
== 0L) { /* Detect and skip Byte order marks. */
977 if (k1
!= 0xff && k1
!= 0xfe && k1
!= 0xef)
982 if (k2
!= 0xff && k2
!= 0xfe && k2
!= 0xbb)
984 else if ((k1
== 0xff && k2
== 0xfe) || /* UTF-16(LE) */
985 (k1
== 0xfe && k2
== 0xff)) /* UTF-16(BE) */
990 if (k1
== 0xef && k2
== 0xbb && k3
== 0xbf) /* UTF-8 */
999 /* Recognize either LF or CR as a line terminator. */
1001 while (last
< buf_size
&& (i
= getc(f
)) != EOF
&& i
!= '\n' && i
!= '\r')
1002 buffer
[last
++] = (packed_ASCII_code
) i
;
1004 if (i
== EOF
&& errno
!= EINTR
&& last
== first
)
1007 /* We didn't get the whole line because our buffer was too small. */
1008 if (i
!= EOF
&& i
!= '\n' && i
!= '\r') {
1009 fprintf(stderr
, "! Unable to read an entire line---bufsize=%u.\n",
1010 (unsigned) buf_size
);
1011 fputs("Please increase buf_size in texmf.cnf.\n", stderr
);
1016 if (last
>= max_buf_stack
)
1017 max_buf_stack
= last
;
1019 /* If next char is LF of a CRLF, read it. */
1021 while ((i
= getc(f
)) == EOF
&& errno
== EINTR
);
1026 /* Trim trailing whitespace. */
1027 while (last
> first
&& ISBLANK(buffer
[last
- 1]))
1030 /* Don't bother using xord if we don't need to. */
1038 /* Get the job name to be used, which may have been set from the
1040 str_number
getjobname(str_number name
)
1042 str_number ret
= name
;
1043 if (c_job_name
!= NULL
)
1044 ret
= maketexstring(c_job_name
);