# read: analogously to write, support reading from in-memory streams in # addition to file descriptors. # # We can pass it either a file descriptor or an address to a stream. If a # file descriptor is passed in, we _read from it using the right syscall. If a # stream is passed in (a fake file descriptor), we read from it instead. This # lets us initialize input for tests. # # A little counter-intuitively, the output of 'read' ends up in.. a stream. So # tests end up doing a redundant copy. Why? Well, consider the alternatives: # # a) Reading into a string, and returning a pointer to the end of the read # region, or a count of bytes written. Now this count or end pointer must be # managed separately by the caller, which can be error-prone. # # b) Having 'read' return a buffer that it allocates. But there's no way to # know in advance how large to make the buffer. If you read less than the # size of the buffer you again end up needing to manage initialized vs # uninitialized memory. # # c) Creating more helpful variants like 'read-byte' or 'read-until' which # also can take a file descriptor or stream, just like 'write'. But such # primitives don't exist in the Linux kernel, so we'd be implementing them # somehow, either with more internal buffering or by making multiple # syscalls. # # Reading into a stream avoids these problems. The buffer is externally # provided and the caller has control over where it's allocated, its lifetime, # and so on. The buffer's read and write pointers are internal to it so it's # easier to keep in a consistent state. And it can now be passed directly to # helpers like 'read-byte' or 'read-until' that only need to support streams, # never file descriptors. # # Like with 'write', we assume our data segment will never begin at an address # shorter than 0x08000000, so any smaller arguments are assumed to be real # file descriptors. # # As a reminder, a stream looks like this: # write: int # index at which to write to next # read: int # index at which to read next # data: (array byte) # prefixed by size as usual == code # instruction effective address register displacement immediate # . op subop mod rm32 base index scale r32 # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes read: # f: fd or (addr stream byte), s: (addr stream byte) -> num-bytes-read/eax: int # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # if (f < 0x08000000) return _read(f, s) # f can't be a user-mode address, so treat it as a kernel file descriptor 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 0x08000000/imm32 # compare *(ebp+8) 73/jump-if-addr>= $read:fake/disp8 # . . push args ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) # . . call e8/call _read/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # return eb/jump $read:end/disp8 $read:fake: # otherwise, treat 'f' as a stream to scan from # . save registers 56/push-esi 57/push-edi # esi = f 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi # edi = s 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to esi # eax = _buffer-4(out = &s->data[s->write], outend = &s->data[s->size], # in = &f->data[f->read], inend = &f->data[f->write]) # . . push &f->data[f->write] 8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy esi+eax+12 to eax 50/push-eax # . . push &f->data[f->read] 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 0/r32/eax 4/disp8 . # copy *(esi+4) to eax 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy esi+eax+12 to eax 50/push-eax # . . push &s->data[s->size] 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 0/r32/eax 8/disp8 . # copy *(edi+8) to eax 8d/copy-address 1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<title>andrewyu.org Mailing List Guidelines</title>
<link rel="stylesheet" href="/plain.css" />
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
<meta charset="utf-8" />
</head>
<body class="indent">
<h1><code>andrewyu.org</code> Mailing List Guidelines</h1>
<p>The following guidelines apply to most <a href="https://mail.andrewyu.org/mailman/listinfo">public mailing lists on <code>andrewyu.org</code></a>. Different lists may have different specific guidelines.</p>
<ul>
<li>
Be considerate of other subscribers on the mailing lists.
</li>
<li>
Plain text, preferrably 72 characters per line.
<br />
Many subscribers and maintainers read their mail on text-based mailers like mail(1), emacs, mutt, etc., and they often find HTML-formatted messages (or lines that stretch beyond 72 characters) unreadable. Many mailing lists strip messages of MIME content before sending them out to the rest of the list. If you don't use plain text, your messages will be reformatted. If they cannot be reformatted, they will be summarily rejected. Use attachments with care, they will be removed from messages on some lists.
</li>
<li>
Include a useful Subject line.
<br />
Messages with an empty Subject will get bounced to the list manager and will take longer to show up. Including a relevant Subject in the message will ensure that more people actually read what you've written. Also, avoid Subject lines with excessive uppercase and exclamations. "Help!" or "I can't get it to work!" are not useful subject lines. Do not change the subject line while on the same topic. You may know what it is regarding, the rest of us who get several hundred messages a day will have no idea.
</li>
<li>
Trim your signature.
<br />
Keep the signature lines at the bottom of your mail to a reasonable length. PGP signatures should be attachments rather than inline.
</li>
<li>
Stay on topic.
<br />
Please keep the subject of the post relevant to the topic of the mailing list.
</li>
<li>
Include important information for questions.
<br />
Don't waste everyone's time with a hopelessly incomplete question. No one other than you has the information needed to resolve your problem, it is better to provide more information than needed than not enough detail.
</li>
<li>
Respect differences in opinion and philosophy.
<br />
Intelligent people may look at the same set of facts and come to very different conclusions. Repeating the same points that didn't convince someone previously rarely changes their mind, and irritates all the other readers.
</li>
<li>
No spam.
</li>
<li>
Interweave quoted original messages with replies.
<br />
Post inline, and trim quotes. This means that your replies are interspersed with the original mail, and any irrelevant content is removed (trimmed):
<pre>From: A
Subject: Re: S
To: B
CC: list
B wrote:
> ...
> Do you think that this is correct?
Yes, I believe so.
> How about iterating through the items and applying the function to each of them?
Sounds good.</pre>
</li>
<li>
Reply to the list.
<br />
For most discussions that are not going wildly off-topic and still may be of interest to those in the list, CC the list so others can follow up. However, as it suggests, if things are going to be irrelevant to the list's topic, reply in private.
</li>
</ul>
<div id="footer">
<hr />
<p><a href="/">Andrew Yu's Website</a></p>
</div>
</body>
</html>