Improve support for DOS-like systems.

Here DOS-like means DOS, Windows, and OS/2.
This commit is contained in:
Lasse Collin 2009-02-13 17:29:02 +02:00
parent b6a30ee8c2
commit 96c46df7de
10 changed files with 86 additions and 30 deletions

View File

@ -34,6 +34,10 @@
# include <windows.h> # include <windows.h>
#endif #endif
#ifdef __DJGPP__
# include <dpmi.h>
#endif
/// \brief Get the amount of physical memory in bytes /// \brief Get the amount of physical memory in bytes
/// ///
@ -76,6 +80,14 @@ physmem(void)
meminfo.dwLength = sizeof(meminfo); meminfo.dwLength = sizeof(meminfo);
if (GlobalMemoryStatusEx(&meminfo)) if (GlobalMemoryStatusEx(&meminfo))
ret = meminfo.ullTotalPhys; ret = meminfo.ullTotalPhys;
#elif defined(__DJGPP__)
__dpmi_free_mem_info meminfo;
if (__dpmi_get_free_memory_information(&meminfo) == 0
&& meminfo.total_number_of_physical_pages
!= (unsigned long)(-1))
ret = (uint64_t)(meminfo.total_number_of_physical_pages)
* 4096;
#endif #endif
return ret; return ret;

View File

@ -154,6 +154,10 @@ typedef unsigned char _Bool;
// Macros // // Macros //
//////////// ////////////
#if defined(_WIN32) || defined(__MSDOS__) || defined(__OS2__)
# define DOSLIKE 1
#endif
#undef memzero #undef memzero
#define memzero(s, n) memset(s, 0, n) #define memzero(s, n) memset(s, 0, n)

View File

@ -60,7 +60,7 @@ init_table(void)
* Solaris assembler doesn't have .p2align, and Darwin uses .align * Solaris assembler doesn't have .p2align, and Darwin uses .align
* differently than GNU/Linux and Solaris. * differently than GNU/Linux and Solaris.
*/ */
#ifdef __MACH__ #if defined(__MACH__) || defined(__MSDOS__)
# define ALIGN(pow2, abs) .align pow2 # define ALIGN(pow2, abs) .align pow2
#else #else
# define ALIGN(pow2, abs) .align abs # define ALIGN(pow2, abs) .align abs
@ -69,7 +69,7 @@ init_table(void)
.text .text
.globl LZMA_CRC32 .globl LZMA_CRC32
#if !defined(__MACH__) && !defined(_WIN32) #if !defined(__MACH__) && !defined(_WIN32) && !defined(__MSDOS__)
.type LZMA_CRC32, @function .type LZMA_CRC32, @function
#endif #endif
@ -275,7 +275,7 @@ LZMA_CRC32:
.ascii " -export:lzma_crc32" .ascii " -export:lzma_crc32"
# endif # endif
#else #elif !defined(__MSDOS__)
/* ELF */ /* ELF */
.size LZMA_CRC32, .-LZMA_CRC32 .size LZMA_CRC32, .-LZMA_CRC32
#endif #endif

View File

@ -53,7 +53,7 @@ init_table(void)
* Solaris assembler doesn't have .p2align, and Darwin uses .align * Solaris assembler doesn't have .p2align, and Darwin uses .align
* differently than GNU/Linux and Solaris. * differently than GNU/Linux and Solaris.
*/ */
#ifdef __MACH__ #if defined(__MACH__) || defined(__MSDOS__)
# define ALIGN(pow2, abs) .align pow2 # define ALIGN(pow2, abs) .align pow2
#else #else
# define ALIGN(pow2, abs) .align abs # define ALIGN(pow2, abs) .align abs
@ -62,7 +62,7 @@ init_table(void)
.text .text
.globl LZMA_CRC64 .globl LZMA_CRC64
#if !defined(__MACH__) && !defined(_WIN32) #if !defined(__MACH__) && !defined(_WIN32) && !defined(__MSDOS__)
.type LZMA_CRC64, @function .type LZMA_CRC64, @function
#endif #endif
@ -261,7 +261,7 @@ LZMA_CRC64:
.ascii " -export:lzma_crc64" .ascii " -export:lzma_crc64"
# endif # endif
#else #elif !defined(__MSDOS__)
/* ELF */ /* ELF */
.size LZMA_CRC64, .-LZMA_CRC64 .size LZMA_CRC64, .-LZMA_CRC64
#endif #endif

View File

