mirror of
https://git.tukaani.org/xz.git
synced 2024-04-04 12:36:23 +02:00
Various changes.
Separate a few reusable components from XZ Utils specific code. The reusable code is now in "tuklib" modules. A few more could be separated still, e.g. bswap.h. Fix some bugs in lzmainfo. Fix physmem and cpucores code on OS/2. Thanks to Elbert Pol for help. Add OpenVMS support into physmem. Add a few #ifdefs to ease building XZ Utils on OpenVMS. Thanks to Jouk Jansen for the original patch.
This commit is contained in:
parent
49cfc8d392
commit
e599bba421
37 changed files with 768 additions and 434 deletions
1
THANKS
1
THANKS
|
@ -16,6 +16,7 @@ has been important. :-) In alphabetical order:
|
||||||
- Robert Elz
|
- Robert Elz
|
||||||
- Mike Frysinger
|
- Mike Frysinger
|
||||||
- Peter Ivanov
|
- Peter Ivanov
|
||||||
|
- Jouk Jansen
|
||||||
- Per Øyvind Karlsen
|
- Per Øyvind Karlsen
|
||||||
- Thomas Klausner
|
- Thomas Klausner
|
||||||
- Richard Koch
|
- Richard Koch
|
||||||
|
|
12
configure.ac
12
configure.ac
|
@ -485,12 +485,7 @@ AC_CHECK_HEADERS([fcntl.h limits.h sys/time.h],
|
||||||
[AC_MSG_ERROR([Required header file(s) are missing.])])
|
[AC_MSG_ERROR([Required header file(s) are missing.])])
|
||||||
|
|
||||||
# If any of these headers are missing, things should still work correctly:
|
# If any of these headers are missing, things should still work correctly:
|
||||||
AC_CHECK_HEADERS([sys/param.h sys/sysctl.h byteswap.h],
|
AC_CHECK_HEADERS([byteswap.h])
|
||||||
[], [], [
|
|
||||||
#ifdef HAVE_SYS_PARAM_H
|
|
||||||
# include <sys/param.h>
|
|
||||||
#endif
|
|
||||||
])
|
|
||||||
|
|
||||||
# Even if we have byteswap.h, we may lack the specific macros/functions.
|
# Even if we have byteswap.h, we may lack the specific macros/functions.
|
||||||
if test x$ac_cv_header_byteswap_h = xyes ; then
|
if test x$ac_cv_header_byteswap_h = xyes ; then
|
||||||
|
@ -558,8 +553,9 @@ gl_GETOPT
|
||||||
# Find the best function to set timestamps.
|
# Find the best function to set timestamps.
|
||||||
AC_CHECK_FUNCS([futimens futimes futimesat utimes utime], [break])
|
AC_CHECK_FUNCS([futimens futimes futimesat utimes utime], [break])
|
||||||
|
|
||||||
lc_PHYSMEM
|
TUKLIB_PROGNAME
|
||||||
lc_CPUCORES
|
TUKLIB_PHYSMEM
|
||||||
|
TUKLIB_CPUCORES
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
|
@ -1,84 +0,0 @@
|
||||||
dnl ###########################################################################
|
|
||||||
dnl
|
|
||||||
dnl lc_PHYSMEM - Check how to find out the amount of physical memory
|
|
||||||
dnl
|
|
||||||
dnl - sysconf() gives all the needed info on GNU+Linux and Solaris.
|
|
||||||
dnl - BSDs use sysctl().
|
|
||||||
dnl - sysinfo() works on Linux/dietlibc and probably on other Linux systems
|
|
||||||
dnl whose libc may lack sysconf().
|
|
||||||
dnl
|
|
||||||
dnl ###########################################################################
|
|
||||||
dnl
|
|
||||||
dnl Author: Lasse Collin
|
|
||||||
dnl
|
|
||||||
dnl This file has been put into the public domain.
|
|
||||||
dnl You can do whatever you want with this file.
|
|
||||||
dnl
|
|
||||||
dnl ###########################################################################
|
|
||||||
AC_DEFUN([lc_PHYSMEM], [
|
|
||||||
AC_MSG_CHECKING([how to detect the amount of physical memory])
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
|
||||||
#include <unistd.h>
|
|
||||||
int
|
|
||||||
main(void)
|
|
||||||
{
|
|
||||||
long i;
|
|
||||||
i = sysconf(_SC_PAGESIZE);
|
|
||||||
i = sysconf(_SC_PHYS_PAGES);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
]])], [
|
|
||||||
AC_DEFINE([HAVE_PHYSMEM_SYSCONF], [1],
|
|
||||||
[Define to 1 if the amount of physical memory can be detected
|
|
||||||
with sysconf(_SC_PAGESIZE) and sysconf(_SC_PHYS_PAGES).])
|
|
||||||
AC_MSG_RESULT([sysconf])
|
|
||||||
], [
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
|
||||||
#include <sys/types.h>
|
|
||||||
#ifdef HAVE_SYS_PARAM_H
|
|
||||||
# include <sys/param.h>
|
|
||||||
#endif
|
|
||||||
#include <sys/sysctl.h>
|
|
||||||
int
|
|
||||||
main(void)
|
|
||||||
{
|
|
||||||
int name[2] = { CTL_HW, HW_PHYSMEM };
|
|
||||||
unsigned long mem;
|
|
||||||
size_t mem_ptr_size = sizeof(mem);
|
|
||||||
sysctl(name, 2, &mem, &mem_ptr_size, NULL, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
]])], [
|
|
||||||
AC_DEFINE([HAVE_PHYSMEM_SYSCTL], [1],
|
|
||||||
[Define to 1 if the amount of physical memory can be detected
|
|
||||||
with sysctl().])
|
|
||||||
AC_MSG_RESULT([sysctl])
|
|
||||||
], [
|
|
||||||
dnl sysinfo() is Linux-specific. Some non-Linux systems have
|
|
||||||
dnl incompatible sysinfo() so we must check $host_os.
|
|
||||||
case $host_os in
|
|
||||||
linux*)
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
|
||||||
#include <sys/sysinfo.h>
|
|
||||||
int
|
|
||||||
main(void)
|
|
||||||
{
|
|
||||||
struct sysinfo si;
|
|
||||||
sysinfo(&si);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
]])], [
|
|
||||||
AC_DEFINE([HAVE_PHYSMEM_SYSINFO], [1],
|
|
||||||
[Define to 1 if the amount of physical memory
|
|
||||||
can be detected with Linux sysinfo().])
|
|
||||||
AC_MSG_RESULT([sysinfo])
|
|
||||||
], [
|
|
||||||
AC_MSG_RESULT([unknown])
|
|
||||||
])
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
AC_MSG_RESULT([unknown])
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
])])
|
|
||||||
])dnl lc_PHYSMEM
|
|
22
m4/tuklib_common.m4
Normal file
22
m4/tuklib_common.m4
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# TUKLIB_COMMON
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# Common checks for tuklib.
|
||||||
|
#
|
||||||
|
# COPYING
|
||||||
|
#
|
||||||
|
# Author: Lasse Collin
|
||||||
|
#
|
||||||
|
# This file has been put into the public domain.
|
||||||
|
# You can do whatever you want with this file.
|
||||||
|
#
|
||||||
|
|
||||||
|
AC_DEFUN_ONCE([TUKLIB_COMMON], [
|
||||||
|
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||||
|
AC_REQUIRE([AC_PROG_CC_C99])
|
||||||
|
AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
|
||||||
|
])dnl
|
|
@ -1,36 +1,35 @@
|
||||||
dnl ###########################################################################
|
#
|
||||||
dnl
|
# SYNOPSIS
|
||||||
dnl lc_CPUCORES - Check how to find out the number of online CPU cores
|
#
|
||||||
dnl
|
# TUKLIB_CPUCORES
|
||||||
dnl Check how to find out the number of available CPU cores in the system.
|
#
|
||||||
dnl sysconf(_SC_NPROCESSORS_ONLN) works on most systems, except that BSDs
|
# DESCRIPTION
|
||||||
dnl use sysctl().
|
#
|
||||||
dnl
|
# Check how to find out the number of available CPU cores in the system.
|
||||||
dnl ###########################################################################
|
# This information is used by tuklib_cpucores.c.
|
||||||
dnl
|
#
|
||||||
dnl Author: Lasse Collin
|
# Currently this supports sysctl() (BSDs, OS/2) and sysconf() (GNU/Linux,
|
||||||
dnl
|
# Solaris, Cygwin).
|
||||||
dnl This file has been put into the public domain.
|
#
|
||||||
dnl You can do whatever you want with this file.
|
# COPYING
|
||||||
dnl
|
#
|
||||||
dnl ###########################################################################
|
# Author: Lasse Collin
|
||||||
AC_DEFUN([lc_CPUCORES], [
|
#
|
||||||
|
# This file has been put into the public domain.
|
||||||
|
# You can do whatever you want with this file.
|
||||||
|
#
|
||||||
|
|
||||||
|
AC_DEFUN_ONCE([TUKLIB_CPUCORES], [
|
||||||
|
AC_REQUIRE([TUKLIB_COMMON])
|
||||||
|
|
||||||
|
# sys/param.h might be needed by sys/sysctl.h.
|
||||||
|
AC_CHECK_HEADERS([sys/param.h])
|
||||||
|
|
||||||
AC_MSG_CHECKING([how to detect the number of available CPU cores])
|
AC_MSG_CHECKING([how to detect the number of available CPU cores])
|
||||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
|
||||||
#include <unistd.h>
|
# Look for sysctl() solution first, because on OS/2, both sysconf()
|
||||||
int
|
# and sysctl() pass the tests in this file, but only sysctl()
|
||||||
main(void)
|
# actually works.
|
||||||
{
|
|
||||||
long i;
|
|
||||||
i = sysconf(_SC_NPROCESSORS_ONLN);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
]])], [
|
|
||||||
AC_DEFINE([HAVE_CPUCORES_SYSCONF], [1],
|
|
||||||
[Define to 1 if the number of available CPU cores can be
|
|
||||||
detected with sysconf(_SC_NPROCESSORS_ONLN).])
|
|
||||||
AC_MSG_RESULT([sysconf])
|
|
||||||
], [
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#ifdef HAVE_SYS_PARAM_H
|
#ifdef HAVE_SYS_PARAM_H
|
||||||
|
@ -47,11 +46,27 @@ main(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
]])], [
|
]])], [
|
||||||
AC_DEFINE([HAVE_CPUCORES_SYSCTL], [1],
|
AC_DEFINE([TUKLIB_CPUCORES_SYSCTL], [1],
|
||||||
[Define to 1 if the number of available CPU cores can be
|
[Define to 1 if the number of available CPU cores can be
|
||||||
detected with sysctl().])
|
detected with sysctl().])
|
||||||
AC_MSG_RESULT([sysctl])
|
AC_MSG_RESULT([sysctl])
|
||||||
], [
|
], [
|
||||||
|
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
||||||
|
#include <unistd.h>
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
long i;
|
||||||
|
i = sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
]])], [
|
||||||
|
AC_DEFINE([TUKLIB_CPUCORES_SYSCONF], [1],
|
||||||
|
[Define to 1 if the number of available CPU cores can be
|
||||||
|
detected with sysconf(_SC_NPROCESSORS_ONLN).])
|
||||||
|
AC_MSG_RESULT([sysconf])
|
||||||
|
], [
|
||||||
AC_MSG_RESULT([unknown])
|
AC_MSG_RESULT([unknown])
|
||||||
])])
|
])])
|
||||||
])dnl lc_CPUCORES
|
])dnl
|
119
m4/tuklib_physmem.m4
Normal file
119
m4/tuklib_physmem.m4
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# TUKLIB_PHYSMEM
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# Check how to get the amount of physical memory.
|
||||||
|
# This information is used in tuklib_physmem.c.
|
||||||
|
#
|
||||||
|
# Supported methods:
|
||||||
|
#
|
||||||
|
# - Windows (including Cygwin), OS/2, DJGPP (DOS), and OpenVMS have
|
||||||
|
# operating-system specific functions.
|
||||||
|
#
|
||||||
|
# - sysconf() works on GNU/Linux and Solaris, and possibly on
|
||||||
|
# some BSDs.
|
||||||
|
#
|
||||||
|
# - BSDs use sysctl().
|
||||||
|
#
|
||||||
|
# - sysinfo() works on Linux/dietlibc and probably on other Linux
|
||||||
|
# systems whose libc may lack sysconf().
|
||||||
|
#
|
||||||
|
# COPYING
|
||||||
|
#
|
||||||
|
# Author: Lasse Collin
|
||||||
|
#
|
||||||
|
# This file has been put into the public domain.
|
||||||
|
# You can do whatever you want with this file.
|
||||||
|
#
|
||||||
|
|
||||||
|
AC_DEFUN_ONCE([TUKLIB_PHYSMEM], [
|
||||||
|
AC_REQUIRE([TUKLIB_COMMON])
|
||||||
|
|
||||||
|
# sys/param.h might be needed by sys/sysctl.h.
|
||||||
|
AC_CHECK_HEADERS([sys/param.h])
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([how to detect the amount of physical memory])
|
||||||
|
|
||||||
|
# Maybe checking $host_os would be enough but this matches what
|
||||||
|
# tuklib_physmem.c does.
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
||||||
|
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__OS2__) \
|
||||||
|
|| defined(__DJGPP__) || defined(__VMS)
|
||||||
|
int main(void) { return 0; }
|
||||||
|
#else
|
||||||
|
#error
|
||||||
|
#endif
|
||||||
|
]])], [
|
||||||
|
AC_MSG_RESULT([special])
|
||||||
|
], [
|
||||||
|
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
||||||
|
#include <unistd.h>
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
long i;
|
||||||
|
i = sysconf(_SC_PAGESIZE);
|
||||||
|
i = sysconf(_SC_PHYS_PAGES);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
]])], [
|
||||||
|
AC_DEFINE([TUKLIB_PHYSMEM_SYSCONF], [1],
|
||||||
|
[Define to 1 if the amount of physical memory can be detected
|
||||||
|
with sysconf(_SC_PAGESIZE) and sysconf(_SC_PHYS_PAGES).])
|
||||||
|
AC_MSG_RESULT([sysconf])
|
||||||
|
], [
|
||||||
|
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
||||||
|
#include <sys/types.h>
|
||||||
|
#ifdef HAVE_SYS_PARAM_H
|
||||||
|
# include <sys/param.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
int name[2] = { CTL_HW, HW_PHYSMEM };
|
||||||
|
unsigned long mem;
|
||||||
|
size_t mem_ptr_size = sizeof(mem);
|
||||||
|
sysctl(name, 2, &mem, &mem_ptr_size, NULL, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
]])], [
|
||||||
|
AC_DEFINE([TUKLIB_PHYSMEM_SYSCTL], [1],
|
||||||
|
[Define to 1 if the amount of physical memory can be detected
|
||||||
|
with sysctl().])
|
||||||
|
AC_MSG_RESULT([sysctl])
|
||||||
|
], [
|
||||||
|
|
||||||
|
# This version of sysinfo() is Linux-specific. Some non-Linux systems have
|
||||||
|
# different sysinfo() so we must check $host_os.
|
||||||
|
case $host_os in
|
||||||
|
linux*)
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
||||||
|
#include <sys/sysinfo.h>
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
struct sysinfo si;
|
||||||
|
sysinfo(&si);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
]])], [
|
||||||
|
AC_DEFINE([TUKLIB_PHYSMEM_SYSINFO], [1],
|
||||||
|
[Define to 1 if the amount of physical memory
|
||||||
|
can be detected with Linux sysinfo().])
|
||||||
|
AC_MSG_RESULT([sysinfo])
|
||||||
|
], [
|
||||||
|
AC_MSG_RESULT([unknown])
|
||||||
|
])
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AC_MSG_RESULT([unknown])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
])])])
|
||||||
|
])dnl
|
25
m4/tuklib_progname.m4
Normal file
25
m4/tuklib_progname.m4
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# TUKLIB_PROGNAME
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# Put argv[0] into a global variable progname. On DOS-like systems,
|
||||||
|
# modify it so that it looks nice (no full path or .exe suffix).
|
||||||
|
#
|
||||||
|
# This .m4 file is needed allow this module to use glibc's
|
||||||
|
# program_invocation_name.
|
||||||
|
#
|
||||||
|
# COPYING
|
||||||
|
#
|
||||||
|
# Author: Lasse Collin
|
||||||
|
#
|
||||||
|
# This file has been put into the public domain.
|
||||||
|
# You can do whatever you want with this file.
|
||||||
|
#
|
||||||
|
|
||||||
|
AC_DEFUN_ONCE([TUKLIB_PROGNAME], [
|
||||||
|
AC_REQUIRE([TUKLIB_COMMON])
|
||||||
|
AC_CHECK_DECLS([program_invocation_name], [], [], [#include <errno.h>])
|
||||||
|
])dnl
|
|
@ -147,10 +147,6 @@ 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)
|
||||||
|
|
||||||
|
|
67
src/common/tuklib_common.h
Normal file
67
src/common/tuklib_common.h
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
/// \file tuklib_common.h
|
||||||
|
/// \brief Common definitions for tuklib modules
|
||||||
|
//
|
||||||
|
// Author: Lasse Collin
|
||||||
|
//
|
||||||
|
// This file has been put into the public domain.
|
||||||
|
// You can do whatever you want with this file.
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef TUKLIB_COMMON_H
|
||||||
|
#define TUKLIB_COMMON_H
|
||||||
|
|
||||||
|
// The config file may be replaced by a package-specific file.
|
||||||
|
// It should include at least stddef.h, inttypes.h, and limits.h.
|
||||||
|
#include "tuklib_config.h"
|
||||||
|
|
||||||
|
// TUKLIB_SYMBOL_PREFIX is prefixed to all symbols exported by
|
||||||
|
// the tuklib modules. If you use a tuklib module in a library,
|
||||||
|
// you should use TUKLIB_SYMBOL_PREFIX to make sure that there
|
||||||
|
// are no symbol conflicts in case someone links your library
|
||||||
|
// into application that also uses the same tuklib module.
|
||||||
|
#ifndef TUKLIB_SYMBOL_PREFIX
|
||||||
|
# define TUKLIB_SYMBOL_PREFIX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TUKLIB_CAT_X(a, b) a ## b
|
||||||
|
#define TUKLIB_CAT(a, b) TUKLIB_CAT_X(a, b)
|
||||||
|
|
||||||
|
#ifndef TUKLIB_SYMBOL
|
||||||
|
# define TUKLIB_SYMBOL(sym) TUKLIB_CAT(TUKLIB_SYMBOL_PREFIX, sym)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TUKLIB_DECLS_BEGIN
|
||||||
|
# ifdef __cplusplus
|
||||||
|
# define TUKLIB_DECLS_BEGIN extern "C" {
|
||||||
|
# else
|
||||||
|
# define TUKLIB_DECLS_BEGIN
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TUKLIB_DECLS_END
|
||||||
|
# ifdef __cplusplus
|
||||||
|
# define TUKLIB_DECLS_END }
|
||||||
|
# else
|
||||||
|
# define TUKLIB_DECLS_END
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TUKLIB_GNUC_REQ(major, minor) \
|
||||||
|
(defined(__GNUC__) && defined(__GNUC_MINOR__) \
|
||||||
|
&& ((__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)) \
|
||||||
|
|| __GNUC__ > (major)))
|
||||||
|
|
||||||
|
#if TUKLIB_GNUC_REQ(2, 5)
|
||||||
|
# define tuklib_attr_noreturn __attribute__((__noreturn__))
|
||||||
|
#else
|
||||||
|
# define tuklib_attr_noreturn
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(__OS2__) || defined(__MSDOS__)
|
||||||
|
# define TUKLIB_DOSLIKE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
1
src/common/tuklib_config.h
Normal file
1
src/common/tuklib_config.h
Normal file
|
@ -0,0 +1 @@
|
||||||
|
#include "sysdefs.h"
|
|
@ -1,7 +1,7 @@
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
/// \file cpucores.h
|
/// \file tuklib_cpucores.c
|
||||||
/// \brief Get the number of online CPU cores
|
/// \brief Get the number of CPU cores online
|
||||||
//
|
//
|
||||||
// Author: Lasse Collin
|
// Author: Lasse Collin
|
||||||
//
|
//
|
||||||
|
@ -10,42 +10,37 @@
|
||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef CPUCORES_H
|
#include "tuklib_cpucores.h"
|
||||||
#define CPUCORES_H
|
|
||||||
|
|
||||||
#if defined(HAVE_CPUCORES_SYSCONF)
|
#if defined(TUKLIB_CPUCORES_SYSCTL)
|
||||||
# include <unistd.h>
|
|
||||||
|
|
||||||
#elif defined(HAVE_CPUCORES_SYSCTL)
|
|
||||||
# ifdef HAVE_SYS_PARAM_H
|
# ifdef HAVE_SYS_PARAM_H
|
||||||
# include <sys/param.h>
|
# include <sys/param.h>
|
||||||
# endif
|
# endif
|
||||||
# ifdef HAVE_SYS_SYSCTL_H
|
|
||||||
# include <sys/sysctl.h>
|
# include <sys/sysctl.h>
|
||||||
# endif
|
|
||||||
|
#elif defined(TUKLIB_CPUCORES_SYSCONF)
|
||||||
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static inline uint32_t
|
extern uint32_t
|
||||||
cpucores(void)
|
tuklib_cpucores(void)
|
||||||
{
|
{
|
||||||
uint32_t ret = 0;
|
uint32_t ret = 0;
|
||||||
|
|
||||||
#if defined(HAVE_CPUCORES_SYSCONF)
|
#if defined(TUKLIB_CPUCORES_SYSCTL)
|
||||||
const long cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
|
||||||
if (cpus > 0)
|
|
||||||
ret = (uint32_t)(cpus);
|
|
||||||
|
|
||||||
#elif defined(HAVE_CPUCORES_SYSCTL)
|
|
||||||
int name[2] = { CTL_HW, HW_NCPU };
|
int name[2] = { CTL_HW, HW_NCPU };
|
||||||
int cpus;
|
int cpus;
|
||||||
size_t cpus_size = sizeof(cpus);
|
size_t cpus_size = sizeof(cpus);
|
||||||
if (sysctl(name, 2, &cpus, &cpus_size, NULL, 0) != -1
|
if (sysctl(name, 2, &cpus, &cpus_size, NULL, 0) != -1
|
||||||
&& cpus_size == sizeof(cpus) && cpus > 0)
|
&& cpus_size == sizeof(cpus) && cpus > 0)
|
||||||
ret = (uint32_t)(cpus);
|
ret = (uint32_t)cpus;
|
||||||
|
|
||||||
|
#elif defined(TUKLIB_CPUCORES_SYSCONF)
|
||||||
|
const long cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
|
if (cpus > 0)
|
||||||
|
ret = (uint32_t)cpus;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
23
src/common/tuklib_cpucores.h
Normal file
23
src/common/tuklib_cpucores.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
/// \file tuklib_cpucores.h
|
||||||
|
/// \brief Get the number of CPU cores online
|
||||||
|
//
|
||||||
|
// Author: Lasse Collin
|
||||||
|
//
|
||||||
|
// This file has been put into the public domain.
|
||||||
|
// You can do whatever you want with this file.
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef TUKLIB_CPUCORES_H
|
||||||
|
#define TUKLIB_CPUCORES_H
|
||||||
|
|
||||||
|
#include "tuklib_common.h"
|
||||||
|
TUKLIB_DECLS_BEGIN
|
||||||
|
|
||||||
|
#define tuklib_cpucores TUKLIB_SYMBOL(tuklib_cpucores)
|
||||||
|
extern uint32_t tuklib_cpucores(void);
|
||||||
|
|
||||||
|
TUKLIB_DECLS_END
|
||||||
|
#endif
|
57
src/common/tuklib_exit.c
Normal file
57
src/common/tuklib_exit.c
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
/// \file tuklib_exit.c
|
||||||
|
/// \brief Close stdout and stderr, and exit
|
||||||
|
//
|
||||||
|
// Author: Lasse Collin
|
||||||
|
//
|
||||||
|
// This file has been put into the public domain.
|
||||||
|
// You can do whatever you want with this file.
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "tuklib_common.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "tuklib_gettext.h"
|
||||||
|
#include "tuklib_progname.h"
|
||||||
|
#include "tuklib_exit.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern void
|
||||||
|
tuklib_exit(int status, int err_status, int show_error)
|
||||||
|
{
|
||||||
|
if (status != err_status) {
|
||||||
|
// Close stdout. If something goes wrong,
|
||||||
|
// print an error message to stderr.
|
||||||
|
const int ferror_err = ferror(stdout);
|
||||||
|
const int fclose_err = fclose(stdout);
|
||||||
|
if (ferror_err || fclose_err) {
|
||||||
|
status = err_status;
|
||||||
|
|
||||||
|
// If it was fclose() that failed, we have the reason
|
||||||
|
// in errno. If only ferror() indicated an error,
|
||||||
|
// we have no idea what the reason was.
|
||||||
|
if (show_error)
|
||||||
|
fprintf(stderr, "%s: %s: %s\n", progname,
|
||||||
|
_("Writing to standard "
|
||||||
|
"output failed"),
|
||||||
|
fclose_err ? strerror(errno)
|
||||||
|
: _("Unknown error"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != err_status) {
|
||||||
|
// Close stderr. If something goes wrong, there's
|
||||||
|
// nothing where we could print an error message.
|
||||||
|
// Just set the exit status.
|
||||||
|
const int ferror_err = ferror(stderr);
|
||||||
|
const int fclose_err = fclose(stderr);
|
||||||
|
if (fclose_err || ferror_err)
|
||||||
|
status = err_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(status);
|
||||||
|
}
|
25
src/common/tuklib_exit.h
Normal file
25
src/common/tuklib_exit.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
/// \file tuklib_exit.h
|
||||||
|
/// \brief Close stdout and stderr, and exit
|
||||||
|
/// \note Requires tuklib_progname and tuklib_gettext modules
|
||||||
|
//
|
||||||
|
// Author: Lasse Collin
|
||||||
|
//
|
||||||
|
// This file has been put into the public domain.
|
||||||
|
// You can do whatever you want with this file.
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef TUKLIB_EXIT_H
|
||||||
|
#define TUKLIB_EXIT_H
|
||||||
|
|
||||||
|
#include "tuklib_common.h"
|
||||||
|
TUKLIB_DECLS_BEGIN
|
||||||
|
|
||||||
|
#define tuklib_exit TUKLIB_SYMBOL(tuklib_exit)
|
||||||
|
extern void tuklib_exit(int status, int err_status, int show_error)
|
||||||
|
tuklib_attr_noreturn;
|
||||||
|
|
||||||
|
TUKLIB_DECLS_END
|
||||||
|
#endif
|
44
src/common/tuklib_gettext.h
Normal file
44
src/common/tuklib_gettext.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
/// \file tuklib_gettext.h
|
||||||
|
/// \brief Wrapper for gettext and friends
|
||||||
|
//
|
||||||
|
// Author: Lasse Collin
|
||||||
|
//
|
||||||
|
// This file has been put into the public domain.
|
||||||
|
// You can do whatever you want with this file.
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef TUKLIB_GETTEXT_H
|
||||||
|
#define TUKLIB_GETTEXT_H
|
||||||
|
|
||||||
|
#include "tuklib_common.h"
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
#ifndef TUKLIB_GETTEXT
|
||||||
|
# ifdef ENABLE_NLS
|
||||||
|
# define TUKLIB_GETTEXT 1
|
||||||
|
# else
|
||||||
|
# define TUKLIB_GETTEXT 0
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TUKLIB_GETTEXT
|
||||||
|
# include <libintl.h>
|
||||||
|
# define tuklib_gettext_init(package, localedir) \
|
||||||
|
do { \
|
||||||
|
setlocale(LC_ALL, ""); \
|
||||||
|
bindtextdomain(package, localedir); \
|
||||||
|
textdomain(package); \
|
||||||
|
} while (0)
|
||||||
|
# define _(msgid) gettext(msgid)
|
||||||
|
# define N_(msgid1, msgid2, n) ngettext(msgid1, msgid2, n)
|
||||||
|
#else
|
||||||
|
# define tuklib_gettext_init(package, localedir) \
|
||||||
|
setlocale(LC_ALL, "")
|
||||||
|
# define _(msgid) (msgid)
|
||||||
|
# define N_(msgid1, msgid2, n) ((n) == 1 ? (msgid1) : (msgid2))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,6 +1,6 @@
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
/// \file open_stdxxx.h
|
/// \file tuklib_open_stdxxx.c
|
||||||
/// \brief Make sure that file descriptors 0, 1, and 2 are open
|
/// \brief Make sure that file descriptors 0, 1, and 2 are open
|
||||||
//
|
//
|
||||||
// Author: Lasse Collin
|
// Author: Lasse Collin
|
||||||
|
@ -10,17 +10,20 @@
|
||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef OPEN_STDXXX_H
|
#include "tuklib_open_stdxxx.h"
|
||||||
#define OPEN_STDXXX_H
|
|
||||||
|
|
||||||
|
#ifndef TUKLIB_DOSLIKE
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
|
# include <errno.h>
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void
|
extern void
|
||||||
open_stdxxx(int status)
|
tuklib_open_stdxxx(int err_status)
|
||||||
{
|
{
|
||||||
|
#ifndef TUKLIB_DOSLIKE
|
||||||
for (int i = 0; i <= 2; ++i) {
|
for (int i = 0; i <= 2; ++i) {
|
||||||
// We use fcntl() to check if the file descriptor is open.
|
// We use fcntl() to check if the file descriptor is open.
|
||||||
if (fcntl(i, F_GETFD) == -1 && errno == EBADF) {
|
if (fcntl(i, F_GETFD) == -1 && errno == EBADF) {
|
||||||
|
@ -38,12 +41,11 @@ open_stdxxx(int status)
|
||||||
// may very well be non-existent. This
|
// may very well be non-existent. This
|
||||||
// error should be extremely rare.
|
// error should be extremely rare.
|
||||||
(void)close(fd);
|
(void)close(fd);
|
||||||
exit(status);
|
exit(err_status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
23
src/common/tuklib_open_stdxxx.h
Normal file
23
src/common/tuklib_open_stdxxx.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
/// \file tuklib_open_stdxxx.h
|
||||||
|
/// \brief Make sure that file descriptors 0, 1, and 2 are open
|
||||||
|
//
|
||||||
|
// Author: Lasse Collin
|
||||||
|
//
|
||||||
|
// This file has been put into the public domain.
|
||||||
|
// You can do whatever you want with this file.
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef TUKLIB_OPEN_STDXXX_H
|
||||||
|
#define TUKLIB_OPEN_STDXXX_H
|
||||||
|
|
||||||
|
#include "tuklib_common.h"
|
||||||
|
TUKLIB_DECLS_BEGIN
|
||||||
|
|
||||||
|
#define tuklib_open_stdxx TUKLIB_SYMBOL(tuklib_open_stdxxx)
|
||||||
|
extern void tuklib_open_stdxxx(int err_status);
|
||||||
|
|
||||||
|
TUKLIB_DECLS_END
|
||||||
|
#endif
|
|
@ -1,6 +1,6 @@
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
/// \file physmem.h
|
/// \file tuklib_physmem.c
|
||||||
/// \brief Get the amount of physical memory
|
/// \brief Get the amount of physical memory
|
||||||
//
|
//
|
||||||
// Author: Lasse Collin
|
// Author: Lasse Collin
|
||||||
|
@ -10,12 +10,11 @@
|
||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef PHYSMEM_H
|
#include "tuklib_physmem.h"
|
||||||
#define PHYSMEM_H
|
|
||||||
|
|
||||||
// Test for Windows first, because we want to use Windows-specific code
|
// We want to use Windows-specific code on Cygwin, which also has memory
|
||||||
// on Cygwin, which also has memory information available via sysconf(), but
|
// information available via sysconf(), but on Cygwin 1.5 and older it
|
||||||
// on Cygwin 1.5 and older it gives wrong results (from our point of view).
|
// gives wrong results (from our point of view).
|
||||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
# ifndef _WIN32_WINNT
|
# ifndef _WIN32_WINNT
|
||||||
# define _WIN32_WINNT 0x0500
|
# define _WIN32_WINNT 0x0500
|
||||||
|
@ -29,28 +28,28 @@
|
||||||
#elif defined(__DJGPP__)
|
#elif defined(__DJGPP__)
|
||||||
# include <dpmi.h>
|
# include <dpmi.h>
|
||||||
|
|
||||||
#elif defined(HAVE_PHYSMEM_SYSCONF)
|
#elif defined(__VMS)
|
||||||
|
# include <lib$routines.h>
|
||||||
|
# include <syidef.h>
|
||||||
|
# include <ssdef.h>
|
||||||
|
|
||||||
|
#elif defined(TUKLIB_PHYSMEM_SYSCONF)
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
|
|
||||||
#elif defined(HAVE_PHYSMEM_SYSCTL)
|
#elif defined(TUKLIB_PHYSMEM_SYSCTL)
|
||||||
# ifdef HAVE_SYS_PARAM_H
|
# ifdef HAVE_SYS_PARAM_H
|
||||||
# include <sys/param.h>
|
# include <sys/param.h>
|
||||||
# endif
|
# endif
|
||||||
# ifdef HAVE_SYS_SYSCTL_H
|
|
||||||
# include <sys/sysctl.h>
|
# include <sys/sysctl.h>
|
||||||
# endif
|
|
||||||
|
|
||||||
#elif defined(HAVE_PHYSMEM_SYSINFO)
|
// This sysinfo() is Linux-specific.
|
||||||
|
#elif defined(TUKLIB_PHYSMEM_SYSINFO)
|
||||||
# include <sys/sysinfo.h>
|
# include <sys/sysinfo.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/// \brief Get the amount of physical memory in bytes
|
extern uint64_t
|
||||||
///
|
tuklib_physmem(void)
|
||||||
/// \return Amount of physical memory in bytes. On error, zero is
|
|
||||||
/// returned.
|
|
||||||
static inline uint64_t
|
|
||||||
physmem(void)
|
|
||||||
{
|
{
|
||||||
uint64_t ret = 0;
|
uint64_t ret = 0;
|
||||||
|
|
||||||
|
@ -93,11 +92,16 @@ physmem(void)
|
||||||
__dpmi_free_mem_info meminfo;
|
__dpmi_free_mem_info meminfo;
|
||||||
if (__dpmi_get_free_memory_information(&meminfo) == 0
|
if (__dpmi_get_free_memory_information(&meminfo) == 0
|
||||||
&& meminfo.total_number_of_physical_pages
|
&& meminfo.total_number_of_physical_pages
|
||||||
!= (unsigned long)(-1))
|
!= (unsigned long)-1)
|
||||||
ret = (uint64_t)(meminfo.total_number_of_physical_pages)
|
ret = (uint64_t)meminfo.total_number_of_physical_pages * 4096;
|
||||||
* 4096;
|
|
||||||
|
|
||||||
#elif defined(HAVE_PHYSMEM_SYSCONF)
|
#elif defined(__VMS)
|
||||||
|
int vms_mem;
|
||||||
|
int val = SYI$_MEMSIZE;
|
||||||
|
if (LIB$GETSYI(&val, &vms_mem, 0, 0, 0, 0) == SS$_NORMAL)
|
||||||
|
ret = (uint64_t)vms_mem * 8192;
|
||||||
|
|
||||||
|
#elif defined(TUKLIB_PHYSMEM_SYSCONF)
|
||||||
const long pagesize = sysconf(_SC_PAGESIZE);
|
const long pagesize = sysconf(_SC_PAGESIZE);
|
||||||
const long pages = sysconf(_SC_PHYS_PAGES);
|
const long pages = sysconf(_SC_PHYS_PAGES);
|
||||||
if (pagesize != -1 || pages != -1)
|
if (pagesize != -1 || pages != -1)
|
||||||
|
@ -106,9 +110,9 @@ physmem(void)
|
||||||
// which may report exactly 4 GiB of RAM, and "long"
|
// which may report exactly 4 GiB of RAM, and "long"
|
||||||
// being 32-bit will overflow. Casting to uint64_t
|
// being 32-bit will overflow. Casting to uint64_t
|
||||||
// hopefully avoids overflows in the near future.
|
// hopefully avoids overflows in the near future.
|
||||||
ret = (uint64_t)(pagesize) * (uint64_t)(pages);
|
ret = (uint64_t)pagesize * (uint64_t)pages;
|
||||||
|
|
||||||
#elif defined(HAVE_PHYSMEM_SYSCTL)
|
#elif defined(TUKLIB_PHYSMEM_SYSCTL)
|
||||||
int name[2] = {
|
int name[2] = {
|
||||||
CTL_HW,
|
CTL_HW,
|
||||||
#ifdef HW_PHYSMEM64
|
#ifdef HW_PHYSMEM64
|
||||||
|
@ -132,13 +136,11 @@ physmem(void)
|
||||||
ret = mem.u32;
|
ret = mem.u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(HAVE_PHYSMEM_SYSINFO)
|
#elif defined(TUKLIB_PHYSMEM_SYSINFO)
|
||||||
struct sysinfo si;
|
struct sysinfo si;
|
||||||
if (sysinfo(&si) == 0)
|
if (sysinfo(&si) == 0)
|
||||||
ret = (uint64_t)(si.totalram) * si.mem_unit;
|
ret = (uint64_t)si.totalram * si.mem_unit;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
28
src/common/tuklib_physmem.h
Normal file
28
src/common/tuklib_physmem.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
/// \file tuklib_physmem.h
|
||||||
|
/// \brief Get the amount of physical memory
|
||||||
|
//
|
||||||
|
// Author: Lasse Collin
|
||||||
|
//
|
||||||
|
// This file has been put into the public domain.
|
||||||
|
// You can do whatever you want with this file.
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef TUKLIB_PHYSMEM_H
|
||||||
|
#define TUKLIB_PHYSMEM_H
|
||||||
|
|
||||||
|
#include "tuklib_common.h"
|
||||||
|
TUKLIB_DECLS_BEGIN
|
||||||
|
|
||||||
|
#define tuklib_physmem TUKLIB_SYMBOL(tuklib_physmem)
|
||||||
|
extern uint64_t tuklib_physmem(void);
|
||||||
|
///<
|
||||||
|
/// \brief Get the amount of physical memory in bytes
|
||||||
|
///
|
||||||
|
/// \return Amount of physical memory in bytes. On error, zero is
|
||||||
|
/// returned.
|
||||||
|
|
||||||
|
TUKLIB_DECLS_END
|
||||||
|
#endif
|
50
src/common/tuklib_progname.c
Normal file
50
src/common/tuklib_progname.c
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
/// \file tuklib_progname.c
|
||||||
|
/// \brief Program name to be displayd in messages
|
||||||
|
//
|
||||||
|
// Author: Lasse Collin
|
||||||
|
//
|
||||||
|
// This file has been put into the public domain.
|
||||||
|
// You can do whatever you want with this file.
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "tuklib_progname.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
#if !HAVE_DECL_PROGRAM_INVOCATION_NAME
|
||||||
|
char *progname = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
extern void
|
||||||
|
tuklib_progname_init(char **argv)
|
||||||
|
{
|
||||||
|
#ifdef TUKLIB_DOSLIKE
|
||||||
|
// On these systems, argv[0] always has the full path and .exe
|
||||||
|
// suffix even if the user just types the plain program name.
|
||||||
|
// We modify argv[0] to make it nicer to read.
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
progname = argv[0];
|
||||||
|
return;
|
||||||
|
}
|
32
src/common/tuklib_progname.h
Normal file
32
src/common/tuklib_progname.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
/// \file tuklib_progname.h
|
||||||
|
/// \brief Program name to be displayd in messages
|
||||||
|
//
|
||||||
|
// Author: Lasse Collin
|
||||||
|
//
|
||||||
|
// This file has been put into the public domain.
|
||||||
|
// You can do whatever you want with this file.
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef TUKLIB_PROGNAME_H
|
||||||
|
#define TUKLIB_PROGNAME_H
|
||||||
|
|
||||||
|
#include "tuklib_common.h"
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
TUKLIB_DECLS_BEGIN
|
||||||
|
|
||||||
|
#if HAVE_DECL_PROGRAM_INVOCATION_NAME
|
||||||
|
# define progname program_invocation_name
|
||||||
|
#else
|
||||||
|
# define progname TUKLIB_SYMBOL(tuklib_progname)
|
||||||
|
extern char *progname;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define tuklib_progname_init TUKLIB_SYMBOL(tuklib_progname_init)
|
||||||
|
extern void tuklib_progname_init(char **argv);
|
||||||
|
|
||||||
|
TUKLIB_DECLS_END
|
||||||
|
#endif
|
|
@ -7,7 +7,10 @@
|
||||||
|
|
||||||
bin_PROGRAMS = lzmainfo
|
bin_PROGRAMS = lzmainfo
|
||||||
|
|
||||||
lzmainfo_SOURCES = lzmainfo.c
|
lzmainfo_SOURCES = \
|
||||||
|
lzmainfo.c \
|
||||||
|
$(top_srcdir)/src/common/tuklib_progname.c \
|
||||||
|
$(top_srcdir)/src/common/tuklib_exit.c
|
||||||
|
|
||||||
lzmainfo_CPPFLAGS = \
|
lzmainfo_CPPFLAGS = \
|
||||||
-DLOCALEDIR=\"$(localedir)\" \
|
-DLOCALEDIR=\"$(localedir)\" \
|
||||||
|
|
|
@ -23,39 +23,9 @@
|
||||||
|
|
||||||
#include "lzma.h"
|
#include "lzma.h"
|
||||||
#include "getopt.h"
|
#include "getopt.h"
|
||||||
|
#include "tuklib_gettext.h"
|
||||||
|
#include "tuklib_progname.h"
|
||||||
/// Name of the program from argv[0]
|
#include "tuklib_exit.h"
|
||||||
static const char *argv0;
|
|
||||||
|
|
||||||
|
|
||||||
/// Close stdout unless we are already going to exit with EXIT_FAILURE.
|
|
||||||
/// If closing stdout fails, set exit status to EXIT_FAILURE and print
|
|
||||||
/// an error message to stderr. We don't care about closing stderr,
|
|
||||||
/// because we don't print anything to stderr unless we are going to
|
|
||||||
/// use EXIT_FAILURE anyway.
|
|
||||||
static void lzma_attribute((noreturn))
|
|
||||||
my_exit(int status)
|
|
||||||
{
|
|
||||||
if (status != EXIT_FAILURE) {
|
|
||||||
const int ferror_err = ferror(stdout);
|
|
||||||
const int fclose_err = fclose(stdout);
|
|
||||||
|
|
||||||
if (ferror_err || fclose_err) {
|
|
||||||
// If it was fclose() that failed, we have the reason
|
|
||||||
// in errno. If only ferror() indicated an error,
|
|
||||||
// we have no idea what the reason was.
|
|
||||||
fprintf(stderr, "%s: %s: %s\n", argv0,
|
|
||||||
_("Writing to standard output "
|
|
||||||
"failed"),
|
|
||||||
fclose_err ? strerror(errno)
|
|
||||||
: _("Unknown error"));
|
|
||||||
status = EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void lzma_attribute((noreturn))
|
static void lzma_attribute((noreturn))
|
||||||
|
@ -63,7 +33,7 @@ help(void)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
_("Usage: %s [--help] [--version] [FILE]...\n"
|
_("Usage: %s [--help] [--version] [FILE]...\n"
|
||||||
"Show information stored in the .lzma file header"), argv0);
|
"Show information stored in the .lzma file header"), progname);
|
||||||
|
|
||||||
printf(_(
|
printf(_(
|
||||||
"\nWith no FILE, or when FILE is -, read standard input.\n"));
|
"\nWith no FILE, or when FILE is -, read standard input.\n"));
|
||||||
|
@ -73,7 +43,7 @@ _("Usage: %s [--help] [--version] [FILE]...\n"
|
||||||
PACKAGE_BUGREPORT);
|
PACKAGE_BUGREPORT);
|
||||||
printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_HOMEPAGE);
|
printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_HOMEPAGE);
|
||||||
|
|
||||||
my_exit(EXIT_SUCCESS);
|
tuklib_exit(EXIT_SUCCESS, EXIT_FAILURE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,7 +51,7 @@ static void lzma_attribute((noreturn))
|
||||||
version(void)
|
version(void)
|
||||||
{
|
{
|
||||||
puts("lzmainfo (" PACKAGE_NAME ") " PACKAGE_VERSION);
|
puts("lzmainfo (" PACKAGE_NAME ") " PACKAGE_VERSION);
|
||||||
my_exit(EXIT_SUCCESS);
|
tuklib_exit(EXIT_SUCCESS, EXIT_FAILURE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -135,7 +105,7 @@ lzmainfo(const char *name, FILE *f)
|
||||||
uint8_t buf[13];
|
uint8_t buf[13];
|
||||||
const size_t size = fread(buf, 1, sizeof(buf), f);
|
const size_t size = fread(buf, 1, sizeof(buf), f);
|
||||||
if (size != 13) {
|
if (size != 13) {
|
||||||
fprintf(stderr, "%s: %s: %s\n", argv0, name,
|
fprintf(stderr, "%s: %s: %s\n", progname, name,
|
||||||
ferror(f) ? strerror(errno)
|
ferror(f) ? strerror(errno)
|
||||||
: _("File is too small to be a .lzma file"));
|
: _("File is too small to be a .lzma file"));
|
||||||
return true;
|
return true;
|
||||||
|
@ -149,16 +119,17 @@ lzmainfo(const char *name, FILE *f)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LZMA_OPTIONS_ERROR:
|
case LZMA_OPTIONS_ERROR:
|
||||||
fprintf(stderr, "%s: %s: %s\n", argv0, name,
|
fprintf(stderr, "%s: %s: %s\n", progname, name,
|
||||||
_("Not a .lzma file"));
|
_("Not a .lzma file"));
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case LZMA_MEM_ERROR:
|
case LZMA_MEM_ERROR:
|
||||||
fprintf(stderr, "%s: %s\n", argv0, strerror(ENOMEM));
|
fprintf(stderr, "%s: %s\n", progname, strerror(ENOMEM));
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "%s: %s\n", argv0, _("Internal error (bug)"));
|
fprintf(stderr, "%s: %s\n", progname,
|
||||||
|
_("Internal error (bug)"));
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,16 +173,19 @@ lzmainfo(const char *name, FILE *f)
|
||||||
extern int
|
extern int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret = EXIT_SUCCESS;
|
tuklib_progname_init(argv);
|
||||||
argv0 = argv[0];
|
tuklib_gettext_init(PACKAGE, LOCALEDIR);
|
||||||
|
|
||||||
parse_args(argc, argv);
|
parse_args(argc, argv);
|
||||||
|
|
||||||
|
int ret = EXIT_SUCCESS;
|
||||||
|
|
||||||
// We print empty lines around the output only when reading from
|
// We print empty lines around the output only when reading from
|
||||||
// files specified on the command line. This is due to how
|
// files specified on the command line. This is due to how
|
||||||
// LZMA Utils did it.
|
// LZMA Utils did it.
|
||||||
if (optind == argc) {
|
if (optind == argc) {
|
||||||
lzmainfo("(stdin)", stdin);
|
if (lzmainfo("(stdin)", stdin))
|
||||||
|
ret = EXIT_FAILURE;
|
||||||
} else {
|
} else {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
@ -224,7 +198,8 @@ main(int argc, char **argv)
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
ret = EXIT_FAILURE;
|
ret = EXIT_FAILURE;
|
||||||
fprintf(stderr, "%s: %s: %s\n",
|
fprintf(stderr, "%s: %s: %s\n",
|
||||||
argv0, argv[optind],
|
progname,
|
||||||
|
argv[optind],
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -238,5 +213,5 @@ main(int argc, char **argv)
|
||||||
} while (++optind < argc);
|
} while (++optind < argc);
|
||||||
}
|
}
|
||||||
|
|
||||||
my_exit(ret);
|
tuklib_exit(ret, EXIT_FAILURE, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,12 @@ xz_SOURCES = \
|
||||||
suffix.c \
|
suffix.c \
|
||||||
suffix.h \
|
suffix.h \
|
||||||
util.c \
|
util.c \
|
||||||
util.h
|
util.h \
|
||||||
|
$(top_srcdir)/src/common/tuklib_open_stdxxx.c \
|
||||||
|
$(top_srcdir)/src/common/tuklib_progname.c \
|
||||||
|
$(top_srcdir)/src/common/tuklib_exit.c \
|
||||||
|
$(top_srcdir)/src/common/tuklib_physmem.c \
|
||||||
|
$(top_srcdir)/src/common/tuklib_cpucores.c
|
||||||
|
|
||||||
if COND_W32
|
if COND_W32
|
||||||
xz_SOURCES += xz_w32res.rc
|
xz_SOURCES += xz_w32res.rc
|
||||||
|
|
|
@ -351,7 +351,7 @@ parse_real(args_info *args, int argc, char **argv)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
message_try_help();
|
message_try_help();
|
||||||
my_exit(E_ERROR);
|
tuklib_exit(E_ERROR, E_ERROR, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,18 +449,12 @@ args_parse(args_info *args, int argc, char **argv)
|
||||||
|
|
||||||
// Check how we were called.
|
// Check how we were called.
|
||||||
{
|
{
|
||||||
#ifdef DOSLIKE
|
|
||||||
// We adjusted argv[0] in the beginning of main() so we don't
|
|
||||||
// need to do anything here.
|
|
||||||
const char *name = argv[0];
|
|
||||||
#else
|
|
||||||
// Remove the leading path name, if any.
|
// 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];
|
||||||
else
|
else
|
||||||
++name;
|
++name;
|
||||||
#endif
|
|
||||||
|
|
||||||
// NOTE: It's possible that name[0] is now '\0' if argv[0]
|
// NOTE: It's possible that name[0] is now '\0' if argv[0]
|
||||||
// is weird, but it doesn't matter here.
|
// is weird, but it doesn't matter here.
|
||||||
|
|
|
@ -14,8 +14,10 @@
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#ifdef DOSLIKE
|
#ifdef TUKLIB_DOSLIKE
|
||||||
# include <io.h>
|
# include <io.h>
|
||||||
|
#else
|
||||||
|
static bool warn_fchown;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMES)
|
#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMES)
|
||||||
|
@ -24,6 +26,8 @@
|
||||||
# include <utime.h>
|
# include <utime.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "tuklib_open_stdxxx.h"
|
||||||
|
|
||||||
#ifndef O_BINARY
|
#ifndef O_BINARY
|
||||||
# define O_BINARY 0
|
# define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,22 +36,17 @@
|
||||||
# define O_NOCTTY 0
|
# define O_NOCTTY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef DOSLIKE
|
|
||||||
# include "open_stdxxx.h"
|
|
||||||
static bool warn_fchown;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
io_init(void)
|
io_init(void)
|
||||||
{
|
{
|
||||||
#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
|
||||||
// print an error message, but our stderr could be screwed anyway.
|
// print an error message, but our stderr could be screwed anyway.
|
||||||
open_stdxxx(E_ERROR);
|
tuklib_open_stdxxx(E_ERROR);
|
||||||
|
|
||||||
|
#ifndef TUKLIB_DOSLIKE
|
||||||
// If fchown() fails setting the owner, we warn about it only if
|
// If fchown() fails setting the owner, we warn about it only if
|
||||||
// we are root.
|
// we are root.
|
||||||
warn_fchown = geteuid() == 0;
|
warn_fchown = geteuid() == 0;
|
||||||
|
@ -64,7 +63,7 @@ io_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// \brief Unlinks a file
|
/// \brief Unlink a file
|
||||||
///
|
///
|
||||||
/// This tries to verify that the file being unlinked really is the file that
|
/// This tries to verify that the file being unlinked really is the file that
|
||||||
/// we want to unlink by verifying device and inode numbers. There's still
|
/// we want to unlink by verifying device and inode numbers. There's still
|
||||||
|
@ -73,9 +72,9 @@ io_init(void)
|
||||||
static void
|
static void
|
||||||
io_unlink(const char *name, const struct stat *known_st)
|
io_unlink(const char *name, const struct stat *known_st)
|
||||||
{
|
{
|
||||||
#ifdef DOSLIKE
|
#if defined(TUKLIB_DOSLIKE) || defined(__VMS)
|
||||||
// On Windows, st_ino is meaningless, so don't bother testing it.
|
// On DOS-like systems, st_ino is meaningless, so don't bother
|
||||||
// Just silence a compiler warning.
|
// testing it. Just silence a compiler warning.
|
||||||
(void)known_st;
|
(void)known_st;
|
||||||
#else
|
#else
|
||||||
struct stat new_st;
|
struct stat new_st;
|
||||||
|
@ -105,7 +104,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 DOSLIKE
|
#ifndef TUKLIB_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
|
||||||
|
@ -240,7 +239,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 DOSLIKE
|
#ifdef TUKLIB_DOSLIKE
|
||||||
setmode(STDIN_FILENO, O_BINARY);
|
setmode(STDIN_FILENO, O_BINARY);
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
|
@ -253,7 +252,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 DOSLIKE
|
#ifndef TUKLIB_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
|
||||||
|
@ -266,7 +265,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(DOSLIKE)
|
#elif !defined(TUKLIB_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.
|
||||||
|
@ -370,7 +369,7 @@ io_open_src(file_pair *pair)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef DOSLIKE
|
#ifndef TUKLIB_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.
|
||||||
|
@ -405,7 +404,7 @@ io_open_src(file_pair *pair)
|
||||||
}
|
}
|
||||||
|
|
||||||
// These are meaningless on Windows.
|
// These are meaningless on Windows.
|
||||||
#ifndef DOSLIKE
|
#ifndef TUKLIB_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
|
||||||
|
@ -457,7 +456,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 DOSLIKE
|
#ifdef TUKLIB_DOSLIKE
|
||||||
(void)close(pair->src_fd);
|
(void)close(pair->src_fd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -471,7 +470,7 @@ io_close_src(file_pair *pair, bool success)
|
||||||
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 DOSLIKE
|
#ifndef TUKLIB_DOSLIKE
|
||||||
(void)close(pair->src_fd);
|
(void)close(pair->src_fd);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -487,7 +486,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 DOSLIKE
|
#ifdef TUKLIB_DOSLIKE
|
||||||
setmode(STDOUT_FILENO, O_BINARY);
|
setmode(STDOUT_FILENO, O_BINARY);
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
|
@ -531,7 +530,9 @@ io_open_dest(file_pair *pair)
|
||||||
// If this really fails... well, we have a safe fallback.
|
// If this really fails... well, we have a safe fallback.
|
||||||
if (fstat(pair->dest_fd, &pair->dest_st)) {
|
if (fstat(pair->dest_fd, &pair->dest_st)) {
|
||||||
pair->dest_st.st_dev = 0;
|
pair->dest_st.st_dev = 0;
|
||||||
|
#ifndef __VMS
|
||||||
pair->dest_st.st_ino = 0;
|
pair->dest_st.st_ino = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "private.h"
|
#include "private.h"
|
||||||
#include "physmem.h"
|
#include "tuklib_physmem.h"
|
||||||
#include "cpucores.h"
|
#include "tuklib_cpucores.h"
|
||||||
|
|
||||||
|
|
||||||
/// Maximum number of free *coder* threads. This can be set with
|
/// Maximum number of free *coder* threads. This can be set with
|
||||||
|
@ -28,7 +28,7 @@ hardware_threadlimit_set(uint32_t new_threadlimit)
|
||||||
{
|
{
|
||||||
if (new_threadlimit == 0) {
|
if (new_threadlimit == 0) {
|
||||||
// The default is the number of available CPU cores.
|
// The default is the number of available CPU cores.
|
||||||
threadlimit = cpucores();
|
threadlimit = tuklib_cpucores();
|
||||||
if (threadlimit == 0)
|
if (threadlimit == 0)
|
||||||
threadlimit = 1;
|
threadlimit = 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -66,7 +66,7 @@ hardware_memlimit_set_percentage(uint32_t percentage)
|
||||||
assert(percentage > 0);
|
assert(percentage > 0);
|
||||||
assert(percentage <= 100);
|
assert(percentage <= 100);
|
||||||
|
|
||||||
uint64_t mem = physmem();
|
uint64_t mem = tuklib_physmem();
|
||||||
|
|
||||||
// If we cannot determine the amount of RAM, assume 32 MiB. Maybe
|
// If we cannot determine the amount of RAM, assume 32 MiB. Maybe
|
||||||
// even that is too much on some systems. But on most systems it's
|
// even that is too much on some systems. But on most systems it's
|
||||||
|
|
100
src/xz/main.c
100
src/xz/main.c
|
@ -42,47 +42,6 @@ set_exit_no_warn(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern void
|
|
||||||
my_exit(enum exit_status_type status)
|
|
||||||
{
|
|
||||||
// Close stdout. If something goes wrong, print an error message
|
|
||||||
// to stderr.
|
|
||||||
{
|
|
||||||
const int ferror_err = ferror(stdout);
|
|
||||||
const int fclose_err = fclose(stdout);
|
|
||||||
if (ferror_err || fclose_err) {
|
|
||||||
// If it was fclose() that failed, we have the reason
|
|
||||||
// in errno. If only ferror() indicated an error,
|
|
||||||
// we have no idea what the reason was.
|
|
||||||
message(V_ERROR, "%s: %s", _("Writing to standard "
|
|
||||||
"output failed"),
|
|
||||||
fclose_err ? strerror(errno)
|
|
||||||
: _("Unknown error"));
|
|
||||||
status = E_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close stderr. If something goes wrong, there's nothing where we
|
|
||||||
// could print an error message. Just set the exit status.
|
|
||||||
{
|
|
||||||
const int ferror_err = ferror(stderr);
|
|
||||||
const int fclose_err = fclose(stderr);
|
|
||||||
if (fclose_err || ferror_err)
|
|
||||||
status = E_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Suppress the exit status indicating a warning if --no-warn
|
|
||||||
// was specified.
|
|
||||||
if (status == E_WARNING && no_warn)
|
|
||||||
status = E_SUCCESS;
|
|
||||||
|
|
||||||
// If we have got a signal, raise it to kill the program.
|
|
||||||
// Otherwise we just call exit().
|
|
||||||
signals_exit();
|
|
||||||
exit(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
read_name(const args_info *args)
|
read_name(const args_info *args)
|
||||||
{
|
{
|
||||||
|
@ -170,45 +129,18 @@ read_name(const args_info *args)
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
// Initialize the file I/O as the very first step. This makes sure
|
// Set up the progname variable.
|
||||||
// that stdin, stdout, and stderr are something valid.
|
tuklib_progname_init(argv);
|
||||||
|
|
||||||
|
// Initialize the file I/O. This makes sure that
|
||||||
|
// stdin, stdout, and stderr are something valid.
|
||||||
io_init();
|
io_init();
|
||||||
|
|
||||||
#ifdef DOSLIKE
|
// Set up the locale and message translations.
|
||||||
// Adjust argv[0] to make it look nicer in messages, and also to
|
tuklib_gettext_init(PACKAGE, LOCALEDIR);
|
||||||
// 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;
|
// Initialize handling of error/warning/other messages.
|
||||||
|
message_init();
|
||||||
// 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.
|
|
||||||
setlocale(LC_ALL, "");
|
|
||||||
|
|
||||||
#ifdef ENABLE_NLS
|
|
||||||
// Set up the message translations too.
|
|
||||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
|
||||||
textdomain(PACKAGE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Set the program invocation name used in various messages, and
|
|
||||||
// do other message handling related initializations.
|
|
||||||
message_init(argv[0]);
|
|
||||||
|
|
||||||
// Set hardware-dependent default values. These can be overriden
|
// Set hardware-dependent default values. These can be overriden
|
||||||
// on the command line, thus this must be done before parse_args().
|
// on the command line, thus this must be done before parse_args().
|
||||||
|
@ -235,7 +167,7 @@ main(int argc, char **argv)
|
||||||
&& strcmp(args.arg_names[0], "-") == 0)) {
|
&& strcmp(args.arg_names[0], "-") == 0)) {
|
||||||
if (is_tty_stdout()) {
|
if (is_tty_stdout()) {
|
||||||
message_try_help();
|
message_try_help();
|
||||||
my_exit(E_ERROR);
|
tuklib_exit(E_ERROR, E_ERROR, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -308,5 +240,15 @@ main(int argc, char **argv)
|
||||||
(void)fclose(args.files_file);
|
(void)fclose(args.files_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
my_exit(exit_status);
|
// If we have got a signal, raise it to kill the program instead
|
||||||
|
// of calling tuklib_exit().
|
||||||
|
signals_exit();
|
||||||
|
|
||||||
|
// Suppress the exit status indicating a warning if --no-warn
|
||||||
|
// was specified.
|
||||||
|
if (exit_status == E_WARNING && no_warn)
|
||||||
|
exit_status = E_SUCCESS;
|
||||||
|
|
||||||
|
tuklib_exit(exit_status, E_ERROR,
|
||||||
|
message_verbosity_get() != V_SILENT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,3 @@ extern void set_exit_status(enum exit_status_type new_status);
|
||||||
/// but nothing worth an error has occurred. This is called when --no-warn
|
/// but nothing worth an error has occurred. This is called when --no-warn
|
||||||
/// is specified.
|
/// is specified.
|
||||||
extern void set_exit_no_warn(void);
|
extern void set_exit_no_warn(void);
|
||||||
|
|
||||||
|
|
||||||
/// Exits the program using the given status. This takes care of closing
|
|
||||||
/// stdin, stdout, and stderr and catches possible errors. If we had got
|
|
||||||
/// a signal, this function will raise it so that to the parent process it
|
|
||||||
/// appears that we were killed by the signal sent by the user.
|
|
||||||
extern void my_exit(enum exit_status_type status) lzma_attribute((noreturn));
|
|
||||||
|
|
|
@ -19,9 +19,6 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
|
||||||
/// Name of the program which is prefixed to the error messages.
|
|
||||||
static const char *argv0;
|
|
||||||
|
|
||||||
/// Number of the current file
|
/// Number of the current file
|
||||||
static unsigned int files_pos = 0;
|
static unsigned int files_pos = 0;
|
||||||
|
|
||||||
|
@ -138,11 +135,8 @@ my_snprintf(char **pos, size_t *left, const char *fmt, ...)
|
||||||
|
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
message_init(const char *given_argv0)
|
message_init(void)
|
||||||
{
|
{
|
||||||
// Name of the program
|
|
||||||
argv0 = given_argv0;
|
|
||||||
|
|
||||||
// If --verbose is used, we use a progress indicator if and only
|
// If --verbose is used, we use a progress indicator if and only
|
||||||
// if stderr is a terminal. If stderr is not a terminal, we print
|
// if stderr is a terminal. If stderr is not a terminal, we print
|
||||||
// verbose information only after finishing the file. As a special
|
// verbose information only after finishing the file. As a special
|
||||||
|
@ -226,6 +220,13 @@ message_verbosity_decrease(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern enum message_verbosity
|
||||||
|
message_verbosity_get(void)
|
||||||
|
{
|
||||||
|
return verbosity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
message_set_files(unsigned int files)
|
message_set_files(unsigned int files)
|
||||||
{
|
{
|
||||||
|
@ -774,7 +775,7 @@ vmessage(enum message_verbosity v, const char *fmt, va_list ap)
|
||||||
|
|
||||||
progress_flush(false);
|
progress_flush(false);
|
||||||
|
|
||||||
fprintf(stderr, "%s: ", argv0);
|
fprintf(stderr, "%s: ", progname);
|
||||||
vfprintf(stderr, fmt, ap);
|
vfprintf(stderr, fmt, ap);
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
|
|
||||||
|
@ -830,7 +831,7 @@ message_fatal(const char *fmt, ...)
|
||||||
vmessage(V_ERROR, fmt, ap);
|
vmessage(V_ERROR, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
my_exit(E_ERROR);
|
tuklib_exit(E_ERROR, E_ERROR, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -894,7 +895,7 @@ message_filters(enum message_verbosity v, const lzma_filter *filters)
|
||||||
if (v > verbosity)
|
if (v > verbosity)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fprintf(stderr, _("%s: Filter chain:"), argv0);
|
fprintf(stderr, _("%s: Filter chain:"), progname);
|
||||||
|
|
||||||
for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) {
|
for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) {
|
||||||
fprintf(stderr, " --");
|
fprintf(stderr, " --");
|
||||||
|
@ -1005,7 +1006,8 @@ message_try_help(void)
|
||||||
{
|
{
|
||||||
// Print this with V_WARNING instead of V_ERROR to prevent it from
|
// Print this with V_WARNING instead of V_ERROR to prevent it from
|
||||||
// showing up when --quiet has been specified.
|
// showing up when --quiet has been specified.
|
||||||
message(V_WARNING, _("Try `%s --help' for more information."), argv0);
|
message(V_WARNING, _("Try `%s --help' for more information."),
|
||||||
|
progname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1017,7 +1019,7 @@ message_version(void)
|
||||||
// line tool version, so print both.
|
// line tool version, so print both.
|
||||||
printf("xz (" PACKAGE_NAME ") " LZMA_VERSION_STRING "\n");
|
printf("xz (" PACKAGE_NAME ") " LZMA_VERSION_STRING "\n");
|
||||||
printf("liblzma %s\n", lzma_version_string());
|
printf("liblzma %s\n", lzma_version_string());
|
||||||
my_exit(E_SUCCESS);
|
tuklib_exit(E_SUCCESS, E_ERROR, verbosity != V_SILENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1026,7 +1028,7 @@ message_help(bool long_help)
|
||||||
{
|
{
|
||||||
printf(_("Usage: %s [OPTION]... [FILE]...\n"
|
printf(_("Usage: %s [OPTION]... [FILE]...\n"
|
||||||
"Compress or decompress FILEs in the .xz format.\n\n"),
|
"Compress or decompress FILEs in the .xz format.\n\n"),
|
||||||
argv0);
|
progname);
|
||||||
|
|
||||||
puts(_("Mandatory arguments to long options are mandatory for "
|
puts(_("Mandatory arguments to long options are mandatory for "
|
||||||
"short options too.\n"));
|
"short options too.\n"));
|
||||||
|
@ -1168,5 +1170,5 @@ message_help(bool long_help)
|
||||||
PACKAGE_BUGREPORT);
|
PACKAGE_BUGREPORT);
|
||||||
printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_HOMEPAGE);
|
printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_HOMEPAGE);
|
||||||
|
|
||||||
my_exit(E_SUCCESS);
|
tuklib_exit(E_SUCCESS, E_ERROR, verbosity != V_SILENT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,9 @@ enum message_verbosity {
|
||||||
|
|
||||||
/// \brief Initializes the message functions
|
/// \brief Initializes the message functions
|
||||||
///
|
///
|
||||||
/// \param argv0 Name of the program i.e. argv[0] from main()
|
|
||||||
/// \param verbosity Verbosity level
|
|
||||||
///
|
|
||||||
/// If an error occurs, this function doesn't return.
|
/// If an error occurs, this function doesn't return.
|
||||||
///
|
///
|
||||||
extern void message_init(const char *argv0);
|
extern void message_init(void);
|
||||||
|
|
||||||
|
|
||||||
/// Increase verbosity level by one step unless it was at maximum.
|
/// Increase verbosity level by one step unless it was at maximum.
|
||||||
|
@ -36,6 +33,9 @@ extern void message_verbosity_increase(void);
|
||||||
/// Decrease verbosity level by one step unless it was at minimum.
|
/// Decrease verbosity level by one step unless it was at minimum.
|
||||||
extern void message_verbosity_decrease(void);
|
extern void message_verbosity_decrease(void);
|
||||||
|
|
||||||
|
/// Get the current verbosity level.
|
||||||
|
extern enum message_verbosity message_verbosity_get(void);
|
||||||
|
|
||||||
|
|
||||||
/// Set the total number of files to be processed (stdin is counted as a file
|
/// Set the total number of files to be processed (stdin is counted as a file
|
||||||
/// here). The default is one.
|
/// here). The default is one.
|
||||||
|
|
|
@ -22,14 +22,9 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifdef ENABLE_NLS
|
#include "tuklib_gettext.h"
|
||||||
# include <libintl.h>
|
#include "tuklib_progname.h"
|
||||||
# define _(msgid) gettext(msgid)
|
#include "tuklib_exit.h"
|
||||||
# define N_(msgid1, msgid2, n) ngettext(msgid1, msgid2, n)
|
|
||||||
#else
|
|
||||||
# define _(msgid) (msgid)
|
|
||||||
# define N_(msgid1, msgid2, n) ((n) == 1 ? (msgid1) : (msgid2))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef STDIN_FILENO
|
#ifndef STDIN_FILENO
|
||||||
# define STDIN_FILENO (fileno(stdin))
|
# define STDIN_FILENO (fileno(stdin))
|
||||||
|
|
|
@ -95,6 +95,7 @@ signals_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __VMS
|
||||||
extern void
|
extern void
|
||||||
signals_block(void)
|
signals_block(void)
|
||||||
{
|
{
|
||||||
|
@ -121,6 +122,7 @@ signals_unblock(void)
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
|
|
|
@ -21,8 +21,10 @@ extern volatile sig_atomic_t user_abort;
|
||||||
extern void signals_init(void);
|
extern void signals_init(void);
|
||||||
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
#if defined(_WIN32) || defined(__VMS)
|
||||||
|
# define signals_block() do { } while (0)
|
||||||
|
# define signals_unblock() do { } while (0)
|
||||||
|
#else
|
||||||
/// Block the signals which don't have SA_RESTART and which would just set
|
/// Block the signals which don't have SA_RESTART and which would just set
|
||||||
/// user_abort to true. This is handy when we don't want to handle EINTR
|
/// user_abort to true. This is handy when we don't want to handle EINTR
|
||||||
/// and don't want SA_RESTART either.
|
/// and don't want SA_RESTART either.
|
||||||
|
@ -30,15 +32,12 @@ extern void signals_block(void);
|
||||||
|
|
||||||
/// Unblock the signals blocked by signals_block().
|
/// Unblock the signals blocked by signals_block().
|
||||||
extern void signals_unblock(void);
|
extern void signals_unblock(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# define signals_exit() do { } while (0)
|
||||||
|
#else
|
||||||
/// If user has sent us a signal earlier to terminate the process,
|
/// If user has sent us a signal earlier to terminate the process,
|
||||||
/// re-raise that signal to actually terminate the process.
|
/// re-raise that signal to actually terminate the process.
|
||||||
extern void signals_exit(void);
|
extern void signals_exit(void);
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define signals_block() do { } while (0)
|
|
||||||
#define signals_unblock() do { } while (0)
|
|
||||||
#define signals_exit() do { } while (0)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include "private.h"
|
#include "private.h"
|
||||||
|
|
||||||
// For case-insensitive filename suffix on case-insensitive systems
|
// For case-insensitive filename suffix on case-insensitive systems
|
||||||
#ifdef DOSLIKE
|
#if defined(TUKLIB_DOSLIKE) || defined(__VMS)
|
||||||
# define strcmp strcasecmp
|
# define strcmp strcasecmp
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -14,13 +14,18 @@
|
||||||
|
|
||||||
bin_PROGRAMS = xzdec lzmadec
|
bin_PROGRAMS = xzdec lzmadec
|
||||||
|
|
||||||
xzdec_SOURCES = xzdec.c
|
xzdec_SOURCES = \
|
||||||
|
xzdec.c \
|
||||||
|
$(top_srcdir)/src/common/tuklib_progname.c \
|
||||||
|
$(top_srcdir)/src/common/tuklib_exit.c \
|
||||||
|
$(top_srcdir)/src/common/tuklib_physmem.c
|
||||||
|
|
||||||
if COND_W32
|
if COND_W32
|
||||||
xzdec_SOURCES += xzdec_w32res.rc
|
xzdec_SOURCES += xzdec_w32res.rc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
xzdec_CPPFLAGS = \
|
xzdec_CPPFLAGS = \
|
||||||
|
-DTUKLIB_GETTEXT=0 \
|
||||||
-I$(top_srcdir)/src/common \
|
-I$(top_srcdir)/src/common \
|
||||||
-I$(top_srcdir)/src/liblzma/api \
|
-I$(top_srcdir)/src/liblzma/api \
|
||||||
-I$(top_builddir)/lib \
|
-I$(top_builddir)/lib \
|
||||||
|
@ -35,7 +40,11 @@ endif
|
||||||
xzdec_LDADD += $(LTLIBINTL)
|
xzdec_LDADD += $(LTLIBINTL)
|
||||||
|
|
||||||
|
|
||||||
lzmadec_SOURCES = xzdec.c
|
lzmadec_SOURCES = \
|
||||||
|
xzdec.c \
|
||||||
|
$(top_srcdir)/src/common/tuklib_progname.c \
|
||||||
|
$(top_srcdir)/src/common/tuklib_exit.c \
|
||||||
|
$(top_srcdir)/src/common/tuklib_physmem.c
|
||||||
|
|
||||||
if COND_W32
|
if COND_W32
|
||||||
lzmadec_SOURCES += lzmadec_w32res.rc
|
lzmadec_SOURCES += lzmadec_w32res.rc
|
||||||
|
|
|
@ -18,14 +18,16 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifdef DOSLIKE
|
#include "getopt.h"
|
||||||
|
#include "tuklib_progname.h"
|
||||||
|
#include "tuklib_exit.h"
|
||||||
|
#include "tuklib_physmem.h"
|
||||||
|
|
||||||
|
#ifdef TUKLIB_DOSLIKE
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
# include <io.h>
|
# include <io.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "getopt.h"
|
|
||||||
#include "physmem.h"
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef LZMADEC
|
#ifdef LZMADEC
|
||||||
# define TOOL_FORMAT "lzma"
|
# define TOOL_FORMAT "lzma"
|
||||||
|
@ -41,9 +43,6 @@ static uint64_t memlimit;
|
||||||
/// --quiet has been given at least twice.
|
/// --quiet has been given at least twice.
|
||||||
static unsigned int display_errors = 2;
|
static unsigned int display_errors = 2;
|
||||||
|
|
||||||
/// Program name to be shown in error messages
|
|
||||||
static const char *argv0;
|
|
||||||
|
|
||||||
|
|
||||||
static void lzma_attribute((format(printf, 1, 2)))
|
static void lzma_attribute((format(printf, 1, 2)))
|
||||||
my_errorf(const char *fmt, ...)
|
my_errorf(const char *fmt, ...)
|
||||||
|
@ -52,7 +51,7 @@ my_errorf(const char *fmt, ...)
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
|
|
||||||
if (display_errors) {
|
if (display_errors) {
|
||||||
fprintf(stderr, "%s: ", argv0);
|
fprintf(stderr, "%s: ", progname);
|
||||||
vfprintf(stderr, fmt, ap);
|
vfprintf(stderr, fmt, ap);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
@ -62,29 +61,6 @@ my_errorf(const char *fmt, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void lzma_attribute((noreturn))
|
|
||||||
my_exit(void)
|
|
||||||
{
|
|
||||||
int status = EXIT_SUCCESS;
|
|
||||||
|
|
||||||
// Close stdout. We don't care about stderr, because we write to it
|
|
||||||
// only when an error has already occurred.
|
|
||||||
const int ferror_err = ferror(stdout);
|
|
||||||
const int fclose_err = fclose(stdout);
|
|
||||||
|
|
||||||
if (ferror_err || fclose_err) {
|
|
||||||
// If it was fclose() that failed, we have the reason
|
|
||||||
// in errno. If only ferror() indicated an error,
|
|
||||||
// we have no idea what the reason was.
|
|
||||||
my_errorf("Writing to standard output failed: %s", fclose_err
|
|
||||||
? strerror(errno) : "Unknown error");
|
|
||||||
status = EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void lzma_attribute((noreturn))
|
static void lzma_attribute((noreturn))
|
||||||
help(void)
|
help(void)
|
||||||
{
|
{
|
||||||
|
@ -108,8 +84,8 @@ help(void)
|
||||||
"\n"
|
"\n"
|
||||||
"Report bugs to <" PACKAGE_BUGREPORT "> (in English or Finnish).\n"
|
"Report bugs to <" PACKAGE_BUGREPORT "> (in English or Finnish).\n"
|
||||||
PACKAGE_NAME " home page: <" PACKAGE_HOMEPAGE ">\n",
|
PACKAGE_NAME " home page: <" PACKAGE_HOMEPAGE ">\n",
|
||||||
argv0, memlimit / (1024 * 1024));
|
progname, memlimit / (1024 * 1024));
|
||||||
my_exit();
|
tuklib_exit(EXIT_SUCCESS, EXIT_FAILURE, display_errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,7 +95,7 @@ version(void)
|
||||||
printf(TOOL_FORMAT "dec (" PACKAGE_NAME ") " LZMA_VERSION_STRING "\n"
|
printf(TOOL_FORMAT "dec (" PACKAGE_NAME ") " LZMA_VERSION_STRING "\n"
|
||||||
"liblzma %s\n", lzma_version_string());
|
"liblzma %s\n", lzma_version_string());
|
||||||
|
|
||||||
my_exit();
|
tuklib_exit(EXIT_SUCCESS, EXIT_FAILURE, display_errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -128,7 +104,7 @@ version(void)
|
||||||
static void
|
static void
|
||||||
memlimit_set_percentage(uint32_t percentage)
|
memlimit_set_percentage(uint32_t percentage)
|
||||||
{
|
{
|
||||||
uint64_t mem = physmem();
|
uint64_t mem = tuklib_physmem();
|
||||||
|
|
||||||
// If we cannot determine the amount of RAM, assume 32 MiB.
|
// If we cannot determine the amount of RAM, assume 32 MiB.
|
||||||
if (mem == 0)
|
if (mem == 0)
|
||||||
|
@ -441,9 +417,8 @@ uncompress(lzma_stream *strm, FILE *file, const char *filename)
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
// Set the argv0 global so that we can print the command name in
|
// Initialize progname which we will be used in error messages.
|
||||||
// error and help messages.
|
tuklib_progname_init(argv);
|
||||||
argv0 = argv[0];
|
|
||||||
|
|
||||||
// Set the default memory usage limit. This is needed before parsing
|
// Set the default memory usage limit. This is needed before parsing
|
||||||
// the command line arguments.
|
// the command line arguments.
|
||||||
|
@ -458,7 +433,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 DOSLIKE
|
#ifdef TUKLIB_DOSLIKE
|
||||||
setmode(fileno(stdin), O_BINARY);
|
setmode(fileno(stdin), O_BINARY);
|
||||||
setmode(fileno(stdout), O_BINARY);
|
setmode(fileno(stdout), O_BINARY);
|
||||||
#endif
|
#endif
|
||||||
|
@ -492,5 +467,5 @@ main(int argc, char **argv)
|
||||||
lzma_end(&strm);
|
lzma_end(&strm);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
my_exit();
|
tuklib_exit(EXIT_SUCCESS, EXIT_FAILURE, display_errors);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue