1 /* RISCOS module implementation */
3 #include "oslib/osfscontrol.h"
4 #include "oslib/osgbpb.h"
6 #include "oslib/osfile.h"
12 #include "structseq.h"
18 /*static PyObject *RiscosError;*/ /* Exception riscos.error */
20 static PyObject
*riscos_error(char *s
)
22 PyErr_SetString(PyExc_OSError
, s
);
26 static PyObject
*riscos_oserror(void)
28 return riscos_error(e
->errmess
);
32 /* RISCOS file commands */
35 riscos_remove(PyObject
*self
, PyObject
*args
)
38 if (!PyArg_ParseTuple(args
, "s:remove", &path1
)) return NULL
;
39 if (remove(path1
)) return PyErr_SetFromErrno(PyExc_OSError
);
45 riscos_rename(PyObject
*self
, PyObject
*args
)
48 if (!PyArg_ParseTuple(args
, "ss:rename", &path1
, &path2
))
50 if (rename(path1
,path2
)) return PyErr_SetFromErrno(PyExc_OSError
);
56 riscos_system(PyObject
*self
, PyObject
*args
)
59 if (!PyArg_ParseTuple(args
, "s:system", &command
)) return NULL
;
60 return PyInt_FromLong(system(command
));
64 riscos_chdir(PyObject
*self
, PyObject
*args
)
67 if (!PyArg_ParseTuple(args
, "s:chdir", &path
)) return NULL
;
68 e
=xosfscontrol_dir(path
);
69 if(e
) return riscos_oserror();
80 e
=xosfscontrol_canonicalise_path(path
,0,0,0,0,&len
);
81 if(e
) return riscos_oserror();
82 obj
=PyString_FromStringAndSize(NULL
,-len
);
83 if(obj
==NULL
) return NULL
;
84 buf
=PyString_AsString(obj
);
85 e
=xosfscontrol_canonicalise_path(path
,buf
,0,0,1-len
,&len
);
86 if(len
!=1) return riscos_error("Error expanding path");
89 return riscos_oserror();
93 riscos_getcwd(PyObject
*self
, PyObject
*unused
)
99 riscos_expand(PyObject
*self
, PyObject
*args
)
102 if (!PyArg_ParseTuple(args
, "s:expand", &path
)) return NULL
;
107 riscos_mkdir(PyObject
*self
, PyObject
*args
)
111 if (!PyArg_ParseTuple(args
, "s|i:mkdir", &path
, &mode
)) return NULL
;
112 e
=xosfile_create_dir(path
,0);
113 if(e
) return riscos_oserror();
119 riscos_listdir(PyObject
*self
, PyObject
*args
)
124 if (!PyArg_ParseTuple(args
, "s:listdir", &path
)) return NULL
;
128 { e
=xosgbpb_dir_entries(path
,(osgbpb_string_list
*)buf
,
129 1,c
,256,0,&count
,&c
);
131 { Py_DECREF(d
);return riscos_oserror();
134 { v
=PyString_FromString(buf
);
135 if(!v
) { Py_DECREF(d
);return 0;}
136 if(PyList_Append(d
,v
)) {Py_DECREF(d
);Py_DECREF(v
);return 0;}
143 PyDoc_STRVAR(stat_result__doc__
,
144 "stat_result: Result from stat or lstat.\n\n\
145 This object may be accessed either as a tuple of\n\
146 (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
147 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
149 RiscOS: The fields st_ftype, st_attrs, and st_obtype are also available.\n\
151 See os.stat for more information.");
153 static PyStructSequence_Field stat_result_fields
[] = {
154 { "st_mode", "protection bits" },
155 { "st_ino", "inode" },
156 { "st_dev", "device" },
157 { "st_nlink", "number of hard links" },
158 { "st_uid", "user ID of owner" },
159 { "st_gid", "group ID of owner" },
160 { "st_size", "total size, in bytes" },
161 { "st_atime", "time of last access" },
162 { "st_mtime", "time of last modification" },
163 { "st_ctime", "time of last change" },
164 { "st_ftype", "file type" },
165 { "st_attrs", "attributes" },
166 { "st_obtype", "object type" },
170 static PyStructSequence_Desc stat_result_desc
= {
171 "riscos.stat_result",
177 static PyTypeObject StatResultType
;
180 riscos_stat(PyObject
*self
, PyObject
*args
)
186 bits ld
,ex
,at
,ft
,mode
;
187 if (!PyArg_ParseTuple(args
, "s:stat", &path
)) return NULL
;
188 e
=xosfile_read_stamped_no_path(path
,&ob
,&ld
,&ex
,&len
,&at
,&ft
);
189 if(e
) return riscos_oserror();
191 { case osfile_IS_FILE
:mode
=0100000;break; /* OCTAL */
192 case osfile_IS_DIR
:mode
=040000;break;
193 case osfile_IS_IMAGE
:mode
=0140000;break;
194 default:return riscos_error("Not found");
196 if(ft
!=-1) t
=unixtime(ld
,ex
);
198 mode
|=((at
&112)*9)>>4;
200 v
= PyStructSequence_New(&StatResultType
);
202 PyStructSequence_SET_ITEM(v
, 0,
203 PyInt_FromLong((long) mode
)); /*st_mode*/
204 PyStructSequence_SET_ITEM(v
, 1, PyInt_FromLong((long) 0)); /*st_ino*/
205 PyStructSequence_SET_ITEM(v
, 2, PyInt_FromLong((long) 0)); /*st_dev*/
206 PyStructSequence_SET_ITEM(v
, 3, PyInt_FromLong((long) 0)); /*st_nlink*/
207 PyStructSequence_SET_ITEM(v
, 4, PyInt_FromLong((long) 0)); /*st_uid*/
208 PyStructSequence_SET_ITEM(v
, 5, PyInt_FromLong((long) 0)); /*st_gid*/
209 PyStructSequence_SET_ITEM(v
, 6,
210 PyInt_FromLong((long) len
)); /*st_size*/
211 PyStructSequence_SET_ITEM(v
, 7, PyInt_FromLong((long) t
)); /*st_atime*/
212 PyStructSequence_SET_ITEM(v
, 8, PyInt_FromLong((long) t
)); /*st_mtime*/
213 PyStructSequence_SET_ITEM(v
, 9, PyInt_FromLong((long) t
)); /*st_ctime*/
214 PyStructSequence_SET_ITEM(v
, 10,
215 PyInt_FromLong((long) ft
)); /*file type*/
216 PyStructSequence_SET_ITEM(v
, 11,
217 PyInt_FromLong((long) at
)); /*attributes*/
218 PyStructSequence_SET_ITEM(v
, 12,
219 PyInt_FromLong((long) ob
)); /*object type*/
221 if (PyErr_Occurred()) {
230 riscos_chmod(PyObject
*self
,PyObject
*args
)
235 attr
=(mode
&0x700)>>8;
237 if (!PyArg_ParseTuple(args
, "si:chmod", &path
,(int*)&mode
)) return NULL
;
238 e
=xosfile_write_attr(path
,attr
);
239 if(e
) return riscos_oserror();
246 riscos_utime(PyObject
*self
, PyObject
*args
)
252 if (!PyArg_ParseTuple(args
, "sO:utime", &path
, &arg
))
255 if (arg
== Py_None
) {
256 /* optional time values not given */
257 Py_BEGIN_ALLOW_THREADS
258 e
=xosfile_stamp(path
);
260 if(e
) return riscos_oserror();
262 else if (!PyArg_Parse(arg
, "(ll)", &atime
, &mtime
)) {
263 PyErr_SetString(PyExc_TypeError
,
264 "utime() arg 2 must be a tuple (atime, mtime)");
269 fileswitch_object_type obj_type
;
270 bits load_addr
, exec_addr
;
272 fileswitch_attr attr
;
274 /* read old catalogue info */
275 Py_BEGIN_ALLOW_THREADS
276 e
=xosfile_read_no_path(path
, &obj_type
, &load_addr
, &exec_addr
, &size
, &attr
);
278 if(e
) return riscos_oserror();
280 /* check if load and exec address really contain filetype and date */
281 if ( (load_addr
& 0xFFF00000U
) != 0xFFF00000U
)
282 return riscos_error("can't set date for object with load and exec addresses");
284 /* convert argument mtime to RISC OS load and exec address */
285 if(acorntime(&exec_addr
, &load_addr
, (time_t) mtime
))
286 return riscos_oserror();
288 /* write new load and exec address */
289 Py_BEGIN_ALLOW_THREADS
290 e
= xosfile_write(path
, load_addr
, exec_addr
, attr
);
292 if(e
) return riscos_oserror();
300 riscos_settype(PyObject
*self
, PyObject
*args
)
304 if (!PyArg_ParseTuple(args
, "si:settype", &path
,&type
))
307 if (!PyArg_ParseTuple(args
, "ss:settype", &path
,&name
)) return NULL
;
308 e
=xosfscontrol_file_type_from_string(name
,(bits
*)&type
);
309 if(e
) return riscos_oserror();
311 e
=xosfile_set_type(path
,type
);
312 if(e
) return riscos_oserror();
318 riscos_getenv(PyObject
*self
, PyObject
*args
)
321 if(!PyArg_ParseTuple(args
,"s:getenv",&name
)) return NULL
;
323 if(value
) return PyString_FromString(value
);
329 riscos_putenv(PyObject
*self
, PyObject
*args
)
333 os_var_type type
=os_VARTYPE_LITERAL_STRING
;
334 if(!PyArg_ParseTuple(args
,"ss|i:putenv",&name
,&value
,&type
)) return NULL
;
335 if(type
!=os_VARTYPE_STRING
&&type
!=os_VARTYPE_MACRO
&&type
!=os_VARTYPE_EXPANDED
336 &&type
!=os_VARTYPE_LITERAL_STRING
)
337 return riscos_error("Bad putenv type");
339 if(type
!=os_VARTYPE_LITERAL_STRING
) len
++;
340 /* Other types need null terminator! */
341 e
=xos_set_var_val(name
,(byte
*)value
,len
,0,type
,0,0);
342 if(e
) return riscos_oserror();
348 riscos_delenv(PyObject
*self
, PyObject
*args
)
351 if(!PyArg_ParseTuple(args
,"s:delenv",&name
)) return NULL
;
352 e
=xos_set_var_val(name
,NULL
,-1,0,0,0,0);
353 if(e
) return riscos_oserror();
359 riscos_getenvdict(PyObject
*self
, PyObject
*args
)
366 if(!PyArg_ParseTuple(args
,"|s:getenvdict",&which
)) return NULL
;
368 if (!dict
) return NULL
;
369 /* XXX This part ignores errors */
370 while(!xos_read_var_val(which
,value
,sizeof(value
)-1,(int)context
,
371 os_VARTYPE_EXPANDED
,&size
,(int *)&context
,0))
374 v
= PyString_FromString(value
);
375 if (v
== NULL
) continue;
376 PyDict_SetItemString(dict
, context
, v
);
382 static PyMethodDef riscos_methods
[] = {
384 {"unlink", riscos_remove
, METH_VARARGS
},
385 {"remove", riscos_remove
, METH_VARARGS
},
386 {"rename", riscos_rename
, METH_VARARGS
},
387 {"system", riscos_system
, METH_VARARGS
},
388 {"rmdir", riscos_remove
, METH_VARARGS
},
389 {"chdir", riscos_chdir
, METH_VARARGS
},
390 {"getcwd", riscos_getcwd
, METH_NOARGS
},
391 {"expand", riscos_expand
, METH_VARARGS
},
392 {"mkdir", riscos_mkdir
, METH_VARARGS
},
393 {"listdir", riscos_listdir
, METH_VARARGS
},
394 {"stat", riscos_stat
, METH_VARARGS
},
395 {"lstat", riscos_stat
, METH_VARARGS
},
396 {"chmod", riscos_chmod
, METH_VARARGS
},
397 {"utime", riscos_utime
, METH_VARARGS
},
398 {"settype", riscos_settype
, METH_VARARGS
},
399 {"getenv", riscos_getenv
, METH_VARARGS
},
400 {"putenv", riscos_putenv
, METH_VARARGS
},
401 {"delenv", riscos_delenv
, METH_VARARGS
},
402 {"getenvdict", riscos_getenvdict
, METH_VARARGS
},
403 {NULL
, NULL
} /* Sentinel */
407 ins(PyObject
*module
, char *symbol
, long value
)
409 return PyModule_AddIntConstant(module
, symbol
, value
);
417 if (ins(d
, "F_OK", (long)F_OK
)) return -1;
420 if (ins(d
, "R_OK", (long)R_OK
)) return -1;
423 if (ins(d
, "W_OK", (long)W_OK
)) return -1;
426 if (ins(d
, "X_OK", (long)X_OK
)) return -1;
429 if (ins(d
, "NGROUPS_MAX", (long)NGROUPS_MAX
)) return -1;
432 if (ins(d
, "TMP_MAX", (long)TMP_MAX
)) return -1;
435 if (ins(d
, "WCONTINUED", (long)WCONTINUED
)) return -1;
438 if (ins(d
, "WNOHANG", (long)WNOHANG
)) return -1;
441 if (ins(d
, "WUNTRACED", (long)WUNTRACED
)) return -1;
444 if (ins(d
, "O_RDONLY", (long)O_RDONLY
)) return -1;
447 if (ins(d
, "O_WRONLY", (long)O_WRONLY
)) return -1;
450 if (ins(d
, "O_RDWR", (long)O_RDWR
)) return -1;
453 if (ins(d
, "O_NDELAY", (long)O_NDELAY
)) return -1;
456 if (ins(d
, "O_NONBLOCK", (long)O_NONBLOCK
)) return -1;
459 if (ins(d
, "O_APPEND", (long)O_APPEND
)) return -1;
462 if (ins(d
, "O_DSYNC", (long)O_DSYNC
)) return -1;
465 if (ins(d
, "O_RSYNC", (long)O_RSYNC
)) return -1;
468 if (ins(d
, "O_SYNC", (long)O_SYNC
)) return -1;
471 if (ins(d
, "O_NOCTTY", (long)O_NOCTTY
)) return -1;
474 if (ins(d
, "O_CREAT", (long)O_CREAT
)) return -1;
477 if (ins(d
, "O_EXCL", (long)O_EXCL
)) return -1;
480 if (ins(d
, "O_TRUNC", (long)O_TRUNC
)) return -1;
483 if (ins(d
, "O_BINARY", (long)O_BINARY
)) return -1;
486 if (ins(d
, "O_TEXT", (long)O_TEXT
)) return -1;
489 if (ins(d
, "O_LARGEFILE", (long)O_LARGEFILE
)) return -1;
494 /* Don't inherit in child processes. */
495 if (ins(d
, "O_NOINHERIT", (long)O_NOINHERIT
)) return -1;
497 #ifdef _O_SHORT_LIVED
498 /* Optimize for short life (keep in memory). */
499 /* MS forgot to define this one with a non-underscore form too. */
500 if (ins(d
, "O_SHORT_LIVED", (long)_O_SHORT_LIVED
)) return -1;
503 /* Automatically delete when last handle is closed. */
504 if (ins(d
, "O_TEMPORARY", (long)O_TEMPORARY
)) return -1;
507 /* Optimize for random access. */
508 if (ins(d
, "O_RANDOM", (long)O_RANDOM
)) return -1;
511 /* Optimize for sequential access. */
512 if (ins(d
, "O_SEQUENTIAL", (long)O_SEQUENTIAL
)) return -1;
515 /* GNU extensions. */
517 /* Direct disk access. */
518 if (ins(d
, "O_DIRECT", (long)O_DIRECT
)) return -1;
521 /* Must be a directory. */
522 if (ins(d
, "O_DIRECTORY", (long)O_DIRECTORY
)) return -1;
525 /* Do not follow links. */
526 if (ins(d
, "O_NOFOLLOW", (long)O_NOFOLLOW
)) return -1;
529 /* These come from sysexits.h */
531 if (ins(d
, "EX_OK", (long)EX_OK
)) return -1;
534 if (ins(d
, "EX_USAGE", (long)EX_USAGE
)) return -1;
535 #endif /* EX_USAGE */
537 if (ins(d
, "EX_DATAERR", (long)EX_DATAERR
)) return -1;
538 #endif /* EX_DATAERR */
540 if (ins(d
, "EX_NOINPUT", (long)EX_NOINPUT
)) return -1;
541 #endif /* EX_NOINPUT */
543 if (ins(d
, "EX_NOUSER", (long)EX_NOUSER
)) return -1;
544 #endif /* EX_NOUSER */
546 if (ins(d
, "EX_NOHOST", (long)EX_NOHOST
)) return -1;
547 #endif /* EX_NOHOST */
548 #ifdef EX_UNAVAILABLE
549 if (ins(d
, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE
)) return -1;
550 #endif /* EX_UNAVAILABLE */
552 if (ins(d
, "EX_SOFTWARE", (long)EX_SOFTWARE
)) return -1;
553 #endif /* EX_SOFTWARE */
555 if (ins(d
, "EX_OSERR", (long)EX_OSERR
)) return -1;
556 #endif /* EX_OSERR */
558 if (ins(d
, "EX_OSFILE", (long)EX_OSFILE
)) return -1;
559 #endif /* EX_OSFILE */
561 if (ins(d
, "EX_CANTCREAT", (long)EX_CANTCREAT
)) return -1;
562 #endif /* EX_CANTCREAT */
564 if (ins(d
, "EX_IOERR", (long)EX_IOERR
)) return -1;
565 #endif /* EX_IOERR */
567 if (ins(d
, "EX_TEMPFAIL", (long)EX_TEMPFAIL
)) return -1;
568 #endif /* EX_TEMPFAIL */
570 if (ins(d
, "EX_PROTOCOL", (long)EX_PROTOCOL
)) return -1;
571 #endif /* EX_PROTOCOL */
573 if (ins(d
, "EX_NOPERM", (long)EX_NOPERM
)) return -1;
574 #endif /* EX_NOPERM */
576 if (ins(d
, "EX_CONFIG", (long)EX_CONFIG
)) return -1;
577 #endif /* EX_CONFIG */
579 if (ins(d
, "EX_NOTFOUND", (long)EX_NOTFOUND
)) return -1;
580 #endif /* EX_NOTFOUND */
589 PyObject
*m
, *d
, *stat_m
;
591 m
= Py_InitModule("riscos", riscos_methods
);
596 d
= PyModule_GetDict(m
);
598 Py_INCREF(PyExc_OSError
);
599 PyModule_AddObject(m
, "error", PyExc_OSError
);
601 PyStructSequence_InitType(&StatResultType
, &stat_result_desc
);
602 PyDict_SetItemString(d
, "stat_result", (PyObject
*) &StatResultType
);