Hi!
Digging a bit in the problem, it's mostly the use of snprintf with
time_t in 64 bits formatted with %ld, but it should be %lld on armhf. It
is generally harmless when the output goes to stdout, but
here with snprintf we reuse the output for something else, and that
doesn't fly.
I propose the enclosed patch, which is not limited to the time_t
problem, and so suppresses also all armhf compiler warnings not present
on amd64 builds.
The builds gives a working zoneminder. It has been tested (i.e. running
with real cameras) for both armhf and amd64, so there is no 64 bits
regression.
--- a/src/zm_logger.cpp
+++ b/src/zm_logger.cpp
@@ -445,7 +445,7 @@ void Logger::logPrint(bool hex, const ch
char *timePtr = timeString;
tm now_tm = {};
timePtr += strftime(timePtr, sizeof(timeString), "%x %H:%M:%S", localtime_r(&timeVal.tv_sec, &now_tm));
- snprintf(timePtr, sizeof(timeString)-(timePtr-timeString), ".%06ld", timeVal.tv_usec);
+ snprintf(timePtr, sizeof(timeString)-(timePtr-timeString), ".%06" __PRI64_PREFIX "d", timeVal.tv_usec);
#if 0
}
#endif
@@ -534,7 +534,7 @@ void Logger::logPrint(bool hex, const ch
"INSERT INTO `Logs` "
"( `TimeKey`, `Component`, `ServerId`, `Pid`, `Level`, `Code`, `Message`, `File`, `Line` )"
" VALUES "
- "( %ld.%06ld, '%s', %d, %d, %d, '%s', '%s', '%s', %d )",
+ "( %" __PRI64_PREFIX "d.%06" __PRI64_PREFIX "d, '%s', %d, %d, %d, '%s', '%s', '%s', %d )",
timeVal.tv_sec, timeVal.tv_usec, mId.c_str(), staticConfig.SERVER_ID, tid, level, classString, escapedString.c_str(), file, line
);
dbQueue.push(std::move(sql_string));
--- a/src/zm_time.h
+++ b/src/zm_time.h
@@ -155,13 +155,13 @@ inline struct timeval tvCheck( struct ti
{
if ( t.tv_usec >= USEC_PER_SEC )
{
- Warning( "Timestamp too large %ld.%ld\n", t.tv_sec, (long int) t.tv_usec );
+ Warning( "Timestamp too large %" __PRI64_PREFIX "d.%ld\n", t.tv_sec, (long int) t.tv_usec );
t.tv_sec += t.tv_usec / USEC_PER_SEC;
t.tv_usec %= USEC_PER_SEC;
}
else if ( t.tv_usec < 0 )
{
- Warning( "Got negative timestamp %ld.%ld\n", t.tv_sec, (long int)t.tv_usec );
+ Warning( "Got negative timestamp %" __PRI64_PREFIX "d.%ld\n", t.tv_sec, (long int)t.tv_usec );
t.tv_usec = 0;
}
return( t );
--- a/src/zm_event.cpp
+++ b/src/zm_event.cpp
@@ -93,7 +93,7 @@ Event::Event(
localtime_r(&now.tv_sec, &tm_info);
strftime(buffer_now, 26, "%Y:%m:%d %H:%M:%S", &tm_info);
- Error("StartDateTime in the future starttime %ld.%06ld >? now %ld.%06ld difference %" PRIi64 "\nstarttime: %s\nnow: %s",
+ Error("StartDateTime in the future starttime %" __PRI64_PREFIX "d.%06" __PRI64_PREFIX "d >? now %" __PRI64_PREFIX "d.%06" __PRI64_PREFIX "d difference %" PRIi64 "\nstarttime: %s\nnow: %s",
start_time.tv_sec, start_time.tv_usec, now.tv_sec, now.tv_usec,
static_cast<int64>(now.tv_sec - start_time.tv_sec),
buffer, buffer_now);
@@ -116,7 +116,7 @@ Event::Event(
"INSERT INTO `Events` "
"( `MonitorId`, `StorageId`, `Name`, `StartDateTime`, `Width`, `Height`, `Cause`, `Notes`, `StateId`, `Orientation`, `Videoed`, `DefaultVideo`, `SaveJPEGs`, `Scheme` )"
" VALUES "
- "( %d, %d, 'New Event', from_unixtime( %ld ), %d, %d, '%s', '%s', %d, %d, %d, '%s', %d, '%s' )",
+ "( %d, %d, 'New Event', from_unixtime( %" __PRI64_PREFIX "d ), %d, %d, '%s', '%s', %d, %d, %d, '%s', %d, '%s' )",
monitor->Id(),
storage->Id(),
start_time.tv_sec,
@@ -174,7 +174,7 @@ Event::~Event() {
// Should not be static because we might be multi-threaded
char sql[ZM_SQL_LGE_BUFSIZ];
snprintf(sql, sizeof(sql),
- "UPDATE Events SET Name='%s%" PRIu64 "', EndDateTime = from_unixtime(%ld), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64 " AND Name='New Event'",
+ "UPDATE Events SET Name='%s%" PRIu64 "', EndDateTime = from_unixtime(%" __PRI64_PREFIX "d), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64 " AND Name='New Event'",
monitor->EventPrefix(), id, end_time.tv_sec,
delta_time.positive?"":"-", delta_time.sec, delta_time.fsec,
frames, alarm_frames,
@@ -183,7 +183,7 @@ Event::~Event() {
if (!zmDbDoUpdate(sql)) {
// Name might have been changed during recording, so just do the update without changing the name.
snprintf(sql, sizeof(sql),
- "UPDATE Events SET EndDateTime = from_unixtime(%ld), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64,
+ "UPDATE Events SET EndDateTime = from_unixtime(%" __PRI64_PREFIX "d), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64,
end_time.tv_sec,
delta_time.positive?"":"-", delta_time.sec, delta_time.fsec,
frames, alarm_frames,
@@ -374,7 +374,7 @@ void Event::WriteDbFrames() {
while (frame_data.size()) {
Frame *frame = frame_data.front();
frame_data.pop();
- frame_insert_sql += stringtf("\n( %" PRIu64 ", %d, '%s', from_unixtime( %ld ), %s%ld.%02ld, %d ),",
+ frame_insert_sql += stringtf("\n( %" PRIu64 ", %d, '%s', from_unixtime( %" __PRI64_PREFIX "d ), %s%ld.%02ld, %d ),",
id, frame->frame_id,
frame_type_names[frame->type],
frame->timestamp.tv_sec,
--- a/src/zm_image.cpp
+++ b/src/zm_image.cpp
@@ -917,7 +917,7 @@ bool Image::ReadRaw(const char *filename
if ( (unsigned int)statbuf.st_size != size ) {
fclose(infile);
- Error("Raw file size mismatch, expected %d bytes, found %ld", size, statbuf.st_size);
+ Error("Raw file size mismatch, expected %d bytes, found %" __PRI64_PREFIX "d", size, statbuf.st_size);
return false;
}
--- a/src/zm_monitor.cpp
+++ b/src/zm_monitor.cpp
@@ -187,7 +187,7 @@ bool Monitor::MonitorLink::connect() {
disconnect();
return false;
} else if (map_stat.st_size < mem_size) {
- Error("Got unexpected memory map file size %ld, expected %jd", map_stat.st_size, mem_size);
+ Error("Got unexpected memory map file size %" __PRI64_PREFIX "d, expected %jd", map_stat.st_size, mem_size);
disconnect();
return false;
}
@@ -949,19 +949,19 @@ bool Monitor::connect() {
return false;
}
} else if (map_stat.st_size == 0) {
- Error("Got empty memory map file size %ld, is the zmc process for this monitor running?", map_stat.st_size);
+ Error("Got empty memory map file size %" __PRI64_PREFIX "d, is the zmc process for this monitor running?", map_stat.st_size);
close(map_fd);
map_fd = -1;
return false;
} else {
- Error("Got unexpected memory map file size %ld, expected %jd", map_stat.st_size, mem_size);
+ Error("Got unexpected memory map file size %" __PRI64_PREFIX "d, expected %jd", map_stat.st_size, mem_size);
close(map_fd);
map_fd = -1;
return false;
}
} // end if map_stat.st_size != mem_size
- Debug(3, "MMap file size is %ld", map_stat.st_size);
+ Debug(3, "MMap file size is %" __PRI64_PREFIX "d", map_stat.st_size);
#ifdef MAP_LOCKED
mem_ptr = (unsigned char *)mmap(nullptr, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, map_fd, 0);
if (mem_ptr == MAP_FAILED) {
@@ -2236,7 +2236,7 @@ void Monitor::ReloadLinkedMonitors(const
while ( 1 ) {
dest_ptr = link_id_str;
while ( *src_ptr >= '0' && *src_ptr <= '9' ) {
- if ( (dest_ptr-link_id_str) < (unsigned int)(sizeof(link_id_str)-1) ) {
+ if ( (size_t)(dest_ptr-link_id_str) < (sizeof(link_id_str)-1) ) {
*dest_ptr++ = *src_ptr++;
} else {
break;
@@ -2625,7 +2625,7 @@ bool Monitor::Decode() {
gettimeofday(&now, nullptr);
shared_data->last_write_time = now.tv_sec;
if (now.tv_sec - packet->timestamp.tv_sec > ZM_WATCH_MAX_DELAY) {
- Warning("Decoding is not keeping up. We are %ld seconds behind capture.",
+ Warning("Decoding is not keeping up. We are %" __PRI64_PREFIX "d seconds behind capture.",
now.tv_sec - packet->timestamp.tv_sec);
}
@@ -2644,7 +2644,7 @@ void Monitor::TimestampImage(Image *ts_i
char label_text[1024];
const char *s_ptr = label_time_text;
char *d_ptr = label_text;
- while ( *s_ptr && ((d_ptr-label_text) < (unsigned int)sizeof(label_text)) ) {
+ while ( *s_ptr && ((size_t)(d_ptr-label_text) < sizeof(label_text)) ) {
if ( *s_ptr == config.timestamp_code_char[0] ) {
bool found_macro = false;
switch ( *(s_ptr+1) ) {
@@ -2657,7 +2657,7 @@ void Monitor::TimestampImage(Image *ts_i
found_macro = true;
break;
case 'f' :
- d_ptr += snprintf(d_ptr, sizeof(label_text)-(d_ptr-label_text), "%02ld", ts_time.tv_usec/10000);
+ d_ptr += snprintf(d_ptr, sizeof(label_text)-(d_ptr-label_text), "%02" __PRI64_PREFIX "d", ts_time.tv_usec/10000);
found_macro = true;
break;
}
--- a/src/zm_fifo.cpp
+++ b/src/zm_fifo.cpp
@@ -148,8 +148,8 @@ bool Fifo::writePacket(std::string filen
bool Fifo::write(uint8_t *data, size_t bytes, int64_t pts) {
if (!(outfile or open())) return false;
// Going to write a brief header
- Debug(1, "Writing header ZM %lu %" PRId64, bytes, pts);
- if ( fprintf(outfile, "ZM %lu %" PRId64 "\n", bytes, pts) < 0 ) {
+ Debug(1, "Writing header ZM %" __PRIPTR_PREFIX "u %" PRId64, bytes, pts);
+ if ( fprintf(outfile, "ZM %" __PRIPTR_PREFIX "u %" PRId64 "\n", bytes, pts) < 0 ) {
if (errno != EAGAIN) {
Error("Problem during writing: %s", strerror(errno));
} else {
--- a/src/zm_packetqueue.cpp
+++ b/src/zm_packetqueue.cpp
@@ -260,7 +260,7 @@ void PacketQueue::clearPackets(const std
--it;
}
}
- Debug(1, "Tail count is %d, queue size is %lu", tail_count, pktQueue.size());
+ Debug(1, "Tail count is %d, queue size is %" __PRIPTR_PREFIX "u", tail_count, pktQueue.size());
if (!keep_keyframes) {
// If not doing passthrough, we don't care about starting with a keyframe so logic is simpler
--- a/src/zm_rtp_source.cpp
+++ b/src/zm_rtp_source.cpp
@@ -196,15 +196,15 @@ void RtpSource::updateRtcpData(
uint32_t rtpTime) {
struct timeval ntpTime = tvMake(ntpTimeSecs, suseconds_t((USEC_PER_SEC*(ntpTimeFrac>>16))/(1<<16)));
- Debug(5, "ntpTime: %ld.%06ld, rtpTime: %x", ntpTime.tv_sec, ntpTime.tv_usec, rtpTime);
+ Debug(5, "ntpTime: %" __PRI64_PREFIX "d.%06" __PRI64_PREFIX "d, rtpTime: %x", ntpTime.tv_sec, ntpTime.tv_usec, rtpTime);
if ( mBaseTimeNtp.tv_sec == 0 ) {
mBaseTimeReal = tvNow();
mBaseTimeNtp = ntpTime;
mBaseTimeRtp = rtpTime;
} else if ( !mRtpClock ) {
- Debug(5, "lastSrNtpTime: %ld.%06ld, rtpTime: %x"
- "ntpTime: %ld.%06ld, rtpTime: %x",
+ Debug(5, "lastSrNtpTime: %" __PRI64_PREFIX "d.%06" __PRI64_PREFIX "d, rtpTime: %x"
+ "ntpTime: %" __PRI64_PREFIX "d.%06" __PRI64_PREFIX "d, rtpTime: %x",
mLastSrTimeNtp.tv_sec, mLastSrTimeNtp.tv_usec, rtpTime,
ntpTime.tv_sec, ntpTime.tv_usec, rtpTime);
--- a/src/zmu.cpp
+++ b/src/zmu.cpp
@@ -542,12 +542,12 @@ int main(int argc, char *argv[]) {
strftime(timestamp_str, sizeof(timestamp_str), "%Y-%m-%d %H:%M:%S", localtime_r(×tamp.tv_sec, &tm_info));
}
if ( image_idx == -1 )
- printf("Time of last image capture: %s.%02ld\n", timestamp_str, timestamp.tv_usec/10000);
+ printf("Time of last image capture: %s.%02" __PRI64_PREFIX "d\n", timestamp_str, timestamp.tv_usec/10000);
else
- printf("Time of image %d capture: %s.%02ld\n", image_idx, timestamp_str, timestamp.tv_usec/10000);
+ printf("Time of image %d capture: %s.%02" __PRI64_PREFIX "d\n", image_idx, timestamp_str, timestamp.tv_usec/10000);
} else {
if ( have_output ) fputc(separator, stdout);
- printf("%ld.%02ld", timestamp.tv_sec, timestamp.tv_usec/10000);
+ printf("%" __PRI64_PREFIX "d.%02" __PRI64_PREFIX "d", timestamp.tv_sec, timestamp.tv_usec/10000);
have_output = true;
}
}
@@ -777,7 +777,7 @@ int main(int argc, char *argv[]) {
std::shared_ptr<Monitor> monitor = Monitor::Load(monitor_id, false, Monitor::QUERY);
if ( monitor && monitor->connect() ) {
struct timeval tv = monitor->GetTimestamp();
- printf( "%4d%5d%6d%9d%11ld.%02ld%6d%6d%8" PRIu64 "%8.2f\n",
+ printf( "%4d%5d%6d%9d%11" __PRI64_PREFIX "d.%02" __PRI64_PREFIX "d%6d%6d%8" PRIu64 "%8.2f\n",
monitor->Id(),
monitor_function,
monitor->GetState(),
@@ -791,7 +791,7 @@ int main(int argc, char *argv[]) {
}
} else {
struct timeval tv = { 0, 0 };
- printf("%4d%5d%6d%9d%11ld.%02ld%6d%6d%8d%8.2f\n",
+ printf("%4d%5d%6d%9d%11" __PRI64_PREFIX "d.%02" __PRI64_PREFIX "d%6d%6d%8d%8.2f\n",
mon_id,
function,
0,
--- a/src/zm_rtsp_server_fifo_source.cpp
+++ b/src/zm_rtsp_server_fifo_source.cpp
@@ -214,7 +214,7 @@ int ZoneMinderFifoSource::getNextFrame()
return 0;
}
if (header_start != m_buffer) {
- Debug(4, "ZM Packet didn't start at beginning of buffer %ld. %c%c",
+ Debug(4, "ZM Packet didn't start at beginning of buffer %" __PRIPTR_PREFIX "d. %c%c",
header_start - m_buffer.head(), m_buffer[0], m_buffer[1]);
}