summaryrefslogtreecommitdiff
path: root/fonts/utilities/mff-29/fx.c
diff options
context:
space:
mode:
Diffstat (limited to 'fonts/utilities/mff-29/fx.c')
-rw-r--r--fonts/utilities/mff-29/fx.c310
1 files changed, 310 insertions, 0 deletions
diff --git a/fonts/utilities/mff-29/fx.c b/fonts/utilities/mff-29/fx.c
new file mode 100644
index 0000000000..86935452e6
--- /dev/null
+++ b/fonts/utilities/mff-29/fx.c
@@ -0,0 +1,310 @@
+/* fx.c 2.9.0 92/07/06 - the simple fork-and-exec function used in mff.c
+ *
+ * The only f&x needed is calling up METAFONT and GFtoPK,
+ * and these programs take only one argument. It is convenient
+ * to allow the templates given to include spaces, e.g.,
+ * `-M "jobserver -q cmmf"' actually runs `jobserver'.
+ *
+ * I have ignored the "struct wait" nonsense -- Edition 7 all the way! :-)
+ *
+ * ATARI ST (and presumablu MS-DOS?) modification -- pdc 25 Jul 91
+ * There is no fork-&-exec in TOS; Use spawnvp instead.
+ *
+-----------------------------------------------------------------------
+ This software module copyright (c) 1990, 1991 Damian Cugley.
+ It is provided for free on an "as-is" basis.
+ See the file COPYING for more information.
+-----------------------------------------------------------------------
+ * Created - pdc Mon 15 Jan 1990
+ */
+
+#include "config.h"
+
+#ifndef NO_EXEC_USE_SPAWN
+# include <signal.h> /* NSIG */
+#else
+# include <process.h> /* P_WAIT */
+#endif /* no_exec_use_spawn */
+
+#include <errno.h>
+
+#include "stdc.h"
+#include "xstdio.h" /* <stdio.h> plus prototypes */
+#include "fatal.h" /* how to error messages */
+#include "strmisc.h" /* incl. <string(s).h> */
+#include "fx.h"
+
+NONRETURNING void exit ARGS((int));
+
+#define TRUE 1
+#define FALSE 0
+
+
+#ifndef lint
+addr realloc ARGS((addr, sizeof_t));
+#else
+# define realloc(P,S) 0
+#endif
+
+#define MORE 16
+/*
+ * generate more argv slots in batches of 16
+ * (I will be surprised if 16 are needed!)
+ */
+
+/*
+ * Construct an argv vector for the child process.
+ *
+ * |command| is pointer to zero-terminated string of characters;
+ * it is broken up as per strword(3) into separate arguments.
+ * |arg| is a final argument to append to the |argv| vector;
+ * it is *not* broken into words.
+ */
+static inline char **
+construct_args(command, argc, argv)
+ int argc;
+ char *command, **argv;
+{
+ int num_args = 0, max_args = MORE + argc;
+ char **nargv = (char **)xmalloc(max_args * sizeof(char *)),
+ *p, *strword_state;
+
+ if (!(p = strword(command, &strword_state)))
+ syntaxf("command string is empty!");
+ /* There should always be at least one word */
+ do
+ {
+ if (max_args - num_args == 1 + argc) /* always two spare arg slots */
+ {
+ /* try to make some more room */
+ nargv = (char **)
+ xrealloc(nargv, (max_args += MORE) * sizeof (char *));
+ }
+ nargv[num_args++] = p;
+ p = strword((char *)NULL, &strword_state);
+ } while (p);
+
+ /* There are always two free slots in the |nargv| array: */
+ while (argc-- > 0)
+ nargv[num_args++] = *argv++;
+
+ nargv[num_args] = (char *)NULL;
+ return nargv;
+}
+
+
+/*
+ * fx -- run a subprocess and wait for it to finish
+ */
+
+#ifdef NO_EXEC_USE_SPAWN
+
+void
+fx(char *command, int argc, char **argv)
+{
+ char **argv = construct_args(command, argc, argv);
+ int exit_code = spawnvp(P_WAIT, argv[0], argv);
+
+ xfree((addr)argv);
+ if (exit_code < 0) /* I am guessing positive exit codes are OK */
+ fatalf("%s terminated with exit code %d\n", command, exit_code);
+}
+
+#else /* EXEC is available: */
+
+#ifdef BSD
+# ifndef vfork
+# define fork vfork
+/*
+ * use vfork in preference to fork -- unless vfork has been #defined
+ * to fork (which might be expected on post-VM-problems UNIXes
+ */
+# endif
+#endif
+
+int wait ARGS((int *));
+int fork ARGS((void));
+int execvp ARGS((const char *, const char **));
+void NONRETURNING _exit ARGS((int));
+
+#ifdef NO_SIGLIST
+
+/*
+ * Must supply own list of signal names:
+ */
+static const char *sys_siglist[] =
+{
+ "shookum hip RALLO dine!", /* there is no signal 0 */
+ "hangup",
+ "interrupt",
+ "quit",
+ "illegal instruction",
+ "trace trap", /* 5 */
+ "IOT Trap",
+ "EMT trap",
+ "arithmetic exception",
+ "kill -KILL",
+ "bus error", /* 10 */
+ "violation of segments",
+ "bad argument to system call",
+ "unrequited pipe",
+ "alarm clock",
+ "software terminate -- from kill(2)", /* 15 */
+ /* that was the Edition 7 signals (0-15)... */
+#ifdef USG
+ "user-defined signal number 1", /* 16 */
+ "user-defined signal number 2", /* 17 */
+ "lonely child process", /* 18 */
+ "death! death! death!", /* 19 -- power failure */
+ /*
+ * For other systems (4.1 BSD?), signals > 15
+ * will be reported numerically.
+ */
+#endif /* USG */
+};
+
+/* define NSIG to be # of messages in above: */
+# undef NSIG
+# define NSIG ((sizeof sys_siglist)/sizeof (char *))
+
+#else /* have siglist */
+ extern const char *sys_siglist[];
+#endif
+
+extern char *sys_errlist[];
+extern int sys_nerr;
+
+
+/*
+ * classic fork and exec -- |command| and |arg| as above.
+ * Waits for child to finish.
+ */
+void /* aborts if can't exec */
+fx(command, argc, argv)
+ int argc;
+ char *command, **argv;
+{
+ int pid, t;
+ int status, /* status word from wait() */
+ exit_code; /* exit code of child */
+
+ argv = construct_args(command, argc, argv);
+
+ if ((pid = fork()) < 0) pfatalf("fork");
+ else if (pid == 0)
+ {
+ /* This is the child */
+ (void)execvp((const char *)argv[0], (const char **)argv);
+ /* If we get here, something's gone wrong: */
+ perrorf(argv[0]);
+ _exit(1); /* don't use exit() in child */
+ }
+
+ /* This is the parent process */
+#ifdef BSD
+ t = wait(&status);
+#else
+ while ((t = wait(&status)) < 0 && errno == EINTR)
+ ;
+#endif
+ if (t != pid) pfatalf("very surprised because wait returned %d", t);
+ xfree((addr)argv);
+
+ if ((status & 0xFF) != 0)
+ {
+ /* Terminated by signal: */
+ int sig = status & 0x7F;
+
+ fprintf(stderr, "%s killed by signal %d", command, sig);
+ if (sig < NSIG)
+ fprintf(stderr, " (%s)\n", sys_siglist[sig]);
+ if (status & 0x80)
+ fprintf(stderr, "Wow, coredump city.\n");
+ exit(1);
+ }
+ else if (exit_code = status >> 8 & 0xFF)
+ {
+ fprintf(stderr, "%s terminated with exit code %d.\n",
+ command, exit_code);
+ exit(1);
+ }
+}
+
+
+#ifdef NO_EXECVP
+/*
+ * This is intended as a version of execvp for systems that don't have it.
+ * (V7, BSD 4.2?)
+ *
+ * If an executable file is found for which execv() fails,
+ * it is assumed to be a shellscript and /bin/sh is invoked with
+ * its full pathname as first argument.
+ *
+ * pdc Thur. 27 June 1991
+ */
+
+#include <sys/param.h>
+#ifndef MAXPATHLEN
+# define MAXPATHLEN 1024
+#endif
+#include "strmisc.h"
+#include "searchpath.h" /* might as well use that */
+
+int /* returns -1 if fails */
+execvp(progname, argv)
+ const char *progname; /* name of prog to search for */
+ const char *argv[]; /* vector of arguments */
+{
+ const char *getenv ARGS((const char *));
+ int execv ARGS((const char *, const char *[]));
+
+ char scratch[MAXPATHLEN];
+ const char *path = getenv("PATH");
+
+ if (!path) path = ""; /* for mad people who like PATH-free shells */
+
+ if (findfile(scratch, progname, path, (char *)0))
+ {
+ if (execv(scratch, argv), errno == ENOEXEC)
+ {
+ /*
+ * a /bin/sh command file
+ * Substitute pathname of file as 1st argument to sh:
+ * execvp("fo", {"fo","arg","brg",0}) ->
+ * /bin/sh /usr/local/bin/fo arg brg
+ */
+ const char **nargv; /* ptr to vect of ptrs to vects of const char */
+ int argc;
+
+ /*
+ * count args:
+ */
+ {
+ register const char **t = argv;
+ while (*t) ++t;
+ argc = (t - argv);
+ }
+
+ /* allocate room for 1 more arg & the NULL */
+ /* copy the NULL and the args except the 0'th arg */
+ nargv = (const char **)xmalloc(sizeof (char *) * (argc + 2));
+ bcopy((addr)(argv + 1), (addr)(nargv + 2),
+ argc*(sizeof (char *)));
+ nargv[0] = "/bin/sh";
+ nargv[1] = scratch;
+ execv(nargv[0], nargv);
+
+ /* failed -- */
+ xfree((addr)nargv);
+ }
+ }
+ else
+ {
+ /* findfile returned FALSE */
+ errno = ENOENT;
+ }
+
+ return -1;
+}
+#endif /* NO_EXECVP */
+#endif /* NO_EXEC_USE_SPAWN */