home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
- #include <libc/stubs.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <dpmi.h>
- #include <go32.h>
- #include <crt0.h>
- #include <libc/farptrgs.h>
- #include <libc/dosio.h>
-
- char *
- __getcwd(char *buf, size_t size)
- {
- char *bp;
- __dpmi_regs r;
- int needed_length, c;
- unsigned use_lfn = _USE_LFN;
- int preserve_case = _preserve_fncase();
- char *name_start;
-
- if (!size)
- {
- errno = EINVAL;
- return 0;
- }
- if (!buf)
- {
- buf = (char *)malloc(size);
- if (!buf)
- {
- errno = ENOMEM;
- return 0;
- }
- }
-
- /* make sure we don't overrun the TB */
- if (size > _go32_info_block.size_of_transfer_buffer)
- size = _go32_info_block.size_of_transfer_buffer;
-
- /* get the path into the transfer buffer at least */
- if(use_lfn)
- r.x.ax = 0x7147;
- else
- r.h.ah = 0x47;
- r.h.dl = 0;
- r.x.si = __tb_offset;
- r.x.ds = __tb_segment;
- __dpmi_int(0x21, &r);
-
- /* current drive may be invalid (it happens) */
- if (r.x.flags & 1)
- {
- errno = __doserr_to_errno(r.x.ax);
- return 0;
- }
-
- /* path is ASCIIZ. Scan it, filling in buf, watching for
- end of buffer. */
- _farsetsel(_dos_ds);
- needed_length = 0;
- while ((c = _farnspeekb(__tb+needed_length)))
- {
- if (needed_length+3 >= size)
- {
- errno = ERANGE;
- return 0;
- }
- buf[3+needed_length] = c;
- needed_length++;
- }
- buf[needed_length+3] = 0;
-
- /* switch FOO\BAR to foo/bar, downcase where appropriate */
- buf[1] = ':';
- buf[2] = '/';
- for (bp = buf+3, name_start = bp - 1; *name_start; bp++)
- {
- char long_name[FILENAME_MAX], short_name[13];
-
- if (*bp == '\\')
- *bp = '/';
- if (!preserve_case && (*bp == '/' || *bp == '\0'))
- {
- memcpy(long_name, name_start+1, bp - name_start - 1);
- long_name[bp - name_start - 1] = '\0';
- if (!strcmp(_lfn_gen_short_fname(long_name, short_name), long_name))
- {
- while (++name_start < bp)
- if (*name_start >= 'A' && *name_start <= 'Z')
- *name_start += 'a' - 'A';
- }
- else
- name_start = bp;
- }
- else if (*bp == '\0')
- break;
- }
-
- /* get current drive */
- r.h.ah = 0x19;
- __dpmi_int(0x21, &r);
-
- buf[0] = r.h.al + (r.h.al < 26 ? 'a' : 'A');
-
- return buf;
- }
-
- #ifdef TEST
-
- int main(void)
- {
- printf (getcwd ((char *)0, FILENAME_MAX + 10));
- return 0;
- }
-
- #endif
-