1 /****************************************************************************
3 * SciTech MGL Graphics Library
5 * ========================================================================
7 * The contents of this file are subject to the SciTech MGL Public
8 * License Version 1.0 (the "License"); you may not use this file
9 * except in compliance with the License. You may obtain a copy of
10 * the License at http://www.scitechsoft.com/mgl-license.txt
12 * Software distributed under the License is distributed on an
13 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * rights and limitations under the License.
17 * The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
19 * The Initial Developer of the Original Code is SciTech Software, Inc.
20 * All Rights Reserved.
22 * ========================================================================
27 * Description: Module to implement a the OS specific side of the Binary
28 * Portable DLL C runtime library. The functions in here
29 * are imported into the Binary Portable DLL's to implement
30 * OS specific services.
32 ****************************************************************************/
35 #if defined(__WIN32_VXD__) || defined(__NT_DRIVER__)
36 #include "drvlib/peloader.h"
37 #include "drvlib/attrib.h"
38 #include "drvlib/libc/init.h"
39 #define __BUILDING_PE_LOADER__
40 #include "drvlib/libc/file.h"
41 #if defined(__WIN32_VXD__)
52 #if defined(__GNUC__) || defined(__UNIX__)
54 #include <sys/types.h>
59 #include "drvlib/attrib.h"
60 #include "drvlib/libc/init.h"
61 #define __BUILDING_PE_LOADER__
62 #include "drvlib/libc/file.h"
63 #if defined(__WINDOWS__) || defined(TNT) || defined(__RTTARGET__)
64 #define WIN32_LEAN_AND_MEAN
73 #define INCL_DOSERRORS
79 /* No text or binary modes for Unix */
86 /*--------------------------- Global variables ----------------------------*/
88 #if defined(__WIN32_VXD__) || defined(__NT_DRIVER__)
90 static FILE *openHandles[MAX_FILES] = {NULL};
93 /* <stdlib.h> stub functions */
94 void _CDECL stub_abort(void);
95 int _CDECL stub_atexit(void (*)(void));
96 void * _CDECL stub_calloc(size_t _nelem, size_t _size);
97 void _CDECL stub_exit(int _status);
98 void _CDECL stub_free(void *_ptr);
99 char * _CDECL stub_getenv(const char *_name);
100 void * _CDECL stub_malloc(size_t _size);
101 void * _CDECL stub_realloc(void *_ptr, size_t _size);
102 int _CDECL stub_system(const char *_s);
103 int _CDECL stub_putenv(const char *_val);
105 /* <libc/file.h> stub functions */
106 int _CDECL stub_open(const char *_path, int _oflag, unsigned _mode);
107 int _CDECL stub_access(const char *_path, int _amode);
108 int _CDECL stub_close(int _fildes);
109 off_t _CDECL stub_lseek(int _fildes, off_t _offset, int _whence);
110 size_t _CDECL stub_read(int _fildes, void *_buf, size_t _nbyte);
111 int _CDECL stub_unlink(const char *_path);
112 size_t _CDECL stub_write(int _fildes, const void *_buf, size_t _nbyte);
113 int _CDECL stub_isatty(int _fildes);
115 /* <stdio.h> stub functions */
116 int _CDECL stub_remove(const char *_filename);
117 int _CDECL stub_rename(const char *_old, const char *_new);
119 /* <time.h> stub functions */
120 time_t _CDECL stub_time(time_t *_tod);
122 /* <signal.h> stub functions */
123 int _CDECL stub_raise(int);
124 void * _CDECL stub_signal(int, void *);
126 /* <drvlib/attrib.h> functions */
127 #define stub_OS_setfileattr _OS_setfileattr
128 #define stub_OS_getcurrentdate _OS_getcurrentdate
130 LIBC_imports _VARAPI ___imports = {
131 sizeof(LIBC_imports),
133 /* <stdlib.h> exports */
145 /* <libc/file.h> exports */
155 /* <stdio.h> exports */
159 /* <signal.h> functions */
163 /* <time.h> exports */
166 /* <drvlib/attrib.h> exports */
168 stub_OS_getcurrentdate,
171 /*---------------------- Stub function implementation ---------------------*/
173 /* <stdlib.h> stub functions */
174 void _CDECL stub_abort(void)
176 #if !defined( __WIN32_VXD__) && !defined(__NT_DRIVER__)
181 int _CDECL stub_atexit(void (*func)(void))
183 #if !defined( __WIN32_VXD__) && !defined(__NT_DRIVER__)
184 return atexit((void(*)(void))func);
190 void * _CDECL stub_calloc(size_t _nelem, size_t _size)
191 { return __PM_calloc(_nelem,_size); }
193 void _CDECL stub_exit(int _status)
195 #if !defined( __WIN32_VXD__) && !defined(__NT_DRIVER__)
200 void _CDECL stub_free(void *_ptr)
203 char * _CDECL stub_getenv(const char *_name)
205 #if defined( __WIN32_VXD__) || defined(__NT_DRIVER__)
208 return getenv(_name);
212 void * _CDECL stub_malloc(size_t _size)
213 { return __PM_malloc(_size); }
215 void * _CDECL stub_realloc(void *_ptr, size_t _size)
216 { return __PM_realloc(_ptr,_size); }
218 int _CDECL stub_system(const char *_s)
220 #if defined(__WINDOWS__) || defined(__WIN32_VXD__) || defined(__NT_DRIVER__) || defined(__SMX32__) || defined(__RTTARGET__)
228 int _CDECL stub_putenv(const char *_val)
230 #if defined( __WIN32_VXD__) || defined(__NT_DRIVER__)
233 return putenv((char*)_val);
237 time_t _CDECL stub_time(time_t *_tod)
239 #if defined( __WIN32_VXD__) || defined(__NT_DRIVER__)
246 #if defined(__MSDOS__)
248 #if defined(TNT) && defined(_MSC_VER)
250 void _CDECL _OS_setfileattr(const char *filename,unsigned attrib)
251 { SetFileAttributes((LPSTR)filename, (DWORD)attrib); }
255 void _CDECL _OS_setfileattr(const char *filename,unsigned attrib)
256 { _dos_setfileattr(filename,attrib); }
260 #elif defined(__WIN32_VXD__)
262 #define USE_LOCAL_FILEIO
263 #define USE_LOCAL_GETDATE
265 /* <libc/file.h> stub functions */
266 int _CDECL stub_open(const char *_path, int _oflag, unsigned _mode)
271 /* Find an empty file handle to use */
272 for (i = 3; i < MAX_FILES; i++) {
279 /* Find the open flags to use */
280 if (_oflag & ___O_TRUNC)
282 else if (_oflag & ___O_CREAT)
286 if (_oflag & ___O_BINARY)
288 if (_oflag & ___O_TEXT)
291 /* Open the file and store the file handle */
292 if ((openHandles[i] = fopen(_path,mode)) == NULL)
297 int _CDECL stub_access(const char *_path, int _amode)
300 int _CDECL stub_close(int _fildes)
302 if (_fildes >= 3 && openHandles[_fildes]) {
303 fclose(openHandles[_fildes]);
304 openHandles[_fildes] = NULL;
309 off_t _CDECL stub_lseek(int _fildes, off_t _offset, int _whence)
312 fseek(openHandles[_fildes],_offset,_whence);
313 return ftell(openHandles[_fildes]);
318 size_t _CDECL stub_read(int _fildes, void *_buf, size_t _nbyte)
321 return fread(_buf,1,_nbyte,openHandles[_fildes]);
325 int _CDECL stub_unlink(const char *_path)
330 if (R0_DeleteFile((char*)_path,0,&error))
335 return i_remove(_path);
338 size_t _CDECL stub_write(int _fildes, const void *_buf, size_t _nbyte)
341 return fwrite(_buf,1,_nbyte,openHandles[_fildes]);
345 int _CDECL stub_isatty(int _fildes)
348 /* <stdio.h> stub functions */
349 int _CDECL stub_remove(const char *_filename)
350 { return stub_unlink(_filename); }
352 int _CDECL stub_rename(const char *_old, const char *_new)
355 void _CDECL _OS_setfileattr(const char *filename,unsigned attrib)
359 R0_SetFileAttributes((char*)filename,attrib,&error);
362 /* Return the current date in days since 1/1/1980 */
363 ulong _CDECL _OS_getcurrentdate(void)
366 VTD_Get_Date_And_Time(&date);
370 #elif defined(__NT_DRIVER__)
372 #define USE_LOCAL_FILEIO
373 #define USE_LOCAL_GETDATE
375 /* <libc/file.h> stub functions */
376 int _CDECL stub_open(const char *_path, int _oflag, unsigned _mode)
381 /* Find an empty file handle to use */
382 for (i = 3; i < MAX_FILES; i++) {
389 /* Find the open flags to use */
390 if (_oflag & ___O_TRUNC)
392 else if (_oflag & ___O_CREAT)
396 if (_oflag & ___O_BINARY)
398 if (_oflag & ___O_TEXT)
401 /* Open the file and store the file handle */
402 if ((openHandles[i] = fopen(_path,mode)) == NULL)
407 int _CDECL stub_close(int _fildes)
409 if (_fildes >= 3 && openHandles[_fildes]) {
410 fclose(openHandles[_fildes]);
411 openHandles[_fildes] = NULL;
416 off_t _CDECL stub_lseek(int _fildes, off_t _offset, int _whence)
419 fseek(openHandles[_fildes],_offset,_whence);
420 return ftell(openHandles[_fildes]);
425 size_t _CDECL stub_read(int _fildes, void *_buf, size_t _nbyte)
428 return fread(_buf,1,_nbyte,openHandles[_fildes]);
432 size_t _CDECL stub_write(int _fildes, const void *_buf, size_t _nbyte)
435 return fwrite(_buf,1,_nbyte,openHandles[_fildes]);
439 int _CDECL stub_access(const char *_path, int _amode)
442 int _CDECL stub_isatty(int _fildes)
445 int _CDECL stub_unlink(const char *_path)
447 // TODO: Implement this!
451 /* <stdio.h> stub functions */
452 int _CDECL stub_remove(const char *_filename)
453 { return stub_unlink(_filename); }
455 int _CDECL stub_rename(const char *_old, const char *_new)
457 // TODO: Implement this!
461 void _CDECL _OS_setfileattr(const char *filename,unsigned attrib)
464 if (attrib & __A_RDONLY)
465 _attr |= FILE_ATTRIBUTE_READONLY;
466 if (attrib & __A_HIDDEN)
467 _attr |= FILE_ATTRIBUTE_HIDDEN;
468 if (attrib & __A_SYSTEM)
469 _attr |= FILE_ATTRIBUTE_SYSTEM;
470 PM_setFileAttr(filename,_attr);
473 /* Return the current date in days since 1/1/1980 */
474 ulong _CDECL _OS_getcurrentdate(void)
477 _int64 count,count_1_1_1980;
487 RtlTimeFieldsToTime(&tm,(PLARGE_INTEGER)&count_1_1_1980);
488 KeQuerySystemTime((PLARGE_INTEGER)&count);
489 return (ulong)( (count - count_1_1_1980) / ((_int64)24 * (_int64)3600 * (_int64)10000000) );
492 #elif defined(__WINDOWS32__) || defined(__RTTARGET__)
494 void _CDECL _OS_setfileattr(const char *filename,unsigned attrib)
495 { SetFileAttributes((LPSTR)filename, (DWORD)attrib); }
497 #elif defined(__OS2__)
499 #define USE_LOCAL_FILEIO
505 void _CDECL _OS_setfileattr(const char *filename,unsigned attrib)
508 if (DosQueryPathInfo((PSZ)filename,FIL_STANDARD,(PVOID)&s,sizeof(s)))
511 DosSetPathInfo((PSZ)filename,FIL_STANDARD,(PVOID)&s,sizeof(s),0L);
514 /* <libc/file.h> stub functions */
516 #define BUF_SIZE 4096
518 /* Note: the implementation of the standard Unix-ish handle-based I/O isn't
519 * complete - but that wasn't the intent either. Note also that we
520 * don't presently support text file I/O, so all text files end
521 * up in Unix format (and are not translated!).
523 int _CDECL stub_open(const char *_path, int _oflag, unsigned _mode)
526 ULONG error, actiontaken, openflag, openmode;
527 char path[PM_MAX_PATH];
529 /* Determine open flags */
530 if (_oflag & ___O_CREAT) {
531 if (_oflag & ___O_EXCL)
532 openflag = OPEN_ACTION_FAIL_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
533 else if (_oflag & ___O_TRUNC)
534 openflag = OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
536 openflag = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
538 else if (_oflag & ___O_TRUNC)
539 openflag = OPEN_ACTION_REPLACE_IF_EXISTS;
541 openflag = OPEN_ACTION_OPEN_IF_EXISTS;
543 /* Determine open mode flags */
544 if (_oflag & ___O_RDONLY)
545 openmode = OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE;
546 else if (_oflag & ___O_WRONLY)
547 openmode = OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYWRITE;
549 openmode = OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYWRITE;
551 /* Copy the path to a variable on the stack. We need to do this
552 * for OS/2 as when the drivers are loaded into shared kernel
553 * memory, we can't pass an address from that memory range to
557 if (DosOpen(path, &handle, &actiontaken, 0, FILE_NORMAL,
558 openflag, openmode, NULL) != NO_ERROR)
561 /* Handle append mode of operation */
562 if (_oflag & ___O_APPEND) {
563 if (DosSetFilePtr(handle, 0, FILE_END, &error) != NO_ERROR)
569 int _CDECL stub_access(const char *_path, int _amode)
571 char path[PM_MAX_PATH];
574 /* Copy the path to a variable on the stack. We need to do this
575 * for OS/2 as when the drivers are loaded into shared kernel
576 * memory, we can't pass an address from that memory range to
580 if (DosQueryPathInfo(path, FIL_STANDARD, &fs, sizeof(fs)) != NO_ERROR)
582 if ((_amode & W_OK) && (fs.attrFile & FILE_READONLY))
587 int _CDECL stub_close(int _fildes)
589 if (DosClose(_fildes) != NO_ERROR)
594 off_t _CDECL stub_lseek(int _fildes, off_t _offset, int _whence)
596 ULONG cbActual, origin;
600 origin = FILE_CURRENT;
608 if (DosSetFilePtr(_fildes, _offset, origin, &cbActual) != NO_ERROR)
613 size_t _CDECL stub_read(int _fildes, void *_buf, size_t _nbyte)
615 ULONG cbActual = 0,cbRead;
617 uchar file_io_buf[BUF_SIZE];
619 /* We need to perform the physical read in chunks into a
620 * a temporary static buffer, since the buffer passed in may be
621 * in kernel space and will cause DosRead to bail internally.
623 while (_nbyte > BUF_SIZE) {
624 if (DosRead(_fildes, file_io_buf, BUF_SIZE, &cbRead) != NO_ERROR)
627 memcpy(p,file_io_buf,BUF_SIZE);
632 if (DosRead(_fildes, file_io_buf, _nbyte, &cbRead) != NO_ERROR)
635 memcpy(p,file_io_buf,_nbyte);
640 size_t _CDECL stub_write(int _fildes, const void *_buf, size_t _nbyte)
642 ULONG cbActual = 0,cbWrite;
643 uchar *p = (PVOID)_buf;
644 uchar file_io_buf[BUF_SIZE];
646 /* We need to perform the physical write in chunks from a
647 * a temporary static buffer, since the buffer passed in may be
648 * in kernel space and will cause DosWrite to bail internally.
650 while (_nbyte > BUF_SIZE) {
651 memcpy(file_io_buf,p,BUF_SIZE);
652 if (DosWrite(_fildes, file_io_buf, BUF_SIZE, &cbWrite) != NO_ERROR)
659 memcpy(file_io_buf,p,_nbyte);
660 if (DosWrite(_fildes, file_io_buf, _nbyte, &cbWrite) != NO_ERROR)
667 int _CDECL stub_unlink(const char *_path)
669 char path[PM_MAX_PATH];
671 /* Copy the path to a variable on the stack. We need to do this
672 * for OS/2 as when the drivers are loaded into shared kernel
673 * memory, we can't pass an address from that memory range to
677 if (DosDelete(path) != NO_ERROR)
682 int _CDECL stub_isatty(int _fildes)
686 if (DosQueryHType(_fildes, &htype, &flags) != NO_ERROR)
688 return ((htype & 0xFF) == HANDTYPE_DEVICE);
691 /* <stdio.h> stub functions */
692 int _CDECL stub_remove(const char *_path)
694 char path[PM_MAX_PATH];
696 /* Copy the path to a variable on the stack. We need to do this
697 * for OS/2 as when the drivers are loaded into shared kernel
698 * memory, we can't pass an address from that memory range to
702 if (DosDelete(path) != NO_ERROR)
707 int _CDECL stub_rename(const char *_old, const char *_new)
709 char old[PM_MAX_PATH];
710 char new[PM_MAX_PATH];
712 /* Copy the path to a variable on the stack. We need to do this
713 * for OS/2 as when the drivers are loaded into shared kernel
714 * memory, we can't pass an address from that memory range to
719 if (DosMove(old, new) != NO_ERROR)
726 void _CDECL _OS_setfileattr(const char *filename,unsigned attrib)
727 { /* Unable to set hidden, system attributes on Unix. */ }
731 #ifndef USE_LOCAL_FILEIO
733 /* <libc/file.h> stub functions */
734 int _CDECL stub_open(const char *_path, int _oflag, unsigned _mode)
737 ___O_RDONLY, O_RDONLY,
738 ___O_WRONLY, O_WRONLY,
740 ___O_BINARY, O_BINARY,
745 ___O_APPEND, O_APPEND,
749 /* Translate the oflag's to the OS dependent versions */
750 for (i = 0; i < sizeof(oflag_tab) / sizeof(int); i += 2) {
751 if (_oflag & oflag_tab[i])
752 oflag |= oflag_tab[i+1];
754 return open(_path,oflag,_mode);
757 int _CDECL stub_access(const char *_path, int _amode)
758 { return access(_path,_amode); }
760 int _CDECL stub_close(int _fildes)
761 { return close(_fildes); }
763 off_t _CDECL stub_lseek(int _fildes, off_t _offset, int _whence)
764 { return lseek(_fildes,_offset,_whence); }
766 size_t _CDECL stub_read(int _fildes, void *_buf, size_t _nbyte)
767 { return read(_fildes,_buf,_nbyte); }
769 int _CDECL stub_unlink(const char *_path)
770 { return unlink(_path); }
772 size_t _CDECL stub_write(int _fildes, const void *_buf, size_t _nbyte)
773 { return write(_fildes,_buf,_nbyte); }
775 int _CDECL stub_isatty(int _fildes)
776 { return isatty(_fildes); }
778 /* <stdio.h> stub functions */
779 int _CDECL stub_remove(const char *_filename)
780 { return remove(_filename); }
782 int _CDECL stub_rename(const char *_old, const char *_new)
783 { return rename(_old,_new); }
787 #ifndef USE_LOCAL_GETDATE
789 /* Return the current date in days since 1/1/1980 */
790 ulong _CDECL _OS_getcurrentdate(void)
793 refTime.tm_year = 80;
799 refTime.tm_isdst = -1;
800 return (time(NULL) - mktime(&refTime)) / (24 * 3600L);
805 int _CDECL stub_raise(int sig)
807 #if defined(__WIN32_VXD__) || defined(__NT_DRIVER__) || defined(__SMX32__)
815 typedef void (*__code_ptr)(int);
817 typedef void (*__code_ptr)();
820 void * _CDECL stub_signal(int sig, void *handler)
822 #if defined(__WIN32_VXD__) || defined(__NT_DRIVER__) || defined(__SMX32__)
825 return (void*)signal(sig,(__code_ptr)handler);