CopyInVector copies a NULL-terminated vector of strings from the task's memory. The copy will fail with syscall.EFAULT if it traverses user memory that is unmapped or not readable by the user. maxElemSize is the maximum size of each individual element. maxTotalSize is the maximum total length of a
(addr hostarch.Addr, maxElemSize, maxTotalSize int)
| 66 | // |
| 67 | // Preconditions: The caller must be running on the task goroutine. |
| 68 | func (t *Task) CopyInVector(addr hostarch.Addr, maxElemSize, maxTotalSize int) ([]string, error) { |
| 69 | var v []string |
| 70 | for { |
| 71 | argAddr := t.Arch().Native(0) |
| 72 | if _, err := argAddr.CopyIn(t, addr); err != nil { |
| 73 | return v, err |
| 74 | } |
| 75 | if t.Arch().Value(argAddr) == 0 { |
| 76 | break |
| 77 | } |
| 78 | // Each string has a zero terminating byte counted, so copying out a string |
| 79 | // requires at least one byte of space. Also, see the calculation below. |
| 80 | if maxTotalSize <= 0 { |
| 81 | return nil, linuxerr.ENOMEM |
| 82 | } |
| 83 | thisMax := maxElemSize |
| 84 | if maxTotalSize < thisMax { |
| 85 | thisMax = maxTotalSize |
| 86 | } |
| 87 | arg, err := t.CopyInString(hostarch.Addr(t.Arch().Value(argAddr)), thisMax) |
| 88 | if err != nil { |
| 89 | return v, err |
| 90 | } |
| 91 | v = append(v, arg) |
| 92 | addr += hostarch.Addr(t.Arch().Width()) |
| 93 | maxTotalSize -= len(arg) + 1 |
| 94 | } |
| 95 | return v, nil |
| 96 | } |
| 97 | |
| 98 | // CopyOutIovecs converts src to an array of struct iovecs and copies it to the |
| 99 | // memory mapped at addr for Task. |
no test coverage detected