[pypy-svn] r18844 - pypy/dist/pypy/translator/c/src
tismer at codespeak.net
tismer at codespeak.net
Sun Oct 23 19:54:00 CEST 2005
Author: tismer
Date: Sun Oct 23 19:53:58 2005
New Revision: 18844
Added:
pypy/dist/pypy/translator/c/src/ll_osdefs.h (contents, props changed)
Modified:
pypy/dist/pypy/translator/c/src/ll_os.h
Log:
added support for os.listdir() for windows.
Unfortunately, the opendir/readdir/closedir interface
does not fit perfectly, so I wrote these functions in
ll_os.h. Not sure whether it is worth rewriting the
interface to be able to express this windows-specific
stuff from higher levels.
* implemented opendir, readdir, closedir in C
* extracted the bulk of definitions from posixmodule.c into ll_osdefs.h
Comments are welcome. Anyway, things compile under Windows, again :-)
Modified: pypy/dist/pypy/translator/c/src/ll_os.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/ll_os.h (original)
+++ pypy/dist/pypy/translator/c/src/ll_os.h Sun Oct 23 19:53:58 2005
@@ -66,6 +66,8 @@
#ifndef PYPY_NOT_MAIN_FILE
+#include "ll_osdefs.h"
+
int LL_os_open(RPyString *filename, int flag, int mode)
{
/* XXX unicode_file_names */
@@ -223,7 +225,12 @@
}
void LL_os_mkdir(RPyString * path, int mode) {
+#if defined(MS_WIN64) || defined(MS_WINDOWS)
+ /* no mode support on Windows */
+ int error = mkdir(RPyString_AsString(path));
+#else
int error = mkdir(RPyString_AsString(path), mode);
+#endif
if (error != 0) {
RPYTHON_RAISE_OSERROR(errno);
}
@@ -283,52 +290,118 @@
/******************** opendir/readdir/closedir ********************/
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#define NAMLEN(dirent) strlen((dirent)->d_name)
-#else
-#if defined(__WATCOMC__) && !defined(__QNX__)
-#include <direct.h>
-#define NAMLEN(dirent) strlen((dirent)->d_name)
-#else
-#define dirent direct
-#define NAMLEN(dirent) (dirent)->d_namlen
-#endif
-#ifdef HAVE_SYS_NDIR_H
-#include <sys/ndir.h>
-#endif
-#ifdef HAVE_SYS_DIR_H
-#include <sys/dir.h>
-#endif
-#ifdef HAVE_NDIR_H
-#include <ndir.h>
-#endif
-#endif
+#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
+
+/* emulation of opendir, readdir, closedir */
+
+/*
+ the problem is that Windows does not have something like
+ opendir. Instead, FindFirstFile creates a handle and
+ yields the first entry found. Furthermore, we need
+ to mangle the filename.
+ To keep the rpython interface, we need to buffer the
+ first result and let readdir return this first time.
+ Drawback of this approach: we need to use malloc,
+ and the way I'm emulating dirent is maybe somewhat hackish.
+
+ XXX we are lacking unicode support, completely.
+ Might need a different interface.
+ */
+
+#undef dirent
+
+typedef struct dirent {
+ HANDLE hFind;
+ WIN32_FIND_DATA FileData;
+ char *d_name; /* faking dirent */
+ int first_done;
+} DIR;
+
+static DIR *opendir(char *dirname)
+{
+ DIR *d = malloc(sizeof(DIR));
+ int lng = strlen(dirname);
+ char *mangled = strcpy(_alloca(lng + 5), dirname);
+ char *p = mangled + lng;
+
+ if (d == NULL)
+ return NULL;
+
+ if (lng && p[-1] == '\\')
+ p--;
+ strcpy(p, "\\*.*");
+
+ d->first_done = 0;
+ d->hFind = FindFirstFile(mangled, &d->FileData);
+ if (d->hFind == INVALID_HANDLE_VALUE) {
+ d->d_name = NULL;
+ errno = GetLastError();
+ if (errno == ERROR_FILE_NOT_FOUND) {
+ errno = 0;
+ return d;
+ }
+ free(d);
+ return NULL;
+ }
+ d->d_name = d->FileData.cFileName;
+ return d;
+}
+
+static struct dirent *readdir(DIR *d)
+{
+ if (!d->first_done) {
+ d->first_done = 1;
+ return d;
+ }
+ if (!FindNextFile(d->hFind, &d->FileData))
+ {
+ errno = GetLastError();
+ if (errno == ERROR_NO_MORE_FILES)
+ errno = 0;
+ return NULL;
+ }
+ d->d_name = d->FileData.cFileName;
+ return d;
+}
+
+static int closedir(DIR *d)
+{
+ HANDLE hFind = d->hFind;
+
+ free(d);
+ if (FindClose(hFind) == 0) {
+ errno = GetLastError();
+ return -1;
+ }
+ return 0;
+}
+
+#endif /* defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) */
struct RPyOpaque_DIR *LL_os_opendir(RPyString *dirname)
{
- DIR *dir = opendir(RPyString_AsString(dirname));
- if (dir == NULL)
- RPYTHON_RAISE_OSERROR(errno);
- return (struct RPyOpaque_DIR *) dir;
+ DIR *dir = opendir(RPyString_AsString(dirname));
+ if (dir == NULL)
+ RPYTHON_RAISE_OSERROR(errno);
+ return (struct RPyOpaque_DIR *) dir;
}
RPyString *LL_os_readdir(struct RPyOpaque_DIR *dir)
{
- struct dirent *d;
- errno = 0;
- d = readdir((DIR *) dir);
- if (d != NULL)
- return RPyString_FromString(d->d_name);
- if (errno)
- RPYTHON_RAISE_OSERROR(errno);
- return NULL;
+ struct dirent *d;
+ errno = 0;
+ d = readdir((DIR *) dir);
+ if (d != NULL)
+ return RPyString_FromString(d->d_name);
+ if (errno)
+ RPYTHON_RAISE_OSERROR(errno);
+ return NULL;
}
void LL_os_closedir(struct RPyOpaque_DIR *dir)
{
- if (closedir((DIR *) dir) < 0)
- RPYTHON_RAISE_OSERROR(errno);
+ if (closedir((DIR *) dir) < 0)
+ RPYTHON_RAISE_OSERROR(errno);
}
#endif /* PYPY_NOT_MAIN_FILE */
Added: pypy/dist/pypy/translator/c/src/ll_osdefs.h
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/c/src/ll_osdefs.h Sun Oct 23 19:53:58 2005
@@ -0,0 +1,282 @@
+/************************************************************/
+ /*** C header subsection: definition part extracted
+ from posixmodule.c ***/
+
+/* this file is only meant to be included by ll_os.h */
+
+#if defined(PYOS_OS2)
+#define INCL_DOS
+#define INCL_DOSERRORS
+#define INCL_DOSPROCESS
+#define INCL_NOPMAPI
+#include <os2.h>
+#if defined(PYCC_GCC)
+#include <ctype.h>
+#include <io.h>
+#include <stdio.h>
+#include <process.h>
+#endif
+#include "osdefs.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h> /* For WNOHANG */
+#endif
+
+#include <signal.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
+
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+
+#ifdef HAVE_SYSEXITS_H
+#include <sysexits.h>
+#endif /* HAVE_SYSEXITS_H */
+
+#ifdef HAVE_SYS_LOADAVG_H
+#include <sys/loadavg.h>
+#endif
+
+/* Various compilers have only certain posix functions */
+/* XXX Gosh I wish these were all moved into pyconfig.h */
+#if defined(PYCC_VACPP) && defined(PYOS_OS2)
+#include <process.h>
+#else
+#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
+#define HAVE_GETCWD 1
+#define HAVE_OPENDIR 1
+#define HAVE_SYSTEM 1
+#if defined(__OS2__)
+#define HAVE_EXECV 1
+#define HAVE_WAIT 1
+#endif
+#include <process.h>
+#else
+#ifdef __BORLANDC__ /* Borland compiler */
+#define HAVE_EXECV 1
+#define HAVE_GETCWD 1
+#define HAVE_OPENDIR 1
+#define HAVE_PIPE 1
+#define HAVE_POPEN 1
+#define HAVE_SYSTEM 1
+#define HAVE_WAIT 1
+#else
+#ifdef _MSC_VER /* Microsoft compiler */
+#define HAVE_GETCWD 1
+#define HAVE_SPAWNV 1
+#define HAVE_EXECV 1
+#define HAVE_PIPE 1
+#define HAVE_POPEN 1
+#define HAVE_SYSTEM 1
+#define HAVE_CWAIT 1
+#define HAVE_FSYNC 1
+#define fsync _commit
+#else
+#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
+/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
+#else /* all other compilers */
+/* Unix functions that the configure script doesn't check for */
+#define HAVE_EXECV 1
+#define HAVE_FORK 1
+#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
+#define HAVE_FORK1 1
+#endif
+#define HAVE_GETCWD 1
+#define HAVE_GETEGID 1
+#define HAVE_GETEUID 1
+#define HAVE_GETGID 1
+#define HAVE_GETPPID 1
+#define HAVE_GETUID 1
+#define HAVE_KILL 1
+#define HAVE_OPENDIR 1
+#define HAVE_PIPE 1
+#ifndef __rtems__
+#define HAVE_POPEN 1
+#endif
+#define HAVE_SYSTEM 1
+#define HAVE_WAIT 1
+#define HAVE_TTYNAME 1
+#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
+#endif /* _MSC_VER */
+#endif /* __BORLANDC__ */
+#endif /* ! __WATCOMC__ || __QNX__ */
+#endif /* ! __IBMC__ */
+
+#ifndef _MSC_VER
+
+#if defined(__sgi)&&_COMPILER_VERSION>=700
+/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
+ (default) */
+extern char *ctermid_r(char *);
+#endif
+
+#ifndef HAVE_UNISTD_H
+#if defined(PYCC_VACPP)
+extern int mkdir(char *);
+#else
+#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
+extern int mkdir(const char *);
+#else
+extern int mkdir(const char *, mode_t);
+#endif
+#endif
+#if defined(__IBMC__) || defined(__IBMCPP__)
+extern int chdir(char *);
+extern int rmdir(char *);
+#else
+extern int chdir(const char *);
+extern int rmdir(const char *);
+#endif
+#ifdef __BORLANDC__
+extern int chmod(const char *, int);
+#else
+extern int chmod(const char *, mode_t);
+#endif
+extern int chown(const char *, uid_t, gid_t);
+extern char *getcwd(char *, int);
+extern char *strerror(int);
+extern int link(const char *, const char *);
+extern int rename(const char *, const char *);
+extern int stat(const char *, struct stat *);
+extern int unlink(const char *);
+extern int pclose(FILE *);
+#ifdef HAVE_SYMLINK
+extern int symlink(const char *, const char *);
+#endif /* HAVE_SYMLINK */
+#ifdef HAVE_LSTAT
+extern int lstat(const char *, struct stat *);
+#endif /* HAVE_LSTAT */
+#endif /* !HAVE_UNISTD_H */
+
+#endif /* !_MSC_VER */
+
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif /* HAVE_UTIME_H */
+
+#ifdef HAVE_SYS_UTIME_H
+#include <sys/utime.h>
+#define HAVE_UTIME_H /* pretend we do for the rest of this file */
+#endif /* HAVE_SYS_UTIME_H */
+
+#ifdef HAVE_SYS_TIMES_H
+#include <sys/times.h>
+#endif /* HAVE_SYS_TIMES_H */
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif /* HAVE_SYS_PARAM_H */
+
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif /* HAVE_SYS_UTSNAME_H */
+
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+#if defined(__WATCOMC__) && !defined(__QNX__)
+#include <direct.h>
+#define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+#define dirent direct
+#define NAMLEN(dirent) (dirent)->d_namlen
+#endif
+#ifdef HAVE_SYS_NDIR_H
+#include <sys/ndir.h>
+#endif
+#ifdef HAVE_SYS_DIR_H
+#include <sys/dir.h>
+#endif
+#ifdef HAVE_NDIR_H
+#include <ndir.h>
+#endif
+#endif
+
+#ifdef _MSC_VER
+#include <direct.h>
+#include <io.h>
+#include <process.h>
+#include "osdefs.h"
+#define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
+#include <windows.h>
+#include <shellapi.h> /* for ShellExecute() */
+#define popen _popen
+#define pclose _pclose
+#endif /* _MSC_VER */
+
+#if defined(PYCC_VACPP) && defined(PYOS_OS2)
+#include <io.h>
+#endif /* OS2 */
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif /* MAXPATHLEN */
+
+#ifdef UNION_WAIT
+/* Emulate some macros on systems that have a union instead of macros */
+
+#ifndef WIFEXITED
+#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
+#endif
+
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
+#endif
+
+#ifndef WTERMSIG
+#define WTERMSIG(u_wait) ((u_wait).w_termsig)
+#endif
+
+#endif /* UNION_WAIT */
+
+/* Don't use the "_r" form if we don't need it (also, won't have a
+ prototype for it, at least on Solaris -- maybe others as well?). */
+#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
+#define USE_CTERMID_R
+#endif
+
+#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
+#define USE_TMPNAM_R
+#endif
+
+/* choose the appropriate stat and fstat functions and return structs */
+#undef STAT
+#if defined(MS_WIN64) || defined(MS_WINDOWS)
+# define STAT _stati64
+# define FSTAT _fstati64
+# define STRUCT_STAT struct _stati64
+#else
+# define STAT stat
+# define FSTAT fstat
+# define STRUCT_STAT struct stat
+#endif
+
+#if defined(MAJOR_IN_MKDEV)
+#include <sys/mkdev.h>
+#else
+#if defined(MAJOR_IN_SYSMACROS)
+#include <sys/sysmacros.h>
+#endif
+#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
+#include <sys/mkdev.h>
+#endif
+#endif
+
+/* Return a dictionary corresponding to the POSIX environment table */
+#ifdef WITH_NEXT_FRAMEWORK
+/* On Darwin/MacOSX a shared library or framework has no access to
+** environ directly, we must obtain it with _NSGetEnviron().
+*/
+#include <crt_externs.h>
+static char **environ;
+#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
+extern char **environ;
+#endif /* !_MSC_VER */
More information about the Pypy-commit
mailing list