summaryrefslogtreecommitdiffstats
path: root/Modules/posixmodule.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1990-10-14 12:07:46 (GMT)
committerGuido van Rossum <guido@python.org>1990-10-14 12:07:46 (GMT)
commit85a5fbbdfea617f6cc8fae82c9e8c2b5c424436d (patch)
treea1bf57db1c75e2a7029c8f2fad5f8dba4b9ba25c /Modules/posixmodule.c
parentc636014c430620325f8d213e9ba10d925991b8d7 (diff)
downloadcpython-85a5fbbdfea617f6cc8fae82c9e8c2b5c424436d.zip
cpython-85a5fbbdfea617f6cc8fae82c9e8c2b5c424436d.tar.gz
cpython-85a5fbbdfea617f6cc8fae82c9e8c2b5c424436d.tar.bz2
Initial revision
Diffstat (limited to 'Modules/posixmodule.c')
-rw-r--r--Modules/posixmodule.c444
1 files changed, 444 insertions, 0 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
new file mode 100644
index 0000000..0c1a487
--- /dev/null
+++ b/Modules/posixmodule.c
@@ -0,0 +1,444 @@
+/* POSIX module implementation */
+
+#include <stdio.h>
+#include <signal.h>
+#include <string.h>
+#include <setjmp.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#ifdef SYSV
+#include <dirent.h>
+#define direct dirent
+#else
+#include <sys/dir.h>
+#endif
+
+#include "PROTO.h"
+#include "object.h"
+#include "intobject.h"
+#include "stringobject.h"
+#include "tupleobject.h"
+#include "listobject.h"
+#include "dictobject.h"
+#include "methodobject.h"
+#include "moduleobject.h"
+#include "objimpl.h"
+#include "import.h"
+#include "sigtype.h"
+#include "modsupport.h"
+#include "errors.h"
+
+extern char *strerror();
+
+#ifdef AMOEBA
+#define NO_LSTAT
+#endif
+
+
+/* Return a dictionary corresponding to the POSIX environment table */
+
+extern char **environ;
+
+static object *
+convertenviron()
+{
+ object *d;
+ char **e;
+ d = newdictobject();
+ if (d == NULL)
+ return NULL;
+ if (environ == NULL)
+ return d;
+ /* XXX This part ignores errors */
+ for (e = environ; *e != NULL; e++) {
+ object *v;
+ char *p = strchr(*e, '=');
+ if (p == NULL)
+ continue;
+ v = newstringobject(p+1);
+ if (v == NULL)
+ continue;
+ *p = '\0';
+ (void) dictinsert(d, *e, v);
+ *p = '=';
+ DECREF(v);
+ }
+ return d;
+}
+
+
+static object *PosixError; /* Exception posix.error */
+
+/* Set a POSIX-specific error from errno, and return NULL */
+
+static object *
+posix_error()
+{
+ object *v = newtupleobject(2);
+ if (v != NULL) {
+ settupleitem(v, 0, newintobject((long)errno));
+ settupleitem(v, 1, newstringobject(strerror(errno)));
+ }
+ err_setval(PosixError, v);
+ if (v != NULL)
+ DECREF(v);
+ return NULL;
+}
+
+
+/* POSIX generic methods */
+
+static object *
+posix_1str(args, func)
+ object *args;
+ int (*func) FPROTO((const char *));
+{
+ object *path1;
+ if (!getstrarg(args, &path1))
+ return NULL;
+ if ((*func)(getstringvalue(path1)) < 0)
+ return posix_error();
+ INCREF(None);
+ return None;
+}
+
+static object *
+posix_2str(args, func)
+ object *args;
+ int (*func) FPROTO((const char *, const char *));
+{
+ object *path1, *path2;
+ if (!getstrstrarg(args, &path1, &path2))
+ return NULL;
+ if ((*func)(getstringvalue(path1), getstringvalue(path2)) < 0)
+ return posix_error();
+ INCREF(None);
+ return None;
+}
+
+static object *
+posix_strint(args, func)
+ object *args;
+ int (*func) FPROTO((const char *, int));
+{
+ object *path1;
+ int i;
+ if (!getstrintarg(args, &path1, &i))
+ return NULL;
+ if ((*func)(getstringvalue(path1), i) < 0)
+ return posix_error();
+ INCREF(None);
+ return None;
+}
+
+static object *
+posix_do_stat(self, args, statfunc)
+ object *self;
+ object *args;
+ int (*statfunc) FPROTO((const char *, struct stat *));
+{
+ struct stat st;
+ object *path;
+ object *v;
+ if (!getstrarg(args, &path))
+ return NULL;
+ if ((*statfunc)(getstringvalue(path), &st) != 0)
+ return posix_error();
+ v = newtupleobject(10);
+ if (v == NULL)
+ return NULL;
+ errno = 0;
+#define SET(i, st_member) settupleitem(v, i, newintobject((long)st.st_member))
+ SET(0, st_mode);
+ SET(1, st_ino);
+ SET(2, st_dev);
+ SET(3, st_nlink);
+ SET(4, st_uid);
+ SET(5, st_gid);
+ SET(6, st_size);
+ SET(7, st_atime);
+ SET(8, st_mtime);
+ SET(9, st_ctime);
+#undef SET
+ if (errno != 0) {
+ DECREF(v);
+ return err_nomem();
+ }
+ return v;
+}
+
+
+/* POSIX methods */
+
+static object *
+posix_chdir(self, args)
+ object *self;
+ object *args;
+{
+ extern int chdir PROTO((const char *));
+ return posix_1str(args, chdir);
+}
+
+static object *
+posix_chmod(self, args)
+ object *self;
+ object *args;
+{
+ extern int chmod PROTO((const char *, mode_t));
+ return posix_strint(args, chmod);
+}
+
+static object *
+posix_getcwd(self, args)
+ object *self;
+ object *args;
+{
+ char buf[1026];
+ extern char *getcwd PROTO((char *, int));
+ if (!getnoarg(args))
+ return NULL;
+ if (getcwd(buf, sizeof buf) == NULL)
+ return posix_error();
+ return newstringobject(buf);
+}
+
+static object *
+posix_link(self, args)
+ object *self;
+ object *args;
+{
+ extern int link PROTO((const char *, const char *));
+ return posix_2str(args, link);
+}
+
+static object *
+posix_listdir(self, args)
+ object *self;
+ object *args;
+{
+ object *name, *d, *v;
+ DIR *dirp;
+ struct direct *ep;
+ if (!getstrarg(args, &name))
+ return NULL;
+ if ((dirp = opendir(getstringvalue(name))) == NULL)
+ return posix_error();
+ if ((d = newlistobject(0)) == NULL) {
+ closedir(dirp);
+ return NULL;
+ }
+ while ((ep = readdir(dirp)) != NULL) {
+ v = newstringobject(ep->d_name);
+ if (v == NULL) {
+ DECREF(d);
+ d = NULL;
+ break;
+ }
+ if (addlistitem(d, v) != 0) {
+ DECREF(v);
+ DECREF(d);
+ d = NULL;
+ break;
+ }
+ DECREF(v);
+ }
+ closedir(dirp);
+ return d;
+}
+
+static object *
+posix_mkdir(self, args)
+ object *self;
+ object *args;
+{
+ extern int mkdir PROTO((const char *, mode_t));
+ return posix_strint(args, mkdir);
+}
+
+static object *
+posix_rename(self, args)
+ object *self;
+ object *args;
+{
+ extern int rename PROTO((const char *, const char *));
+ return posix_2str(args, rename);
+}
+
+static object *
+posix_rmdir(self, args)
+ object *self;
+ object *args;
+{
+ extern int rmdir PROTO((const char *));
+ return posix_1str(args, rmdir);
+}
+
+static object *
+posix_stat(self, args)
+ object *self;
+ object *args;
+{
+ extern int stat PROTO((const char *, struct stat *));
+ return posix_do_stat(self, args, stat);
+}
+
+static object *
+posix_system(self, args)
+ object *self;
+ object *args;
+{
+ object *command;
+ int sts;
+ if (!getstrarg(args, &command))
+ return NULL;
+ sts = system(getstringvalue(command));
+ return newintobject((long)sts);
+}
+
+static object *
+posix_umask(self, args)
+ object *self;
+ object *args;
+{
+ int i;
+ if (!getintarg(args, &i))
+ return NULL;
+ i = umask(i);
+ if (i < 0)
+ return posix_error();
+ return newintobject((long)i);
+}
+
+static object *
+posix_unlink(self, args)
+ object *self;
+ object *args;
+{
+ extern int unlink PROTO((const char *));
+ return posix_1str(args, unlink);
+}
+
+static object *
+posix_utimes(self, args)
+ object *self;
+ object *args;
+{
+ object *path;
+ struct timeval tv[2];
+ if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
+ err_badarg();
+ return NULL;
+ }
+ if (!getstrarg(gettupleitem(args, 0), &path) ||
+ !getlonglongargs(gettupleitem(args, 1),
+ &tv[0].tv_sec, &tv[1].tv_sec))
+ return NULL;
+ tv[0].tv_usec = tv[1].tv_usec = 0;
+ if (utimes(getstringvalue(path), tv) < 0)
+ return posix_error();
+ INCREF(None);
+ return None;
+}
+
+#ifdef NO_GETCWD
+
+/* Quick hack to get posix.getcwd() working for pure BSD 4.3 */
+/* XXX This assumes MAXPATHLEN = 1024 !!! */
+
+static char *
+getcwd(buf, size)
+ char *buf;
+ int size;
+{
+ extern char *getwd PROTO((char *));
+ register char *ret = getwd(buf);
+ if (ret == NULL)
+ errno = EACCES; /* Most likely error */
+ return ret;
+}
+
+#endif /* NO_GETCWD */
+
+
+#ifndef NO_LSTAT
+
+static object *
+posix_lstat(self, args)
+ object *self;
+ object *args;
+{
+ extern int lstat PROTO((const char *, struct stat *));
+ return posix_do_stat(self, args, lstat);
+}
+
+static object *
+posix_readlink(self, args)
+ object *self;
+ object *args;
+{
+ char buf[1024]; /* XXX Should use MAXPATHLEN */
+ object *path;
+ int n;
+ if (!getstrarg(args, &path))
+ return NULL;
+ n = readlink(getstringvalue(path), buf, sizeof buf);
+ if (n < 0)
+ return posix_error();
+ return newsizedstringobject(buf, n);
+}
+
+static object *
+posix_symlink(self, args)
+ object *self;
+ object *args;
+{
+ extern int symlink PROTO((const char *, const char *));
+ return posix_2str(args, symlink);
+}
+
+#endif /* NO_LSTAT */
+
+
+static struct methodlist posix_methods[] = {
+ {"chdir", posix_chdir},
+ {"chmod", posix_chmod},
+ {"getcwd", posix_getcwd},
+ {"link", posix_link},
+ {"listdir", posix_listdir},
+ {"mkdir", posix_mkdir},
+ {"rename", posix_rename},
+ {"rmdir", posix_rmdir},
+ {"stat", posix_stat},
+ {"system", posix_system},
+ {"umask", posix_umask},
+ {"unlink", posix_unlink},
+ {"utimes", posix_utimes},
+#ifndef NO_LSTAT
+ {"lstat", posix_lstat},
+ {"readlink", posix_readlink},
+ {"symlink", posix_symlink},
+#endif
+ {NULL, NULL} /* Sentinel */
+};
+
+
+void
+initposix()
+{
+ object *m, *d, *v;
+
+ m = initmodule("posix", posix_methods);
+ d = getmoduledict(m);
+
+ /* Initialize posix.environ dictionary */
+ v = convertenviron();
+ if (v == NULL || dictinsert(d, "environ", v) != 0)
+ fatal("can't define posix.environ");
+ DECREF(v);
+
+ /* Initialize posix.error exception */
+ PosixError = newstringobject("posix.error");
+ if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
+ fatal("can't define posix.error");
+}