ExifTool daemon becomes unresponsive if the output is closed prematurely
thecodewarrior opened this issue · comments
When streaming files through exiftool using named pipes, prematurely closing the output makes the daemon unresponsive. It responds to -stay_open false
, but it never prints {ready}
and it doesn't respond when I try to issue it another command. Every other failure mode I tested is handled gracefully, but this particular I/O failure isn't. I'm working around this in my application by draining the output of the exiftool daemon when I kill the whole pipeline, but I'd prefer it if I didn't have to do that.
I made a script that can reproduce the hang:
#!/bin/bash
rm _in _out _commands
mkfifo _in _out _commands
echo -n 'ExifTool '; exiftool -ver
exiftool -stay_open true -@ _commands &
echo $'-v3\n-exif:Software=hi\n-o\n_out\n_in\n-execute' > _commands
cat image.jpg > _in &
head -c 2000 _out > out.jpg
echo "### prematurely closed output ###"
echo "### trying to use exiftool again ###"
echo $'-v3\n-exif:Software=hi\n-o\n_out\n_in\n-execute' > _commands
cat image.jpg > _in &
cat _out > out2.jpg
echo "### issuing the stop command ###"
echo $'-stay_open\nfalse' > _commands &
Output
~/D/c/r/exiftool> ./issue_128.sh
ExifTool 12.40
Writing IFD0:Software
======== _in
'_in' --> '_out'
Rewriting _in...
Editing tags in: APP0 APP1 IFD0 JFIF
Creating tags in: APP1 IFD0
JPEG APP1 (174 bytes):
0000: 45 78 69 66 00 00 4d 4d 00 2a 00 00 00 08 00 06 [Exif..MM.*......]
0010: 01 06 00 03 00 00 00 01 00 02 00 00 01 12 00 03 [................]
0020: 00 00 00 01 00 01 00 00 01 1a 00 05 00 00 00 01 [................]
0030: 00 00 00 56 01 1b 00 05 00 00 00 01 00 00 00 5e [...V...........^]
0040: 01 28 00 03 00 00 00 01 00 02 00 00 87 69 00 04 [.(...........i..]
0050: 00 00 00 01 00 00 00 66 00 00 00 00 00 00 00 48 [.......f.......H]
0060: 00 00 00 01 00 00 00 48 00 00 00 01 00 05 90 00 [.......H........]
[snip 62 bytes]
Rewriting IFD0
+ IFD0:Software = 'hi'
Rewriting ExifIFD
JPEG APP1 (2335 bytes):
0000: 68 74 74 70 3a 2f 2f 6e 73 2e 61 64 6f 62 65 2e [http://ns.adobe.]
0010: 63 6f 6d 2f 78 61 70 2f 31 2e 30 2f 00 3c 3f 78 [com/xap/1.0/.<?x]
0020: 70 61 63 6b 65 74 20 62 65 67 69 6e 3d 22 ef bb [packet begin="..]
0030: bf 22 20 69 64 3d 22 57 35 4d 30 4d 70 43 65 68 [." id="W5M0MpCeh]
0040: 69 48 7a 72 65 53 7a 4e 54 63 7a 6b 63 39 64 22 [iHzreSzNTczkc9d"]
0050: 3f 3e 20 3c 78 3a 78 6d 70 6d 65 74 61 20 78 6d [?> <x:xmpmeta xm]
0060: 6c 6e 73 3a 78 3d 22 61 64 6f 62 65 3a 6e 73 3a [lns:x="adobe:ns:]
[snip 2223 bytes]
JPEG DQT (65 bytes):
JPEG DQT (65 bytes):
JPEG SOF0:
JPEG DHT (27 bytes):
JPEG DHT (90 bytes):
JPEG DHT (25 bytes):
JPEG DHT (53 bytes):
JPEG SOS
### prematurely closed output ###
### trying to use exiftool again ###
^C⏎
~/D/c/r/exiftool [SIGINT]>
I also have a script that demonstrates the other failure modes I tested:
#!/bin/bash
rm _in _out _commands
mkfifo _in _out _commands
echo -n 'ExifTool '; exiftool -ver
exiftool -stay_open true -@ _commands &
echo $'-exif:Software=hi\n-o\n_out\n_in\n-execute' > _commands
echo "### starting operation ###"
cat image.jpg > _in & # good
#head -c 100000 image.jpg > _in & # input closed prematurely (in the middle of pixel data)
#head -c 300 image.jpg > _in & # incomplete input (incomplete header)
#tail -c 100000 image.jpg > _in & # invalid input (garbage data)
#cat image.webp > _in & # unsupported write format
#cat text.txt > _in & # garbage format
cat _out > out.jpg # good
#head -c 10000 _out > out.jpg # output closed prematurely
echo "### finished operation ###"
echo "### issuing the stop command ###"
echo $'-stay_open\nfalse' > _commands &
I have tried your first script (on MacOS 10.14.6) and it works fine for me for a 2697-byte JPG image (t/images/Canon.jpg from the full distribution):
ExifTool 12.36
Writing IFD0:Software
======== _in
'_in' --> '_out'
Rewriting _in...
Editing tags in: APP0 APP1 IFD0 JFIF
Creating tags in: APP1 IFD0
JPEG APP1 (2442 bytes):
0000: 45 78 69 66 00 00 49 49 2a 00 08 00 00 00 09 00 [Exif..II*.......]
0010: 0f 01 02 00 06 00 00 00 7a 00 00 00 10 01 02 00 [........z.......]
0020: 18 00 00 00 80 00 00 00 12 01 03 00 01 00 00 00 [................]
0030: 01 00 00 00 1a 01 05 00 01 00 00 00 98 00 00 00 [................]
0040: 1b 01 05 00 01 00 00 00 a0 00 00 00 28 01 03 00 [............(...]
0050: 01 00 00 00 02 00 00 00 32 01 02 00 14 00 00 00 [........2.......]
0060: a8 00 00 00 13 02 03 00 01 00 00 00 01 00 00 00 [................]
[snip 2330 bytes]
Rewriting IFD0
+ IFD0:Software = 'hi'
Rewriting ExifIFD
Rewriting MakerNoteCanon
Rewriting CanonCameraSettings
Rewriting CanonFocalLength
Rewriting CanonShotInfo
Rewriting CanonFileInfo
Rewriting CanonCameraInfoUnknown
Rewriting MeasuredColor
Rewriting ColorBalance
Rewriting InteropIFD
JPEG DQT (130 bytes):
JPEG SOF0:
JPEG DHT (73 bytes):
JPEG SOS
### prematurely closed output ###
### trying to use exiftool again ###
1 image files created
{ready}
Writing IFD0:Software
======== _in
'_in' --> '_out'
Rewriting _in...
Editing tags in: APP0 APP1 IFD0 JFIF
Creating tags in: APP1 IFD0
JPEG APP1 (2442 bytes):
0000: 45 78 69 66 00 00 49 49 2a 00 08 00 00 00 09 00 [Exif..II*.......]
0010: 0f 01 02 00 06 00 00 00 7a 00 00 00 10 01 02 00 [........z.......]
0020: 18 00 00 00 80 00 00 00 12 01 03 00 01 00 00 00 [................]
0030: 01 00 00 00 1a 01 05 00 01 00 00 00 98 00 00 00 [................]
0040: 1b 01 05 00 01 00 00 00 a0 00 00 00 28 01 03 00 [............(...]
0050: 01 00 00 00 02 00 00 00 32 01 02 00 14 00 00 00 [........2.......]
0060: a8 00 00 00 13 02 03 00 01 00 00 00 01 00 00 00 [................]
[snip 2330 bytes]
Rewriting IFD0
+ IFD0:Software = 'hi'
Rewriting ExifIFD
Rewriting MakerNoteCanon
Rewriting CanonCameraSettings
Rewriting CanonFocalLength
Rewriting CanonShotInfo
Rewriting CanonFileInfo
Rewriting CanonCameraInfoUnknown
Rewriting MeasuredColor
Rewriting ColorBalance
Rewriting InteropIFD
JPEG DQT (130 bytes):
JPEG SOF0:
JPEG DHT (73 bytes):
JPEG SOS
1 image files created
{ready}
### issuing the stop command ###
Can't reproduce this problem, and no response from the OP, so closing this issue.