:: commit 2a2d3b265b077e3f1c9c3445581e94753e22d47e

Kamila Szewczyk <kspalaiologos@gmail.com> — 2022-05-06 11:53

parents: 0cab2ae3de

dynamic library, general improvements

diff --git a/.gitignore b/.gitignore
index c989814..715ebb5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,7 @@ config.h
 configure~
 
 Makefile
+
+bzip3.so
+
+libbz3.so
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 3f99eae..de8f3f6 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -14,6 +14,7 @@
         "fstream": "c",
         "istream": "c",
         "sstream": "c",
-        "streambuf": "c"
+        "streambuf": "c",
+        "config.h": "c"
     }
 }
\ No newline at end of file
diff --git a/Makefile.in b/Makefile.in
index 88f5c02..e68e5e0 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -4,15 +4,18 @@ CFLAGS=-O2 -march=native -mtune=native -flto -Iinclude -g3
 
 .PHONY: all clean format install cloc
 
-OBJECTS=obj/main.o obj/libsais.o obj/crc32.o obj/mtf.o obj/srt.o obj/rle.o \
-        obj/cm.o obj/libbz3.o obj/txt.o obj/lzp.o
+LIBBZ3_OBJECTS=obj/libsais.o obj/crc32.o obj/mtf.o obj/srt.o obj/rle.o \
+               obj/cm.o obj/libbz3.o obj/txt.o obj/lzp.o
 
-all: bzip3
+all: bzip3 bzip3.so
 
 obj/%.o: src/%.c
 	$(CC) $(CFLAGS) -c $< -o $@
 
-bzip3: $(OBJECTS)
+bzip3.so: $(LIBBZ3_OBJECTS)
+	$(CC) -shared $(CFLAGS) -o $@ $^ -lm
+
+bzip3: obj/main.o $(LIBBZ3_OBJECTS)
 	$(CC) $(CFLAGS) -o $@ $^ -lm
 
 clean:
@@ -22,7 +25,9 @@ format:
 	clang-format -i src/*.c include/*.h
 
 install:
-	install -v -m 755 bzip3 @prefix@/bin
+	@INSTALL@ -v -m 755 bzip3 @prefix@/bin
+	@INSTALL@ -v -m 755 bzip3.so @prefix@/lib
+	@INSTALL@ -v -m 755 include/libbz3.h @prefix@/include
 
 cloc:
 	cloc src/*.c include/*.h
diff --git a/config.h.in b/config.h.in
index 279aa0d..8adeeaf 100644
--- a/config.h.in
+++ b/config.h.in
@@ -9,8 +9,8 @@
 /* Define to 1 if you have the `calloc' function. */
 #undef HAVE_CALLOC
 
-/* Define to 1 if you have the <fcntl.h> header file. */
-#undef HAVE_FCNTL_H
+/* Define to 1 if you have the `fileno' function. */
+#undef HAVE_FILENO
 
 /* Define to 1 if you have the `free' function. */
 #undef HAVE_FREE
@@ -21,6 +21,9 @@
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
+/* Define to 1 if you have the `isatty' function. */
+#undef HAVE_ISATTY
+
 /* Define to 1 if you have the `m' library (-lm). */
 #undef HAVE_LIBM
 
diff --git a/configure b/configure
index 9883245..ee84775 100755
--- a/configure
+++ b/configure
@@ -3804,12 +3804,6 @@ if test "x$ac_cv_header_arpa_inet_h" = xyes
 then :
   printf "%s\n" "#define HAVE_ARPA_INET_H 1" >>confdefs.h
 
-fi
-ac_fn_c_check_header_compile "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default"
-if test "x$ac_cv_header_fcntl_h" = xyes
-then :
-  printf "%s\n" "#define HAVE_FCNTL_H 1" >>confdefs.h
-
 fi
 ac_fn_c_check_header_compile "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default"
 if test "x$ac_cv_header_inttypes_h" = xyes
@@ -4402,6 +4396,18 @@ then :
   printf "%s\n" "#define HAVE_FREE 1" >>confdefs.h
 
 fi
+ac_fn_c_check_func "$LINENO" "isatty" "ac_cv_func_isatty"
+if test "x$ac_cv_func_isatty" = xyes
+then :
+  printf "%s\n" "#define HAVE_ISATTY 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "fileno" "ac_cv_func_fileno"
+if test "x$ac_cv_func_fileno" = xyes
+then :
+  printf "%s\n" "#define HAVE_FILENO 1" >>confdefs.h
+
+fi
 
 
 ac_config_files="$ac_config_files Makefile"
diff --git a/configure.ac b/configure.ac
index 4216a3f..1c49df9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -16,7 +16,7 @@ AC_PROG_INSTALL
 AC_CHECK_LIB([m], [log2])
 
 # Checks for header files.
-AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h stdint.h stdlib.h stdio.h unistd.h])
+AC_CHECK_HEADERS([arpa/inet.h inttypes.h stdint.h stdlib.h stdio.h unistd.h])
 
 # Checks for typedefs, structures, and compiler/platform characteristics.
 AC_C_INLINE
@@ -34,7 +34,7 @@ AC_CHECK_TYPES([ptrdiff_t])
 AC_C_BIGENDIAN
 
 # Checks for library functions.
-AC_CHECK_FUNCS([memmove memcpy memset ntohl htonl memcmp calloc malloc free])
+AC_CHECK_FUNCS([memmove memcpy memset ntohl htonl memcmp calloc malloc free isatty fileno])
 
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
diff --git a/include/common.h b/include/common.h
index e196da5..4a06348 100644
--- a/include/common.h
+++ b/include/common.h
@@ -20,6 +20,8 @@
 #ifndef _COMMON_H
 #define _COMMON_H
 
+#include "../config.h"
+
 #define KiB(x) ((x)*1024)
 #define MiB(x) ((x)*1024 * 1024)
 
@@ -35,4 +37,41 @@ typedef int8_t s8;
 typedef int16_t s16;
 typedef int32_t s32;
 
+// Supply ntohl and htonl.
+#if HAVE_ARPA_INET_H == 1 && HAVE_HTONL == 1 && HAVE_NTOHL == 1
+    #include <arpa/inet.h>
+#else
+    #ifndef WORDS_BIGENDIAN
+        #include <string.h>
+    #endif
+
+    static u32 ntohl(u32 value) {
+        #ifdef WORDS_BIGENDIAN
+            return value;
+        #else
+            u8 data[4];
+            memcpy(&data, &value, sizeof(data));
+
+            return ((u32) data[3])
+                 | ((u32) data[2] << 8)
+                 | ((u32) data[1] << 16)
+                 | ((u32) data[0] << 24);
+        #endif
+    }
+
+    static u32 htonl(u32 value) {
+        #ifdef WORDS_BIGENDIAN
+            return value;
+        #else
+            u8 data[4];
+            memcpy(&data, &value, sizeof(data));
+
+            return ((u32) data[3])
+                 | ((u32) data[2] << 8)
+                 | ((u32) data[1] << 16)
+                 | ((u32) data[0] << 24);
+        #endif
+    }
+#endif
+
 #endif
diff --git a/include/libbz3.h b/include/libbz3.h
index bde29f2..234a6b9 100644
--- a/include/libbz3.h
+++ b/include/libbz3.h
@@ -20,7 +20,7 @@
 #ifndef _LIBBZ3_H
 #define _LIBBZ3_H
 
-#include "common.h"
+#include <stdint.h>
 
 #define BZ3_OK 0
 #define BZ3_ERR_OUT_OF_BOUNDS -1
@@ -35,7 +35,7 @@ struct bz3_state;
 /**
  * @brief Get the last error number associated with a given state.
  */
-s8 bz3_last_error(struct bz3_state * state);
+int8_t bz3_last_error(struct bz3_state * state);
 
 /**
  * @brief Return a user-readable message explaining the cause of the last error.
@@ -46,7 +46,7 @@ const char * bz3_strerror(struct bz3_state * state);
  * @brief Construct a new block encoder state, which will encode blocks as big as the given block size.
  * The decoder will be able to decode blocks at most as big as the given block size.
  */
-struct bz3_state * bz3_new(s32 block_size);
+struct bz3_state * bz3_new(int32_t block_size);
 
 /**
  * @brief Free the memory occupied by a block encoder state.
@@ -58,7 +58,7 @@ void bz3_free(struct bz3_state * state);
  * `buffer' must be able to hold at least `size + size / 4' bytes. The size must not
  * exceed the block size associated with the state.
  */
-s32 bz3_encode_block(struct bz3_state * state, u8 * buffer, s32 size);
+int32_t bz3_encode_block(struct bz3_state * state, uint8_t * buffer, int32_t size);
 
 /**
  * @brief Decode a single block.
@@ -67,6 +67,6 @@ s32 bz3_encode_block(struct bz3_state * state, u8 * buffer, s32 size);
  * @param size The size of the compressed data in `buffer'
  * @param orig_size The original size of the data before compression.
  */
-s32 bz3_decode_block(struct bz3_state * state, u8 * buffer, s32 size, s32 orig_size);
+int32_t bz3_decode_block(struct bz3_state * state, uint8_t * buffer, int32_t size, int32_t orig_size);
 
 #endif
diff --git a/src/libbz3.c b/src/libbz3.c
index 49697f5..cae1839 100644
--- a/src/libbz3.c
+++ b/src/libbz3.c
@@ -19,7 +19,6 @@
 
 #include "libbz3.h"
 
-#include <arpa/inet.h>
 #include <stdlib.h>
 #include <string.h>
 
diff --git a/src/main.c b/src/main.c
index 84ec081..0817c28 100644
--- a/src/main.c
+++ b/src/main.c
@@ -16,13 +16,11 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <fcntl.h>
 #include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <arpa/inet.h>
 
 #include "common.h"
 #include "libbz3.h"
@@ -93,6 +91,13 @@ int main(int argc, char * argv[]) {
         return 1;
     }
 
+    #if HAVE_ISATTY == 1 && HAVE_FILENO == 1
+    if((isatty(fileno(output_des)) && mode == 1) || (isatty(fileno(input_des)) && mode == -1)) {
+        fprintf(stderr, "Refusing to read/write binary data from/to the terminal.\n");
+        return 1;
+    }
+    #endif
+
     switch (mode) {
         case 1:
             fwrite("BZ3v1", 5, 1, output_des);
tab: 248 wrap: offon