SolidSyslog coverage report
Current view: top level - Platform/VxWorks64/Source - SolidSyslogVxWorks64File.c (source / functions) Coverage Total Hit
Test: SolidSyslog Lines: 100.0 % 113 113
Test Date: 2026-11-12 23:14:35 Functions: 100.0 % 19 19
Branches: 100.0 % 62 62

             Branch data     Line data    Source code
       1                 :             : /* SPDX-FileCopyrightText: Copyright 2026 Cozens Software Solutions Limited
       2                 :             :  * SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0 OR LicenseRef-PolyForm-Internal-Use-1.0.0 OR LicenseRef-COSOSO-Commercial
       3                 :             :  */
       4                 :             : 
       5                 :             : #include "SolidSyslogVxWorks64File.h"
       6                 :             : 
       7                 :             : #include <errno.h>
       8                 :             : #include <stdbool.h>
       9                 :             : #include <stddef.h>
      10                 :             : 
      11                 :             : #include "vxWorks.h"
      12                 :             : 
      13                 :             : #include <sys/stat.h>
      14                 :             : 
      15                 :             : #include "dosFsLib.h"
      16                 :             : #include "ioLib.h"
      17                 :             : 
      18                 :             : #include "SolidSyslogError.h"
      19                 :             : #include "SolidSyslogErrorCategory.h"
      20                 :             : #include "SolidSyslogFileCategories.h"
      21                 :             : #include "SolidSyslogFileDefinition.h"
      22                 :             : #include "SolidSyslogNullFile.h"
      23                 :             : #include "SolidSyslogVxWorks64FileErrors.h"
      24                 :             : #include "SolidSyslogVxWorks64FilePrivate.h"
      25                 :             : 
      26                 :             : const struct SolidSyslogErrorSource SolidSyslogVxWorks64FileErrorSource = {"VxWorks64File", SolidSyslogFileErrors_Name};
      27                 :             : 
      28                 :             : /* rw------- : dosFs ignores the mode, HRFS keeps it. Spelled in hex because
      29                 :             :  * MISRA 7.1 rules out the octal the permission bits are usually written in. */
      30                 :             : enum
      31                 :             : {
      32                 :             :     VXWORKS64FILE_OWNER_READ_WRITE = 0x180
      33                 :             : };
      34                 :             : 
      35                 :             : static bool VxWorks64File_Open(struct SolidSyslogFile* base, const char* path);
      36                 :             : static void VxWorks64File_Close(struct SolidSyslogFile* base);
      37                 :             : static bool VxWorks64File_IsOpen(struct SolidSyslogFile* base);
      38                 :             : static bool VxWorks64File_Read(struct SolidSyslogFile* base, void* buf, size_t count);
      39                 :             : static bool VxWorks64File_Write(struct SolidSyslogFile* base, const void* buf, size_t count);
      40                 :             : static void VxWorks64File_SeekTo(struct SolidSyslogFile* base, size_t offset);
      41                 :             : static bool VxWorks64File_Size(struct SolidSyslogFile* base, size_t* size);
      42                 :             : static void VxWorks64File_Truncate(struct SolidSyslogFile* base);
      43                 :             : static bool VxWorks64File_Exists(struct SolidSyslogFile* base, const char* path);
      44                 :             : static bool VxWorks64File_Delete(struct SolidSyslogFile* base, const char* path);
      45                 :             : 
      46                 :             : static inline struct SolidSyslogVxWorks64File* VxWorks64File_SelfFromBase(struct SolidSyslogFile* base);
      47                 :             : static inline bool VxWorks64File_IsWholeTransfer(int transferred, size_t count);
      48                 :             : static inline bool VxWorks64File_Commit(int fd);
      49                 :             : static inline bool VxWorks64File_Sync(int fd);
      50                 :             : static inline bool VxWorks64File_CommitFileSystem(int fd);
      51                 :             : static inline void VxWorks64File_ReportFailure(enum SolidSyslogFileErrors code, int nativeErrno);
      52                 :             : static inline bool VxWorks64File_IsNotThere(int removeErrno);
      53                 :             : 
      54                 :          86 : void SolidSyslogVxWorks64File_Initialise(struct SolidSyslogFile* base)
      55                 :             : {
      56                 :          86 :     struct SolidSyslogVxWorks64File* self = VxWorks64File_SelfFromBase(base);
      57                 :          86 :     self->Base.Open = VxWorks64File_Open;
      58                 :          86 :     self->Base.Close = VxWorks64File_Close;
      59                 :          86 :     self->Base.IsOpen = VxWorks64File_IsOpen;
      60                 :          86 :     self->Base.Read = VxWorks64File_Read;
      61                 :          86 :     self->Base.Write = VxWorks64File_Write;
      62                 :          86 :     self->Base.SeekTo = VxWorks64File_SeekTo;
      63                 :          86 :     self->Base.Size = VxWorks64File_Size;
      64                 :          86 :     self->Base.Truncate = VxWorks64File_Truncate;
      65                 :          86 :     self->Base.Exists = VxWorks64File_Exists;
      66                 :          86 :     self->Base.Delete = VxWorks64File_Delete;
      67                 :          86 :     self->Fd = ERROR;
      68                 :          86 : }
      69                 :             : 
      70                 :          86 : void SolidSyslogVxWorks64File_Cleanup(struct SolidSyslogFile* base)
      71                 :             : {
      72                 :          86 :     VxWorks64File_Close(base);
      73                 :             :     /* Use-after-destroy lands on the NullFile vtable. */
      74                 :          86 :     *base = *SolidSyslogNullFile_Get();
      75                 :          86 : }
      76                 :             : 
      77                 :         602 : static inline struct SolidSyslogVxWorks64File* VxWorks64File_SelfFromBase(struct SolidSyslogFile* base)
      78                 :             : {
      79                 :         602 :     return (struct SolidSyslogVxWorks64File*) base;
      80                 :             : }
      81                 :             : 
      82                 :          68 : static bool VxWorks64File_Open(struct SolidSyslogFile* base, const char* path)
      83                 :             : {
      84                 :          68 :     struct SolidSyslogVxWorks64File* self = VxWorks64File_SelfFromBase(base);
      85                 :          68 :     self->Fd = open(path, O_RDWR | O_CREAT, VXWORKS64FILE_OWNER_READ_WRITE);
      86                 :             :     /* Read errno straight after the call that set it, with nothing between
      87                 :             :      * (MISRA 22.10). */
      88         [ +  + ]:          68 :     int openErrno = (self->Fd == ERROR) ? errno : 0;
      89                 :          68 :     bool opened = self->Fd != ERROR;
      90         [ +  + ]:          68 :     if (!opened)
      91                 :             :     {
      92                 :           3 :         VxWorks64File_ReportFailure(SOLIDSYSLOG_FILE_ERROR_OPEN_FAILED, openErrno);
      93                 :             :     }
      94                 :          68 :     return opened;
      95                 :             : }
      96                 :             : 
      97                 :             : /* The fault, with the errno behind it when the call left one. */
      98                 :             : // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) -- every caller passes a named code and the errno it read
      99                 :          22 : static inline void VxWorks64File_ReportFailure(enum SolidSyslogFileErrors code, int nativeErrno)
     100                 :             : {
     101         [ +  + ]:          22 :     if (nativeErrno != 0)
     102                 :             :     {
     103                 :          19 :         SolidSyslog_ErrorWithNativeCode(
     104                 :             :             SOLIDSYSLOG_FILE_IO_FAILED_SEVERITY,
     105                 :             :             &SolidSyslogVxWorks64FileErrorSource,
     106                 :             :             SOLIDSYSLOG_CAT_FILE_IO_FAILED,
     107                 :             :             (int32_t) code,
     108                 :             :             (int32_t) nativeErrno
     109                 :             :         );
     110                 :             :     }
     111                 :             :     else
     112                 :             :     {
     113                 :           3 :         VxWorks64File_Report(SOLIDSYSLOG_FILE_IO_FAILED_SEVERITY, SOLIDSYSLOG_CAT_FILE_IO_FAILED, code);
     114                 :             :     }
     115                 :          22 : }
     116                 :             : 
     117                 :         111 : static void VxWorks64File_Close(struct SolidSyslogFile* base)
     118                 :             : {
     119                 :         111 :     struct SolidSyslogVxWorks64File* self = VxWorks64File_SelfFromBase(base);
     120         [ +  + ]:         111 :     if (VxWorks64File_IsOpen(base))
     121                 :             :     {
     122                 :          65 :         int status = close(self->Fd);
     123         [ +  + ]:          65 :         int closeErrno = (status == ERROR) ? errno : 0;
     124                 :             :         /* The descriptor is released whether or not the close could flush. */
     125                 :          65 :         self->Fd = ERROR;
     126         [ +  + ]:          65 :         if (status == ERROR)
     127                 :             :         {
     128                 :           2 :             VxWorks64File_ReportFailure(SOLIDSYSLOG_FILE_ERROR_CLOSE_FAILED, closeErrno);
     129                 :             :         }
     130                 :             :     }
     131                 :         111 : }
     132                 :             : 
     133                 :         192 : static bool VxWorks64File_IsOpen(struct SolidSyslogFile* base)
     134                 :             : {
     135                 :         192 :     const struct SolidSyslogVxWorks64File* self = VxWorks64File_SelfFromBase(base);
     136                 :         192 :     return self->Fd != ERROR;
     137                 :             : }
     138                 :             : 
     139                 :          29 : static bool VxWorks64File_Read(struct SolidSyslogFile* base, void* buf, size_t count)
     140                 :             : {
     141                 :          29 :     const struct SolidSyslogVxWorks64File* self = VxWorks64File_SelfFromBase(base);
     142                 :          29 :     int transferred = read(self->Fd, (char*) buf, count);
     143                 :             :     /* A short read sets no errno; the store judges it. */
     144         [ +  + ]:          29 :     int readErrno = (transferred == ERROR) ? errno : 0;
     145         [ +  + ]:          29 :     if (transferred == ERROR)
     146                 :             :     {
     147                 :           2 :         VxWorks64File_ReportFailure(SOLIDSYSLOG_FILE_ERROR_READ_FAILED, readErrno);
     148                 :             :     }
     149                 :          29 :     return VxWorks64File_IsWholeTransfer(transferred, count);
     150                 :             : }
     151                 :             : 
     152                 :             : /* The kernel's read and write answer an int: ERROR, or how many bytes moved. */
     153                 :          66 : static inline bool VxWorks64File_IsWholeTransfer(int transferred, size_t count)
     154                 :             : {
     155   [ +  +  +  + ]:          66 :     return (transferred >= 0) && ((size_t) transferred == count);
     156                 :             : }
     157                 :             : 
     158                 :          37 : static bool VxWorks64File_Write(struct SolidSyslogFile* base, const void* buf, size_t count)
     159                 :             : {
     160                 :          37 :     const struct SolidSyslogVxWorks64File* self = VxWorks64File_SelfFromBase(base);
     161                 :             :     /* The kernel's write takes a char*, though it only reads the buffer. */
     162                 :          37 :     int written = write(self->Fd, (char*) buf, count);
     163                 :             :     /* A short write sets no errno. */
     164         [ +  + ]:          37 :     int writeErrno = (written == ERROR) ? errno : 0;
     165                 :          37 :     bool committed = VxWorks64File_IsWholeTransfer(written, count);
     166         [ +  + ]:          37 :     if (committed)
     167                 :             :     {
     168                 :          32 :         committed = VxWorks64File_Commit(self->Fd);
     169                 :             :     }
     170                 :             :     else
     171                 :             :     {
     172                 :           5 :         VxWorks64File_ReportFailure(SOLIDSYSLOG_FILE_ERROR_WRITE_FAILED, writeErrno);
     173                 :             :     }
     174                 :          37 :     return committed;
     175                 :             : }
     176                 :             : 
     177                 :             : /* FIOSYNC flushes the file to its device, then FIOCOMMITFS commits any
     178                 :             :  * transaction beneath it. */
     179                 :          32 : static inline bool VxWorks64File_Commit(int fd)
     180                 :             : {
     181                 :          32 :     bool committed = VxWorks64File_Sync(fd);
     182         [ +  + ]:          32 :     if (committed)
     183                 :             :     {
     184                 :          29 :         committed = VxWorks64File_CommitFileSystem(fd);
     185                 :             :     }
     186                 :          32 :     return committed;
     187                 :             : }
     188                 :             : 
     189                 :          32 : static inline bool VxWorks64File_Sync(int fd)
     190                 :             : {
     191                 :          32 :     int status = ioctl(fd, FIOSYNC, 0);
     192         [ +  + ]:          32 :     int syncErrno = (status == ERROR) ? errno : 0;
     193                 :          32 :     bool synced = status != ERROR;
     194         [ +  + ]:          32 :     if (!synced)
     195                 :             :     {
     196                 :           3 :         VxWorks64File_ReportFailure(SOLIDSYSLOG_FILE_ERROR_SYNC_FAILED, syncErrno);
     197                 :             :     }
     198                 :          32 :     return synced;
     199                 :             : }
     200                 :             : 
     201                 :          29 : static inline bool VxWorks64File_CommitFileSystem(int fd)
     202                 :             : {
     203                 :          29 :     int status = ioctl(fd, FIOCOMMITFS, 0);
     204         [ +  + ]:          29 :     int commitErrno = (status == ERROR) ? errno : 0;
     205                 :             :     /* ENOTSUP: no transaction to commit. */
     206   [ +  +  +  + ]:          29 :     bool committed = (status != ERROR) || (commitErrno == ENOTSUP);
     207         [ +  + ]:          29 :     if (!committed)
     208                 :             :     {
     209                 :           3 :         VxWorks64File_ReportFailure(SOLIDSYSLOG_FILE_ERROR_COMMIT_FAILED, commitErrno);
     210                 :             :     }
     211                 :          29 :     return committed;
     212                 :             : }
     213                 :             : 
     214                 :          43 : static void VxWorks64File_SeekTo(struct SolidSyslogFile* base, size_t offset)
     215                 :             : {
     216                 :          43 :     const struct SolidSyslogVxWorks64File* self = VxWorks64File_SelfFromBase(base);
     217                 :          43 :     off_t position = lseek(self->Fd, (off_t) offset, SEEK_SET);
     218         [ +  + ]:          43 :     int seekErrno = (position == ERROR) ? errno : 0;
     219         [ +  + ]:          43 :     if (position == ERROR)
     220                 :             :     {
     221                 :           1 :         VxWorks64File_ReportFailure(SOLIDSYSLOG_FILE_ERROR_SEEK_FAILED, seekErrno);
     222                 :             :     }
     223                 :          43 : }
     224                 :             : 
     225                 :          18 : static bool VxWorks64File_Size(struct SolidSyslogFile* base, size_t* size)
     226                 :             : {
     227                 :          18 :     const struct SolidSyslogVxWorks64File* self = VxWorks64File_SelfFromBase(base);
     228                 :          18 :     off_t end = lseek(self->Fd, 0, SEEK_END);
     229                 :          18 :     bool known = end != ERROR;
     230         [ +  + ]:          18 :     int sizeErrno = known ? 0 : errno;
     231         [ +  + ]:          18 :     if (!known)
     232                 :             :     {
     233                 :           2 :         VxWorks64File_ReportFailure(SOLIDSYSLOG_FILE_ERROR_SIZE_FAILED, sizeErrno);
     234                 :             :     }
     235         [ +  + ]:          18 :     *size = known ? (size_t) end : 0U;
     236                 :          18 :     return known;
     237                 :             : }
     238                 :             : 
     239                 :          18 : static void VxWorks64File_Truncate(struct SolidSyslogFile* base)
     240                 :             : {
     241                 :          18 :     const struct SolidSyslogVxWorks64File* self = VxWorks64File_SelfFromBase(base);
     242                 :          18 :     int status = ioctl(self->Fd, FIOTRUNC, 0);
     243         [ +  + ]:          18 :     int truncateErrno = (status == ERROR) ? errno : 0;
     244         [ +  + ]:          18 :     if (status == ERROR)
     245                 :             :     {
     246                 :           1 :         VxWorks64File_ReportFailure(SOLIDSYSLOG_FILE_ERROR_TRUNCATE_FAILED, truncateErrno);
     247                 :             :     }
     248                 :          18 : }
     249                 :             : 
     250                 :             : /* stat answers for the path without opening it, so a scan of the block index
     251                 :             :  * space costs no descriptors. A path without a status answers false whatever
     252                 :             :  * the reason, and reports nothing: the open that follows on the same volume
     253                 :             :  * reports, and the store freezes on it. */
     254                 :        1308 : static bool VxWorks64File_Exists(struct SolidSyslogFile* base, const char* path)
     255                 :             : {
     256                 :             :     (void) base;
     257                 :             :     struct stat status;
     258                 :        1308 :     return stat(path, &status) == OK;
     259                 :             : }
     260                 :             : 
     261                 :             : /* True only for a path remove took away or found absent. Any other failure
     262                 :             :  * leaves the file on the volume, and answering false lets the store freeze
     263                 :             :  * rather than forget a block it will find again at its next start-up. */
     264                 :           7 : static bool VxWorks64File_Delete(struct SolidSyslogFile* base, const char* path)
     265                 :             : {
     266                 :             :     (void) base;
     267                 :           7 :     STATUS status = remove(path);
     268         [ +  + ]:           7 :     int removeErrno = (status == ERROR) ? errno : 0;
     269   [ +  +  +  + ]:           7 :     return (status == OK) || VxWorks64File_IsNotThere(removeErrno);
     270                 :             : }
     271                 :             : 
     272                 :             : /* Each file system names an absent path its own way, measured on the target:
     273                 :             :  * HRFS sets ENOENT, dosFs S_dosFsLib_FILE_NOT_FOUND. */
     274                 :           6 : static inline bool VxWorks64File_IsNotThere(int removeErrno)
     275                 :             : {
     276   [ +  +  +  + ]:           6 :     return (removeErrno == ENOENT) || (removeErrno == S_dosFsLib_FILE_NOT_FOUND);
     277                 :             : }
        

Generated by: LCOV version 2.0-1