prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Unlink simprocedure missing errno behavior
  <!--
  *Disclaimer:
  The angr suite is maintained by a small team of volunteers.
  While we cannot guarantee any timeliness for fixes and enhancements, we will do our best.
  For more real-time help with angr, from us and the community, join our [Slack.](http://angr.io/invite/)*
  -->
  
  ---
  
  **Is your feature request related to a problem? Please describe.**
  The unlink() function/syscall can set a diverse range of errno values. The simprocedure version of unlink doesn't model any of them, which causes incorrect execution of programs that use this interface.
  
  The problem I'm specifically having is distinguishing failure because an existing file can't be removed, and failure because there is no file to remove.
  
  **Describe the solution you would like.**
  Add relevant errno assignments to the simprocedure.  I'm not sure if the simfs function gives enough data to decide which error to return on failure, so its return might need to be augmented, as well.
  
  **Please include a sample of what *should* work if this feature is implemented.**
  Currently, the marked branch in the following C code is unreachable:
  
  ```
  int my_remove() {
     if(remove("/foo/bar")) {
        if(ERRNO == ENOENT) {
           //UNREACHABLE D:
           return 0
        }
        return 1
     }
     return 0
  }
  ```
  
  **Describe alternatives you have considered.**
  Forcing the simfs remove() operation to succeed would make my problem go away, but it doesn't solve the general issue that code reading the errno values after a failure won't work properly.
  
  **Additional context.**
  <!--
  Add any other context or screenshots about the feature request here.
  -->
  
  
  </issue>
  <code>
  [start of angr/procedures/linux_kernel/unlink.py]
  1 import angr
  2 
  3 ######################################
  4 # unlink
  5 ######################################
  6 
  7 class unlink(angr.SimProcedure): #pylint:disable=W0622
  8     #pylint:disable=arguments-differ
  9 
  10     def run(self, path_addr):
  11         # This is a dummy for now
  12         strlen = angr.SIM_PROCEDURES['libc']['strlen']
  13 
  14         p_strlen = self.inline_call(strlen, path_addr)
  15         str_expr = self.state.memory.load(path_addr, p_strlen.max_null_index, endness='Iend_BE')
  16         str_val = self.state.solver.eval(str_expr, cast_to=bytes)
  17 
  18         if self.state.fs.delete(str_val):
  19             return 0
  20         else:
  21             return -1
  22
  [end of angr/procedures/linux_kernel/unlink.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/angr/procedures/linux_kernel/unlink.py b/angr/procedures/linux_kernel/unlink.py
  --- a/angr/procedures/linux_kernel/unlink.py
  +++ b/angr/procedures/linux_kernel/unlink.py
  @@ -15,6 +15,10 @@
           str_expr = self.state.memory.load(path_addr, p_strlen.max_null_index, endness='Iend_BE')
           str_val = self.state.solver.eval(str_expr, cast_to=bytes)
   
  +        # Check if entity exists before attempting to unlink
  +        if not self.state.fs.get(str_val):
  +            return self.state.libc.ret_errno('ENOENT')
  +
           if self.state.fs.delete(str_val):
               return 0
           else:
  
verification_info: {"golden_diff": "diff --git a/angr/procedures/linux_kernel/unlink.py b/angr/procedures/linux_kernel/unlink.py\n--- a/angr/procedures/linux_kernel/unlink.py\n+++ b/angr/procedures/linux_kernel/unlink.py\n@@ -15,6 +15,10 @@\n         str_expr = self.state.memory.load(path_addr, p_strlen.max_null_index, endness='Iend_BE')\n         str_val = self.state.solver.eval(str_expr, cast_to=bytes)\n \n+        # Check if entity exists before attempting to unlink\n+        if not self.state.fs.get(str_val):\n+            return self.state.libc.ret_errno('ENOENT')\n+\n         if self.state.fs.delete(str_val):\n             return 0\n         else:\n", "issue": "Unlink simprocedure missing errno behavior\n<!--\r\n*Disclaimer:\r\nThe angr suite is maintained by a small team of volunteers.\r\nWhile we cannot guarantee any timeliness for fixes and enhancements, we will do our best.\r\nFor more real-time help with angr, from us and the community, join our [Slack.](http://angr.io/invite/)*\r\n-->\r\n\r\n---\r\n\r\n**Is your feature request related to a problem? Please describe.**\r\nThe unlink() function/syscall can set a diverse range of errno values. The simprocedure version of unlink doesn't model any of them, which causes incorrect execution of programs that use this interface.\r\n\r\nThe problem I'm specifically having is distinguishing failure because an existing file can't be removed, and failure because there is no file to remove.\r\n\r\n**Describe the solution you would like.**\r\nAdd relevant errno assignments to the simprocedure.  I'm not sure if the simfs function gives enough data to decide which error to return on failure, so its return might need to be augmented, as well.\r\n\r\n**Please include a sample of what *should* work if this feature is implemented.**\r\nCurrently, the marked branch in the following C code is unreachable:\r\n\r\n```\r\nint my_remove() {\r\n   if(remove(\"/foo/bar\")) {\r\n      if(ERRNO == ENOENT) {\r\n         //UNREACHABLE D:\r\n         return 0\r\n      }\r\n      return 1\r\n   }\r\n   return 0\r\n}\r\n```\r\n\r\n**Describe alternatives you have considered.**\r\nForcing the simfs remove() operation to succeed would make my problem go away, but it doesn't solve the general issue that code reading the errno values after a failure won't work properly.\r\n\r\n**Additional context.**\r\n<!--\r\nAdd any other context or screenshots about the feature request here.\r\n-->\r\n\n", "before_files": [{"content": "import angr\n\n######################################\n# unlink\n######################################\n\nclass unlink(angr.SimProcedure): #pylint:disable=W0622\n    #pylint:disable=arguments-differ\n\n    def run(self, path_addr):\n        # This is a dummy for now\n        strlen = angr.SIM_PROCEDURES['libc']['strlen']\n\n        p_strlen = self.inline_call(strlen, path_addr)\n        str_expr = self.state.memory.load(path_addr, p_strlen.max_null_index, endness='Iend_BE')\n        str_val = self.state.solver.eval(str_expr, cast_to=bytes)\n\n        if self.state.fs.delete(str_val):\n            return 0\n        else:\n            return -1\n", "path": "angr/procedures/linux_kernel/unlink.py"}]}