📄 environ.c
字号:
/* * $Id: environ.c,v 1.14 2003/10/16 14:21:28 andrew_belov Exp $ * --------------------------------------------------------------------------- * This module contains platform-specific routines along with a set of hacks * to implement the common functions of Borland compilers and their behavior. * */#include "arj.h"#if TARGET!=UNIX#include <conio.h>#include <io.h>#include <process.h>#endif#include <fcntl.h>#if COMPILER==BCC #include <dir.h>#elif COMPILER==MSC||COMPILER==MSVC||COMPILER==ICC #include <direct.h>#endif#if TARGET!=UNIX #include <share.h>#endif#if COMPILER==MSC||COMPILER==MSVC||COMPILER==ICC||COMPILER==HIGHC||defined(__EMX__)||(TARGET==OS2&&defined(LIBC)) #include <sys/types.h> #include <sys/stat.h> #if COMPILER==HIGHC&&!defined(LIBC) #define SH_DENYRW _SH_DENYRW #define SH_DENYWR _SH_DENYWR #define SH_DENYNO _SH_DENYNO #endif#elif TARGET!=UNIX #include <share.h>#endif#if COMPILER==BCC&&TARGET==DOS #include <sys/stat.h> /* S_* only */#endif#if TARGET==UNIX #ifdef SUNOS #include <sys/statvfs.h> #include <termio.h> #endif #ifdef __sco__ #include <sys/statvfs.h> #endif #include <unistd.h> #include <fnmatch.h> #include <signal.h> /* fork()+spawnvp() control */ #include <utime.h> #include <sys/time.h> /* LIBC high-resolution timing */ #include <sys/resource.h> /* Priority control */ /* For Linux-specific IOCTL. sys/statfs.h is no longer included, since struct statfs is duplicated in linux/fs.h */ #if defined(linux) #include <sys/ioctl.h> #include <linux/fs.h> #elif defined(__FreeBSD__) #include <sys/param.h> #include <sys/mount.h> #elif defined(__QNXNTO__) #include <sys/statvfs.h> #else #include <sys/statfs.h> #endif#endif#ifdef TILED #include <dos.h>#endif#if TARGET==DOS #include "win95dos.h"#endif#if TARGET==WIN32&&!defined(F_OK) #define F_OK 0 /* For MSVCRT */#endif/* IBM toolkit -> EMX wrapper */#ifdef __EMX__ #define DosCaseMap DosMapCase #define DosQCurDisk DosQueryCurrentDisk #define DosQFileInfo DosQueryFileInfo #define DosQFSInfo DosQueryFSInfo #define DosSelectDisk DosSetDefaultDisk #define DosSetPrty DosSetPriority#endifDEBUGHDR(__FILE__) /* Debug information block *//* * DOS legacy */#if TARGET==DOS/* INT 24h */#define INT24 0x24#define INT24_IGNORE 0#define INT24_RETRY 1#define INT24_ABORT 2#define INT24_FAIL 3#define INT24_DPF_WRITING 0x0100 /* Device processing flag in AX */#define INT24_IO_ERROR 0x8000/* Character device IOCTL statements */#define CHDI_STDOUT 0x0001#define CHDI_STDIN 0x0002#define CHDI_NUL 0x0004#define CHDI_CLOCK 0x0008#define CHDI_SPECIAL 0x0010#define CHDI_BINARY 0x0020#define CHDI_EOF_ON_INPUT 0x0040#define CHDI_SET 0x0080#define CHDI_OPENCLOSE 0x0800#define CHDI_OUTPUT_TILL_BUSY 0x2000#define CHDI_CAN_IOCTL 0x4000/* File IOCTL statements */#define CHDF_NOT_WRITTEN 0x0040#define CHDF_NOT_FILE 0x0080#define CHDF_EXT_INT24 0x0100 /* DOS 4.x only */#define CHDF_NOT_REMOVABLE 0x0800#define CHDF_NO_TIMESTAMPING 0x4000#define CHDF_IS_REMOTE 0x8000/* This macro checks if DOS version is less than 3.10 */#define is_dos_31 (_osmajor<3||_osmajor==3&&_osminor<10)/* For MS C, a macro to query the current time */#if COMPILER==MSC #define g_timer(t) t=*(long FAR *)0x0000046CL#endif#endif /* TARGET==DOS *//* An OS/2 & Win32 macro to join timestamps */#if TARGET==OS2||TARGET==WIN32 #define make_ftime(fd, ft) ((unsigned long)*(USHORT *)&fd<<16)+(unsigned long)*(USHORT *)&ft#endif/* Allowable DOS file attributes (HSRA) */#if TARGET!=UNIX #define STD_FILE_ATTR (FATTR_ARCH|FATTR_SYSTEM|FATTR_HIDDEN|FATTR_RDONLY)#endif/* Attribute comparision for UNIX */#if TARGET==UNIX #define match_unix_attrs(attr, pattern) (((pattern)==0)||(((attr)&(pattern))==(pattern)))#endif/* Command-line input limit */#if TARGET==DOS #define INPUT_LIMIT 127#endif/* UNIX file time requests */#if TARGET==UNIX #define UFTREQ_FTIME 0 #define UFTREQ_ATIME 1 #define UFTREQ_CTIME 2#endif/* * Exported variables *//* Line feed string */#if SFX_LEVEL>=ARJSFX||defined(REARJ) char simple_lf[]="\n";#endif/* Carriage return */#if SFX_LEVEL>=ARJ||TARGET==DOS&&(SFX_LEVEL>=ARJSFX||defined(REARJ)) char simple_cr[]="\r";#endif/* The following systems are considered equal to host OS under which ARJ is run. The contents of this list greatly depend upon the host OS itself... */#if SFX_LEVEL>=ARJSFX #if TARGET==DOS int friendly_systems[]={OS_DOS, OS_WIN95, OS_WINNT, -1}; #elif TARGET==OS2 int friendly_systems[]={OS_DOS, OS_OS2, OS_WIN95, OS_WINNT, -1}; #elif TARGET==WIN32 int friendly_systems[]={OS_DOS, OS_WIN95, OS_WINNT, -1}; #elif TARGET==UNIX int friendly_systems[]={OS_UNIX, OS_NEXT, -1}; #endif#endif/* Standard devices */#if SFX_LEVEL>=ARJSFX #if TARGET==UNIX char dev_null[]="/dev/null"; /* NULL device */ char dev_con[]="/dev/tty"; /* Console device */ #else char dev_null[]="NUL"; /* NULL device */ char dev_con[]="CON"; /* Console device */ #endif#endif/* Wildcard used to select all files */#if SFX_LEVEL>=ARJSFX||defined(REARJ) #if TARGET==DOS char all_wildcard[]="*.*"; #else char all_wildcard[]="*"; #endif#endif/* Win32 can't use setftime_on_stream - this is required for ARJSFXJR: */#if SFX_LEVEL==ARJSFXJR&&TARGET==WIN32 #define NEED_SETFTIME_HACK#endif/* * Internal variables *//* Attribute format */#if SFX_LEVEL>=ARJSFX static char attrib_buf[]="---W"; /* ASHR if all set */#endif/* Arbitrary disk drive for LFN testing */#if SFX_LEVEL>=ARJSFX||defined(REARJ) static char drive_c[]="C:"; /* Although it's incorrect... */#endif/* Directory specifiers for file search */#if SFX_LEVEL>=ARJ||defined(REARJ) /* Subdirectory/root search wildcard */ #if TARGET==DOS char root_wildcard[]="\\*.*"; #elif TARGET==OS2||TARGET==WIN32 char root_wildcard[]="\\*"; #elif TARGET==UNIX char root_wildcard[]="/*"; #endif char up_dir_spec[]=".."; /* Parent directory specifier */ char pathsep_str[]={PATHSEP_DEFAULT, '\0'};#endif#if SFX_LEVEL>=ARJ||defined(REARJ)||(SFX_LEVEL>=ARJSFXV&&TARGET==UNIX) char cur_dir_spec[]="."; /* Current directory specifier */#endif/* FCB mask (used to fill in FCBs) */#if SFX_LEVEL>=ARJSFXV&&TARGET==DOS static char fcb_mask[]="???????????";#endif/* Queues for detecting child session shutdown */#if TARGET==OS2&&defined(REARJ) static char rearj_q_fmt[]="\\QUEUES\\REARJ#%u";#endif/* Name of file that is currently being opened */#if COMPILER==MSC&&TARGET==DOS static char *f_file_ptr=NULL;#endif/* For the case if the environment doesn't allow to query EXE name, we'll store our own ones. */#if TARGET==DOS #if SFX_LEVEL>=ARJ static char default_exe[]="arj" EXE_EXTENSION; #elif SFX_LEVEL>=ARJSFXJR static char default_exe[]="arjsfx" EXE_EXTENSION; #elif defined(REARJ) static char default_exe[]="rearj" EXE_EXTENSION; #endif#endif/* * Frequently used Borland routines *//* Returns 0 for A:, 1 for B:, etc. */#if defined(HAVE_DRIVES)&&((SFX_LEVEL>=ARJSFX||defined(REARJ))&&COMPILER!=BCC)int getdisk(){ #if TARGET==DOS int rc; _dos_getdrive((unsigned int *)&rc); return(rc-1); #elif TARGET==OS2 #ifndef __32BIT__ USHORT rc; ULONG total; DosQCurDisk(&rc, &total); return(rc-1); #else ULONG rc, total; DosQCurDisk(&rc, &total); return(rc-1); #endif #elif TARGET==WIN32 char cur_dir[CCHMAXPATH]; if(GetCurrentDirectory(sizeof(cur_dir), cur_dir)&&cur_dir[1]==':') return(cur_dir[0]-'A'); else return(-1); #endif}#endif/* Performs heap checking if required */#if SFX_LEVEL>=ARJint verify_heap(){ #if COMPILER==BCC return(heapcheck()==_HEAPCORRUPT); #elif COMPILER==MSC||COMPILER==MSVC int rc; rc=_heapchk(); return(rc!=_HEAPOK&&rc!=_HEAPEMPTY); #elif COMPILER==ICC&&defined(DEBUG) _heap_check(); return(0); #else return(0); /* Not implemented otherwise */ #endif}#endif/* Performs far heap verification (if there is any) */#if SFX_LEVEL>=ARJint verify_far_heap(){ #if COMPILER==BCC return(farheapcheck()); #elif COMPILER==MSC return(_fheapchk()); #elif !defined(TILED) return(verify_heap()); #else return(0); /* Don't even bother of it */ #endif}#endif/* Returns the available stack space */#if SFX_LEVEL>=ARJstatic unsigned int get_stack_space(){ #if defined(__BORLANDC__) return(stackavail()); #elif defined(__TURBOC__) return(_stklen+_SP); #elif COMPILER==MSC return(stackavail()); #else return(32767); #endif}#endif/* Changes the current drive to 0=A:, 1=B:, and so on... */#if defined(HAVE_DRIVES)&&(defined(REARJ)&&COMPILER!=BCC)int setdisk(int drive){ #if TARGET==DOS int numdrives; _dos_setdrive(drive+1, &numdrives); return(numdrives); #elif TARGET==OS2 #ifdef __32BIT__ ULONG rc; #else USHORT rc; #endif ULONG total; rc=DosSelectDisk(drive+1); if(rc) return(0); DosQCurDisk(&rc, &total); return(total); #elif TARGET==WIN32 char t[4]; t[0]=drive+'A'; t[1]=':'; t[2]='\0'; SetCurrentDirectory(t); return(25); /* Dummy value */ #endif}#endif/* Returns the number of bytes available in the far heap (quite slow) */#if SFX_LEVEL>=ARJSFXV&&COMPILER!=BCClong farcoreleft(){ #if TARGET==DOS void _huge *hp; static long rc=736L; long s_rc; s_rc=rc; rc+=2L; do hp=halloc(rc-=2L, 1024); while(hp==NULL&&rc>0L); if(hp!=NULL) hfree(hp); if(rc<s_rc) return(rc*1024L); do { hp=halloc(rc+=16L, 1024); if(hp!=NULL) hfree(hp); } while(hp!=NULL); return((rc-16L)*1024L); #elif TARGET==OS2 #ifdef __32BIT__ ULONG rc; DosQuerySysInfo(QSV_MAXPRMEM, QSV_MAXPRMEM, (PVOID)&rc, sizeof(rc)); return(rc); #else ULONG rc; DosMemAvail(&rc); return(rc); #endif #elif TARGET==WIN32 MEMORYSTATUS memstat; memstat.dwLength=sizeof(memstat); GlobalMemoryStatus(&memstat); return(max(0x7FFFFFFFUL, memstat.dwAvailVirtual)); #else return(1048576L); /* BUGBUG: TODO: FIXME */ #endif}#endif/* Returns the current time of day */#if (SFX_LEVEL>=ARJSFXV||defined(REARJ)||defined(REGISTER))&&COMPILER!=BCCvoid arj_gettime(struct time *ts){ #if TARGET==DOS struct dostime_t dts; _dos_gettime(&dts); ts->ti_hour=dts.hour; ts->ti_min=dts.minute; ts->ti_sec=dts.second; ts->ti_hund=dts.hsecond; #elif TARGET==OS2 DATETIME dts; DosGetDateTime(&dts); ts->ti_hour=dts.hours; ts->ti_min=dts.minutes; ts->ti_sec=dts.seconds; ts->ti_hund=dts.hundredths; #elif TARGET==WIN32 SYSTEMTIME st; GetLocalTime(&st); ts->ti_hour=st.wHour; ts->ti_min=st.wMinute; ts->ti_sec=st.wSecond; ts->ti_hund=st.wMilliseconds/10; #else time_t t; struct timeval v; struct tm *tms; do { t=time(NULL); gettimeofday(&v, NULL); } while(time(NULL)!=t); tms=localtime(&t); ts->ti_hour=tms->tm_hour; ts->ti_min=tms->tm_min; ts->ti_sec=tms->tm_sec; ts->ti_hund=v.tv_usec/10000; #endif}#endif/* Returns the current date */#if defined(REARJ)&&COMPILER!=BCCvoid arj_getdate(struct date *ds){ #if TARGET==DOS struct dosdate_t dds; _dos_getdate(&dds); ds->da_year=1980+dds.year; ds->da_day=dds.day; ds->da_mon=dds.month; #elif TARGET==OS2 DATETIME dts; DosGetDateTime(&dts); ds->da_year=dts.year; ds->da_day=dts.day; ds->da_mon=dts.month; #elif TARGET==WIN32 SYSTEMTIME st; GetLocalTime(&st); ds->da_year=st.wYear; ds->da_day=st.wDay;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -