]> sigrok.org Git - libsigrok.git/blobdiff - src/resource.c
Add support for the Tenma 77-9380A multimeter.
[libsigrok.git] / src / resource.c
index b29be60863b0eb83584d04bfe777f75b6a666d46..bf28169be769f6e6906b844e0a84a240b4812723 100644 (file)
  * Access to resource files.
  */
 
+/** Retrieve the size of the open stream @a file.
+ *
+ * This function only works on seekable streams. However, the set of seekable
+ * streams is generally congruent with the set of streams that have a size.
+ * Code that needs to work with any type of stream (including pipes) should
+ * require neither seekability nor advance knowledge of the size.
+ * On failure, the return value is negative and errno is set.
+ *
+ * @param file An I/O stream opened in binary mode.
+ * @return The size of @a file in bytes, or a negative value on failure.
+ *
+ * @private
+ */
+SR_PRIV int64_t sr_file_get_size(FILE *file)
+{
+       off_t filepos, filesize;
+
+       /* ftello() and fseeko() are not standard C, but part of POSIX.1-2001.
+        * Thus, if these functions are available at all, they can reasonably
+        * be expected to also conform to POSIX semantics. In particular, this
+        * means that ftello() after fseeko(..., SEEK_END) has a defined result
+        * and can be used to get the size of a seekable stream.
+        * On Windows, the result is fully defined only for binary streams.
+        */
+       filepos = ftello(file);
+       if (filepos < 0)
+               return -1;
+
+       if (fseeko(file, 0, SEEK_END) < 0)
+               return -1;
+
+       filesize = ftello(file);
+       if (filesize < 0)
+               return -1;
+
+       if (fseeko(file, filepos, SEEK_SET) < 0)
+               return -1;
+
+       return filesize;
+}
+
 static FILE *try_open_file(const char *datadir, const char *subdir,
                const char *name)
 {
@@ -58,7 +99,10 @@ static int resource_open_default(struct sr_resource *res,
                const char *name, void *cb_data)
 {
        int64_t filesize;
-       const char *builtindir, *subdir;
+#ifdef FIRMWARE_DIR
+       const char *builtindir;
+#endif
+       const char *subdir;
        const char *const *datadirs;
        FILE *file;
 
@@ -66,7 +110,9 @@ static int resource_open_default(struct sr_resource *res,
 
        switch (res->type) {
        case SR_RESOURCE_FIRMWARE:
+#ifdef FIRMWARE_DIR
                builtindir = FIRMWARE_DIR;
+#endif
                subdir = "sigrok-firmware";
                break;
        default:
@@ -79,9 +125,10 @@ static int resource_open_default(struct sr_resource *res,
         * Scan the hard-coded directory before the system directories to
         * avoid picking up possibly outdated files from a system install.
         */
+#ifdef FIRMWARE_DIR
        if (!file)
                file = try_open_file(builtindir, "", name);
-
+#endif
        if (!file) {
                datadirs = g_get_system_data_dirs();
                while (*datadirs && !file)