18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
28c2ecf20Sopenharmony_ci/******************************************************************************
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Module Name: cfsize - Common get file size function
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Copyright (C) 2000 - 2020, Intel Corp.
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci *****************************************************************************/
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <acpi/acpi.h>
118c2ecf20Sopenharmony_ci#include "accommon.h"
128c2ecf20Sopenharmony_ci#include "acapps.h"
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#define _COMPONENT          ACPI_TOOLS
158c2ecf20Sopenharmony_ciACPI_MODULE_NAME("cmfsize")
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci/*******************************************************************************
188c2ecf20Sopenharmony_ci *
198c2ecf20Sopenharmony_ci * FUNCTION:    cm_get_file_size
208c2ecf20Sopenharmony_ci *
218c2ecf20Sopenharmony_ci * PARAMETERS:  file                    - Open file descriptor
228c2ecf20Sopenharmony_ci *
238c2ecf20Sopenharmony_ci * RETURN:      File Size. On error, -1 (ACPI_UINT32_MAX)
248c2ecf20Sopenharmony_ci *
258c2ecf20Sopenharmony_ci * DESCRIPTION: Get the size of a file. Uses seek-to-EOF. File must be open.
268c2ecf20Sopenharmony_ci *              Does not disturb the current file pointer.
278c2ecf20Sopenharmony_ci *
288c2ecf20Sopenharmony_ci ******************************************************************************/
298c2ecf20Sopenharmony_ciu32 cm_get_file_size(ACPI_FILE file)
308c2ecf20Sopenharmony_ci{
318c2ecf20Sopenharmony_ci	long file_size;
328c2ecf20Sopenharmony_ci	long current_offset;
338c2ecf20Sopenharmony_ci	acpi_status status;
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	/* Save the current file pointer, seek to EOF to obtain file size */
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci	current_offset = ftell(file);
388c2ecf20Sopenharmony_ci	if (current_offset < 0) {
398c2ecf20Sopenharmony_ci		goto offset_error;
408c2ecf20Sopenharmony_ci	}
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	status = fseek(file, 0, SEEK_END);
438c2ecf20Sopenharmony_ci	if (ACPI_FAILURE(status)) {
448c2ecf20Sopenharmony_ci		goto seek_error;
458c2ecf20Sopenharmony_ci	}
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci	file_size = ftell(file);
488c2ecf20Sopenharmony_ci	if (file_size < 0) {
498c2ecf20Sopenharmony_ci		goto offset_error;
508c2ecf20Sopenharmony_ci	}
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	/* Restore original file pointer */
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	status = fseek(file, current_offset, SEEK_SET);
558c2ecf20Sopenharmony_ci	if (ACPI_FAILURE(status)) {
568c2ecf20Sopenharmony_ci		goto seek_error;
578c2ecf20Sopenharmony_ci	}
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	return ((u32)file_size);
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_cioffset_error:
628c2ecf20Sopenharmony_ci	fprintf(stderr, "Could not get file offset\n");
638c2ecf20Sopenharmony_ci	return (ACPI_UINT32_MAX);
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ciseek_error:
668c2ecf20Sopenharmony_ci	fprintf(stderr, "Could not set file offset\n");
678c2ecf20Sopenharmony_ci	return (ACPI_UINT32_MAX);
688c2ecf20Sopenharmony_ci}
69