perl 4.0 patch 14: patch #11, continued
[p5sagit/p5-mst-13.2.git] / msdos / chdir.c
1 /*
2  *    (C) Copyright 1990, 1991 Tom Dinger
3  *
4  *    You may distribute under the terms of either the GNU General Public
5  *    License or the Artistic License, as specified in the README file.
6  *
7  */
8
9 /*
10  * A "DOS-aware" chdir() function, that will change current drive as well.
11  *
12  *      chdir( "B:" )   -- changes to the default directory, on drive B:
13  *      chdir( "C:\FOO" )  changes to the specified directory, on drive C:
14  *      chdir( "\BAR" )    changes to the specified directory on the current
15  *                         drive.
16  */
17
18 #include <stdlib.h>
19 #include <ctype.h>
20 #include <direct.h>
21 #include <dos.h>
22 #include <errno.h>
23
24 #include "config.h"
25 #ifdef chdir
26 #undef chdir
27 #endif
28
29 /* We should have the line:
30  *
31  * #define chdir perl_chdir
32  *
33  * in some header for perl (I put it in config.h) so that all
34  * references to chdir() become references to this function.
35  */
36
37 /*------------------------------------------------------------------*/
38
39 #if defined(BUGGY_MSC5) /* only needed for MSC 5.1 */
40
41 int _chdrive( int drivenum )
42 {
43 unsigned int    ndrives;
44 unsigned int    tmpdrive;
45
46
47 _dos_setdrive( drivenum, &ndrives );
48
49 /* check for illegal drive letter */
50 _dos_getdrive( &tmpdrive );
51
52 return (tmpdrive != drivenum) ? -1 : 0 ;
53 }
54
55 #endif
56
57 /*-----------------------------------------------------------------*/
58
59 int perl_chdir( char * path )
60 {
61 int             drive_letter;
62 unsigned int    drivenum;
63
64
65 if ( path && *path && (path[1] == ':') )
66     {
67     /* The path starts with a drive letter */
68     /* Change current drive */
69     drive_letter = *path;
70     if ( isalpha(drive_letter) )
71         {
72         /* Drive letter legal */
73         if ( islower(drive_letter) )
74             drive_letter = toupper(drive_letter);
75         drivenum = drive_letter - 'A' + 1;
76
77         /* Change drive */
78         if ( _chdrive( drivenum ) == -1 )
79             {
80             /* Drive change failed -- must be illegal drive letter */
81             errno = ENODEV;
82             return -1;
83             }
84
85         /* Now see if that's all we do */
86         if ( ! path[2] )
87             return 0;           /* no path after drive -- all done */
88         }
89     /* else drive letter illegal -- fall into "normal" chdir */
90     }
91
92 /* Here with some path as well */
93 return chdir( path );
94
95 /* end perl_chdir() */
96 }