LCOV - code coverage report
Current view: top level - shared - dlt_multiple_files.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 69.6 % 194 135
Test Date: 2026-08-27 10:11:10 Functions: 100.0 % 13 13

            Line data    Source code
       1              : /*
       2              :  * SPDX license identifier: MPL-2.0
       3              :  *
       4              :  * Copyright (C) 2022, Daimler TSS GmbH
       5              :  *
       6              :  * This file is part of COVESA Project DLT - Diagnostic Log and Trace.
       7              :  *
       8              :  * This Source Code Form is subject to the terms of the
       9              :  * Mozilla Public License (MPL), v. 2.0.
      10              :  * If a copy of the MPL was not distributed with this file,
      11              :  * You can obtain one at http://mozilla.org/MPL/2.0/.
      12              :  *
      13              :  * For further information see https://www.covesa.global/.
      14              :  */
      15              : 
      16              : /*!
      17              :  * \author
      18              :  * Oleg Tropmann <oleg.tropmann@daimler.com>
      19              :  * Daniel Weber <daniel.w.weber@daimler.com>
      20              :  *
      21              :  * \copyright Copyright © 2022 Daimler TSS GmbH. \n
      22              :  * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
      23              :  *
      24              :  * \file dlt_daemon_log.c
      25              :  */
      26              : 
      27              : #include <stdio.h>
      28              : #include <stdlib.h>
      29              : #include <string.h>
      30              : #include <time.h>
      31              : #include <sys/types.h>
      32              : #include <sys/stat.h>
      33              : #include <fcntl.h>
      34              : #include <unistd.h>
      35              : #include <dirent.h>
      36              : #include <syslog.h>
      37              : #include <errno.h>
      38              : #include <stdarg.h>
      39              : 
      40              : #include "dlt_multiple_files.h"
      41              : #include "dlt_common.h"
      42              : #include "dlt_log.h"
      43              : 
      44           12 : unsigned int multiple_files_buffer_storage_dir_info(const char* path, const char* file_name, char* newest, char* oldest)
      45              : {
      46              :     int i = 0;
      47              :     unsigned int num_log_files = 0;
      48           12 :     struct dirent** files = {0};
      49              :     char* tmp_old = NULL;
      50              :     char* tmp_new = NULL;
      51              : 
      52           12 :     if ((path == NULL) || (file_name == NULL) || (newest == NULL) || (oldest == NULL)) {
      53            0 :         fprintf(stderr, "multiple_files_buffer_storage_dir_info: Invalid parameter(s)");
      54            0 :         return 0;
      55              :     }
      56              : 
      57           12 :     const int file_cnt = scandir(path, &files, NULL, alphasort);
      58           12 :     if (file_cnt <= 0)
      59              :         return 0;
      60              : 
      61          421 :     for (i = 0; i < file_cnt; i++) {
      62              :         int len = 0;
      63          409 :         len = (int)strlen(file_name);
      64              : 
      65          409 :         if ((strncmp(files[i]->d_name, file_name, (size_t)len) == 0)
      66          181 :             && (files[i]->d_name[len] == MULTIPLE_FILES_FILENAME_INDEX_DELIM[0])) {
      67           35 :             num_log_files++;
      68              : 
      69           35 :             if ((tmp_old == NULL) || (strlen(tmp_old) >= strlen(files[i]->d_name))) {
      70              :                 if (tmp_old == NULL) {
      71              :                     tmp_old = files[i]->d_name;
      72           23 :                 } else if (strlen(tmp_old) > strlen(files[i]->d_name)) {
      73              :                     /* when file name is smaller, it is older */
      74              :                     tmp_old = files[i]->d_name;
      75           20 :                 } else if (strcmp(tmp_old, files[i]->d_name) > 0) {
      76              :                     /* filename length is equal, do a string compare */
      77              :                     tmp_old = files[i]->d_name;
      78              :                 }
      79              :             }
      80              : 
      81           35 :             if ((tmp_new == NULL) || (strlen(tmp_new) <= strlen(files[i]->d_name))) {
      82              :                 if (tmp_new == NULL) {
      83              :                     tmp_new = files[i]->d_name;
      84           20 :                 } else if (strlen(tmp_new) < strlen(files[i]->d_name)) {
      85              :                     /* when file name is longer, it is younger */
      86              :                     tmp_new = files[i]->d_name;
      87           20 :                 } else if (strcmp(tmp_new, files[i]->d_name) < 0) {
      88              :                     tmp_new = files[i]->d_name;
      89              :                 }
      90              :             }
      91              :         }
      92              :     }
      93              : 
      94           12 :     if (num_log_files > 0) {
      95           12 :         if ((tmp_old != NULL) && (strlen(tmp_old) < NAME_MAX)) {
      96              :             strncpy(oldest, tmp_old, NAME_MAX);
      97           12 :             oldest[NAME_MAX] = '\0';
      98              :         } else if ((tmp_old != NULL) && (strlen(tmp_old) >= NAME_MAX)) {
      99              :             printf("length mismatch of file %s\n", tmp_old);
     100              :         }
     101              : 
     102           12 :         if ((tmp_new != NULL) && (strlen(tmp_new) < NAME_MAX)) {
     103              :             strncpy(newest, tmp_new, NAME_MAX);
     104           12 :             newest[NAME_MAX] = '\0';
     105              :         } else if ((tmp_new != NULL) && (strlen(tmp_new) >= NAME_MAX)) {
     106              :             printf("length mismatch of file %s\n", tmp_new);
     107              :         }
     108              :     }
     109              : 
     110              :     /* free scandir result */
     111          421 :     for (i = 0; i < file_cnt; i++)
     112          409 :         free(files[i]);
     113              : 
     114           12 :     free(files);
     115              : 
     116           12 :     return num_log_files;
     117              : }
     118              : 
     119            9 : void multiple_files_buffer_file_name(MultipleFilesRingBuffer* files_buffer, const unsigned int idx)
     120              : {
     121              :     char file_index[11]; /* UINT_MAX = 4294967295 -> 10 digits */
     122              :     snprintf(file_index, sizeof(file_index), "%010u", idx);
     123              : 
     124              :     /* create log file name */
     125            9 :     char* file_name = files_buffer->filename;
     126              :     size_t bufsize = sizeof(files_buffer->filename);
     127              :     memset(file_name, 0, bufsize);
     128              : 
     129              :     int written = snprintf(
     130            9 :         file_name, bufsize, "%s%s%s%s", files_buffer->filenameBase, MULTIPLE_FILES_FILENAME_INDEX_DELIM, file_index,
     131            9 :         files_buffer->filenameExt);
     132            9 :     if (written < 0 || (size_t)written >= bufsize) {
     133            0 :         file_name[bufsize - 1] = '\0';
     134              :     }
     135            9 : }
     136              : 
     137           52 : unsigned int multiple_files_buffer_get_idx_of_log_file(char* file)
     138              : {
     139           52 :     if ((file == NULL) || (file[0] == '\0'))
     140              :         return 0;
     141              : 
     142           52 :     const char d[2] = MULTIPLE_FILES_FILENAME_INDEX_DELIM;
     143              :     char* token;
     144              : 
     145           52 :     token = strtok(file, d);
     146              :     /* we are interested in 2. token because of log file name */
     147           52 :     token = strtok(NULL, d);
     148              : 
     149           52 :     return token != NULL ? (unsigned int)strtol(token, NULL, 10) : 0;
     150              : }
     151              : 
     152            9 : DltReturnValue multiple_files_buffer_create_new_file(MultipleFilesRingBuffer* files_buffer)
     153              : {
     154            9 :     if (files_buffer == NULL) {
     155            0 :         fprintf(stderr, "multiple files buffer not set\n");
     156            0 :         return DLT_RETURN_ERROR;
     157              :     }
     158              : 
     159              :     time_t t;
     160              :     struct tm tmp;
     161              :     char file_path[PATH_MAX + 1];
     162              :     unsigned int idx = 0;
     163              :     int ret = 0;
     164              : 
     165              :     /* set filename */
     166            9 :     if (files_buffer->filenameTimestampBased) {
     167              :         /* timestamp format: "yyyymmdd_hhmmss" */
     168              :         char timestamp[16];
     169            0 :         t = time(NULL);
     170            0 :         tzset();
     171            0 :         localtime_r(&t, &tmp);
     172              : 
     173            0 :         strftime(timestamp, sizeof(timestamp), "%Y%m%d_%H%M%S", &tmp);
     174              : 
     175              :         ret = snprintf(
     176            0 :             files_buffer->filename, sizeof(files_buffer->filename), "%s%s%s%s", files_buffer->filenameBase,
     177            0 :             MULTIPLE_FILES_FILENAME_TIMESTAMP_DELIM, timestamp, files_buffer->filenameExt);
     178              : 
     179            0 :         if ((ret < 0) || ((size_t)ret >= (int)sizeof(files_buffer->filename))) {
     180            0 :             fprintf(stderr, "filename cannot be concatenated\n");
     181            0 :             return DLT_RETURN_ERROR;
     182              :         }
     183              : 
     184            0 :         ret = snprintf(file_path, sizeof(file_path), "%s/%s", files_buffer->directory, files_buffer->filename);
     185              : 
     186            0 :         if ((ret < 0) || ((size_t)ret >= (int)sizeof(file_path))) {
     187            0 :             fprintf(stderr, "file path cannot be concatenated\n");
     188            0 :             return DLT_RETURN_ERROR;
     189              :         }
     190              :     } else {
     191            9 :         char newest[NAME_MAX + 1] = {0};
     192            9 :         char oldest[NAME_MAX + 1] = {0};
     193              :         /* targeting newest file, ignoring number of files in dir returned */
     194            9 :         if (0
     195            9 :             == multiple_files_buffer_storage_dir_info(
     196            9 :                 files_buffer->directory, files_buffer->filenameBase, newest, oldest)) {
     197              :             printf("No multiple files found\n");
     198              :         }
     199              : 
     200            9 :         idx = multiple_files_buffer_get_idx_of_log_file(newest) + 1;
     201              : 
     202            9 :         multiple_files_buffer_file_name(files_buffer, idx);
     203            9 :         ret = snprintf(file_path, sizeof(file_path), "%s/%s", files_buffer->directory, files_buffer->filename);
     204              : 
     205            9 :         if ((ret < 0) || (ret >= NAME_MAX)) {
     206            0 :             fprintf(stderr, "filename cannot be concatenated\n");
     207            0 :             return DLT_RETURN_ERROR;
     208              :         }
     209              :     }
     210              : 
     211              :     /* open DLT output file */
     212            9 :     errno = 0;
     213            9 :     files_buffer->ohandle = open(file_path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */
     214              : 
     215            9 :     if (files_buffer->ohandle == -1) {
     216              :         /* file cannot be opened */
     217            0 :         fprintf(stderr, "file %s cannot be created, error: %s\n", file_path, strerror(errno));
     218            0 :         return DLT_RETURN_ERROR;
     219              :     }
     220              : 
     221              :     return DLT_RETURN_OK;
     222              : }
     223              : 
     224           21 : ssize_t multiple_files_buffer_get_total_size(const MultipleFilesRingBuffer* files_buffer)
     225              : {
     226           21 :     if (files_buffer == NULL) {
     227            0 :         fprintf(stderr, "multiple files buffer not set\n");
     228            0 :         return -1;
     229              :     }
     230              : 
     231              :     struct dirent* dp;
     232              :     char filename[PATH_MAX + 1];
     233              :     ssize_t size = 0;
     234              :     struct stat status;
     235              : 
     236              :     /* go through all dlt files in directory */
     237           21 :     DIR* dir = opendir(files_buffer->directory);
     238           21 :     if (!dir) {
     239            0 :         fprintf(stderr, "directory %s cannot be opened, error=%s\n", files_buffer->directory, strerror(errno));
     240            0 :         return -1;
     241              :     }
     242              : 
     243          756 :     while ((dp = readdir(dir)) != NULL) {
     244              :         // consider files matching with a specific base name and a particular extension
     245          735 :         if (strstr(dp->d_name, files_buffer->filenameBase) && strstr(dp->d_name, files_buffer->filenameExt)) {
     246              :             int res = snprintf(filename, sizeof(filename), "%s/%s", files_buffer->directory, dp->d_name);
     247              : 
     248              :             /* if the total length of the string is greater than the buffer, silently forget it. */
     249              :             /* snprintf: a return value of size  or more means that the output was truncated */
     250              :             /*           if an output error is encountered, a negative value is returned. */
     251           78 :             if (((unsigned int)res < sizeof(filename)) && (res > 0)) {
     252           78 :                 errno = 0;
     253           78 :                 if (0 == stat(filename, &status))
     254           78 :                     size += (ssize_t)status.st_size;
     255              :                 else
     256            0 :                     fprintf(stderr, "file %s cannot be stat-ed, error=%s\n", filename, strerror(errno));
     257              :             }
     258              :         }
     259              :     }
     260              : 
     261           21 :     closedir(dir);
     262              : 
     263              :     /* return size */
     264           21 :     return size;
     265              : }
     266              : 
     267            9 : int multiple_files_buffer_delete_oldest_file(MultipleFilesRingBuffer* files_buffer)
     268              : {
     269            9 :     if (files_buffer == NULL) {
     270            0 :         fprintf(stderr, "multiple files buffer not set\n");
     271            0 :         return -1; /* ERROR */
     272              :     }
     273              : 
     274              :     struct dirent* dp;
     275              :     char filename[PATH_MAX + 1];
     276              :     char filename_oldest[PATH_MAX + 1];
     277              :     unsigned long size_oldest = 0;
     278              :     struct stat status;
     279              :     time_t time_oldest = 0;
     280              :     int index_oldest = INT_MAX;
     281              : 
     282            9 :     filename[0] = 0;
     283            9 :     filename_oldest[0] = 0;
     284              : 
     285              :     /* go through all dlt files in directory */
     286            9 :     DIR* dir = opendir(files_buffer->directory);
     287              : 
     288            9 :     if (!dir)
     289              :         return -1;
     290              : 
     291          335 :     while ((dp = readdir(dir)) != NULL) {
     292          326 :         if (strstr(dp->d_name, files_buffer->filenameBase) && strstr(dp->d_name, files_buffer->filenameExt)) {
     293              :             int res = snprintf(filename, sizeof(filename), "%s/%s", files_buffer->directory, dp->d_name);
     294              : 
     295              :             /* if the total length of the string is greater than the buffer, silently forget it. */
     296              :             /* snprintf: a return value of size  or more means that the output was truncated */
     297              :             /*           if an output error is encountered, a negative value is returned. */
     298           43 :             if (((unsigned int)res >= sizeof(filename)) || (res <= 0)) {
     299              :                 printf("Filename for delete oldest too long. Skip file.\n");
     300            0 :                 continue;
     301              :             }
     302              : 
     303           43 :             if (files_buffer->filenameTimestampBased) {
     304            0 :                 errno = 0;
     305            0 :                 if (0 == stat(filename, &status)) {
     306            0 :                     if ((time_oldest == 0) || (status.st_mtime < time_oldest)) {
     307            0 :                         time_oldest = status.st_mtime;
     308            0 :                         size_oldest = (unsigned long)status.st_size;
     309              :                         strncpy(filename_oldest, filename, PATH_MAX);
     310            0 :                         filename_oldest[PATH_MAX] = 0;
     311              :                     }
     312              :                 } else {
     313            0 :                     printf("Old file %s cannot be stat-ed, error=%s\n", filename, strerror(errno));
     314              :                 }
     315              :             } else {
     316              :                 // index based
     317           43 :                 const unsigned int index = multiple_files_buffer_get_idx_of_log_file(filename);
     318           43 :                 if (index < (unsigned int)index_oldest) {
     319           27 :                     index_oldest = (int)index;
     320              : #if defined(__GNUC__) && __GNUC__ >= 7
     321              : #pragma GCC diagnostic push
     322              : #pragma GCC diagnostic ignored "-Wformat-truncation"
     323              : #endif
     324              :                     snprintf(filename, sizeof(filename), "%s/%s", files_buffer->directory, dp->d_name);
     325              : #if defined(__GNUC__) && __GNUC__ >= 7
     326              : #pragma GCC diagnostic pop
     327              : #endif
     328              :                     strncpy(filename_oldest, filename, PATH_MAX);
     329           27 :                     filename_oldest[PATH_MAX] = 0;
     330              :                 }
     331              :             }
     332              :         }
     333              :     }
     334              : 
     335            9 :     closedir(dir);
     336              : 
     337              :     /* delete file */
     338            9 :     if (filename_oldest[0]) {
     339            9 :         if (remove(filename_oldest)) {
     340            0 :             fprintf(stderr, "Remove file %s failed! error=%s\n", filename_oldest, strerror(errno));
     341            0 :             return -1; /* ERROR */
     342              :         }
     343              :     } else {
     344            0 :         fprintf(stderr, "No file to be removed!\n");
     345            0 :         return -1; /* ERROR */
     346              :     }
     347              : 
     348              :     /* return size of deleted file*/
     349            9 :     return (int)size_oldest;
     350              : }
     351              : 
     352           12 : DltReturnValue multiple_files_buffer_check_size(MultipleFilesRingBuffer* files_buffer)
     353              : {
     354           12 :     if (files_buffer == NULL) {
     355            0 :         fprintf(stderr, "multiple files buffer not set\n");
     356            0 :         return DLT_RETURN_ERROR;
     357              :     }
     358              : 
     359              :     struct stat status;
     360              : 
     361              :     /* check for existence of buffer files directory */
     362           12 :     errno = 0;
     363           12 :     if (stat(files_buffer->directory, &status) == -1) {
     364            0 :         fprintf(
     365              :             stderr, "Buffer files directory: %s doesn't exist, error=%s\n", files_buffer->directory, strerror(errno));
     366            0 :         return DLT_RETURN_ERROR;
     367              :     }
     368              :     /* check for accessibility of buffer files directory */
     369           12 :     else if (access(files_buffer->directory, W_OK) != 0) {
     370            0 :         fprintf(stderr, "Buffer files directory: %s doesn't have the write access \n", files_buffer->directory);
     371            0 :         return DLT_RETURN_ERROR;
     372              :     }
     373              : 
     374              :     ssize_t total_size = 0;
     375              :     /* check size of complete buffer file */
     376           21 :     while ((total_size = multiple_files_buffer_get_total_size(files_buffer))
     377           21 :            > (files_buffer->maxSize - files_buffer->fileSize)) {
     378              :         /* remove the oldest files as long as new file will not fit in completely into complete multiple files buffer */
     379            9 :         if (multiple_files_buffer_delete_oldest_file(files_buffer) < 0)
     380              :             return DLT_RETURN_ERROR;
     381              :     }
     382              : 
     383           12 :     return total_size == -1 ? DLT_RETURN_ERROR : DLT_RETURN_OK;
     384              : }
     385              : 
     386            3 : DltReturnValue multiple_files_buffer_open_file_for_append(MultipleFilesRingBuffer* files_buffer)
     387              : {
     388            3 :     if (files_buffer == NULL || files_buffer->filenameTimestampBased)
     389              :         return DLT_RETURN_ERROR;
     390              : 
     391            3 :     char newest[NAME_MAX + 1] = {0};
     392            3 :     char oldest[NAME_MAX + 1] = {0};
     393              :     /* targeting the newest file, ignoring number of files in dir returned */
     394              : 
     395            3 :     if (0
     396            3 :         == multiple_files_buffer_storage_dir_info(
     397            3 :             files_buffer->directory, files_buffer->filenameBase, newest, oldest)) {
     398              :         // no file for appending found. Create a new one
     399              :         printf("No multiple files for appending found. Create a new one\n");
     400            0 :         return multiple_files_buffer_create_new_file(files_buffer);
     401              :     }
     402              : 
     403              :     char file_path[PATH_MAX + 1];
     404              :     int ret = snprintf(file_path, sizeof(file_path), "%s/%s", files_buffer->directory, newest);
     405              : 
     406            3 :     if ((ret < 0) || (ret >= NAME_MAX)) {
     407            0 :         fprintf(stderr, "filename cannot be concatenated\n");
     408            0 :         return DLT_RETURN_ERROR;
     409              :     }
     410              : 
     411              :     /* open DLT output file */
     412            3 :     errno = 0;
     413            3 :     files_buffer->ohandle = open(file_path, O_WRONLY | O_APPEND); /* mode: wb */
     414              : 
     415            3 :     return files_buffer->ohandle == -1 ? DLT_RETURN_ERROR : DLT_RETURN_OK;
     416              : }
     417              : 
     418            3 : DltReturnValue multiple_files_buffer_init(
     419              :     MultipleFilesRingBuffer* files_buffer, const char* directory, const int file_size, const int max_size,
     420              :     const bool filename_timestamp_based, const bool append, const char* filename_base, const char* filename_ext)
     421              : {
     422            3 :     if (files_buffer == NULL) {
     423            0 :         fprintf(stderr, "multiple files buffer not set\n");
     424            0 :         return DLT_RETURN_ERROR;
     425              :     }
     426              : 
     427              :     /* init parameters */
     428            3 :     strncpy(files_buffer->directory, directory, NAME_MAX);
     429            3 :     files_buffer->directory[NAME_MAX] = 0;
     430            3 :     files_buffer->fileSize = file_size;
     431            3 :     files_buffer->maxSize = max_size;
     432            3 :     files_buffer->filenameTimestampBased = filename_timestamp_based;
     433            3 :     strncpy(files_buffer->filenameBase, filename_base, NAME_MAX);
     434            3 :     files_buffer->filenameBase[NAME_MAX] = 0;
     435            3 :     strncpy(files_buffer->filenameExt, filename_ext, NAME_MAX);
     436            3 :     files_buffer->filenameExt[NAME_MAX] = 0;
     437              : 
     438            3 :     if (DLT_RETURN_ERROR == multiple_files_buffer_check_size(files_buffer))
     439              :         return DLT_RETURN_ERROR;
     440              : 
     441            3 :     return (!files_buffer->filenameTimestampBased && append) ?
     442            6 :                multiple_files_buffer_open_file_for_append(files_buffer) :
     443            0 :                multiple_files_buffer_create_new_file(files_buffer);
     444              : }
     445              : 
     446           12 : void multiple_files_buffer_rotate_file(MultipleFilesRingBuffer* files_buffer, const int size)
     447              : {
     448              :     /* check file size here */
     449           12 :     if ((lseek(files_buffer->ohandle, 0, SEEK_CUR) + size) < files_buffer->fileSize)
     450              :         return;
     451              : 
     452              :     /* close old file */
     453            9 :     close(files_buffer->ohandle);
     454            9 :     files_buffer->ohandle = -1;
     455              : 
     456              :     /* check complete files size, remove old logs if needed */
     457            9 :     if (DLT_RETURN_ERROR == multiple_files_buffer_check_size(files_buffer))
     458              :         return;
     459              : 
     460              :     /* create new file */
     461            9 :     multiple_files_buffer_create_new_file(files_buffer);
     462              : }
     463              : 
     464           12 : DltReturnValue multiple_files_buffer_write_chunk(
     465              :     const MultipleFilesRingBuffer* files_buffer, const unsigned char* data, const int size)
     466              : {
     467           12 :     if (files_buffer == NULL) {
     468            0 :         fprintf(stderr, "multiple files buffer not set\n");
     469            0 :         return DLT_RETURN_ERROR;
     470              :     }
     471              : 
     472           12 :     if (data && (files_buffer->ohandle >= 0)) {
     473           12 :         if (write(files_buffer->ohandle, data, (size_t)size) != (ssize_t)size) {
     474            0 :             fprintf(stderr, "file write failed!\n");
     475            0 :             return DLT_RETURN_ERROR;
     476              :         }
     477              :     }
     478              :     return DLT_RETURN_OK;
     479              : }
     480              : 
     481           12 : DltReturnValue multiple_files_buffer_write(
     482              :     MultipleFilesRingBuffer* files_buffer, const unsigned char* data, const int size)
     483              : {
     484           12 :     if (files_buffer->ohandle < 0)
     485              :         return DLT_RETURN_ERROR;
     486              : 
     487           12 :     multiple_files_buffer_rotate_file(files_buffer, size);
     488              : 
     489              :     /* write data into log file */
     490           12 :     return multiple_files_buffer_write_chunk(files_buffer, data, size);
     491              : }
     492              : 
     493            3 : DltReturnValue multiple_files_buffer_free(const MultipleFilesRingBuffer* files_buffer)
     494              : {
     495            3 :     if (files_buffer == NULL) {
     496            0 :         fprintf(stderr, "multiple files buffer not set\n");
     497            0 :         return DLT_RETURN_ERROR;
     498              :     }
     499              : 
     500            3 :     if (files_buffer->ohandle < 0)
     501              :         return DLT_RETURN_ERROR;
     502              : 
     503              :     /* close last used log file */
     504            3 :     close(files_buffer->ohandle);
     505              : 
     506            3 :     return DLT_RETURN_OK;
     507              : }
        

Generated by: LCOV version 2.0-1