| 
									
										
										
										
											1997-07-19 21:33:10 +00:00
										 |  |  | /* A multi-threaded telnet-like server that gives a Python prompt.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Usage: pysvr [port] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For security reasons, it only accepts requests from the current host. | 
					
						
							|  |  |  | This can still be insecure, but restricts violations from people who | 
					
						
							|  |  |  | can log in on your machine.  Use with caution! | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <ctype.h>
 | 
					
						
							|  |  |  | #include <errno.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <sys/types.h>
 | 
					
						
							|  |  |  | #include <sys/socket.h>
 | 
					
						
							|  |  |  | #include <netinet/in.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <pthread.h>
 | 
					
						
							| 
									
										
										
										
											2000-11-03 08:18:37 +00:00
										 |  |  | #include <getopt.h>
 | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* XXX Umpfh.
 | 
					
						
							|  |  |  |    Python.h defines a typedef destructor, which conflicts with pthread.h. | 
					
						
							|  |  |  |    So Python.h must be included after pthread.h. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <Python.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-10-05 22:16:07 +00:00
										 |  |  | extern int Py_VerboseFlag; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | #ifndef PORT
 | 
					
						
							|  |  |  | #define PORT 4000
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct workorder { | 
					
						
							|  |  |  | 	int conn; | 
					
						
							|  |  |  | 	struct sockaddr_in addr; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Forward */ | 
					
						
							|  |  |  | static void init_python(void); | 
					
						
							|  |  |  | static void usage(void); | 
					
						
							|  |  |  | static void oprogname(void); | 
					
						
							|  |  |  | static void main_thread(int); | 
					
						
							|  |  |  | static void create_thread(int, struct sockaddr_in *); | 
					
						
							|  |  |  | static void *service_thread(struct workorder *); | 
					
						
							|  |  |  | static void run_interpreter(FILE *, FILE *); | 
					
						
							|  |  |  | static int run_command(char *, PyObject *); | 
					
						
							| 
									
										
										
										
											1997-08-02 02:02:22 +00:00
										 |  |  | static void ps(void); | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static char *progname = "pysvr"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-08-02 02:02:22 +00:00
										 |  |  | static PyThreadState *gtstate; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | main(int argc, char **argv) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int port = PORT; | 
					
						
							|  |  |  | 	int c; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (argc > 0 && argv[0] != NULL && argv[0][0] != '\0') | 
					
						
							|  |  |  | 		progname = argv[0]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-10-05 22:16:07 +00:00
										 |  |  | 	while ((c = getopt(argc, argv, "v")) != EOF) { | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | 		switch (c) { | 
					
						
							| 
									
										
										
										
											1999-10-05 22:16:07 +00:00
										 |  |  | 		case 'v': | 
					
						
							|  |  |  | 			Py_VerboseFlag++; | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | 		default: | 
					
						
							|  |  |  | 			usage(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (optind < argc) { | 
					
						
							|  |  |  | 		if (optind+1 < argc) { | 
					
						
							|  |  |  | 			oprogname(); | 
					
						
							|  |  |  | 			fprintf(stderr, "too many arguments\n"); | 
					
						
							|  |  |  | 			usage(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		port = atoi(argv[optind]); | 
					
						
							|  |  |  | 		if (port <= 0) { | 
					
						
							|  |  |  | 			fprintf(stderr, "bad port (%s)\n", argv[optind]); | 
					
						
							|  |  |  | 			usage(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	main_thread(port); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fprintf(stderr, "Bye.\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	exit(0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char usage_line[] = "usage: %s [port]\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2000-07-22 19:25:51 +00:00
										 |  |  | usage(void) | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	fprintf(stderr, usage_line, progname); | 
					
						
							|  |  |  | 	exit(2); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | main_thread(int port) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1997-08-02 02:02:22 +00:00
										 |  |  | 	int sock, conn, size, i; | 
					
						
							| 
									
										
										
										
											1997-07-19 21:33:10 +00:00
										 |  |  | 	struct sockaddr_in addr, clientaddr; | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	sock = socket(PF_INET, SOCK_STREAM, 0); | 
					
						
							|  |  |  | 	if (sock < 0) { | 
					
						
							|  |  |  | 		oprogname(); | 
					
						
							|  |  |  | 		perror("can't create socket"); | 
					
						
							|  |  |  | 		exit(1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-12-25 04:48:51 +00:00
										 |  |  | #ifdef SO_REUSEADDR
 | 
					
						
							|  |  |  | 	i = 1; | 
					
						
							|  |  |  | 	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &i, sizeof i); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-08-02 02:02:22 +00:00
										 |  |  | 	memset((char *)&addr, '\0', sizeof addr); | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | 	addr.sin_family = AF_INET; | 
					
						
							|  |  |  | 	addr.sin_port = htons(port); | 
					
						
							|  |  |  | 	addr.sin_addr.s_addr = 0L; | 
					
						
							|  |  |  | 	if (bind(sock, (struct sockaddr *)&addr, sizeof addr) < 0) { | 
					
						
							|  |  |  | 		oprogname(); | 
					
						
							|  |  |  | 		perror("can't bind socket to address"); | 
					
						
							|  |  |  | 		exit(1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (listen(sock, 5) < 0) { | 
					
						
							|  |  |  | 		oprogname(); | 
					
						
							|  |  |  | 		perror("can't listen on socket"); | 
					
						
							|  |  |  | 		exit(1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fprintf(stderr, "Listening on port %d...\n", port); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-08-02 02:02:22 +00:00
										 |  |  | 	for (i = 0; ; i++) { | 
					
						
							| 
									
										
										
										
											1997-07-19 21:33:10 +00:00
										 |  |  | 		size = sizeof clientaddr; | 
					
						
							| 
									
										
										
										
											1997-08-02 02:02:22 +00:00
										 |  |  | 		memset((char *) &clientaddr, '\0', size); | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | 		conn = accept(sock, (struct sockaddr *) &clientaddr, &size); | 
					
						
							|  |  |  | 		if (conn < 0) { | 
					
						
							|  |  |  | 			oprogname(); | 
					
						
							|  |  |  | 			perror("can't accept connection from socket"); | 
					
						
							|  |  |  | 			exit(1); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-07-19 21:33:10 +00:00
										 |  |  | 		size = sizeof addr; | 
					
						
							| 
									
										
										
										
											1997-08-02 02:02:22 +00:00
										 |  |  | 		memset((char *) &addr, '\0', size); | 
					
						
							| 
									
										
										
										
											1997-07-19 21:33:10 +00:00
										 |  |  | 		if (getsockname(conn, (struct sockaddr *)&addr, &size) < 0) { | 
					
						
							|  |  |  | 			oprogname(); | 
					
						
							|  |  |  | 			perror("can't get socket name of connection"); | 
					
						
							|  |  |  | 			exit(1); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (clientaddr.sin_addr.s_addr != addr.sin_addr.s_addr) { | 
					
						
							|  |  |  | 			oprogname(); | 
					
						
							|  |  |  | 			perror("connection from non-local host refused"); | 
					
						
							|  |  |  | 			fprintf(stderr, "(addr=%lx, clientaddr=%lx)\n", | 
					
						
							|  |  |  | 				ntohl(addr.sin_addr.s_addr), | 
					
						
							|  |  |  | 				ntohl(clientaddr.sin_addr.s_addr)); | 
					
						
							|  |  |  | 			close(conn); | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1997-08-02 02:02:22 +00:00
										 |  |  | 		if (i == 4) { | 
					
						
							|  |  |  | 			close(conn); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | 		create_thread(conn, &clientaddr); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-08-02 02:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	close(sock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gtstate) { | 
					
						
							|  |  |  | 		PyEval_AcquireThread(gtstate); | 
					
						
							|  |  |  | 		gtstate = NULL; | 
					
						
							|  |  |  | 		Py_Finalize(); | 
					
						
							| 
									
										
										
										
											1999-10-05 22:16:07 +00:00
										 |  |  | 		/* And a second time, just because we can. */ | 
					
						
							|  |  |  | 		Py_Finalize(); /* This should be harmless. */ | 
					
						
							| 
									
										
										
										
											1997-08-02 02:02:22 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	exit(0); | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | create_thread(int conn, struct sockaddr_in *addr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct workorder *work; | 
					
						
							|  |  |  | 	pthread_t tdata; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	work = malloc(sizeof(struct workorder)); | 
					
						
							|  |  |  | 	if (work == NULL) { | 
					
						
							|  |  |  | 		oprogname(); | 
					
						
							|  |  |  | 		fprintf(stderr, "out of memory for thread.\n"); | 
					
						
							|  |  |  | 		close(conn); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	work->conn = conn; | 
					
						
							|  |  |  | 	work->addr = *addr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	init_python(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (pthread_create(&tdata, NULL, (void *)service_thread, work) < 0) { | 
					
						
							|  |  |  | 		oprogname(); | 
					
						
							|  |  |  | 		perror("can't create new thread"); | 
					
						
							|  |  |  | 		close(conn); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (pthread_detach(tdata) < 0) { | 
					
						
							|  |  |  | 		oprogname(); | 
					
						
							|  |  |  | 		perror("can't detach from thread"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyThreadState *the_tstate; | 
					
						
							|  |  |  | static PyInterpreterState *the_interp; | 
					
						
							|  |  |  | static PyObject *the_builtins; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2000-07-22 19:25:51 +00:00
										 |  |  | init_python(void) | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-08-02 02:02:22 +00:00
										 |  |  | 	if (gtstate) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	Py_Initialize(); /* Initialize the interpreter */ | 
					
						
							|  |  |  | 	PyEval_InitThreads(); /* Create (and acquire) the interpreter lock */ | 
					
						
							|  |  |  | 	gtstate = PyEval_SaveThread(); /* Release the thread state */ | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void * | 
					
						
							|  |  |  | service_thread(struct workorder *work) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	FILE *input, *output; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fprintf(stderr, "Start thread for connection %d.\n", work->conn); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-08-02 02:02:22 +00:00
										 |  |  | 	ps(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | 	input = fdopen(work->conn, "r"); | 
					
						
							|  |  |  | 	if (input == NULL) { | 
					
						
							|  |  |  | 		oprogname(); | 
					
						
							|  |  |  | 		perror("can't create input stream"); | 
					
						
							|  |  |  | 		goto done; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	output = fdopen(work->conn, "w"); | 
					
						
							|  |  |  | 	if (output == NULL) { | 
					
						
							|  |  |  | 		oprogname(); | 
					
						
							|  |  |  | 		perror("can't create output stream"); | 
					
						
							|  |  |  | 		fclose(input); | 
					
						
							|  |  |  | 		goto done; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	setvbuf(input, NULL, _IONBF, 0); | 
					
						
							|  |  |  | 	setvbuf(output, NULL, _IONBF, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	run_interpreter(input, output); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fclose(input); | 
					
						
							|  |  |  | 	fclose(output); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   done: | 
					
						
							|  |  |  | 	fprintf(stderr, "End thread for connection %d.\n", work->conn); | 
					
						
							|  |  |  | 	close(work->conn); | 
					
						
							|  |  |  | 	free(work); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2000-07-22 19:25:51 +00:00
										 |  |  | oprogname(void) | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int save = errno; | 
					
						
							|  |  |  | 	fprintf(stderr, "%s: ", progname); | 
					
						
							|  |  |  | 	errno = save; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | run_interpreter(FILE *input, FILE *output) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyThreadState *tstate; | 
					
						
							|  |  |  | 	PyObject *new_stdin, *new_stdout; | 
					
						
							| 
									
										
										
										
											1997-07-25 20:59:55 +00:00
										 |  |  | 	PyObject *mainmod, *globals; | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | 	char buffer[1000]; | 
					
						
							|  |  |  | 	char *p, *q; | 
					
						
							|  |  |  | 	int n, end; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-07-25 20:59:55 +00:00
										 |  |  | 	PyEval_AcquireLock(); | 
					
						
							|  |  |  | 	tstate = Py_NewInterpreter(); | 
					
						
							|  |  |  | 	if (tstate == NULL) { | 
					
						
							|  |  |  | 		fprintf(output, "Sorry -- can't create an interpreter\n"); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-07-25 20:59:55 +00:00
										 |  |  | 	mainmod = PyImport_AddModule("__main__"); | 
					
						
							|  |  |  | 	globals = PyModule_GetDict(mainmod); | 
					
						
							|  |  |  | 	Py_INCREF(globals); | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	new_stdin = PyFile_FromFile(input, "<socket-in>", "r", NULL); | 
					
						
							|  |  |  | 	new_stdout = PyFile_FromFile(output, "<socket-out>", "w", NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-08-02 02:02:22 +00:00
										 |  |  | 	PySys_SetObject("stdin", new_stdin); | 
					
						
							|  |  |  | 	PySys_SetObject("stdout", new_stdout); | 
					
						
							|  |  |  | 	PySys_SetObject("stderr", new_stdout); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | 	for (n = 1; !PyErr_Occurred(); n++) { | 
					
						
							|  |  |  | 		Py_BEGIN_ALLOW_THREADS | 
					
						
							|  |  |  | 		fprintf(output, "%d> ", n); | 
					
						
							|  |  |  | 		p = fgets(buffer, sizeof buffer, input); | 
					
						
							|  |  |  | 		Py_END_ALLOW_THREADS | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (p == NULL) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		if (p[0] == '\377' && p[1] == '\354') | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		q = strrchr(p, '\r'); | 
					
						
							|  |  |  | 		if (q && q[1] == '\n' && q[2] == '\0') { | 
					
						
							|  |  |  | 			*q++ = '\n'; | 
					
						
							|  |  |  | 			*q++ = '\0'; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		while (*p && isspace(*p)) | 
					
						
							|  |  |  | 			p++; | 
					
						
							|  |  |  | 		if (p[0] == '#' || p[0] == '\0') | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		end = run_command(buffer, globals); | 
					
						
							|  |  |  | 		if (end < 0) | 
					
						
							|  |  |  | 			PyErr_Print(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (end) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Py_XDECREF(globals); | 
					
						
							|  |  |  | 	Py_XDECREF(new_stdin); | 
					
						
							|  |  |  | 	Py_XDECREF(new_stdout); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-07-25 20:59:55 +00:00
										 |  |  | 	Py_EndInterpreter(tstate); | 
					
						
							|  |  |  | 	PyEval_ReleaseLock(); | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	fprintf(output, "Goodbye!\n"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | run_command(char *buffer, PyObject *globals) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *m, *d, *v; | 
					
						
							| 
									
										
										
										
											1997-07-25 20:59:55 +00:00
										 |  |  | 	fprintf(stderr, "run_command: %s", buffer); | 
					
						
							|  |  |  | 	if (strchr(buffer, '\n') == NULL) | 
					
						
							|  |  |  | 		fprintf(stderr, "\n"); | 
					
						
							| 
									
										
										
										
											1997-07-19 21:00:47 +00:00
										 |  |  | 	v = PyRun_String(buffer, Py_single_input, globals, globals); | 
					
						
							|  |  |  | 	if (v == NULL) { | 
					
						
							|  |  |  | 		if (PyErr_Occurred() == PyExc_SystemExit) { | 
					
						
							|  |  |  | 			PyErr_Clear(); | 
					
						
							|  |  |  | 			return 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		PyErr_Print(); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	Py_DECREF(v); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											1997-08-02 02:02:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2000-07-22 19:25:51 +00:00
										 |  |  | ps(void) | 
					
						
							| 
									
										
										
										
											1997-08-02 02:02:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	char buffer[100]; | 
					
						
							|  |  |  | 	sprintf(buffer, "ps -l -p %d </dev/null | tail +2l\n", getpid()); | 
					
						
							|  |  |  | 	system(buffer); | 
					
						
							|  |  |  | } |