mirror of
https://github.com/python/cpython.git
synced 2025-11-02 03:01:58 +00:00
Initial revision
This commit is contained in:
parent
c636014c43
commit
85a5fbbdfe
78 changed files with 13589 additions and 0 deletions
444
Modules/posixmodule.c
Normal file
444
Modules/posixmodule.c
Normal file
|
|
@ -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");
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue