From be4c0f56a28831f6121ef545ca8afb44a6723022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Thu, 4 Jan 2001 20:30:56 +0000 Subject: [PATCH] Recognize pyc files even if they don't end in pyc. Patch #103067 with modifications as discussed in email. --- Misc/NEWS | 8 ++++++++ Python/pythonrun.c | 40 +++++++++++++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index 8f661061561..d2dfbec7d1b 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -3,6 +3,14 @@ What's New in Python 2.1 alpha 1? Core language, builtins, and interpreter +- The interpreter accepts now bytecode files on the command line even + if they do not have a .pyc or .pyo extension. On Linux, after executing + + echo ':pyc:M::\x87\xc6\x0d\x0a::/usr/local/bin/python:' > /proc/sys/fs/binfmt_misc/register + + any byte code file can be used as an executable (i.e. as an argument + to execve(2)). + - %[xXo] formats of negative Python longs now produce a sign character. In 1.6 and earlier, they never produced a sign, and raised an error if the value of the long was too large diff --git a/Python/pythonrun.c b/Python/pythonrun.c index e29e719d109..45d21dd7720 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -546,6 +546,38 @@ PyRun_SimpleFile(FILE *fp, char *filename) return PyRun_SimpleFileEx(fp, filename, 0); } +/* Check whether a file maybe a pyc file: Look at the extension, + the file type, and, if we may close it, at the first few bytes. */ + +static int +maybe_pyc_file(FILE *fp, char* filename, char* ext, int closeit) +{ + if (strcmp(ext, ".pyc") == 0 || strcmp(ext, ".pyo") == 0) + return 1; + +#ifdef macintosh + /* On a mac, we also assume a pyc file for types 'PYC ' and 'APPL' */ + if (PyMac_getfiletype(filename) == 'PYC ' + || PyMac_getfiletype(filename) == 'APPL') + return 1; +#endif /* macintosh */ + + /* Only look into the file if we are allowed to close it, since + it then should also be seekable. */ + if (closeit) { + /* Read only two bytes of the magic. If the file was opened in + text mode, the bytes 3 and 4 of the magic (\r\n) might not + be read as they are on disk. */ + unsigned int halfmagic = PyImport_GetMagicNumber() & 0xFFFF; + unsigned char buf[2]; + if (fread(buf, 1, 2, fp) == 2 + && (buf[1]<<8 | buf[0]) == halfmagic) + return 1; + fseek(fp, 0, SEEK_SET); + } + return 0; +} + int PyRun_SimpleFileEx(FILE *fp, char *filename, int closeit) { @@ -557,13 +589,7 @@ PyRun_SimpleFileEx(FILE *fp, char *filename, int closeit) return -1; d = PyModule_GetDict(m); ext = filename + strlen(filename) - 4; - if (strcmp(ext, ".pyc") == 0 || strcmp(ext, ".pyo") == 0 -#ifdef macintosh - /* On a mac, we also assume a pyc file for types 'PYC ' and 'APPL' */ - || PyMac_getfiletype(filename) == 'PYC ' - || PyMac_getfiletype(filename) == 'APPL' -#endif /* macintosh */ - ) { + if (maybe_pyc_file(fp, filename, ext, closeit)) { /* Try to run a pyc file. First, re-open in binary */ if (closeit) fclose(fp);