From 3884e893c82a50e93ad79f532dd170c374c07a8e Mon Sep 17 00:00:00 2001 From: Mobin Aydinfar Date: Fri, 29 May 2026 03:31:23 +0330 Subject: [PATCH 1/2] dinitctl: show the service description file path in service status Add a "File" field to the service status showing the path of the service description file. Addresses #508 --- src/dinitctl.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/dinitctl.cc b/src/dinitctl.cc index e997c1b8..a6df002f 100644 --- a/src/dinitctl.cc +++ b/src/dinitctl.cc @@ -1627,8 +1627,13 @@ static int service_status(dinit_conn_t &dinit_conn, const char *service_name, ct return 1; } - // Issue STATUS request { + // Determine the service description path + std::string sdf_path = get_service_description_dir(socknum, rbuffer, handle); + sdf_path.append(1, '/'); + sdf_path.append(service_name, strip_service_arg(service_name)); + + // Issue STATUS request char status_req_id = proto_version < 5 ? (char)cp_cmd::SERVICESTATUS : (char)cp_cmd::SERVICESTATUS5; unsigned status_buf_size = proto_version < 5 ? STATUS_BUFFER_SIZE : STATUS_BUFFER5_SIZE; @@ -1720,6 +1725,7 @@ static int service_status(dinit_conn_t &dinit_conn, const char *service_name, ct } cout << "Service: " << service_name << "\n" + " File: " << sdf_path << "\n" " State: "; switch (current) { From 12c0f3d8872133e6de05aab7ac59b933ef74d0e0 Mon Sep 17 00:00:00 2001 From: Mobin Aydinfar Date: Fri, 19 Jun 2026 21:45:05 +0330 Subject: [PATCH 2/2] dinitctl: indicate modified service description file in service status Show "(modified since loaded)" at the end of the "File" field when the service description file has changed since it was loaded. Use the newer "SERVICESTATUS6" protocol request which is required to implement this feature. Fallback to the older protocol requests when the daemon doesn't support the newer one, making this feature unavailable in that case. --- src/dinitctl.cc | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/dinitctl.cc b/src/dinitctl.cc index a6df002f..17568186 100644 --- a/src/dinitctl.cc +++ b/src/dinitctl.cc @@ -1634,8 +1634,11 @@ static int service_status(dinit_conn_t &dinit_conn, const char *service_name, ct sdf_path.append(service_name, strip_service_arg(service_name)); // Issue STATUS request - char status_req_id = proto_version < 5 ? (char)cp_cmd::SERVICESTATUS : (char)cp_cmd::SERVICESTATUS5; - unsigned status_buf_size = proto_version < 5 ? STATUS_BUFFER_SIZE : STATUS_BUFFER5_SIZE; + char status_req_id = proto_version >= 6 ? (char)cp_cmd::SERVICESTATUS6 + : (proto_version == 5 ? (char)cp_cmd::SERVICESTATUS5 + : (char)cp_cmd::SERVICESTATUS); + unsigned status_buf_size = proto_version >= 6 ? STATUS_BUFFER6_SIZE + : (proto_version == 5 ? STATUS_BUFFER5_SIZE : STATUS_BUFFER_SIZE); auto m = membuf() .append(status_req_id) @@ -1652,6 +1655,23 @@ static int service_status(dinit_conn_t &dinit_conn, const char *service_name, ct fill_buffer_to(rbuffer, socknum, status_buf_size + 1 /* reserved */); rbuffer.consume(1); + // Check the service description file hasn't changed. We already located said file, so stat + // it to find the modification time, then compare that with the modification time according + // to dinit. + bool sdf_has_changed = false; + if (proto_version >= 6) { + struct stat sdf_statbuf; + if (stat(sdf_path.c_str(), &sdf_statbuf) == 0) { + struct timespec dinit_sdf_time; + rbuffer.extract(&dinit_sdf_time, STATUS_BUFFER5_SIZE, sizeof(dinit_sdf_time)); + + auto &file_time = get_timespec(sdf_statbuf); + + sdf_has_changed = (dinit_sdf_time.tv_sec != file_time.tv_sec + || dinit_sdf_time.tv_nsec != file_time.tv_nsec); + } + } + service_state_t current = static_cast(rbuffer[0]); service_state_t target = static_cast(rbuffer[1]); @@ -1725,8 +1745,9 @@ static int service_status(dinit_conn_t &dinit_conn, const char *service_name, ct } cout << "Service: " << service_name << "\n" - " File: " << sdf_path << "\n" - " State: "; + " File: " << sdf_path; + if (sdf_has_changed) cout << " (modified since loaded)"; + cout << "\n State: "; switch (current) { case service_state_t::STOPPED: