sysmodule.c revision dbd9ba6a6c19c3d06f5684b3384a934f740038db
1/***********************************************************
2Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
6
7See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
9******************************************************************/
10
11/* System module */
12
13/*
14Various bits of information used by the interpreter are collected in
15module 'sys'.
16Function member:
17- exit(sts): raise SystemExit
18Data members:
19- stdin, stdout, stderr: standard file objects
20- modules: the table of modules (dictionary)
21- path: module search path (list of strings)
22- argv: script arguments (list of strings)
23- ps1, ps2: optional primary and secondary prompts (strings)
24*/
25
26#include "Python.h"
27
28#include "osdefs.h"
29
30#ifdef HAVE_UNISTD_H
31#include <unistd.h>
32#endif
33
34#ifdef MS_COREDLL
35extern void *PyWin_DLLhModule;
36/* A string loaded from the DLL at startup: */
37extern const char *PyWin_DLLVersionString;
38#endif
39
40PyObject *
41PySys_GetObject(name)
42	char *name;
43{
44	PyThreadState *tstate = PyThreadState_Get();
45	PyObject *sd = tstate->interp->sysdict;
46	if (sd == NULL)
47		return NULL;
48	return PyDict_GetItemString(sd, name);
49}
50
51FILE *
52PySys_GetFile(name, def)
53	char *name;
54	FILE *def;
55{
56	FILE *fp = NULL;
57	PyObject *v = PySys_GetObject(name);
58	if (v != NULL && PyFile_Check(v))
59		fp = PyFile_AsFile(v);
60	if (fp == NULL)
61		fp = def;
62	return fp;
63}
64
65int
66PySys_SetObject(name, v)
67	char *name;
68	PyObject *v;
69{
70	PyThreadState *tstate = PyThreadState_Get();
71	PyObject *sd = tstate->interp->sysdict;
72	if (v == NULL) {
73		if (PyDict_GetItemString(sd, name) == NULL)
74			return 0;
75		else
76			return PyDict_DelItemString(sd, name);
77	}
78	else
79		return PyDict_SetItemString(sd, name, v);
80}
81
82static PyObject *
83sys_exc_info(self, args)
84	PyObject *self;
85	PyObject *args;
86{
87	PyThreadState *tstate;
88	if (!PyArg_ParseTuple(args, ":exc_info"))
89		return NULL;
90	tstate = PyThreadState_Get();
91	return Py_BuildValue(
92		"(OOO)",
93		tstate->exc_type != NULL ? tstate->exc_type : Py_None,
94		tstate->exc_value != NULL ? tstate->exc_value : Py_None,
95		tstate->exc_traceback != NULL ?
96			tstate->exc_traceback : Py_None);
97}
98
99static char exc_info_doc[] =
100"exc_info() -> (type, value, traceback)\n\
101\n\
102Return information about the exception that is currently being handled.\n\
103This should be called from inside an except clause only.";
104
105static PyObject *
106sys_exit(self, args)
107	PyObject *self;
108	PyObject *args;
109{
110	/* Raise SystemExit so callers may catch it or clean up. */
111	PyErr_SetObject(PyExc_SystemExit, args);
112	return NULL;
113}
114
115static char exit_doc[] =
116"exit([status])\n\
117\n\
118Exit the interpreter by raising SystemExit(status).\n\
119If the status is omitted or None, it defaults to zero (i.e., success).\n\
120If the status numeric, it will be used as the system exit status.\n\
121If it is another kind of object, it will be printed and the system\n\
122exit status will be one (i.e., failure).";
123
124static PyObject *
125sys_getdefaultencoding(self, args)
126	PyObject *self;
127	PyObject *args;
128{
129	if (!PyArg_ParseTuple(args, ":getdefaultencoding"))
130		return NULL;
131	return PyString_FromString(PyUnicode_GetDefaultEncoding());
132}
133
134static char getdefaultencoding_doc[] =
135"getdefaultencoding() -> string\n\
136\n\
137Return the current default string encoding used by the Unicode \n\
138implementation.";
139
140static PyObject *
141sys_setdefaultencoding(self, args)
142	PyObject *self;
143	PyObject *args;
144{
145	char *encoding;
146	if (!PyArg_ParseTuple(args, "s:setdefaultencoding", &encoding))
147		return NULL;
148	if (PyUnicode_SetDefaultEncoding(encoding))
149	    	return NULL;
150	Py_INCREF(Py_None);
151	return Py_None;
152}
153
154static char setdefaultencoding_doc[] =
155"setdefaultencoding(encoding)\n\
156\n\
157Set the current default string encoding used by the Unicode implementation.";
158
159static PyObject *
160sys_settrace(self, args)
161	PyObject *self;
162	PyObject *args;
163{
164	PyThreadState *tstate = PyThreadState_Get();
165	if (args == Py_None)
166		args = NULL;
167	else
168		Py_XINCREF(args);
169	Py_XDECREF(tstate->sys_tracefunc);
170	tstate->sys_tracefunc = args;
171	Py_INCREF(Py_None);
172	return Py_None;
173}
174
175static char settrace_doc[] =
176"settrace(function)\n\
177\n\
178Set the global debug tracing function.  It will be called on each\n\
179function call.  See the debugger chapter in the library manual.";
180
181static PyObject *
182sys_setprofile(self, args)
183	PyObject *self;
184	PyObject *args;
185{
186	PyThreadState *tstate = PyThreadState_Get();
187	if (args == Py_None)
188		args = NULL;
189	else
190		Py_XINCREF(args);
191	Py_XDECREF(tstate->sys_profilefunc);
192	tstate->sys_profilefunc = args;
193	Py_INCREF(Py_None);
194	return Py_None;
195}
196
197static char setprofile_doc[] =
198"setprofile(function)\n\
199\n\
200Set the profiling function.  It will be called on each function call\n\
201and return.  See the profiler chapter in the library manual.";
202
203static PyObject *
204sys_setcheckinterval(self, args)
205	PyObject *self;
206	PyObject *args;
207{
208	PyThreadState *tstate = PyThreadState_Get();
209	if (!PyArg_ParseTuple(args, "i:setcheckinterval", &tstate->interp->checkinterval))
210		return NULL;
211	Py_INCREF(Py_None);
212	return Py_None;
213}
214
215static char setcheckinterval_doc[] =
216"setcheckinterval(n)\n\
217\n\
218Tell the Python interpreter to check for asynchronous events every\n\
219n instructions.  This also affects how often thread switches occur.";
220
221#ifdef USE_MALLOPT
222/* Link with -lmalloc (or -lmpc) on an SGI */
223#include <malloc.h>
224
225static PyObject *
226sys_mdebug(self, args)
227	PyObject *self;
228	PyObject *args;
229{
230	int flag;
231	if (!PyArg_ParseTuple(args, "i:mdebug", &flag))
232		return NULL;
233	mallopt(M_DEBUG, flag);
234	Py_INCREF(Py_None);
235	return Py_None;
236}
237#endif /* USE_MALLOPT */
238
239static PyObject *
240sys_getrefcount(self, args)
241	PyObject *self;
242	PyObject *args;
243{
244	PyObject *arg;
245	if (!PyArg_ParseTuple(args, "O:getrefcount", &arg))
246		return NULL;
247	return PyInt_FromLong(arg->ob_refcnt);
248}
249
250#ifdef Py_TRACE_REFS
251static PyObject *
252sys_gettotalrefcount(PyObject *self, PyObject *args)
253{
254	extern long _Py_RefTotal;
255	if (!PyArg_ParseTuple(args, ":gettotalrefcount"))
256		return NULL;
257	return PyInt_FromLong(_Py_RefTotal);
258}
259
260#endif /* Py_TRACE_REFS */
261
262static char getrefcount_doc[] =
263"getrefcount(object) -> integer\n\
264\n\
265Return the current reference count for the object.  This includes the\n\
266temporary reference in the argument list, so it is at least 2.";
267
268#ifdef COUNT_ALLOCS
269static PyObject *
270sys_getcounts(self, args)
271	PyObject *self, *args;
272{
273	extern PyObject *get_counts(void);
274
275	if (!PyArg_ParseTuple(args, ":getcounts"))
276		return NULL;
277	return get_counts();
278}
279#endif
280
281#ifdef Py_TRACE_REFS
282/* Defined in objects.c because it uses static globals if that file */
283extern PyObject *_Py_GetObjects(PyObject *, PyObject *);
284#endif
285
286#ifdef DYNAMIC_EXECUTION_PROFILE
287/* Defined in ceval.c because it uses static globals if that file */
288extern PyObject *_Py_GetDXProfile(PyObject *,  PyObject *);
289#endif
290
291static PyMethodDef sys_methods[] = {
292	/* Might as well keep this in alphabetic order */
293	{"exc_info",	sys_exc_info, 1, exc_info_doc},
294	{"exit",	sys_exit, 0, exit_doc},
295	{"getdefaultencoding", sys_getdefaultencoding, 1, getdefaultencoding_doc},
296#ifdef COUNT_ALLOCS
297	{"getcounts",	sys_getcounts, 1},
298#endif
299#ifdef DYNAMIC_EXECUTION_PROFILE
300	{"getdxp",	_Py_GetDXProfile, 1},
301#endif
302#ifdef Py_TRACE_REFS
303	{"getobjects",	_Py_GetObjects, 1},
304	{"gettotalrefcount", sys_gettotalrefcount, 1},
305#endif
306	{"getrefcount",	sys_getrefcount, 1, getrefcount_doc},
307#ifdef USE_MALLOPT
308	{"mdebug",	sys_mdebug, 1},
309#endif
310	{"setdefaultencoding", sys_setdefaultencoding, 1, setdefaultencoding_doc},
311	{"setcheckinterval",	sys_setcheckinterval, 1, setcheckinterval_doc},
312	{"setprofile",	sys_setprofile, 0, setprofile_doc},
313	{"settrace",	sys_settrace, 0, settrace_doc},
314	{NULL,		NULL}		/* sentinel */
315};
316
317static PyObject *
318list_builtin_module_names()
319{
320	PyObject *list = PyList_New(0);
321	int i;
322	if (list == NULL)
323		return NULL;
324	for (i = 0; PyImport_Inittab[i].name != NULL; i++) {
325		PyObject *name = PyString_FromString(
326			PyImport_Inittab[i].name);
327		if (name == NULL)
328			break;
329		PyList_Append(list, name);
330		Py_DECREF(name);
331	}
332	if (PyList_Sort(list) != 0) {
333		Py_DECREF(list);
334		list = NULL;
335	}
336	if (list) {
337		PyObject *v = PyList_AsTuple(list);
338		Py_DECREF(list);
339		list = v;
340	}
341	return list;
342}
343
344/* XXX This doc string is too long to be a single string literal in VC++ 5.0.
345   Two literals concatenated works just fine.  If you have a K&R compiler
346   or other abomination that however *does* understand longer strings,
347   get rid of the !!! comment in the middle and the quotes that surround it. */
348static char sys_doc[] =
349"This module provides access to some objects used or maintained by the\n\
350interpreter and to functions that interact strongly with the interpreter.\n\
351\n\
352Dynamic objects:\n\
353\n\
354argv -- command line arguments; argv[0] is the script pathname if known\n\
355path -- module search path; path[0] is the script directory, else ''\n\
356modules -- dictionary of loaded modules\n\
357exitfunc -- you may set this to a function to be called when Python exits\n\
358\n\
359stdin -- standard input file object; used by raw_input() and input()\n\
360stdout -- standard output file object; used by the print statement\n\
361stderr -- standard error object; used for error messages\n\
362  By assigning another file object (or an object that behaves like a file)\n\
363  to one of these, it is possible to redirect all of the interpreter's I/O.\n\
364\n\
365last_type -- type of last uncaught exception\n\
366last_value -- value of last uncaught exception\n\
367last_traceback -- traceback of last uncaught exception\n\
368  These three are only available in an interactive session after a\n\
369  traceback has been printed.\n\
370\n\
371exc_type -- type of exception currently being handled\n\
372exc_value -- value of exception currently being handled\n\
373exc_traceback -- traceback of exception currently being handled\n\
374  The function exc_info() should be used instead of these three,\n\
375  because it is thread-safe.\n\
376"
377#ifndef MS_WIN16
378/* Concatenating string here */
379"\n\
380Static objects:\n\
381\n\
382maxint -- the largest supported integer (the smallest is -maxint-1)\n\
383builtin_module_names -- tuple of module names built into this intepreter\n\
384version -- the version of this interpreter as a string\n\
385version_info -- version information as a tuple\n\
386hexversion -- version information encoded as a single integer\n\
387copyright -- copyright notice pertaining to this interpreter\n\
388platform -- platform identifier\n\
389executable -- pathname of this Python interpreter\n\
390prefix -- prefix used to find the Python library\n\
391exec_prefix -- prefix used to find the machine-specific Python library\n\
392dllhandle -- [Windows only] integer handle of the Python DLL\n\
393winver -- [Windows only] version number of the Python DLL\n\
394__stdin__ -- the original stdin; don't use!\n\
395__stdout__ -- the original stdout; don't use!\n\
396__stderr__ -- the original stderr; don't use!\n\
397\n\
398Functions:\n\
399\n\
400exc_info() -- return thread-safe information about the current exception\n\
401exit() -- exit the interpreter by raising SystemExit\n\
402getrefcount() -- return the reference count for an object (plus one :-)\n\
403setcheckinterval() -- control how often the interpreter checks for events\n\
404setprofile() -- set the global profiling function\n\
405settrace() -- set the global debug tracing function\n\
406";
407#endif
408
409PyObject *
410_PySys_Init()
411{
412	extern int fclose(FILE *);
413	PyObject *m, *v, *sysdict;
414	PyObject *sysin, *sysout, *syserr;
415	char *s;
416
417	m = Py_InitModule3("sys", sys_methods, sys_doc);
418	sysdict = PyModule_GetDict(m);
419
420	sysin = PyFile_FromFile(stdin, "<stdin>", "r", NULL);
421	sysout = PyFile_FromFile(stdout, "<stdout>", "w", NULL);
422	syserr = PyFile_FromFile(stderr, "<stderr>", "w", NULL);
423	if (PyErr_Occurred())
424		return NULL;
425	PyDict_SetItemString(sysdict, "stdin", sysin);
426	PyDict_SetItemString(sysdict, "stdout", sysout);
427	PyDict_SetItemString(sysdict, "stderr", syserr);
428	/* Make backup copies for cleanup */
429	PyDict_SetItemString(sysdict, "__stdin__", sysin);
430	PyDict_SetItemString(sysdict, "__stdout__", sysout);
431	PyDict_SetItemString(sysdict, "__stderr__", syserr);
432	Py_XDECREF(sysin);
433	Py_XDECREF(sysout);
434	Py_XDECREF(syserr);
435	PyDict_SetItemString(sysdict, "version",
436			     v = PyString_FromString(Py_GetVersion()));
437	Py_XDECREF(v);
438	PyDict_SetItemString(sysdict, "hexversion",
439			     v = PyInt_FromLong(PY_VERSION_HEX));
440	Py_XDECREF(v);
441	/*
442	 * These release level checks are mutually exclusive and cover
443	 * the field, so don't get too fancy with the pre-processor!
444	 */
445#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA
446	s = "alpha";
447#endif
448#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA
449	s = "beta";
450#endif
451#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA
452	s = "candidate";
453#endif
454#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL
455	s = "final";
456#endif
457	PyDict_SetItemString(sysdict, "version_info",
458			     v = Py_BuildValue("iiisi", PY_MAJOR_VERSION,
459					       PY_MINOR_VERSION,
460					       PY_MICRO_VERSION, s,
461					       PY_RELEASE_SERIAL));
462	Py_XDECREF(v);
463	PyDict_SetItemString(sysdict, "copyright",
464			     v = PyString_FromString(Py_GetCopyright()));
465	Py_XDECREF(v);
466	PyDict_SetItemString(sysdict, "platform",
467			     v = PyString_FromString(Py_GetPlatform()));
468	Py_XDECREF(v);
469	PyDict_SetItemString(sysdict, "executable",
470			     v = PyString_FromString(Py_GetProgramFullPath()));
471	Py_XDECREF(v);
472	PyDict_SetItemString(sysdict, "prefix",
473			     v = PyString_FromString(Py_GetPrefix()));
474	Py_XDECREF(v);
475	PyDict_SetItemString(sysdict, "exec_prefix",
476		   v = PyString_FromString(Py_GetExecPrefix()));
477	Py_XDECREF(v);
478	PyDict_SetItemString(sysdict, "maxint",
479			     v = PyInt_FromLong(PyInt_GetMax()));
480	Py_XDECREF(v);
481	PyDict_SetItemString(sysdict, "builtin_module_names",
482		   v = list_builtin_module_names());
483	Py_XDECREF(v);
484#ifdef MS_COREDLL
485	PyDict_SetItemString(sysdict, "dllhandle",
486			     v = PyLong_FromVoidPtr(PyWin_DLLhModule));
487	Py_XDECREF(v);
488	PyDict_SetItemString(sysdict, "winver",
489			     v = PyString_FromString(PyWin_DLLVersionString));
490	Py_XDECREF(v);
491#endif
492	if (PyErr_Occurred())
493		return NULL;
494	return m;
495}
496
497static PyObject *
498makepathobject(path, delim)
499	char *path;
500	int delim;
501{
502	int i, n;
503	char *p;
504	PyObject *v, *w;
505
506	n = 1;
507	p = path;
508	while ((p = strchr(p, delim)) != NULL) {
509		n++;
510		p++;
511	}
512	v = PyList_New(n);
513	if (v == NULL)
514		return NULL;
515	for (i = 0; ; i++) {
516		p = strchr(path, delim);
517		if (p == NULL)
518			p = strchr(path, '\0'); /* End of string */
519		w = PyString_FromStringAndSize(path, (int) (p - path));
520		if (w == NULL) {
521			Py_DECREF(v);
522			return NULL;
523		}
524		PyList_SetItem(v, i, w);
525		if (*p == '\0')
526			break;
527		path = p+1;
528	}
529	return v;
530}
531
532void
533PySys_SetPath(path)
534	char *path;
535{
536	PyObject *v;
537	if ((v = makepathobject(path, DELIM)) == NULL)
538		Py_FatalError("can't create sys.path");
539	if (PySys_SetObject("path", v) != 0)
540		Py_FatalError("can't assign sys.path");
541	Py_DECREF(v);
542}
543
544static PyObject *
545makeargvobject(argc, argv)
546	int argc;
547	char **argv;
548{
549	PyObject *av;
550	if (argc <= 0 || argv == NULL) {
551		/* Ensure at least one (empty) argument is seen */
552		static char *empty_argv[1] = {""};
553		argv = empty_argv;
554		argc = 1;
555	}
556	av = PyList_New(argc);
557	if (av != NULL) {
558		int i;
559		for (i = 0; i < argc; i++) {
560			PyObject *v = PyString_FromString(argv[i]);
561			if (v == NULL) {
562				Py_DECREF(av);
563				av = NULL;
564				break;
565			}
566			PyList_SetItem(av, i, v);
567		}
568	}
569	return av;
570}
571
572void
573PySys_SetArgv(argc, argv)
574	int argc;
575	char **argv;
576{
577	PyObject *av = makeargvobject(argc, argv);
578	PyObject *path = PySys_GetObject("path");
579	if (av == NULL)
580		Py_FatalError("no mem for sys.argv");
581	if (PySys_SetObject("argv", av) != 0)
582		Py_FatalError("can't assign sys.argv");
583	if (path != NULL) {
584		char *argv0 = argv[0];
585		char *p = NULL;
586		int n = 0;
587		PyObject *a;
588#ifdef HAVE_READLINK
589		char link[MAXPATHLEN+1];
590		char argv0copy[2*MAXPATHLEN+1];
591		int nr = 0;
592		if (argc > 0 && argv0 != NULL)
593			nr = readlink(argv0, link, MAXPATHLEN);
594		if (nr > 0) {
595			/* It's a symlink */
596			link[nr] = '\0';
597			if (link[0] == SEP)
598				argv0 = link; /* Link to absolute path */
599			else if (strchr(link, SEP) == NULL)
600				; /* Link without path */
601			else {
602				/* Must join(dirname(argv0), link) */
603				char *q = strrchr(argv0, SEP);
604				if (q == NULL)
605					argv0 = link; /* argv0 without path */
606				else {
607					/* Must make a copy */
608					strcpy(argv0copy, argv0);
609					q = strrchr(argv0copy, SEP);
610					strcpy(q+1, link);
611					argv0 = argv0copy;
612				}
613			}
614		}
615#endif /* HAVE_READLINK */
616#if SEP == '\\' /* Special case for MS filename syntax */
617		if (argc > 0 && argv0 != NULL) {
618			char *q;
619			p = strrchr(argv0, SEP);
620			/* Test for alternate separator */
621			q = strrchr(p ? p : argv0, '/');
622			if (q != NULL)
623				p = q;
624			if (p != NULL) {
625				n = p + 1 - argv0;
626				if (n > 1 && p[-1] != ':')
627					n--; /* Drop trailing separator */
628			}
629		}
630#else /* All other filename syntaxes */
631		if (argc > 0 && argv0 != NULL)
632			p = strrchr(argv0, SEP);
633		if (p != NULL) {
634			n = p + 1 - argv0;
635#if SEP == '/' /* Special case for Unix filename syntax */
636			if (n > 1)
637				n--; /* Drop trailing separator */
638#endif /* Unix */
639		}
640#endif /* All others */
641		a = PyString_FromStringAndSize(argv0, n);
642		if (a == NULL)
643			Py_FatalError("no mem for sys.path insertion");
644		if (PyList_Insert(path, 0, a) < 0)
645			Py_FatalError("sys.path.insert(0) failed");
646		Py_DECREF(a);
647	}
648	Py_DECREF(av);
649}
650
651
652/* APIs to write to sys.stdout or sys.stderr using a printf-like interface.
653   Adapted from code submitted by Just van Rossum.
654
655   PySys_WriteStdout(format, ...)
656   PySys_WriteStderr(format, ...)
657
658      The first function writes to sys.stdout; the second to sys.stderr.  When
659      there is a problem, they write to the real (C level) stdout or stderr;
660      no exceptions are raised.
661
662      Both take a printf-style format string as their first argument followed
663      by a variable length argument list determined by the format string.
664
665      *** WARNING ***
666
667      The format should limit the total size of the formatted output string to
668      1000 bytes.  In particular, this means that no unrestricted "%s" formats
669      should occur; these should be limited using "%.<N>s where <N> is a
670      decimal number calculated so that <N> plus the maximum size of other
671      formatted text does not exceed 1000 bytes.  Also watch out for "%f",
672      which can print hundreds of digits for very large numbers.
673
674 */
675
676static void
677mywrite(name, fp, format, va)
678	char *name;
679	FILE *fp;
680	const char *format;
681	va_list va;
682{
683	PyObject *file;
684	PyObject *error_type, *error_value, *error_traceback;
685
686	PyErr_Fetch(&error_type, &error_value, &error_traceback);
687	file = PySys_GetObject(name);
688	if (file == NULL || PyFile_AsFile(file) == fp)
689		vfprintf(fp, format, va);
690	else {
691		char buffer[1001];
692		if (vsprintf(buffer, format, va) >= sizeof(buffer))
693		    Py_FatalError("PySys_WriteStdout/err: buffer overrun");
694		if (PyFile_WriteString(buffer, file) != 0) {
695			PyErr_Clear();
696			fputs(buffer, fp);
697		}
698	}
699	PyErr_Restore(error_type, error_value, error_traceback);
700}
701
702void
703#ifdef HAVE_STDARG_PROTOTYPES
704PySys_WriteStdout(const char *format, ...)
705#else
706PySys_WriteStdout(va_alist)
707	va_dcl
708#endif
709{
710	va_list va;
711
712#ifdef HAVE_STDARG_PROTOTYPES
713	va_start(va, format);
714#else
715	char *format;
716	va_start(va);
717	format = va_arg(va, char *);
718#endif
719	mywrite("stdout", stdout, format, va);
720	va_end(va);
721}
722
723void
724#ifdef HAVE_STDARG_PROTOTYPES
725PySys_WriteStderr(const char *format, ...)
726#else
727PySys_WriteStderr(va_alist)
728	va_dcl
729#endif
730{
731	va_list va;
732
733#ifdef HAVE_STDARG_PROTOTYPES
734	va_start(va, format);
735#else
736	char *format;
737	va_start(va);
738	format = va_arg(va, char *);
739#endif
740	mywrite("stderr", stderr, format, va);
741	va_end(va);
742}
743