@ -424,15 +424,12 @@ args_parse(args_info *args, int argc, char **argv)
// Check how we were called. // Check how we were called.
{ {
// Remove the leading path name, if any. #ifdef DOSLIKE
#ifdef _WIN32 // We adjusted argv[0] in the beginning of main() so we don't
// Some systems support both / and \ to separate path // need to do anything here.
// components. const char *name = argv[0];
const char *name = argv[0] + strlen(argv[0]);
while (argv[0] < name && name[-1] != '/' && name[-1] != '\\')
--name;
#else #else
// POSIX // Remove the leading path name, if any.
const char *name = strrchr(argv[0], '/'); const char *name = strrchr(argv[0], '/');
if (name == NULL) if (name == NULL)
name = argv[0]; name = argv[0];

View File

@ -21,6 +21,10 @@
#include <fcntl.h> #include <fcntl.h>
#ifdef DOSLIKE
# include <io.h>
#endif
#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMES) #if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMES)
# include <sys/time.h> # include <sys/time.h>
#elif defined(HAVE_UTIME) #elif defined(HAVE_UTIME)
@ -35,7 +39,7 @@
# define O_NOCTTY 0 # define O_NOCTTY 0
#endif #endif
#ifndef _WIN32 #ifndef DOSLIKE
# include "open_stdxxx.h" # include "open_stdxxx.h"
static bool warn_fchown; static bool warn_fchown;
#endif #endif
@ -44,7 +48,7 @@ static bool warn_fchown;
extern void extern void
io_init(void) io_init(void)
{ {
#ifndef _WIN32 #ifndef DOSLIKE
// Make sure that stdin, stdout, and and stderr are connected to // Make sure that stdin, stdout, and and stderr are connected to
// a valid file descriptor. Exit immediatelly with exit code ERROR // a valid file descriptor. Exit immediatelly with exit code ERROR
// if we cannot make the file descriptors valid. Maybe we should // if we cannot make the file descriptors valid. Maybe we should
@ -56,6 +60,13 @@ io_init(void)
warn_fchown = geteuid() == 0; warn_fchown = geteuid() == 0;
#endif #endif
#ifdef __DJGPP__
// Avoid doing useless things when statting files.
// This isn't important but doesn't hurt.
_djstat_flags = _STAT_INODE | _STAT_EXEC_EXT
| _STAT_EXEC_MAGIC | _STAT_DIRSIZE;
#endif
return; return;
} }
@ -70,7 +81,7 @@ static void
io_unlink(const char *name, const struct stat *known_st) io_unlink(const char *name, const struct stat *known_st)
{ {
// On Windows, st_ino is meaningless, so don't bother testing it. // On Windows, st_ino is meaningless, so don't bother testing it.
#ifndef _WIN32 #ifndef DOSLIKE
struct stat new_st; struct stat new_st;
if (lstat(name, &new_st) if (lstat(name, &new_st)
@ -98,7 +109,7 @@ static void
io_copy_attrs(const file_pair *pair) io_copy_attrs(const file_pair *pair)
{ {
// Skip chown and chmod on Windows. // Skip chown and chmod on Windows.
#ifndef _WIN32 #ifndef DOSLIKE
// This function is more tricky than you may think at first. // This function is more tricky than you may think at first.
// Blindly copying permissions may permit users to access the // Blindly copying permissions may permit users to access the
// destination file who didn't have permission to access the // destination file who didn't have permission to access the
@ -233,7 +244,7 @@ io_open_src(file_pair *pair)
// There's nothing to open when reading from stdin. // There's nothing to open when reading from stdin.
if (pair->src_name == stdin_filename) { if (pair->src_name == stdin_filename) {
pair->src_fd = STDIN_FILENO; pair->src_fd = STDIN_FILENO;
#ifdef _WIN32 #ifdef DOSLIKE
setmode(STDIN_FILENO, O_BINARY); setmode(STDIN_FILENO, O_BINARY);
#endif #endif
return false; return false;
@ -246,7 +257,7 @@ io_open_src(file_pair *pair)
// Flags for open() // Flags for open()
int flags = O_RDONLY | O_BINARY | O_NOCTTY; int flags = O_RDONLY | O_BINARY | O_NOCTTY;
#ifndef _WIN32 #ifndef DOSLIKE
// If we accept only regular files, we need to be careful to avoid // If we accept only regular files, we need to be careful to avoid
// problems with special files like devices and FIFOs. O_NONBLOCK // problems with special files like devices and FIFOs. O_NONBLOCK
// prevents blocking when opening such files. When we want to accept // prevents blocking when opening such files. When we want to accept
@ -259,7 +270,7 @@ io_open_src(file_pair *pair)
#if defined(O_NOFOLLOW) #if defined(O_NOFOLLOW)
if (reg_files_only) if (reg_files_only)
flags |= O_NOFOLLOW; flags |= O_NOFOLLOW;
#elif !defined(_WIN32) #elif !defined(DOSLIKE)
// Some POSIX-like systems lack O_NOFOLLOW (it's not required // Some POSIX-like systems lack O_NOFOLLOW (it's not required
// by POSIX). Check for symlinks with a separate lstat() on // by POSIX). Check for symlinks with a separate lstat() on
// these systems. // these systems.
@ -363,7 +374,7 @@ io_open_src(file_pair *pair)
return true; return true;
} }
#ifndef _WIN32 #ifndef DOSLIKE
// Drop O_NONBLOCK, which is used only when we are accepting only // Drop O_NONBLOCK, which is used only when we are accepting only
// regular files. After the open() call, we want things to block // regular files. After the open() call, we want things to block
// instead of giving EAGAIN. // instead of giving EAGAIN.
@ -398,7 +409,7 @@ io_open_src(file_pair *pair)
} }
// These are meaningless on Windows. // These are meaningless on Windows.
#ifndef _WIN32 #ifndef DOSLIKE
if (pair->src_st.st_mode & (S_ISUID | S_ISGID)) { if (pair->src_st.st_mode & (S_ISUID | S_ISGID)) {
// gzip rejects setuid and setgid files even // gzip rejects setuid and setgid files even
// when --force was used. bzip2 doesn't check // when --force was used. bzip2 doesn't check
@ -450,7 +461,7 @@ static void
io_close_src(file_pair *pair, bool success) io_close_src(file_pair *pair, bool success)
{ {
if (pair->src_fd != STDIN_FILENO && pair->src_fd != -1) { if (pair->src_fd != STDIN_FILENO && pair->src_fd != -1) {
#ifdef _WIN32 #ifdef DOSLIKE
(void)close(pair->src_fd); (void)close(pair->src_fd);
#endif #endif
@ -459,12 +470,12 @@ io_close_src(file_pair *pair, bool success)
// happens to get same inode number, which would make us // happens to get same inode number, which would make us
// unlink() wrong file. // unlink() wrong file.
// //
// NOTE: Windows is an exception to this, because it doesn't // NOTE: DOS-like systems are an exception to this, because
// allow unlinking files that are open. *sigh* // they don't allow unlinking files that are open. *sigh*
if (success && !opt_keep_original) if (success && !opt_keep_original)
io_unlink(pair->src_name, &pair->src_st); io_unlink(pair->src_name, &pair->src_st);
#ifndef _WIN32 #ifndef DOSLIKE
(void)close(pair->src_fd); (void)close(pair->src_fd);
#endif #endif
} }
@ -480,7 +491,7 @@ io_open_dest(file_pair *pair)
// We don't modify or free() this. // We don't modify or free() this.
pair->dest_name = (char *)"(stdout)"; pair->dest_name = (char *)"(stdout)";
pair->dest_fd = STDOUT_FILENO; pair->dest_fd = STDOUT_FILENO;
#ifdef _WIN32 #ifdef DOSLIKE
setmode(STDOUT_FILENO, O_BINARY); setmode(STDOUT_FILENO, O_BINARY);
#endif #endif
return false; return false;

View File

@ -164,6 +164,29 @@ main(int argc, char **argv)
// that stdin, stdout, and stderr are something valid. // that stdin, stdout, and stderr are something valid.
io_init(); io_init();
#ifdef DOSLIKE
// Adjust argv[0] to make it look nicer in messages, and also to
// help the code in args.c.
{
// Strip the leading path.
char *p = argv[0] + strlen(argv[0]);
while (argv[0] < p && p[-1] != '/' && p[-1] != '\\')
--p;
argv[0] = p;
// Strip the .exe suffix.
p = strrchr(p, '.');
if (p != NULL)
*p = '\0';
// Make it lowercase.
for (p = argv[0]; *p != '\0'; ++p)
if (*p >= 'A' && *p <= 'Z')
*p = *p - 'A' + 'a';
}
#endif
// Set up the locale. // Set up the locale.
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");

View File

@ -207,6 +207,9 @@ message_init(const char *given_argv0)
#ifdef _WIN32 #ifdef _WIN32
timer_queue = CreateTimerQueue(); timer_queue = CreateTimerQueue();
#else #else
# ifndef SA_RESTART
# define SA_RESTART 0
# endif
// Establish the signal handler for SIGALRM. Since this signal // Establish the signal handler for SIGALRM. Since this signal
// doesn't require any quick action, we set SA_RESTART. // doesn't require any quick action, we set SA_RESTART.
struct sigaction sa; struct sigaction sa;

View File

@ -19,6 +19,11 @@
#include "private.h" #include "private.h"
// For case-insensitive filename suffix on case-insensitive systems
#ifdef DOSLIKE
# define strcmp strcasecmp
#endif
static char *custom_suffix = NULL; static char *custom_suffix = NULL;

View File

@ -24,8 +24,9 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#ifdef _WIN32 #ifdef DOSLIKE
# include <fcntl.h> # include <fcntl.h>
# include <io.h>
#endif #endif
#include "getopt.h" #include "getopt.h"
@ -408,7 +409,7 @@ main(int argc, char **argv)
lzma_stream strm = LZMA_STREAM_INIT; lzma_stream strm = LZMA_STREAM_INIT;
// Some systems require setting stdin and stdout to binary mode. // Some systems require setting stdin and stdout to binary mode.
#ifdef _WIN32 #ifdef DOSLIKE
setmode(fileno(stdin), O_BINARY); setmode(fileno(stdin), O_BINARY);
setmode(fileno(stdout), O_BINARY); setmode(fileno(stdout), O_BINARY);
#endif #endif