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 */
34 static PyObject
*riscos_remove(PyObject
*self
,PyObject
*args
)
36 if (!PyArg_Parse(args
, "s", &path1
)) return NULL
;
37 if (remove(path1
)) return PyErr_SetFromErrno(PyExc_OSError
);
42 static PyObject
*riscos_rename(PyObject
*self
,PyObject
*args
)
43 { char *path1
, *path2
;
44 if (!PyArg_Parse(args
, "(ss)", &path1
, &path2
)) return NULL
;
45 if (rename(path1
,path2
)) return PyErr_SetFromErrno(PyExc_OSError
);
50 static PyObject
*riscos_system(PyObject
*self
,PyObject
*args
)
52 if (!PyArg_Parse(args
, "s", &command
)) return NULL
;
53 return PyInt_FromLong(system(command
));
56 static PyObject
*riscos_chdir(PyObject
*self
,PyObject
*args
)
58 if (!PyArg_Parse(args
, "s", &path
)) return NULL
;
59 e
=xosfscontrol_dir(path
);
60 if(e
) return riscos_oserror();
65 static PyObject
*canon(char *path
)
69 e
=xosfscontrol_canonicalise_path(path
,0,0,0,0,&len
);
70 if(e
) return riscos_oserror();
71 obj
=PyString_FromStringAndSize(NULL
,-len
);
72 if(obj
==NULL
) return NULL
;
73 buf
=PyString_AsString(obj
);
74 e
=xosfscontrol_canonicalise_path(path
,buf
,0,0,1-len
,&len
);
75 if(len
!=1) return riscos_error("Error expanding path");
78 return riscos_oserror();
81 static PyObject
*riscos_getcwd(PyObject
*self
,PyObject
*args
)
82 { if(!PyArg_NoArgs(args
)) return NULL
;
86 static PyObject
*riscos_expand(PyObject
*self
,PyObject
*args
)
88 if (!PyArg_Parse(args
, "s", &path
)) return NULL
;
92 static PyObject
*riscos_mkdir(PyObject
*self
,PyObject
*args
)
95 if (!PyArg_ParseTuple(args
, "s|i", &path
, &mode
)) return NULL
;
96 e
=xosfile_create_dir(path
,0);
97 if(e
) return riscos_oserror();
102 static PyObject
*riscos_listdir(PyObject
*self
,PyObject
*args
)
103 { char *path
,buf
[256];
106 if (!PyArg_Parse(args
, "s", &path
)) return NULL
;
110 { e
=xosgbpb_dir_entries(path
,(osgbpb_string_list
*)buf
,
111 1,c
,256,0,&count
,&c
);
113 { Py_DECREF(d
);return riscos_oserror();
116 { v
=PyString_FromString(buf
);
117 if(!v
) { Py_DECREF(d
);return 0;}
118 if(PyList_Append(d
,v
)) {Py_DECREF(d
);Py_DECREF(v
);return 0;}
125 PyDoc_STRVAR(stat_result__doc__
,
126 "stat_result: Result from stat or lstat.\n\n\
127 This object may be accessed either as a tuple of\n\
128 (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
129 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
131 RiscOS: The fields st_ftype, st_attrs, and st_obtype are also available.\n\
133 See os.stat for more information.");
135 static PyStructSequence_Field stat_result_fields
[] = {
136 { "st_mode", "protection bits" },
137 { "st_ino", "inode" },
138 { "st_dev", "device" },
139 { "st_nlink", "number of hard links" },
140 { "st_uid", "user ID of owner" },
141 { "st_gid", "group ID of owner" },
142 { "st_size", "total size, in bytes" },
143 { "st_atime", "time of last access" },
144 { "st_mtime", "time of last modification" },
145 { "st_ctime", "time of last change" },
146 { "st_ftype", "file type" },
147 { "st_attrs", "attributes" },
148 { "st_obtype", "object type" },
152 static PyStructSequence_Desc stat_result_desc
= {
153 "riscos.stat_result",
159 static PyTypeObject StatResultType
;
161 static PyObject
*riscos_stat(PyObject
*self
,PyObject
*args
)
167 bits ld
,ex
,at
,ft
,mode
;
168 if (!PyArg_Parse(args
, "s", &path
)) return NULL
;
169 e
=xosfile_read_stamped_no_path(path
,&ob
,&ld
,&ex
,&len
,&at
,&ft
);
170 if(e
) return riscos_oserror();
172 { case osfile_IS_FILE
:mode
=0100000;break; /* OCTAL */
173 case osfile_IS_DIR
:mode
=040000;break;
174 case osfile_IS_IMAGE
:mode
=0140000;break;
175 default:return riscos_error("Not found");
177 if(ft
!=-1) t
=unixtime(ld
,ex
);
179 mode
|=((at
&112)*9)>>4;
181 v
= PyStructSequence_New(&StatResultType
);
183 PyStructSequence_SET_ITEM(v
, 0,
184 PyInt_FromLong((long) mode
)); /*st_mode*/
185 PyStructSequence_SET_ITEM(v
, 1, PyInt_FromLong((long) 0)); /*st_ino*/
186 PyStructSequence_SET_ITEM(v
, 2, PyInt_FromLong((long) 0)); /*st_dev*/
187 PyStructSequence_SET_ITEM(v
, 3, PyInt_FromLong((long) 0)); /*st_nlink*/
188 PyStructSequence_SET_ITEM(v
, 4, PyInt_FromLong((long) 0)); /*st_uid*/
189 PyStructSequence_SET_ITEM(v
, 5, PyInt_FromLong((long) 0)); /*st_gid*/
190 PyStructSequence_SET_ITEM(v
, 6,
191 PyInt_FromLong((long) len
)); /*st_size*/
192 PyStructSequence_SET_ITEM(v
, 7, PyInt_FromLong((long) t
)); /*st_atime*/
193 PyStructSequence_SET_ITEM(v
, 8, PyInt_FromLong((long) t
)); /*st_mtime*/
194 PyStructSequence_SET_ITEM(v
, 9, PyInt_FromLong((long) t
)); /*st_ctime*/
195 PyStructSequence_SET_ITEM(v
, 10,
196 PyInt_FromLong((long) ft
)); /*file type*/
197 PyStructSequence_SET_ITEM(v
, 11,
198 PyInt_FromLong((long) at
)); /*attributes*/
199 PyStructSequence_SET_ITEM(v
, 12,
200 PyInt_FromLong((long) ob
)); /*object type*/
202 if (PyErr_Occurred()) {
210 static PyObject
*riscos_chmod(PyObject
*self
,PyObject
*args
)
214 attr
=(mode
&0x700)>>8;
216 if (!PyArg_Parse(args
, "(si)", &path
,(int*)&mode
)) return NULL
;
217 e
=xosfile_write_attr(path
,attr
);
218 if(e
) return riscos_oserror();
224 static PyObject
*riscos_utime(PyObject
*self
,PyObject
*args
)
230 if (!PyArg_ParseTuple(args
, "sO:utime", &path
, &arg
))
233 if (arg
== Py_None
) {
234 /* optional time values not given */
235 Py_BEGIN_ALLOW_THREADS
236 e
=xosfile_stamp(path
);
238 if(e
) return riscos_oserror();
240 else if (!PyArg_Parse(arg
, "(ll)", &atime
, &mtime
)) {
241 PyErr_SetString(PyExc_TypeError
,
242 "utime() arg 2 must be a tuple (atime, mtime)");
247 fileswitch_object_type obj_type
;
248 bits load_addr
, exec_addr
;
250 fileswitch_attr attr
;
252 /* read old catalogue info */
253 Py_BEGIN_ALLOW_THREADS
254 e
=xosfile_read_no_path(path
, &obj_type
, &load_addr
, &exec_addr
, &size
, &attr
);
256 if(e
) return riscos_oserror();
258 /* check if load and exec address really contain filetype and date */
259 if ( (load_addr
& 0xFFF00000U
) != 0xFFF00000U
)
260 return riscos_error("can't set date for object with load and exec addresses");
262 /* convert argument mtime to RISC OS load and exec address */
263 if(acorntime(&exec_addr
, &load_addr
, (time_t) mtime
))
264 return riscos_oserror();
266 /* write new load and exec address */
267 Py_BEGIN_ALLOW_THREADS
268 e
= xosfile_write(path
, load_addr
, exec_addr
, attr
);
270 if(e
) return riscos_oserror();
277 static PyObject
*riscos_settype(PyObject
*self
,PyObject
*args
)
280 if (!PyArg_Parse(args
, "(si)", &path
,&type
))
282 if (!PyArg_Parse(args
, "(ss)", &path
,&name
)) return NULL
;
283 e
=xosfscontrol_file_type_from_string(name
,(bits
*)&type
);
284 if(e
) return riscos_oserror();
286 e
=xosfile_set_type(path
,type
);
287 if(e
) return riscos_oserror();
292 static PyObject
*riscos_getenv(PyObject
*self
,PyObject
*args
)
294 if(!PyArg_Parse(args
,"s",&name
)) return NULL
;
296 if(value
) return PyString_FromString(value
);
301 static PyObject
*riscos_putenv(PyObject
*self
,PyObject
*args
)
304 os_var_type type
=os_VARTYPE_LITERAL_STRING
;
305 if(!PyArg_ParseTuple(args
,"ss|i",&name
,&value
,&type
)) return NULL
;
306 if(type
!=os_VARTYPE_STRING
&&type
!=os_VARTYPE_MACRO
&&type
!=os_VARTYPE_EXPANDED
307 &&type
!=os_VARTYPE_LITERAL_STRING
)
308 return riscos_error("Bad putenv type");
310 if(type
!=os_VARTYPE_LITERAL_STRING
) len
++;
311 /* Other types need null terminator! */
312 e
=xos_set_var_val(name
,(byte
*)value
,len
,0,type
,0,0);
313 if(e
) return riscos_oserror();
318 static PyObject
*riscos_delenv(PyObject
*self
,PyObject
*args
)
320 if(!PyArg_Parse(args
,"s",&name
)) return NULL
;
321 e
=xos_set_var_val(name
,NULL
,-1,0,0,0,0);
322 if(e
) return riscos_oserror();
327 static PyObject
*riscos_getenvdict(PyObject
*self
,PyObject
*args
)
333 if(!PyArg_ParseTuple(args
,"|s",&which
)) return NULL
;
335 if (!dict
) return NULL
;
336 /* XXX This part ignores errors */
337 while(!xos_read_var_val(which
,value
,sizeof(value
)-1,(int)context
,
338 os_VARTYPE_EXPANDED
,&size
,(int *)&context
,0))
341 v
= PyString_FromString(value
);
342 if (v
== NULL
) continue;
343 PyDict_SetItemString(dict
, context
, v
);
349 static PyMethodDef riscos_methods
[] = {
351 {"unlink", riscos_remove
},
352 {"remove", riscos_remove
},
353 {"rename", riscos_rename
},
354 {"system", riscos_system
},
355 {"rmdir", riscos_remove
},
356 {"chdir", riscos_chdir
},
357 {"getcwd", riscos_getcwd
},
358 {"expand", riscos_expand
},
359 {"mkdir", riscos_mkdir
,1},
360 {"listdir", riscos_listdir
},
361 {"stat", riscos_stat
},
362 {"lstat", riscos_stat
},
363 {"chmod", riscos_chmod
},
364 {"utime", riscos_utime
},
365 {"settype", riscos_settype
},
366 {"getenv", riscos_getenv
},
367 {"putenv", riscos_putenv
},
368 {"delenv", riscos_delenv
},
369 {"getenvdict", riscos_getenvdict
,1},
370 {NULL
, NULL
} /* Sentinel */
374 ins(PyObject
*module
, char *symbol
, long value
)
376 return PyModule_AddIntConstant(module
, symbol
, value
);
384 if (ins(d
, "F_OK", (long)F_OK
)) return -1;
387 if (ins(d
, "R_OK", (long)R_OK
)) return -1;
390 if (ins(d
, "W_OK", (long)W_OK
)) return -1;
393 if (ins(d
, "X_OK", (long)X_OK
)) return -1;
396 if (ins(d
, "NGROUPS_MAX", (long)NGROUPS_MAX
)) return -1;
399 if (ins(d
, "TMP_MAX", (long)TMP_MAX
)) return -1;
402 if (ins(d
, "WCONTINUED", (long)WCONTINUED
)) return -1;
405 if (ins(d
, "WNOHANG", (long)WNOHANG
)) return -1;
408 if (ins(d
, "WUNTRACED", (long)WUNTRACED
)) return -1;
411 if (ins(d
, "O_RDONLY", (long)O_RDONLY
)) return -1;
414 if (ins(d
, "O_WRONLY", (long)O_WRONLY
)) return -1;
417 if (ins(d
, "O_RDWR", (long)O_RDWR
)) return -1;
420 if (ins(d
, "O_NDELAY", (long)O_NDELAY
)) return -1;
423 if (ins(d
, "O_NONBLOCK", (long)O_NONBLOCK
)) return -1;
426 if (ins(d
, "O_APPEND", (long)O_APPEND
)) return -1;
429 if (ins(d
, "O_DSYNC", (long)O_DSYNC
)) return -1;
432 if (ins(d
, "O_RSYNC", (long)O_RSYNC
)) return -1;
435 if (ins(d
, "O_SYNC", (long)O_SYNC
)) return -1;
438 if (ins(d
, "O_NOCTTY", (long)O_NOCTTY
)) return -1;
441 if (ins(d
, "O_CREAT", (long)O_CREAT
)) return -1;
444 if (ins(d
, "O_EXCL", (long)O_EXCL
)) return -1;
447 if (ins(d
, "O_TRUNC", (long)O_TRUNC
)) return -1;
450 if (ins(d
, "O_BINARY", (long)O_BINARY
)) return -1;
453 if (ins(d
, "O_TEXT", (long)O_TEXT
)) return -1;
456 if (ins(d
, "O_LARGEFILE", (long)O_LARGEFILE
)) return -1;
461 /* Don't inherit in child processes. */
462 if (ins(d
, "O_NOINHERIT", (long)O_NOINHERIT
)) return -1;
464 #ifdef _O_SHORT_LIVED
465 /* Optimize for short life (keep in memory). */
466 /* MS forgot to define this one with a non-underscore form too. */
467 if (ins(d
, "O_SHORT_LIVED", (long)_O_SHORT_LIVED
)) return -1;
470 /* Automatically delete when last handle is closed. */
471 if (ins(d
, "O_TEMPORARY", (long)O_TEMPORARY
)) return -1;
474 /* Optimize for random access. */
475 if (ins(d
, "O_RANDOM", (long)O_RANDOM
)) return -1;
478 /* Optimize for sequential access. */
479 if (ins(d
, "O_SEQUENTIAL", (long)O_SEQUENTIAL
)) return -1;
482 /* GNU extensions. */
484 /* Direct disk access. */
485 if (ins(d
, "O_DIRECT", (long)O_DIRECT
)) return -1;
488 /* Must be a directory. */
489 if (ins(d
, "O_DIRECTORY", (long)O_DIRECTORY
)) return -1;
492 /* Do not follow links. */
493 if (ins(d
, "O_NOFOLLOW", (long)O_NOFOLLOW
)) return -1;
496 /* These come from sysexits.h */
498 if (ins(d
, "EX_OK", (long)EX_OK
)) return -1;
501 if (ins(d
, "EX_USAGE", (long)EX_USAGE
)) return -1;
502 #endif /* EX_USAGE */
504 if (ins(d
, "EX_DATAERR", (long)EX_DATAERR
)) return -1;
505 #endif /* EX_DATAERR */
507 if (ins(d
, "EX_NOINPUT", (long)EX_NOINPUT
)) return -1;
508 #endif /* EX_NOINPUT */
510 if (ins(d
, "EX_NOUSER", (long)EX_NOUSER
)) return -1;
511 #endif /* EX_NOUSER */
513 if (ins(d
, "EX_NOHOST", (long)EX_NOHOST
)) return -1;
514 #endif /* EX_NOHOST */
515 #ifdef EX_UNAVAILABLE
516 if (ins(d
, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE
)) return -1;
517 #endif /* EX_UNAVAILABLE */
519 if (ins(d
, "EX_SOFTWARE", (long)EX_SOFTWARE
)) return -1;
520 #endif /* EX_SOFTWARE */
522 if (ins(d
, "EX_OSERR", (long)EX_OSERR
)) return -1;
523 #endif /* EX_OSERR */
525 if (ins(d
, "EX_OSFILE", (long)EX_OSFILE
)) return -1;
526 #endif /* EX_OSFILE */
528 if (ins(d
, "EX_CANTCREAT", (long)EX_CANTCREAT
)) return -1;
529 #endif /* EX_CANTCREAT */
531 if (ins(d
, "EX_IOERR", (long)EX_IOERR
)) return -1;
532 #endif /* EX_IOERR */
534 if (ins(d
, "EX_TEMPFAIL", (long)EX_TEMPFAIL
)) return -1;
535 #endif /* EX_TEMPFAIL */
537 if (ins(d
, "EX_PROTOCOL", (long)EX_PROTOCOL
)) return -1;
538 #endif /* EX_PROTOCOL */
540 if (ins(d
, "EX_NOPERM", (long)EX_NOPERM
)) return -1;
541 #endif /* EX_NOPERM */
543 if (ins(d
, "EX_CONFIG", (long)EX_CONFIG
)) return -1;
544 #endif /* EX_CONFIG */
546 if (ins(d
, "EX_NOTFOUND", (long)EX_NOTFOUND
)) return -1;
547 #endif /* EX_NOTFOUND */
556 PyObject
*m
, *d
, *stat_m
;
558 m
= Py_InitModule("riscos", riscos_methods
);
563 d
= PyModule_GetDict(m
);
565 Py_INCREF(PyExc_OSError
);
566 PyModule_AddObject(m
, "error", PyExc_OSError
);
568 PyStructSequence_InitType(&StatResultType
, &stat_result_desc
);
569 PyDict_SetItemString(d
, "stat_result", (PyObject
*) &StatResultType
);