home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pyth_os2.zip / python-1.0.2 / Modules / dosmodule.c < prev    next >
C/C++ Source or Header  |  1994-02-15  |  11KB  |  579 lines

  1. /***********************************************************
  2. Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
  3. Amsterdam, The Netherlands.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its
  8. documentation for any purpose and without fee is hereby granted,
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in
  11. supporting documentation, and that the names of Stichting Mathematisch
  12. Centrum or CWI not be used in advertising or publicity pertaining to
  13. distribution of the software without specific, written prior permission.
  14.  
  15. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  16. THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17. FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  18. FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  20. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  21. OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  
  23. ******************************************************************/
  24.  
  25. /* Operating system module implementation for MS-DOS */
  26. /* Tested with Microsoft C 7.0 (as part of MSVC++ Pro 1.0) */
  27.  
  28. #include <dos.h>
  29.  
  30. #include <stdlib.h>
  31. #include <signal.h>
  32. #include <string.h>
  33. #include <setjmp.h>
  34. #include <sys/types.h>
  35. #include <sys/stat.h>
  36.  
  37. #include <direct.h> /* chdir(), mkdir(), rmdir(), getcwd() */
  38.  
  39. #include "allobjects.h"
  40. #include "modsupport.h"
  41. #include "ceval.h"
  42.  
  43.  
  44. /* Return a dictionary corresponding to the DOS environment table */
  45.  
  46. static object *
  47. convertenviron()
  48. {
  49.     object *d;
  50.     char **e;
  51.     d = newdictobject();
  52.     if (d == NULL)
  53.         return NULL;
  54.     if (environ == NULL)
  55.         return d;
  56.     /* XXX This part ignores errors */
  57.     for (e = environ; *e != NULL; e++) {
  58.         object *v;
  59.         char *p = strchr(*e, '=');
  60.         if (p == NULL)
  61.             continue;
  62.         v = newstringobject(p+1);
  63.         if (v == NULL)
  64.             continue;
  65.         *p = '\0';
  66.         (void) dictinsert(d, *e, v);
  67.         *p = '=';
  68.         DECREF(v);
  69.     }
  70.     return d;
  71. }
  72.  
  73.  
  74. static object *DosError; /* Exception dos.error */
  75.  
  76. /* Set a DOS-specific error from errno, and return NULL */
  77.  
  78. static object *
  79. dos_error()
  80. {
  81.      return err_errno(DosError);
  82. }
  83.  
  84.  
  85. /* DOS generic methods */
  86.  
  87. static object *
  88. dos_1str(args, func)
  89.     object *args;
  90.     int (*func) FPROTO((const char *));
  91. {
  92.     char *path1;
  93.     int res;
  94.     if (!getargs(args, "s", &path1))
  95.         return NULL;
  96.     BGN_SAVE
  97.     res = (*func)(path1);
  98.     END_SAVE
  99.     if (res < 0)
  100.         return dos_error();
  101.     INCREF(None);
  102.     return None;
  103. }
  104.  
  105. static object *
  106. dos_2str(args, func)
  107.     object *args;
  108.     int (*func) FPROTO((const char *, const char *));
  109. {
  110.     char *path1, *path2;
  111.     int res;
  112.     if (!getargs(args, "(ss)", &path1, &path2))
  113.         return NULL;
  114.     BGN_SAVE
  115.     res = (*func)(path1, path2);
  116.     END_SAVE
  117.     if (res < 0)
  118.         return dos_error();
  119.     INCREF(None);
  120.     return None;
  121. }
  122.  
  123. static object *
  124. dos_strint(args, func)
  125.     object *args;
  126.     int (*func) FPROTO((const char *, int));
  127. {
  128.     char *path;
  129.     int i;
  130.     int res;
  131.     if (!getargs(args, "(si)", &path, &i))
  132.         return NULL;
  133.     BGN_SAVE
  134.     res = (*func)(path, i);
  135.     END_SAVE
  136.     if (res < 0)
  137.         return dos_error();
  138.     INCREF(None);
  139.     return None;
  140. }
  141.  
  142. static object *
  143. dos_do_stat(self, args, statfunc)
  144.     object *self;
  145.     object *args;
  146.     int (*statfunc) FPROTO((const char *, struct stat *));
  147. {
  148.     struct stat st;
  149.     char *path;
  150.     int res;
  151.     if (!getargs(args, "s", &path))
  152.         return NULL;
  153.     BGN_SAVE
  154.     res = (*statfunc)(path, &st);
  155.     END_SAVE
  156.     if (res != 0)
  157.         return dos_error();
  158.     return mkvalue("(llllllllll)",
  159.             (long)st.st_mode,
  160.             (long)st.st_ino,
  161.             (long)st.st_dev,
  162.             (long)st.st_nlink,
  163.             (long)st.st_uid,
  164.             (long)st.st_gid,
  165.             (long)st.st_size,
  166.             (long)st.st_atime,
  167.             (long)st.st_mtime,
  168.             (long)st.st_ctime);
  169. }
  170.  
  171.  
  172. /* DOS methods */
  173.  
  174. static object *
  175. dos_chdir(self, args)
  176.     object *self;
  177.     object *args;
  178. {
  179.     return dos_1str(args, chdir);
  180. }
  181.  
  182. static object *
  183. dos_chmod(self, args)
  184.     object *self;
  185.     object *args;
  186. {
  187.     extern int chmod();
  188.     return dos_strint(args, chmod);
  189. }
  190.  
  191. static object *
  192. dos_getcwd(self, args)
  193.     object *self;
  194.     object *args;
  195. {
  196.     char buf[1026];
  197.     char *res;
  198.     if (!getnoarg(args))
  199.         return NULL;
  200.     BGN_SAVE
  201.     res = getcwd(buf, sizeof buf);
  202.     END_SAVE
  203.     if (res == NULL)
  204.         return dos_error();
  205.     return newstringobject(buf);
  206. }
  207.  
  208. static object *
  209. dos_listdir(self, args)
  210.     object *self;
  211.     object *args;
  212. {
  213.     char *name;
  214.     int len;
  215.     object *d, *v;
  216.     struct find_t ep;
  217.     int rv;
  218.     char namebuf[256];
  219.  
  220.     if (!getargs(args, "s#", &name, &len))
  221.         return NULL;
  222.     if (len >= 250) {
  223.         err_setstr(ValueError, "path too long");
  224.         return NULL;
  225.     }
  226.     strcpy(namebuf, name);
  227.     if (namebuf[len-1] != '/' && namebuf[len-1] != '\\')
  228.         namebuf[len++] = '/';
  229.     strcpy(namebuf + len, "*.*");
  230.  
  231.     if ((d = newlistobject(0)) == NULL)
  232.         return NULL;
  233.  
  234.     if (_dos_findfirst(namebuf,
  235.             _A_HIDDEN|_A_RDONLY|_A_SYSTEM|_A_SUBDIR, &ep) != 0)
  236.         return dos_error();
  237.     do {
  238.         char *p;
  239.         for (p = ep.name; *p != '\0'; p++)
  240.             *p = tolower(*p);
  241.         v = newstringobject(ep.name);
  242.         if (v == NULL) {
  243.             DECREF(d);
  244.             d = NULL;
  245.             break;
  246.         }
  247.         if (addlistitem(d, v) != 0) {
  248.             DECREF(v);
  249.             DECREF(d);
  250.             d = NULL;
  251.             break;
  252.         }
  253.         DECREF(v);
  254.     } while (_dos_findnext(&ep) == 0);
  255.  
  256.     return d;
  257. }
  258.  
  259. static object *
  260. dos_mkdir(self, args)
  261.     object *self;
  262.     object *args;
  263. {
  264.     return dos_strint(args, mkdir);
  265. }
  266.  
  267. static object *
  268. dos_rename(self, args)
  269.     object *self;
  270.     object *args;
  271. {
  272.     return dos_2str(args, rename);
  273. }
  274.  
  275. static object *
  276. dos_rmdir(self, args)
  277.     object *self;
  278.     object *args;
  279. {
  280.     return dos_1str(args, rmdir);
  281. }
  282.  
  283. static object *
  284. dos_stat(self, args)
  285.     object *self;
  286.     object *args;
  287. {
  288.     return dos_do_stat(self, args, stat);
  289. }
  290.  
  291. static object *
  292. dos_system(self, args)
  293.     object *self;
  294.     object *args;
  295. {
  296.     char *command;
  297.     long sts;
  298.     if (!getargs(args, "s", &command))
  299.         return NULL;
  300.     BGN_SAVE
  301.     sts = system(command);
  302.     END_SAVE
  303.     return newintobject(sts);
  304. }
  305.  
  306. static object *
  307. dos_unlink(self, args)
  308.     object *self;
  309.     object *args;
  310. {
  311.     return dos_1str(args, unlink);
  312. }
  313.  
  314. static object *
  315. dos_utime(self, args)
  316.     object *self;
  317.     object *args;
  318. {
  319.     char *path;
  320.     int res;
  321.  
  322. #ifdef UTIME_STRUCT
  323.     struct utimbuf buf;
  324. #define ATIME buf.actime
  325. #define MTIME buf.modtime
  326. #define UTIME_ARG &buf
  327.  
  328. #else
  329.     time_t buf[2];
  330. #define ATIME buf[0]
  331. #define MTIME buf[1]
  332. #define UTIME_ARG buf
  333. #endif
  334.  
  335.     if (!getargs(args, "(s(ll))", &path, &ATIME, &MTIME))
  336.         return NULL;
  337.     BGN_SAVE
  338.     res = utime(path, UTIME_ARG);
  339.     END_SAVE
  340.     if (res < 0)
  341.         return dos_error();
  342.     INCREF(None);
  343.     return None;
  344. #undef UTIME_ARG
  345. #undef ATIME
  346. #undef MTIME
  347. }
  348.  
  349. /* Functions acting on file descriptors */
  350.  
  351. static object *
  352. dos_open(self, args)
  353.     object *self;
  354.     object *args;
  355. {
  356.     char *file;
  357.     int flag;
  358.     int mode = 0777;
  359.     int fd;
  360.     if (!getargs(args, "(si)", &file, &flag)) {
  361.         err_clear();
  362.         if (!getargs(args, "(sii)", &file, &flag, &mode))
  363.             return NULL;
  364.     }
  365.     BGN_SAVE
  366.     fd = open(file, flag, mode);
  367.     END_SAVE
  368.     if (fd < 0)
  369.         return dos_error();
  370.     return newintobject((long)fd);
  371. }
  372.  
  373. static object *
  374. dos_close(self, args)
  375.     object *self;
  376.     object *args;
  377. {
  378.     int fd, res;
  379.     if (!getargs(args, "i", &fd))
  380.         return NULL;
  381.     BGN_SAVE
  382.     res = close(fd);
  383.     END_SAVE
  384.     if (res < 0)
  385.         return dos_error();
  386.     INCREF(None);
  387.     return None;
  388. }
  389.  
  390. static object *
  391. dos_dup(self, args)
  392.     object *self;
  393.     object *args;
  394. {
  395.     int fd;
  396.     if (!getargs(args, "i", &fd))
  397.         return NULL;
  398.     BGN_SAVE
  399.     fd = dup(fd);
  400.     END_SAVE
  401.     if (fd < 0)
  402.         return dos_error();
  403.     return newintobject((long)fd);
  404. }
  405.  
  406. static object *
  407. dos_dup2(self, args)
  408.     object *self;
  409.     object *args;
  410. {
  411.     int fd, fd2, res;
  412.     if (!getargs(args, "(ii)", &fd, &fd2))
  413.         return NULL;
  414.     BGN_SAVE
  415.     res = dup2(fd, fd2);
  416.     END_SAVE
  417.     if (res < 0)
  418.         return dos_error();
  419.     INCREF(None);
  420.     return None;
  421. }
  422.  
  423. static object *
  424. dos_lseek(self, args)
  425.     object *self;
  426.     object *args;
  427. {
  428.     int fd, how;
  429.     long pos, res;
  430.     if (!getargs(args, "(ili)", &fd, &pos, &how))
  431.         return NULL;
  432. #ifdef SEEK_SET
  433.     /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
  434.     switch (how) {
  435.     case 0: how = SEEK_SET; break;
  436.     case 1: how = SEEK_CUR; break;
  437.     case 2: how = SEEK_END; break;
  438.     }
  439. #endif
  440.     BGN_SAVE
  441.     res = lseek(fd, pos, how);
  442.     END_SAVE
  443.     if (res < 0)
  444.         return dos_error();
  445.     return newintobject(res);
  446. }
  447.  
  448. static object *
  449. dos_read(self, args)
  450.     object *self;
  451.     object *args;
  452. {
  453.     int fd, size;
  454.     object *buffer;
  455.     if (!getargs(args, "(ii)", &fd, &size))
  456.         return NULL;
  457.     buffer = newsizedstringobject((char *)NULL, size);
  458.     if (buffer == NULL)
  459.         return NULL;
  460.     BGN_SAVE
  461.     size = read(fd, getstringvalue(buffer), size);
  462.     END_SAVE
  463.     if (size < 0) {
  464.         DECREF(buffer);
  465.         return dos_error();
  466.     }
  467.     resizestring(&buffer, size);
  468.     return buffer;
  469. }
  470.  
  471. static object *
  472. dos_write(self, args)
  473.     object *self;
  474.     object *args;
  475. {
  476.     int fd, size;
  477.     char *buffer;
  478.     if (!getargs(args, "(is#)", &fd, &buffer, &size))
  479.         return NULL;
  480.     BGN_SAVE
  481.     size = write(fd, buffer, size);
  482.     END_SAVE
  483.     if (size < 0)
  484.         return dos_error();
  485.     return newintobject((long)size);
  486. }
  487.  
  488. static object *
  489. dos_fstat(self, args)
  490.     object *self;
  491.     object *args;
  492. {
  493.     int fd;
  494.     struct stat st;
  495.     int res;
  496.     if (!getargs(args, "i", &fd))
  497.         return NULL;
  498.     BGN_SAVE
  499.     res = fstat(fd, &st);
  500.     END_SAVE
  501.     if (res != 0)
  502.         return dos_error();
  503.     return mkvalue("(llllllllll)",
  504.             (long)st.st_mode,
  505.             (long)st.st_ino,
  506.             (long)st.st_dev,
  507.             (long)st.st_nlink,
  508.             (long)st.st_uid,
  509.             (long)st.st_gid,
  510.             (long)st.st_size,
  511.             (long)st.st_atime,
  512.             (long)st.st_mtime,
  513.             (long)st.st_ctime);
  514. }
  515.  
  516. static object *
  517. dos_fdopen(self, args)
  518.     object *self;
  519.     object *args;
  520. {
  521.     extern int fclose PROTO((FILE *));
  522.     int fd;
  523.     char *mode;
  524.     FILE *fp;
  525.     if (!getargs(args, "(is)", &fd, &mode))
  526.         return NULL;
  527.     BGN_SAVE
  528.     fp = fdopen(fd, mode);
  529.     END_SAVE
  530.     if (fp == NULL)
  531.         return dos_error();
  532.     return newopenfileobject(fp, "(fdopen)", mode, fclose);
  533. }
  534.  
  535. static struct methodlist dos_methods[] = {
  536.     {"chdir",    dos_chdir},
  537.     {"chmod",    dos_chmod},
  538.     {"getcwd",    dos_getcwd},
  539.     {"listdir",    dos_listdir},
  540.     {"mkdir",    dos_mkdir},
  541.     {"rename",    dos_rename},
  542.     {"rmdir",    dos_rmdir},
  543.     {"stat",    dos_stat},
  544.     {"system",    dos_system},
  545.     {"unlink",    dos_unlink},
  546.     {"utime",    dos_utime},
  547.     {"open",    dos_open},
  548.     {"close",    dos_close},
  549.     {"dup",        dos_dup},
  550.     {"dup2",    dos_dup2},
  551.     {"lseek",    dos_lseek},
  552.     {"read",    dos_read},
  553.     {"write",    dos_write},
  554.     {"fstat",    dos_fstat},
  555.     {"fdopen",    dos_fdopen},
  556.     {NULL,        NULL}         /* Sentinel */
  557. };
  558.  
  559.  
  560. void
  561. initdos()
  562. {
  563.     object *m, *d, *v;
  564.  
  565.     m = initmodule("dos", dos_methods);
  566.     d = getmoduledict(m);
  567.  
  568.     /* Initialize dos.environ dictionary */
  569.     v = convertenviron();
  570.     if (v == NULL || dictinsert(d, "environ", v) != 0)
  571.         fatal("can't define dos.environ");
  572.     DECREF(v);
  573.  
  574.     /* Initialize dos.error exception */
  575.     DosError = newstringobject("dos.error");
  576.     if (DosError == NULL || dictinsert(d, "error", DosError) != 0)
  577.         fatal("can't define dos.error");
  578. }
  579.