diff options
author | Guido van Rossum <guido@python.org> | 1990-10-14 12:07:46 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1990-10-14 12:07:46 (GMT) |
commit | 85a5fbbdfea617f6cc8fae82c9e8c2b5c424436d (patch) | |
tree | a1bf57db1c75e2a7029c8f2fad5f8dba4b9ba25c /Modules/posixmodule.c | |
parent | c636014c430620325f8d213e9ba10d925991b8d7 (diff) | |
download | cpython-85a5fbbdfea617f6cc8fae82c9e8c2b5c424436d.zip cpython-85a5fbbdfea617f6cc8fae82c9e8c2b5c424436d.tar.gz cpython-85a5fbbdfea617f6cc8fae82c9e8c2b5c424436d.tar.bz2 |
Initial revision
Diffstat (limited to 'Modules/posixmodule.c')
-rw-r--r-- | Modules/posixmodule.c | 444 |
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"); +} |