Loading commands/text/head.cpp +50 −0 Changes for commands/text/head.cpp: 50 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -29,6 +29,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <iostream> #include <string> #include <vector> #include <algorithm> #include <cstring> #include <cerrno> #include <unistd.h> #include <fcntl.h> #include "shell.h" #include "textutil.h" Loading Loading @@ -95,6 +100,51 @@ namespace fresh { namespace cmd { bool first=true; for(auto &f: files){ std::string data; if(!allBut){ // first N lines/bytes: stream and stop early (so // "yes | head" ends), leaving a seekable input // positioned right after what was printed int fd=f=="-" ? 0 : open(f.c_str(),O_RDONLY); if(fd<0){ out.flush(); std::cerr << "head: cannot open '" << f << "' for reading: " << strerror(errno) << std::endl; status=1; continue; } if(showHeaders){ out << (first ? "" : "\n") << "==> " << (f=="-" ? "standard input" : f) << " <==\n"; } first=false; long long left=count; char buf[65536]; while(left>0){ ssize_t r=::read(fd,buf,sizeof buf); if(r<0){ if(errno==EINTR) continue; out.flush(); std::cerr << "head: error reading '" << f << "': " << strerror(errno) << std::endl; status=1; break; } if(r==0) break; size_t take=0; if(bytes){ take=(size_t)std::min<long long>(left,r); left-=(long long)take; }else{ while(take<(size_t)r && left>0){ const char *nl=(const char*)memchr(buf+take,'\n',(size_t)r-take); if(!nl){ take=(size_t)r; break; } take=(size_t)(nl-buf)+1; --left; } } out.write(buf,take); if(take<(size_t)r) lseek(fd,(off_t)take-(off_t)r,SEEK_CUR); } if(fd!=0) close(fd); continue; } if(!text::readInput(f,data)){ out.flush(); std::cerr << "head: cannot open '" << f << "' for reading: " << strerror(errno) << std::endl; Loading Loading
commands/text/head.cpp +50 −0 Changes for commands/text/head.cpp: 50 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -29,6 +29,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <iostream> #include <string> #include <vector> #include <algorithm> #include <cstring> #include <cerrno> #include <unistd.h> #include <fcntl.h> #include "shell.h" #include "textutil.h" Loading Loading @@ -95,6 +100,51 @@ namespace fresh { namespace cmd { bool first=true; for(auto &f: files){ std::string data; if(!allBut){ // first N lines/bytes: stream and stop early (so // "yes | head" ends), leaving a seekable input // positioned right after what was printed int fd=f=="-" ? 0 : open(f.c_str(),O_RDONLY); if(fd<0){ out.flush(); std::cerr << "head: cannot open '" << f << "' for reading: " << strerror(errno) << std::endl; status=1; continue; } if(showHeaders){ out << (first ? "" : "\n") << "==> " << (f=="-" ? "standard input" : f) << " <==\n"; } first=false; long long left=count; char buf[65536]; while(left>0){ ssize_t r=::read(fd,buf,sizeof buf); if(r<0){ if(errno==EINTR) continue; out.flush(); std::cerr << "head: error reading '" << f << "': " << strerror(errno) << std::endl; status=1; break; } if(r==0) break; size_t take=0; if(bytes){ take=(size_t)std::min<long long>(left,r); left-=(long long)take; }else{ while(take<(size_t)r && left>0){ const char *nl=(const char*)memchr(buf+take,'\n',(size_t)r-take); if(!nl){ take=(size_t)r; break; } take=(size_t)(nl-buf)+1; --left; } } out.write(buf,take); if(take<(size_t)r) lseek(fd,(off_t)take-(off_t)r,SEEK_CUR); } if(fd!=0) close(fd); continue; } if(!text::readInput(f,data)){ out.flush(); std::cerr << "head: cannot open '" << f << "' for reading: " << strerror(errno) << std::endl; Loading