å³å¸httpdãæ¸ãã¦ã¿ã
libtaskã®ä¾ã¨ãã¦ãhttpdãæ¸ãã¦ã¿ãã200è¡ãããã ãã©ãã³ã¢ã®é¨åã¯ãããªæããfdread/fdwriteã¯ãã³ããããã³ã°I/Oãªãã ãã©ãæ®éã®ã·ã³ã°ã«ã¹ã¬ããããã°ã©ã ã®ããã«selectã«ã¼ããæ¸ãå¿ è¦ããªããã©ããªã£ã¦ãããã¨ããã¨ãlibtaskå é¨ã§ã¹ã±ã¸ã¥ã¼ã©ãåå¨ãã¦ããã®ã ãã¿ã¹ã¯ãI/Oå¾ ã¡ãå¿ è¦ã«ãªãã¨ãã©ã¤ãã©ãªå ã§æ示çã«ã¹ã±ã¸ã¥ã¼ã©ã«å¶å¾¡ã移ãã次ã®ã¿ã¹ã¯ã«åãæ¿ããã
void httpdtask(void *arg) { int rfd, fd, n; int status; char *msg; struct stat stat; char fullpath[PATH_MAX], buf[4096]; rfd = (int)arg; status = parserequest(rfd, fullpath, &stat); switch (status) { case HTTP_OK: fd = open(fullpath, O_RDONLY); if (fd < 0) { perror("open"); goto end; } sendheader(rfd, status, strstatus(status), &stat); for (;;) { n = fdread(fd, buf, sizeof(buf)); if (n <= 0) break; n = fdwrite(rfd, buf, n); if (n < 0) break; } close(fd); break; default: msg = strstatus(status); sendheader(rfd, status, msg, 0); n = snprintf(buf, BUFSIZ, "<html><title>%d %s</title>" "<body><h1>%d %s</h1></body></html>", status, msg, status, msg); fdwrite(rfd, buf, n); break; } end: close(rfd); } void taskmain(int argc, char **argv) { int cfd, fd; int rport; char remote[16]; if (argc != 3) { fprintf(stderr, "usage: httpd documentroot port\n"); exit(1); } documentroot = argv[1]; port = atoi(argv[2]); fd = netannounce(TCP, 0, port); if (fd < 0) { fprintf(stderr, "cannot announce on tcp port %d: %s\n", port, strerror(errno)); exit(1); } fdnoblock(fd); for (;;) { cfd = netaccept(fd, remote, &rport); if (cfd < 0) break; fdnoblock(cfd); taskcreate(httpdtask, (void *)cfd, 32768); } }