specified FILEHANDLE, using the system call read(2). It bypasses
stdio, so mixing this with other kinds of reads may cause confusion.
Returns the number of bytes actually read, or undef if there was an
-error. SCALAR will be grown or shrunk to the length actually read. An
-OFFSET may be specified to place the read data at some other place than
-the beginning of the string.
+error. SCALAR will be grown or shrunk to the length actually read.
+An OFFSET may be specified to place the read data at some other
+place than the beginning of the string. A negative OFFSET counts
+backwards from the end of the string.
=item system LIST
Attempts to write LENGTH bytes of data from variable SCALAR to the
specified FILEHANDLE, using the system call write(2). It bypasses
stdio, so mixing this with prints may cause confusion. Returns the
-number of bytes actually written, or undef if there was an error. An
-OFFSET may be specified to get the write data from some other place than
-the beginning of the string.
+number of bytes actually written, or undef if there was an error.
+An OFFSET may be specified to get the write data from some other place
+than the beginning of the string. A negative OFFSET counts backwards
+from the end of the string.
=item tell FILEHANDLE
if (op->op_type == OP_RECV) {
bufsize = sizeof buf;
buffer = SvGROW(bufsv, length+1);
+ /* 'offset' means 'flags' here */
length = recvfrom(PerlIO_fileno(IoIFP(io)), buffer, length, offset,
(struct sockaddr *)buf, &bufsize);
if (length < 0)
if (op->op_type == OP_RECV)
DIE(no_sock_func, "recv");
#endif
+ if (offset < 0) {
+ if (-offset > blen)
+ DIE("Too negative offset");
+ offset += blen;
+ }
bufsize = SvCUR(bufsv);
buffer = SvGROW(bufsv, length+offset+1);
if (offset > bufsize) { /* Zero any newly allocated space */
}
}
else if (op->op_type == OP_SYSWRITE) {
- if (MARK < SP)
+ if (MARK < SP) {
offset = SvIVx(*++MARK);
- else
+ if (offset < 0) {
+ if (-offset > blen)
+ DIE("Too negative offset");
+ offset += blen;
+ }
+ } else
offset = 0;
if (length > blen - offset)
length = blen - offset;