prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  phd throws an exception when output pipe fails, as with e.g. `head`
  We should silence the BrokenPipeError exception when `pwn phd` output closes.
  
  ```
  $ phd < /dev/random | head -n 1
  00000000  43 18 3f 38  0e 45 9c 5d  d9 b8 ed 44  7c 64 ee e3  │C·?8│·E·]│···D│|d··│
  Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>
  BrokenPipeError: [Errno 32] Broken pipe
  ```
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `pwnlib/commandline/phd.py`
  Content:
  ```
  1 #!/usr/bin/env python2
  2 from __future__ import absolute_import
  3 from __future__ import division
  4 
  5 import argparse
  6 import os
  7 import sys
  8 import io
  9 
  10 import pwnlib.args
  11 pwnlib.args.free_form = False
  12 
  13 from pwn import *
  14 from pwnlib.commandline import common
  15 
  16 parser = common.parser_commands.add_parser(
  17     'phd',
  18     help = 'Pretty hex dump',
  19     description = 'Pretty hex dump'
  20 )
  21 
  22 parser.add_argument(
  23     'file',
  24     metavar='file',
  25     nargs='?',
  26     help='File to hexdump.  Reads from stdin if missing.',
  27     type=argparse.FileType('rb'),
  28     default=getattr(sys.stdin, 'buffer', sys.stdin)
  29 )
  30 
  31 parser.add_argument(
  32     "-w", "--width",
  33     help="Number of bytes per line.",
  34     default='16',
  35 )
  36 
  37 parser.add_argument(
  38     "-l", "--highlight",
  39     help="Byte to highlight.",
  40     nargs="*",
  41 )
  42 
  43 parser.add_argument(
  44     "-s", "--skip",
  45     help="Skip this many initial bytes.",
  46     default='0',
  47 )
  48 
  49 parser.add_argument(
  50     "-c", "--count",
  51     help="Only show this many bytes.",
  52     default='-1',
  53 )
  54 
  55 parser.add_argument(
  56     "-o", "--offset",
  57     help="Addresses in left hand column starts at this address.",
  58     default='0',
  59 )
  60 
  61 parser.add_argument(
  62     "--color",
  63     nargs='?',
  64     help="Colorize the output.  When 'auto' output is colorized exactly when stdout is a TTY.  Default is 'auto'.",
  65     choices = ('always', 'never', 'auto'),
  66     default='auto',
  67 )
  68 
  69 def asint(s):
  70     if   s.startswith('0x'):
  71         return int(s, 16)
  72     elif s.startswith('0'):
  73         return int(s, 8)
  74     else:
  75         return int(s, 10)
  76 
  77 def main(args):
  78     infile = args.file
  79     width  = asint(args.width)
  80     skip   = asint(args.skip)
  81     count  = asint(args.count)
  82     offset = asint(args.offset)
  83 
  84     # if `--color` has no argument it is `None`
  85     color = args.color or 'always'
  86     text.when = color
  87 
  88     if skip:
  89         try:
  90             infile.seek(skip, os.SEEK_CUR)
  91         except IOError:
  92             infile.read(skip)
  93 
  94     if count != -1:
  95         infile = io.BytesIO(infile.read(count))
  96 
  97     hl = []
  98     if args.highlight:
  99         for hs in args.highlight:
  100             for h in hs.split(','):
  101                 hl.append(asint(h))
  102 
  103     try:
  104         for line in hexdump_iter(infile, width, highlight = hl, begin = offset + skip):
  105             print(line)
  106     except (KeyboardInterrupt, IOError):
  107         pass
  108 
  109 if __name__ == '__main__':
  110     pwnlib.commandline.common.main(__file__)
  111
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/pwnlib/commandline/phd.py b/pwnlib/commandline/phd.py
  --- a/pwnlib/commandline/phd.py
  +++ b/pwnlib/commandline/phd.py
  @@ -4,6 +4,7 @@
   
   import argparse
   import os
  +import signal
   import sys
   import io
   
  @@ -100,6 +101,8 @@
               for h in hs.split(','):
                   hl.append(asint(h))
   
  +    signal.signal(signal.SIGPIPE, signal.SIG_DFL)
  +
       try:
           for line in hexdump_iter(infile, width, highlight = hl, begin = offset + skip):
               print(line)
  
verification_info: {"golden_diff": "diff --git a/pwnlib/commandline/phd.py b/pwnlib/commandline/phd.py\n--- a/pwnlib/commandline/phd.py\n+++ b/pwnlib/commandline/phd.py\n@@ -4,6 +4,7 @@\n \n import argparse\n import os\n+import signal\n import sys\n import io\n \n@@ -100,6 +101,8 @@\n             for h in hs.split(','):\n                 hl.append(asint(h))\n \n+    signal.signal(signal.SIGPIPE, signal.SIG_DFL)\n+\n     try:\n         for line in hexdump_iter(infile, width, highlight = hl, begin = offset + skip):\n             print(line)\n", "issue": "phd throws an exception when output pipe fails, as with e.g. `head`\nWe should silence the BrokenPipeError exception when `pwn phd` output closes.\r\n\r\n```\r\n$ phd < /dev/random | head -n 1\r\n00000000  43 18 3f 38  0e 45 9c 5d  d9 b8 ed 44  7c 64 ee e3  \u2502C\u00b7?8\u2502\u00b7E\u00b7]\u2502\u00b7\u00b7\u00b7D\u2502|d\u00b7\u00b7\u2502\r\nException ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>\r\nBrokenPipeError: [Errno 32] Broken pipe\r\n```\n", "before_files": [{"content": "#!/usr/bin/env python2\nfrom __future__ import absolute_import\nfrom __future__ import division\n\nimport argparse\nimport os\nimport sys\nimport io\n\nimport pwnlib.args\npwnlib.args.free_form = False\n\nfrom pwn import *\nfrom pwnlib.commandline import common\n\nparser = common.parser_commands.add_parser(\n    'phd',\n    help = 'Pretty hex dump',\n    description = 'Pretty hex dump'\n)\n\nparser.add_argument(\n    'file',\n    metavar='file',\n    nargs='?',\n    help='File to hexdump.  Reads from stdin if missing.',\n    type=argparse.FileType('rb'),\n    default=getattr(sys.stdin, 'buffer', sys.stdin)\n)\n\nparser.add_argument(\n    \"-w\", \"--width\",\n    help=\"Number of bytes per line.\",\n    default='16',\n)\n\nparser.add_argument(\n    \"-l\", \"--highlight\",\n    help=\"Byte to highlight.\",\n    nargs=\"*\",\n)\n\nparser.add_argument(\n    \"-s\", \"--skip\",\n    help=\"Skip this many initial bytes.\",\n    default='0',\n)\n\nparser.add_argument(\n    \"-c\", \"--count\",\n    help=\"Only show this many bytes.\",\n    default='-1',\n)\n\nparser.add_argument(\n    \"-o\", \"--offset\",\n    help=\"Addresses in left hand column starts at this address.\",\n    default='0',\n)\n\nparser.add_argument(\n    \"--color\",\n    nargs='?',\n    help=\"Colorize the output.  When 'auto' output is colorized exactly when stdout is a TTY.  Default is 'auto'.\",\n    choices = ('always', 'never', 'auto'),\n    default='auto',\n)\n\ndef asint(s):\n    if   s.startswith('0x'):\n        return int(s, 16)\n    elif s.startswith('0'):\n        return int(s, 8)\n    else:\n        return int(s, 10)\n\ndef main(args):\n    infile = args.file\n    width  = asint(args.width)\n    skip   = asint(args.skip)\n    count  = asint(args.count)\n    offset = asint(args.offset)\n\n    # if `--color` has no argument it is `None`\n    color = args.color or 'always'\n    text.when = color\n\n    if skip:\n        try:\n            infile.seek(skip, os.SEEK_CUR)\n        except IOError:\n            infile.read(skip)\n\n    if count != -1:\n        infile = io.BytesIO(infile.read(count))\n\n    hl = []\n    if args.highlight:\n        for hs in args.highlight:\n            for h in hs.split(','):\n                hl.append(asint(h))\n\n    try:\n        for line in hexdump_iter(infile, width, highlight = hl, begin = offset + skip):\n            print(line)\n    except (KeyboardInterrupt, IOError):\n        pass\n\nif __name__ == '__main__':\n    pwnlib.commandline.common.main(__file__)\n", "path": "pwnlib/commandline/phd.py"}], "after_files": [{"content": "#!/usr/bin/env python2\nfrom __future__ import absolute_import\nfrom __future__ import division\n\nimport argparse\nimport os\nimport signal\nimport sys\nimport io\n\nimport pwnlib.args\npwnlib.args.free_form = False\n\nfrom pwn import *\nfrom pwnlib.commandline import common\n\nparser = common.parser_commands.add_parser(\n    'phd',\n    help = 'Pretty hex dump',\n    description = 'Pretty hex dump'\n)\n\nparser.add_argument(\n    'file',\n    metavar='file',\n    nargs='?',\n    help='File to hexdump.  Reads from stdin if missing.',\n    type=argparse.FileType('rb'),\n    default=getattr(sys.stdin, 'buffer', sys.stdin)\n)\n\nparser.add_argument(\n    \"-w\", \"--width\",\n    help=\"Number of bytes per line.\",\n    default='16',\n)\n\nparser.add_argument(\n    \"-l\", \"--highlight\",\n    help=\"Byte to highlight.\",\n    nargs=\"*\",\n)\n\nparser.add_argument(\n    \"-s\", \"--skip\",\n    help=\"Skip this many initial bytes.\",\n    default='0',\n)\n\nparser.add_argument(\n    \"-c\", \"--count\",\n    help=\"Only show this many bytes.\",\n    default='-1',\n)\n\nparser.add_argument(\n    \"-o\", \"--offset\",\n    help=\"Addresses in left hand column starts at this address.\",\n    default='0',\n)\n\nparser.add_argument(\n    \"--color\",\n    nargs='?',\n    help=\"Colorize the output.  When 'auto' output is colorized exactly when stdout is a TTY.  Default is 'auto'.\",\n    choices = ('always', 'never', 'auto'),\n    default='auto',\n)\n\ndef asint(s):\n    if   s.startswith('0x'):\n        return int(s, 16)\n    elif s.startswith('0'):\n        return int(s, 8)\n    else:\n        return int(s, 10)\n\ndef main(args):\n    infile = args.file\n    width  = asint(args.width)\n    skip   = asint(args.skip)\n    count  = asint(args.count)\n    offset = asint(args.offset)\n\n    # if `--color` has no argument it is `None`\n    color = args.color or 'always'\n    text.when = color\n\n    if skip:\n        try:\n            infile.seek(skip, os.SEEK_CUR)\n        except IOError:\n            infile.read(skip)\n\n    if count != -1:\n        infile = io.BytesIO(infile.read(count))\n\n    hl = []\n    if args.highlight:\n        for hs in args.highlight:\n            for h in hs.split(','):\n                hl.append(asint(h))\n\n    signal.signal(signal.SIGPIPE, signal.SIG_DFL)\n\n    try:\n        for line in hexdump_iter(infile, width, highlight = hl, begin = offset + skip):\n            print(line)\n    except (KeyboardInterrupt, IOError):\n        pass\n\nif __name__ == '__main__':\n    pwnlib.commandline.common.main(__file__)\n", "path": "pwnlib/commandline/phd.py"}]}