home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************\
- ** **
- ** AMIGA module implementation, for SAS/C version 6.58 **
- ** **
- ** Made by Irmen de Jong (ijong@gak.nl) **
- ** **
- ** 27-mar-96: Added a lot of AmiTCP functions! **
- ** 2-apr-96: Many small fixes & enhancements. **
- ** 11-apr-96: Totally rewritten the environment handling. **
- ** Now creates 4 separate dictionaries. **
- ** Fixed link(), added symlink() and readlink(). **
- ** 29-may-96: Added filenote() and fullpath() **
- ** 11-jun-96: Moved filenote() to doslib/SetComment **
- ** 12-jun-96: Removed execv **
- ** 29-Aug-96: fixed getcwd(), some minor errno fixes **
- ** 26-Dec-96: upgraded to 1.4: added putenv(), remove() **
- ** fixed mkdir: default protbits (0777) **
- ** 6-Apr-97: fixed bug in readlink (lock was incorrect) **
- ** 6-Nov-97: added uname() **
- ** **
- ** Adapted from posixmodule.c; implements as much of the **
- ** functionality of this module as possible. **
- ** **
- ** **
- ** TO DO: Implement execv(e) and threads (if possible). **
- ** **
- ** NOTE: Don't forget __io2errno conversion!!!!!!!!!!!!!!!! **
- ** **
- \**************************************************************/
-
-
- #include "allobjects.h"
- #include "modsupport.h"
- #include "ceval.h"
- #include "sysmodule.h"
- #include "osdefs.h"
-
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <stat.h>
- #include <dos.h>
- #include <sys/types.h>
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <dos/dosextens.h>
- #include <dos/var.h>
- #include <dos/dostags.h>
- #include <exec/execbase.h>
-
- #include "mytime.h" /* For clock_t on some systems */
-
- #ifdef HAVE_UTIME_H
- #include <utime.h>
- #endif
-
- #include <dirent.h>
- #define NAMLEN(dirent) strlen((dirent)->d_name)
-
- #ifdef AMITCP
- #include <clib/netlib_protos.h>
- #endif
-
- /* defined elsewhere */
- extern int setenv(const char *name, const char *value, int overwrite);
-
- /* Prototypes for functions defined in modules/amigamodule.c */
-
- /***
- static int _static_inline_select(int , fd_set * , fd_set * , fd_set * , struct compatible_timeval * );
- static unsigned char * _static_inline_inet_ntoa(struct in_addr );
- static struct in_addr _static_inline_inet_makeaddr(int , int );
- static unsigned long _static_inline_inet_lnaof(struct in_addr );
- static unsigned long _static_inline_inet_netof(struct in_addr );
- ***/
-
-
-
- /* Return a dictionary corresponding to the AmigaDOS environment table. */
- /* That is, scan ENV: for global environment variables. */
- /* The local shell environment variables are put into another table. */
- /* (changed 31-mar-96) */
-
- static int
- convertenviron(PyObject **glob, PyObject **loc,
- PyObject **both, PyObject **aliases)
- {
- BPTR dlok;
- struct FileInfoBlock __aligned fib;
- PyObject *v;
- char buf[200];
- struct LocalVar *lvar;
- struct List *localvars;
-
- *glob=newdictobject();
- *loc=newdictobject();
- *both=newdictobject();
- *aliases=newdictobject();
-
- if(!*glob || !*loc || !*both || !*aliases)
- {
- if(*glob) DECREF(*glob);
- if(*loc) DECREF(*loc);
- if(*both) DECREF(*both);
- if(*aliases) DECREF(*aliases);
- return 0;
- }
-
- /* Read global vars from ENV: */
- /* Put them in 'glob' and in 'both'. */
-
- if(dlok=Lock("ENV:",ACCESS_READ))
- {
- if(Examine(dlok,&fib))
- {
- while(ExNext(dlok,&fib))
- {
- if(fib.fib_DirEntryType<0)
- {
- int len=GetVar(fib.fib_FileName,buf,200,GVF_GLOBAL_ONLY);
- if(len>=0 && (v=newstringobject(buf)))
- {
- dictinsert(*glob,fib.fib_FileName,v);
- dictinsert(*both,fib.fib_FileName,v);
- DECREF(v);
- }
- }
- }
- }
- }
-
- if(dlok) UnLock(dlok);
-
- /* Scan the local shell environment, including "RC" and "Result2"! */
- /* Put shell vars in 'loc' and 'both', and aliases in 'aliases'. */
- /* Because of the fact that the inserting of local vars into 'both' */
- /* happens AFTER the insertion of global vars, the formor overwrite */
- /* the latter, and thus have higher priority (as it should be). */
-
- localvars = (struct List*) &((struct Process*)FindTask(0))->pr_LocalVars;
-
- if(!IsListEmpty(localvars))
- {
- lvar = (struct LocalVar*) localvars->lh_Head;
- do {
- strncpy(buf,lvar->lv_Value,lvar->lv_Len);
- buf[lvar->lv_Len]=0;
-
- if(v=newstringobject(buf))
- {
- if(lvar->lv_Node.ln_Type==LV_VAR)
- {
- dictinsert(*loc,lvar->lv_Node.ln_Name,v);
- dictinsert(*both,lvar->lv_Node.ln_Name,v);
- }
- else if(lvar->lv_Node.ln_Type==LV_ALIAS)
- dictinsert(*aliases,lvar->lv_Node.ln_Name,v);
-
- DECREF(v);
- }
- } while((lvar=(struct LocalVar*)lvar->lv_Node.ln_Succ)->lv_Node.ln_Succ);
- }
-
-
- return 1;
- }
-
-
- static object *AmigaError; /* Exception amiga.error */
-
- /* Set a Amiga-specific error from errno, and return NULL */
-
- static object * amiga_error(void)
- {
- return err_errno(AmigaError);
- }
-
-
- /* AMIGA generic methods */
-
- static object *
- amiga_1str(object *args, int (*func)(const char *))
- {
- char *path1;
- int res;
- if (!getargs(args, "s", &path1))
- return NULL;
- BGN_SAVE
- res = (*func)(path1);
- END_SAVE
- if (res < 0)
- return amiga_error();
- INCREF(None);
- return None;
- }
-
- static object *
- amiga_2str(object *args, int (*func)(const char *, const char *))
- {
- char *path1, *path2;
- int res;
- if (!getargs(args, "(ss)", &path1, &path2))
- return NULL;
- BGN_SAVE
- res = (*func)(path1, path2);
- END_SAVE
- if (res < 0)
- return amiga_error();
- INCREF(None);
- return None;
- }
-
- static object *
- amiga_strint(object *args, int (*func)(const char *, int))
- {
- char *path;
- int i;
- int res;
- if (!getargs(args, "(si)", &path, &i))
- return NULL;
- BGN_SAVE
- res = (*func)(path, i);
- END_SAVE
- if (res < 0)
- return amiga_error();
- INCREF(None);
- return None;
- }
-
- static object *
- amiga_strintint(object *args, int (*func)(const char *, int, int))
- {
- char *path;
- int i,i2;
- int res;
- if (!getargs(args, "(sii)", &path, &i, &i2))
- return NULL;
- BGN_SAVE
- res = (*func)(path, i, i2);
- END_SAVE
- if (res < 0)
- return amiga_error();
- INCREF(None);
- return None;
- }
-
- static object *
- amiga_do_stat(object *self, object *args, int (*statfunc)(const char *, struct stat *))
- {
- struct stat st;
- char *path;
- int res;
- if (!getargs(args, "s", &path))
- return NULL;
- BGN_SAVE
- res = (*statfunc)(path, &st);
- END_SAVE
- if (res != 0)
- return amiga_error();
- return mkvalue("(llllllllll)",
- (long)st.st_mode,
- (long)st.st_ino,
- (long)st.st_dev,
- (long)st.st_nlink,
- (long)st.st_uid,
- (long)st.st_gid,
- (long)st.st_size,
- (long)st.st_atime,
- (long)st.st_mtime,
- (long)st.st_ctime);
- }
-
-
- /* AMIGA methods */
-
- static object *
- amiga_chdir(object *self, object *args)
- {
- return amiga_1str(args, chdir);
- }
-
- static object *
- amiga_chmod(object *self, object *args)
- {
- return amiga_strint(args, chmod);
- }
-
- #ifdef HAVE_CHOWN
- static object *
- amiga_chown(object *self, object *args)
- {
- return amiga_strintint(args, chown);
- }
- #endif /* HAVE_CHOWN */
-
- #ifdef HAVE_GETCWD
- static object *
- amiga_getcwd(object *self, object *args)
- {
- char buf[MAXPATHLEN];
- char *res;
- if (!getnoarg(args))
- return NULL;
- BGN_SAVE
- res = getcwd(buf, sizeof buf);
- END_SAVE
- if (res == NULL)
- return amiga_error();
- return newstringobject(buf);
- }
- #endif
-
- /** Amiga implementation of link(2) (2-apr-96) **/
-
- static BOOL checkIt(char *from, BPTR to, BOOL root)
- {
- struct FileInfoBlock __aligned fib;
-
- if(Examine(to,&fib))
- {
- if(fib.fib_EntryType>0)
- {
- // directory! Check some things (loops etc)
- char* pp;
- char p;
- BPTR fromLock,temp;
-
- // only superuser may link directories
- if(!root)
- {
- errno=EPERM; return FALSE;
- }
-
- pp = PathPart(from);
- p = *pp;
- *pp = 0;
- fromLock=Lock(from,SHARED_LOCK);
- *pp=p;
-
- if(fromLock)
- {
- do {
- if(SameLock(fromLock,to)==LOCK_SAME)
- {
- UnLock(fromLock);
- errno = ELOOP;
- return FALSE; // link loop
- }
-
- temp = fromLock;
- fromLock = ParentDir(fromLock);
- UnLock(temp);
- } while (fromLock);
-
- return TRUE; // dir, OK.
- }
- else errno=__io2errno(_OSERR=IoErr());
- }
- else return TRUE; // file, OK.
- }
- else errno=__io2errno(_OSERR=IoErr());
-
- return FALSE;
- }
-
- /* LINK: make hardlink from 'from' to 'to' (to must exist, from is new) */
- /* 'from' may not be a directory if you are not the super-user. */
- /* 0=ok, -1=err */
- static int link(const char *to, const char *from)
- {
- BOOL root;
- BPTR toLock;
-
- /* are we superuser? */
- if (!checkusergrouplib())
- {
- err_clear();
- root=TRUE; /* can't tell... so be root */
- }
- else if(getuid()==0) root = TRUE;
- else root=FALSE;
-
- if(toLock=Lock(to,SHARED_LOCK))
- {
- if(checkIt(from,toLock,root))
- {
- if(MakeLink(from,(LONG)toLock,FALSE))
- {
- UnLock(toLock);
- return 0;
- }
- else errno=__io2errno(_OSERR=IoErr());
- }
- UnLock(toLock);
- }
- else errno=__io2errno(_OSERR=IoErr());
-
- return -1;
- }
-
-
- static object *
- amiga_link(object *self, object *args)
- {
- return amiga_2str(args, link);
- }
-
- static object *
- amiga_listdir(object *self, object *args)
- {
- BPTR dlok;
- char *name;
- struct FileInfoBlock __aligned fib;
- PyObject *d;
-
- if (!getargs(args, "s", &name)) return NULL;
-
- if ((d = newlistobject(0)) == NULL) return NULL;
-
- if(dlok=Lock(name,ACCESS_READ))
- {
- if(Examine(dlok,&fib))
- {
- while(ExNext(dlok,&fib))
- {
- PyObject *v = PyString_FromString(fib.fib_FileName);
- if(v==NULL)
- {
- Py_DECREF(d); d=NULL; break;
- }
-
- if(addlistitem(d,v)!=0)
- {
- Py_DECREF(v); Py_DECREF(d); d=NULL; break;
- }
- Py_DECREF(v);
- }
- }
- UnLock(dlok);
- }
-
- if(IoErr()==ERROR_NO_MORE_ENTRIES) return d;
-
- Py_DECREF(d);
- errno=__io2errno(_OSERR=IoErr());
- return amiga_error();
- }
-
- /** custom mkdir() implementation **/
- /** This version actually sets protection bits **/
-
- static int my_mkdir(const char* path, int p)
- {
- if(checkusergrouplib()) p &= ~getumask();
- else err_clear();
-
- if(0==mkdir(path))
- {
- return chmod(path,p);
- }
- return -1;
- }
-
- static object *
- amiga_mkdir(object *self, object *args)
- {
- int res;
- char *path;
- int mode = 0777;
- if (!newgetargs(args, "s|i", &path, &mode)) return NULL;
- BGN_SAVE
- res = my_mkdir(path, mode);
- END_SAVE
- if (res < 0) return amiga_error();
- INCREF(None); return None;
- }
-
- static object *
- amiga_rename(object *self, object *args)
- {
- return amiga_2str(args, rename);
- }
-
- static object *
- amiga_rmdir(object *self, object *args)
- {
- return amiga_1str(args, rmdir);
- }
-
- static object *
- amiga_stat(object *self, object *args)
- {
- return amiga_do_stat(self, args, stat);
- }
-
- static object *
- amiga_system(object *self, object *args)
- {
- char *command;
- long sts;
- if (!getargs(args, "s", &command))
- return NULL;
- BGN_SAVE
- sts = system(command);
- END_SAVE
- return newintobject(sts);
- }
-
- #ifdef AMITCP
- static object *
- amiga_umask(object *self, object *args)
- {
- int i;
- if (!checkusergrouplib()) return NULL;
- if (!getintarg(args, &i))
- return NULL;
- i = umask(i);
- if (i < 0)
- return amiga_error();
- return newintobject((long)i);
- }
- #endif
-
- #define _UNAME_BUFLEN 32
- struct _utsname {
- char sysname[_UNAME_BUFLEN];
- char nodename[_UNAME_BUFLEN];
- char release[_UNAME_BUFLEN];
- char version[_UNAME_BUFLEN];
- char machine[_UNAME_BUFLEN];
- };
-
- static object *
- amiga_uname(object *self, object *args)
- {
- struct _utsname u;
- object *v;
- int res;
- if (!getnoarg(args))
- return NULL;
- strcpy(u.sysname,"AmigaDOS");
- strcpy(u.version,"1");
- strcpy(u.machine,"m68k");
- BGN_SAVE
- if (!checkbsdsocketlib())
- {
- char *v;
- err_clear();
- res=0; v=getenv("HOSTNAME");
- if(v) strcpy(u.nodename, v);
- else strcpy(u.nodename, "localhost");
- }
- else res = gethostname(u.nodename, _UNAME_BUFLEN-1);
- if(res>=0)
- {
- LONG ver_major = SysBase->LibNode.lib_Version;
- LONG ver_minor = SysBase->SoftVer;
- sprintf (u.release, "%d.%d", ver_major,ver_minor);
- if(ver_major<36)
- strcpy(u.version,"1");
- else if(ver_major<39)
- strcpy(u.version,"2");
- else
- strcpy(u.version,"3");
- }
- END_SAVE
- if (res < 0)
- return amiga_error();
- return mkvalue("(sssss)",
- u.sysname,
- u.nodename,
- u.release,
- u.version,
- u.machine);
- }
-
- static object *
- amiga_unlink(object *self, object *args)
- {
- return amiga_1str(args, unlink);
- }
-
- #ifdef AMITCP
- static object *
- amiga_utime(object *self, object *args)
- {
- char *path;
- long atime, mtime;
- int res;
-
- #ifdef HAVE_UTIME_H
- struct utimbuf buf;
- #define ATIME buf.actime
- #define MTIME buf.modtime
- #define UTIME_ARG &buf
- #else /* HAVE_UTIME_H */
- time_t buf[2];
- #define ATIME buf[0]
- #define MTIME buf[1]
- #define UTIME_ARG buf
- #endif /* HAVE_UTIME_H */
-
- if (!getargs(args, "(s(ll))", &path, &atime, &mtime))
- return NULL;
- ATIME = atime;
- MTIME = mtime;
- BGN_SAVE
- res = utime(path, UTIME_ARG);
- END_SAVE
- if (res < 0)
- return amiga_error();
- INCREF(None);
- return None;
- #undef UTIME_ARG
- #undef ATIME
- #undef MTIME
- }
- #endif
-
-
- /* Process operations */
-
- /* XXX Removed _exit. You are VERY STUPID if you used this. (2-apr-96) */
-
- /* XXX Removed execv. You must use system/exit combination instead. */
- /* Maybe one day I'll implement a REAL execv ?? */
-
-
-
- #ifdef HAVE_GETEGID
- static object *
- amiga_getegid(object *self, object *args)
- {
- if (!checkusergrouplib()) return NULL;
- if (!getnoarg(args))
- return NULL;
- return newintobject((long)getegid());
- }
- #endif
-
- #ifdef HAVE_GETEUID
- static object *
- amiga_geteuid(object *self, object *args)
- {
- if (!checkusergrouplib()) return NULL;
- if (!getnoarg(args))
- return NULL;
- return newintobject((long)geteuid());
- }
- #endif
-
- #ifdef HAVE_GETGID
- static object *
- amiga_getgid(object *self, object *args)
- {
- if (!checkusergrouplib()) return NULL;
- if (!getnoarg(args))
- return NULL;
- return newintobject((long)getgid());
- }
- #endif
-
- static object *
- amiga_getpid(object *self, object *args)
- {
- if (!getnoarg(args))
- return NULL;
- return newintobject((long)FindTask(0));
- }
-
- #ifdef HAVE_GETPGRP
- static object *
- amiga_getpgrp(object *self, object *args)
- {
- if (!checkusergrouplib()) return NULL;
- if (!getnoarg(args))
- return NULL;
- #ifdef GETPGRP_HAVE_ARG
- return newintobject((long)getpgrp(0));
- #else /* GETPGRP_HAVE_ARG */
- return newintobject((long)getpgrp());
- #endif /* GETPGRP_HAVE_ARG */
- }
- #endif /* HAVE_GETPGRP */
-
- #ifdef HAVE_SETPGRP
- static object *
- amiga_setpgrp(object *self, object *args)
- {
- if (!checkusergrouplib()) return NULL;
- if (!getnoarg(args))
- return NULL;
- #ifdef SETPGRP_HAVE_ARG
- if (setpgrp(0, 0) < 0)
- #else /* SETPGRP_HAVE_ARG */
- if (setpgrp() < 0)
- #endif /* SETPGRP_HAVE_ARG */
- return amiga_error();
- INCREF(None);
- return None;
- }
-
- #endif /* HAVE_SETPGRP */
-
- #ifdef HAVE_GETPPID
- static object *
- amiga_getppid(object *self, object *args)
- {
- if (!getnoarg(args))
- return NULL;
- return newintobject((long)getppid());
- }
- #endif
-
- #ifdef HAVE_GETUID
- static object *
- amiga_getuid(object *self, object *args)
- {
- if (!checkusergrouplib()) return NULL;
- if (!getnoarg(args))
- return NULL;
- return newintobject((long)getuid());
- }
- #endif
-
- FILE *popen(const char *command, const char *type)
- {
- char file[50];
-
- FILE *fh;
-
- static int num = 1;
-
- if((type[0]!='r') && (type[0]!='w'))
- {
- errno=EINVAL;
- return 0;
- }
-
- sprintf(file,"PIPE:Py_%ld_%ld",num++,FindTask(0));
-
- if(fh=fopen(file,type))
- {
- BPTR fh2;
- LONG mode;
-
- if(type[0]=='r') mode=MODE_NEWFILE;
- if(type[0]=='w') mode=MODE_OLDFILE;
- if(fh2=Open(file,mode))
- {
- BPTR fh3;
- if(type[0]=='r')
- {
- /* execute command with output to fh */
- fh3=Open("*",MODE_OLDFILE); /* should use CONSOLE: */
- if(fh3 && (0==SystemTags(command,SYS_Asynch,TRUE,SYS_Output,fh2,
- SYS_Input,fh3,TAG_DONE)))
- {
- return fh;
- }
- }
- else /** if(type[0]=='w') **/
- {
- /* execute command with input from fh */
- fh3=Open("*",MODE_NEWFILE); /* should use CONSOLE: */
- if(fh3 && (0==SystemTags(command,SYS_Asynch,TRUE,SYS_Input,fh2,
- SYS_Output,fh3,TAG_DONE)))
- {
- return fh;
- }
- }
- fclose(fh); Close(fh2); if(fh3) Close(fh3);
- errno=EAGAIN;
- return 0;
- }
- fclose(fh);
- }
- errno=ENOENT;
- return 0;
- }
-
- int pclose(FILE *stream)
- {
- if(stream)
- {
- fclose(stream);
- return 0;
- }
- errno=EINVAL;
- return -1;
- }
-
- static object *
- amiga_popen(object *self, object *args)
- {
- char *name;
- char *mode = "r";
- int bufsize = -1;
- FILE *fp;
- object *f;
- if (!newgetargs(args, "s|si", &name, &mode, &bufsize))
- return NULL;
- BGN_SAVE
- fp = popen(name, mode);
- END_SAVE
- if (fp == NULL)
- return amiga_error();
- f = newopenfileobject(fp, name, mode, pclose);
- if (f != NULL)
- setfilebufsize(f, bufsize);
- return f;
- }
-
- #ifdef HAVE_SETUID
- static object *
- amiga_setuid(object *self, object *args)
- {
- int uid;
- if (!checkusergrouplib()) return NULL;
- if (!getargs(args, "i", &uid))
- return NULL;
- if (setuid(uid) < 0)
- return amiga_error();
- INCREF(None);
- return None;
- }
- #endif /* HAVE_SETUID */
-
- #ifdef HAVE_SETGID
- static object *
- amiga_setgid(object *self, object *args)
- {
- int gid;
- if (!checkusergrouplib()) return NULL;
- if (!getargs(args, "i", &gid))
- return NULL;
- if (setgid(gid) < 0)
- return amiga_error();
- INCREF(None);
- return None;
- }
- #endif /* HAVE_SETGID */
-
- static object *
- amiga_lstat(object *self, object *args)
- {
- #ifdef HAVE_LSTAT
- return amiga_do_stat(self, args, lstat);
- #else /* !HAVE_LSTAT */
- return amiga_do_stat(self, args, stat);
- #endif /* !HAVE_LSTAT */
- }
-
- static object *
- amiga_readlink(object *self, object *args)
- {
- char buf[MAXPATHLEN];
- char *path;
- struct MsgPort *port;
- struct stat st;
-
- if (!getargs(args, "s", &path)) return NULL;
-
- if(!(port=DeviceProc(path)))
- {
- err_setstr(IOError,"no deviceproc"); return NULL;
- }
-
- errno=0;
-
- BGN_SAVE
- if(lstat(path,&st)>=0)
- {
- if(S_ISLNK(st.st_mode))
- {
- char c;
- BPTR dirlock;
- BPTR olddir;
- char *p;
- char *link;
-
- p = PathPart(path);
- link = FilePart(path);
- c = *p; *p='\0';
- dirlock=Lock(path,ACCESS_READ); *p=c;
- if(dirlock)
- {
- olddir=CurrentDir(dirlock);
-
- if(!ReadLink(port,dirlock,link,buf,sizeof(buf)))
- errno=__io2errno(_OSERR=IoErr());
-
- dirlock=CurrentDir(olddir);
- UnLock(dirlock);
- }
- else errno=__io2errno(_OSERR=IoErr());
- }
- else errno=EINVAL;
- }
-
- END_SAVE
- if(errno!=0) return amiga_error();
- else return newstringobject(buf);
- }
-
- /** Amiga implementation of symlink(2) (12-Apr-96) **/
- static int symlink(const char *to, const char *from)
- {
- /* symbolic link 'from' is created to 'to' */
- /* 0=ok, else -1 + errno */
-
- BPTR toLock;
-
- if(toLock=Lock(to,SHARED_LOCK))
- {
- if(checkIt(from,toLock,TRUE))
- {
- UnLock(toLock);
- if(MakeLink(from,(LONG)to,TRUE)) return 0;
- else errno=__io2errno(_OSERR=IoErr());
- }
- else UnLock(toLock);
- }
- else errno=__io2errno(_OSERR=IoErr());
-
- return -1;
- }
-
- static object *
- amiga_symlink(object *self, object *args)
- {
- return amiga_2str(args, symlink);
- }
-
- #ifdef HAVE_SETSID
- static object *
- amiga_setsid(object *self, object *args)
- {
- if (!checkusergrouplib()) return NULL;
- if (!getnoarg(args))
- return NULL;
- if ((int)setsid() < 0)
- return amiga_error();
- INCREF(None);
- return None;
- }
- #endif /* HAVE_SETSID */
-
- #ifdef HAVE_SETPGID
- static object *
- amiga_setpgid(object *self, object *args)
- {
- int pid, pgrp;
- if (!getargs(args, "(ii)", &pid, &pgrp))
- return NULL;
- if (setpgid(pid, pgrp) < 0)
- return amiga_error();
- INCREF(None);
- return None;
- }
- #endif /* HAVE_SETPGID */
-
- /* Functions acting on file descriptors */
-
- static object *
- amiga_open(object *self, object *args)
- {
- char *file;
- int flag;
- int mode = 0777;
- int fd;
- if (!getargs(args, "(si)", &file, &flag)) {
- err_clear();
- if (!getargs(args, "(sii)", &file, &flag, &mode))
- return NULL;
- }
- BGN_SAVE
- fd = open(file, flag, mode);
- END_SAVE
- if (fd < 0)
- return amiga_error();
- return newintobject((long)fd);
- }
-
- static object *
- amiga_close(object *self, object *args)
- {
- int fd, res;
- if (!getargs(args, "i", &fd))
- return NULL;
- BGN_SAVE
- res = close(fd);
- END_SAVE
- if (res < 0)
- return amiga_error();
- INCREF(None);
- return None;
- }
-
- #ifdef AMITCP
- static object *
- amiga_dup(object *self, object *args)
- {
- int fd;
- if (!checkbsdsocketlib()) { err_clear(); errno=EIO; return amiga_error(); }
- if (!getargs(args, "i", &fd))
- return NULL;
- BGN_SAVE
- fd = dup(fd);
- END_SAVE
- if (fd < 0)
- return amiga_error();
- return newintobject((long)fd);
- }
-
- static object *
- amiga_dup2(object *self, object *args)
- {
- int fd, fd2, res;
- if (!checkbsdsocketlib()) { err_clear(); errno=EIO; return amiga_error(); }
- if (!getargs(args, "(ii)", &fd, &fd2))
- return NULL;
- BGN_SAVE
- res = dup2(fd, fd2);
- END_SAVE
- if (res < 0)
- return amiga_error();
- INCREF(None);
- return None;
- }
- #endif
-
- static object *
- amiga_lseek(object *self, object *args)
- {
- int fd, how;
- long pos, res;
- if (!getargs(args, "(ili)", &fd, &pos, &how))
- return NULL;
- #ifdef SEEK_SET
- /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
- switch (how) {
- case 0: how = SEEK_SET; break;
- case 1: how = SEEK_CUR; break;
- case 2: how = SEEK_END; break;
- }
- #endif /* SEEK_END */
- BGN_SAVE
- res = lseek(fd, pos, how);
- END_SAVE
- if (res < 0)
- return amiga_error();
- return newintobject(res);
- }
-
- static object *
- amiga_read(object *self, object *args)
- {
- int fd, size;
- object *buffer;
- if (!getargs(args, "(ii)", &fd, &size))
- return NULL;
- buffer = newsizedstringobject((char *)NULL, size);
- if (buffer == NULL)
- return NULL;
- BGN_SAVE
- size = read(fd, getstringvalue(buffer), size);
- END_SAVE
- if (size < 0) {
- DECREF(buffer);
- return amiga_error();
- }
- resizestring(&buffer, size);
- return buffer;
- }
-
- static object *
- amiga_write(object *self, object *args)
- {
- int fd, size;
- char *buffer;
- if (!getargs(args, "(is#)", &fd, &buffer, &size))
- return NULL;
- BGN_SAVE
- size = write(fd, buffer, size);
- END_SAVE
- if (size < 0)
- return amiga_error();
- return newintobject((long)size);
- }
-
- static object *
- amiga_fstat(object *self, object *args)
- {
- int fd;
- struct stat st;
- int res;
- if (!getargs(args, "i", &fd))
- return NULL;
- BGN_SAVE
- res = fstat(fd, &st);
- END_SAVE
- if (res != 0)
- return amiga_error();
- return mkvalue("(llllllllll)",
- (long)st.st_mode,
- (long)st.st_ino,
- (long)st.st_dev,
- (long)st.st_nlink,
- (long)st.st_uid,
- (long)st.st_gid,
- (long)st.st_size,
- (long)st.st_atime,
- (long)st.st_mtime,
- (long)st.st_ctime);
- }
-
- static object *
- amiga_fdopen(object *self, object *args)
- {
- int fd;
- char *mode = "r";
- int bufsize = -1;
- FILE *fp;
- object *f;
- if (!newgetargs(args, "i|si", &fd, &mode, &bufsize))
- return NULL;
- BGN_SAVE
- fp = fdopen(fd, mode);
- END_SAVE
- if (fp == NULL)
- return amiga_error();
- f = newopenfileobject(fp, "(fdopen)", mode, fclose);
- if (f != NULL)
- setfilebufsize(f, bufsize);
- return f;
- }
-
- #if 0
- /*** XXX pipe() is useless without fork() or threads ***/
- /*** TODO: guess what.. implement threads! ***/
- static int pipe(int *fildes)
- {
- /* 0=ok, -1=err, errno=EMFILE,ENFILE,EFAULT */
- char buf[50];
- static int num = 1;
-
- sprintf(buf,"PIPE:Py%ld_%ld",FindTask(0),num++);
- fildes[0]=open(buf,O_RDONLY,0);
- if(fildes[0]>0)
- {
- fildes[1]=open(buf,O_WRONLY|O_CREAT,FIBF_OTR_READ|FIBF_OTR_WRITE);
- if(fildes[1]>0)
- {
- return 0;
- }
- close(fildes[0]);
- }
- return -1;
- }
-
- static object *
- amiga_pipe(object *self, object *args)
- {
- int fds[2];
- int res;
- if (!getargs(args, ""))
- return NULL;
- BGN_SAVE
- res = pipe(fds);
- END_SAVE
- if (res != 0)
- return amiga_error();
- return mkvalue("(ii)", fds[0], fds[1]);
- }
- #endif
-
-
- static object *
- amiga_fullpath(object *self, object *args)
- {
- BOOL ok=FALSE;
- BPTR lk;
- char *path;
- char buf[MAXPATHLEN];
-
- if (!newgetargs(args, "s", &path)) return NULL;
-
- BGN_SAVE
- if(lk=Lock(path,SHARED_LOCK))
- {
- ok=NameFromLock(lk,buf,sizeof(buf));
- UnLock(lk);
- }
- END_SAVE
-
- if(!ok)
- {
- errno=__io2errno(_OSERR=IoErr());
- return amiga_error();
- }
- else return newstringobject(buf);
- }
-
- static object *amiga_putenv(object *self, object *args)
- {
- char *s1, *s2;
-
- if (!newgetargs(args, "ss", &s1, &s2)) return NULL;
- if(setenv(s1,s2,1))
- {
- amiga_error(); return NULL;
- }
-
- INCREF(None); return None;
- }
-
- static struct methodlist amiga_methods[] = {
- {"chdir", amiga_chdir},
- {"chmod", amiga_chmod},
- #ifdef HAVE_CHOWN
- {"chown", amiga_chown},
- #endif
- #ifdef HAVE_GETCWD
- {"getcwd", amiga_getcwd},
- #endif
- {"fullpath", amiga_fullpath,1},
- {"link", amiga_link},
- {"listdir", amiga_listdir},
- {"lstat", amiga_lstat},
- {"mkdir", amiga_mkdir , 1},
- {"readlink", amiga_readlink},
- {"rename", amiga_rename},
- {"rmdir", amiga_rmdir},
- {"stat", amiga_stat},
- {"symlink", amiga_symlink},
- {"system", amiga_system},
- #ifdef AMITCP
- {"umask", amiga_umask},
- #endif
- {"uname", amiga_uname},
- {"unlink", amiga_unlink},
- {"remove", amiga_unlink},
- #ifdef AMITCP
- {"utime", amiga_utime},
- #endif
- #ifdef HAVE_TIMES
- {"times", amiga_times},
- #endif
- #ifdef HAVE_GETEGID
- {"getegid", amiga_getegid},
- #endif
- #ifdef HAVE_GETEUID
- {"geteuid", amiga_geteuid},
- #endif
- #ifdef HAVE_GETGID
- {"getgid", amiga_getgid},
- #endif
- {"getpid", amiga_getpid},
- #ifdef HAVE_GETPGRP
- {"getpgrp", amiga_getpgrp},
- #endif
- #ifdef HAVE_GETPPID
- {"getppid", amiga_getppid},
- #endif
- #ifdef HAVE_GETUID
- {"getuid", amiga_getuid},
- #endif
- {"popen", amiga_popen, 1},
- #ifdef HAVE_SETUID
- {"setuid", amiga_setuid},
- #endif
- #ifdef HAVE_SETGID
- {"setgid", amiga_setgid},
- #endif
- #ifdef HAVE_SETPGRP
- {"setpgrp", amiga_setpgrp},
- #endif
- #ifdef HAVE_SETSID
- {"setsid", amiga_setsid},
- #endif
- #ifdef HAVE_SETPGID
- {"setpgid", amiga_setpgid},
- #endif
- #ifdef HAVE_TCGETPGRP
- {"tcgetpgrp", amiga_tcgetpgrp},
- #endif
- #ifdef HAVE_TCSETPGRP
- {"tcsetpgrp", amiga_tcsetpgrp},
- #endif
- {"open", amiga_open},
- {"close", amiga_close},
- #ifdef AMITCP
- {"dup", amiga_dup},
- {"dup2", amiga_dup2},
- #endif
- {"lseek", amiga_lseek},
- {"read", amiga_read},
- {"write", amiga_write},
- {"fstat", amiga_fstat},
- {"fdopen", amiga_fdopen, 1},
- {"putenv", amiga_putenv, 1},
- #if 0
- /* XXX TODO: implement threads. Otherwise pipe() is useless. */
- {"pipe", amiga_pipe},
- #endif
- {NULL, NULL} /* Sentinel */
- };
-
-
- void
- initamiga(void)
- {
- object *m, *d, *globv, *locv, *bothv, *aliases;
-
- m = initmodule("amiga", amiga_methods);
- d = getmoduledict(m);
-
- /* Initialize amiga.environ dictionary */
- if(!convertenviron(&globv, &locv, &bothv, &aliases))
- fatal("can't read environment");
-
- if (dictinsert(d, "environ", bothv) != 0)
- fatal("can't define amiga.environ");
- DECREF(bothv);
- if (dictinsert(d, "globalvars", globv) != 0)
- fatal("can't define amiga.globalvars");
- DECREF(globv);
- if (dictinsert(d, "shellvars", locv) != 0)
- fatal("can't define amiga.shellvars");
- DECREF(locv);
- if (dictinsert(d, "shellaliases", aliases ) != 0)
- fatal("can't define amiga.shellaliases");
- DECREF(aliases);
-
- /* Initialize amiga.error exception */
- AmigaError = newstringobject("amiga.error");
- if (AmigaError == NULL || dictinsert(d, "error", AmigaError) != 0)
- fatal("can't define amiga.error");
- }
-