mirror of https://git.tukaani.org/xz.git
Improve support for DOS-like systems.
Here DOS-like means DOS, Windows, and OS/2.
This commit is contained in:
parent
b6a30ee8c2
commit
96c46df7de
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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];
|
||||||
|
|
39
src/xz/io.c
39
src/xz/io.c
|
@ -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;
|
||||||
|
|
|
@ -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, "");
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue