GCC Code Coverage Report


Directory: ./
File: playlist/PlaylistEntryScript.cpp
Date: 2026-10-29 08:11:58
Exec Total Coverage
Lines: 63 85 74.1%
Functions: 9 11 81.8%
Branches: 32 68 47.1%

Line Branch Exec Source
1 /*
2 * This file is part of the Falcon Player (FPP) and is Copyright (C)
3 * 2013-2022 by the Falcon Player Developers.
4 *
5 * The Falcon Player (FPP) is free software, and is covered under
6 * multiple Open Source licenses. Please see the included 'LICENSES'
7 * file for descriptions of what files are covered by each license.
8 *
9 * This source file is covered under the LGPL v2.1 as described in the
10 * included LICENSE.LGPL file.
11 */
12
13 #include "fpp-pch.h"
14
15 #include "fpp-json.h"
16
17 #include <sys/types.h>
18 #include <sys/wait.h>
19 #include <signal.h>
20
21 #include "../common.h"
22 #include "../log.h"
23
24 #include "PlaylistEntryScript.h"
25 #include "scripts.h"
26
27 /*
28 *
29 */
30 25 PlaylistEntryScript::PlaylistEntryScript(Playlist* playlist, PlaylistEntryBase* parent) :
31 PlaylistEntryBase(playlist, parent),
32 25 m_blocking(0),
33 25 m_scriptProcess(0),
34 25 m_startTime(0) {
35
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 LogDebug(VB_PLAYLIST, "PlaylistEntryScript::PlaylistEntryScript()\n");
36
37
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 m_type = "script";
38 25 }
39
40 /*
41 *
42 */
43 84 PlaylistEntryScript::~PlaylistEntryScript() {
44 84 }
45
46 /*
47 *
48 */
49 25 int PlaylistEntryScript::Init(Json::Value& config) {
50 25 LogDebug(VB_PLAYLIST, "PlaylistEntryScript::Init()\n");
51
52
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (!config.isMember("scriptName")) {
53 ✗ LogErr(VB_PLAYLIST, "Missing scriptName entry\n");
54 ✗ return 0;
55 }
56
57
2/4
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
25 m_scriptFilename = config["scriptName"].asString();
58
2/4
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
25 m_scriptArgs = config["scriptArgs"].asString();
59 25 m_blocking = config["blocking"].asBool();
60
61 25 return PlaylistEntryBase::Init(config);
62 }
63
64 /*
65 *
66 */
67 24 int PlaylistEntryScript::StartPlaying(void) {
68 24 LogDebug(VB_PLAYLIST, "PlaylistEntryScript::StartPlaying()\n");
69
70
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 if (!CanPlay()) {
71 ✗ FinishPlay();
72 ✗ return 0;
73 }
74
75 24 m_startTime = GetMonotonicTimeMicros();
76 24 PlaylistEntryBase::StartPlaying();
77
3/6
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
24 m_scriptProcess = RunScript(m_scriptFilename, m_scriptArgs);
78
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 4 times.
24 if (m_scriptProcess <= 0) {
79 // Refused or failed to start. m_scriptProcess is only ever 0 or a
80 // live child: Stop() signals it, and kill(-1) would signal every
81 // process on the box.
82 20 m_scriptProcess = 0;
83 20 FinishPlay();
84 20 return 0;
85 }
86
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (!m_blocking) {
87 1 m_scriptProcess = 0;
88 1 FinishPlay();
89 1 return 0;
90 }
91
92 3 return PlaylistEntryBase::StartPlaying();
93 }
94 377 int PlaylistEntryScript::Process(void) {
95
5/6
✓ Branch 0 taken 377 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 375 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 375 times.
377 if (m_scriptProcess && !isChildRunning()) {
96 2 m_scriptProcess = 0;
97 2 FinishPlay();
98 }
99 377 return PlaylistEntryBase::Process();
100 }
101 /*
102 *
103 */
104 1 int PlaylistEntryScript::Stop(void) {
105 1 LogDebug(VB_PLAYLIST, "PlaylistEntryScript::Stop()\n");
106
107
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (m_scriptProcess > 0) {
108 1 kill(m_scriptProcess, SIGTERM);
109 1 FinishPlay();
110 }
111
112 1 return PlaylistEntryBase::Stop();
113 }
114
115 377 bool PlaylistEntryScript::isChildRunning() {
116
1/2
✓ Branch 0 taken 377 times.
✗ Branch 1 not taken.
377 if (m_scriptProcess > 0) {
117 377 int status = 0;
118
3/4
✓ Branch 0 taken 377 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 375 times.
377 if (waitpid(m_scriptProcess, &status, WNOHANG)) {
119 2 return false;
120 } else {
121 375 return true;
122 }
123 }
124 ✗ return false;
125 }
126
127 /*
128 *
129 */
130 ✗ void PlaylistEntryScript::Dump(void) {
131 ✗ PlaylistEntryBase::Dump();
132
133 ✗ LogDebug(VB_PLAYLIST, "Script Filename: %s\n", m_scriptFilename.c_str());
134 ✗ LogDebug(VB_PLAYLIST, "Blocking : %d\n", m_blocking);
135 ✗ }
136
137 4 uint64_t PlaylistEntryScript::GetElapsedMS() {
138 4 long long t = GetMonotonicTimeMicros();
139 4 t -= m_startTime;
140 4 t /= 1000;
141 4 return t;
142 }
143
144 /*
145 *
146 */
147 28 Json::Value PlaylistEntryScript::GetConfig(void) {
148 28 Json::Value result = PlaylistEntryBase::GetConfig();
149
150
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 long long t = GetMonotonicTimeMicros();
151 28 t -= m_startTime;
152 28 t /= 1000;
153 28 t /= 1000;
154
2/4
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
28 result["scriptFilename"] = m_scriptFilename;
155
2/4
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
28 result["blocking"] = m_blocking;
156
2/4
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
28 result["secondsElapsed"] = (Json::UInt64)t;
157
158 28 return result;
159 ✗ }
160
161 ✗ Json::Value PlaylistEntryScript::GetMqttStatus(void) {
162 ✗ Json::Value result = PlaylistEntryBase::GetMqttStatus();
163
164 ✗ long long t = GetMonotonicTimeMicros();
165 ✗ t -= m_startTime;
166 ✗ t /= 1000;
167 ✗ t /= 1000;
168 ✗ result["scriptFilename"] = m_scriptFilename;
169 ✗ result["blocking"] = m_blocking;
170 ✗ result["secondsElapsed"] = (Json::UInt64)t;
171
172 ✗ return result;
173 ✗ }
174