# # patch "ChangeLog" # from [bdf39a53f4a1e9026721dcf3c85146d53f0dde8a] # to [9593950beb4e191745e0eea67086df8e5de148e0] # # patch "automate.cc" # from [3a4841e00a7323a15db6d505853ee0bb9d9b73ff] # to [5416a4b51b9029e98cede29f658fb1120ee7bb65] # ======================================================================== --- ChangeLog bdf39a53f4a1e9026721dcf3c85146d53f0dde8a +++ ChangeLog 9593950beb4e191745e0eea67086df8e5de148e0 @@ -1,3 +1,10 @@ +2005-11-26 Grahame Bowland + + * automate.cc (automate_stdio) add wrapper function to read() + so that loops will not wind backwards possibly overrunning buffers + if an error occurs. Hopefully fixes some of the strange edge cases + seen using automate. (Closes #15062 in bug tracker) + 2005-11-26 Matthew Gregan * botan/mem_pool.cpp (Pooling_Allocator::allocate): Botan's ======================================================================== --- automate.cc 3a4841e00a7323a15db6d505853ee0bb9d9b73ff +++ automate.cc 5416a4b51b9029e98cede29f658fb1120ee7bb65 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -1175,6 +1176,22 @@ s.flush(); } +static ssize_t +automate_stdio_read(int d, void *buf, size_t nbytes) +{ + ssize_t rv; + + /* EINTR occurs if the process receives a signal while in read(); this is + recoverable by simply reading again. + */ + do { + rv = read(d, buf, nbytes); + } while (rv == -EINTR); + + E(rv >= 0, F("read from client failed: %s") % strerror(rv)); + return rv; +} + static void automate_stdio(std::vector args, std::string const & help_name, @@ -1194,9 +1211,9 @@ bool first=true; int toklen=0; bool firstchar=true; - for(n=read(0, &c, 1); c != 'l' && n; n=read(0, &c, 1)) + for(n=automate_stdio_read(0, &c, 1); c != 'l' && n; n=automate_stdio_read(0, &c, 1)) ; - for(n=read(0, &c, 1); c!='e' && n; n=read(0, &c, 1)) + for(n=automate_stdio_read(0, &c, 1); c!='e' && n; n=automate_stdio_read(0, &c, 1)) { if(c<='9' && c>='0') { @@ -1207,7 +1224,7 @@ char *tok=new char[toklen]; int count=0; while(count