aboutsummaryrefslogtreecommitdiff
path: root/dpi/file.c
diff options
context:
space:
mode:
authorJorge Arellano Cid <jcid@dillo.org>2009-11-01 16:31:59 -0300
committerJorge Arellano Cid <jcid@dillo.org>2009-11-01 16:31:59 -0300
commitdf2f261ccb261447576b98b9e466f06daf33115d (patch)
treefbb802b7b019c806bea8e6d9b4c7dc12f6ede53d /dpi/file.c
parent29ea3975335bad3fa72afe8c1724d1d00355c396 (diff)
Removed the write/fwrite mix in dpip. Introduced a_Dpip_dsh_trywrite()
Several cleanups and more error handling sprinkled all over too.
Diffstat (limited to 'dpi/file.c')
-rw-r--r--dpi/file.c68
1 files changed, 40 insertions, 28 deletions
diff --git a/dpi/file.c b/dpi/file.c
index 235a474d..c8c14b14 100644
--- a/dpi/file.c
+++ b/dpi/file.c
@@ -60,7 +60,7 @@
typedef enum {
- st_start,
+ st_start = 10,
st_dpip,
st_http,
st_content,
@@ -92,6 +92,8 @@ typedef struct {
int err_code;
int flags;
int old_style;
+
+ Dstr *dbuf;
} ClientInfo;
/*
@@ -115,7 +117,7 @@ fd_set read_set, write_set;
*/
static void File_close(int fd)
{
- while (close(fd) < 0 && errno == EINTR)
+ while (fd >= 0 && close(fd) < 0 && errno == EINTR)
;
}
@@ -547,7 +549,7 @@ static const char *File_content_type(const char *filename)
File_close(fd);
}
}
-
+ _MSG("File_content_type: name=%s ct=%s\n", filename, ct);
return ct;
}
@@ -697,7 +699,7 @@ static int File_send_file(ClientInfo *client)
const char *ct;
const char *unknown_type = "application/octet-stream";
char buf[LBUF], *d_cmd, *name;
- int st, namelen;
+ int st, st2, namelen;
bool_t gzipped = FALSE;
if (client->state == st_start) {
@@ -744,27 +746,30 @@ static int File_send_file(ClientInfo *client)
} else if (client->state == st_http) {
/* Send body -- raw file contents */
- do {
- if ((st = read(client->file_fd, buf, LBUF)) > 0) {
- if (a_Dpip_dsh_write(client->sh, 0, buf, (size_t)st) != 0)
- break;
- } else if (st < 0) {
- perror("[read]");
- if (errno == EINTR || errno == EAGAIN)
- continue;
+ if (client->dbuf->len > 0) {
+ /* send pending data */
+ st = a_Dpip_dsh_trywrite(client->sh,
+ client->dbuf->str, client->dbuf->len);
+ if (st > 0)
+ dStr_erase(client->dbuf, 0, st);
+ } else {
+ /* ok to send new data */
+ do {
+ st = read(client->file_fd, buf, LBUF);
+ } while (st < 0 && errno == EINTR);
+ if (st == -1) {
+ MSG("\nexit(1), ERROR while reading from file '%s': %s\n\n",
+ client->filename, dStrerror(errno));
+ exit(1);
+ } else if (st == 0) {
+ client->state = st_content;
+ client->flags |= FILE_DONE;
+ } else {
+ /* partial write */
+ st2 = a_Dpip_dsh_trywrite(client->sh, buf, st);
+ if (st2 > 0 && st2 < st)
+ dStr_append_l(client->dbuf, buf + st2, st - st2);
}
- } while (st > 0);
-
- /* TODO: It may be better to send an error report to dillo instead of
- * calling exit() */
- if (st == -1) {
- MSG("ERROR while reading from file \"%s\", error was \"%s\"\n",
- client->filename, dStrerror(errno));
- exit(1);
- } else if (st == 0) {
- client->state = st_content;
- File_close(client->file_fd);
- client->flags |= FILE_DONE;
}
}
@@ -859,6 +864,7 @@ static void File_toggle_html_style(ClientInfo *client)
*/
static void termination_handler(int signum)
{
+ MSG("\nexit(signum), signum=%d\n\n", signum);
exit(signum);
}
@@ -883,6 +889,8 @@ static ClientInfo *File_add_client(int sock_fd)
new_client->err_code = 0;
new_client->flags = FILE_READ;
new_client->old_style = OLD_STYLE;
+ new_client->dbuf = dStr_sized_new(8*1024);
+
dList_append(Clients, new_client);
return new_client;
}
@@ -897,8 +905,10 @@ static void File_remove_client(ClientInfo *client)
_MSG("Closing Socket Handler\n");
a_Dpip_dsh_close(client->sh);
a_Dpip_dsh_free(client->sh);
+ File_close(client->file_fd);
dFree(client->orig_url);
dFree(client->filename);
+ dStr_free(client->dbuf, TRUE);
File_dillodir_free(client->d_dir);
dFree(client);
@@ -914,7 +924,8 @@ static void File_serve_client(void *data, int f_write)
int st;
while (1) {
- MSG("File_serve_client %p, flags=%d\n", client, client->flags);
+ _MSG("File_serve_client %p, flags=%d state=%d\n",
+ client, client->flags, client->state);
if (client->flags & (FILE_DONE | FILE_ERR))
break;
if (client->flags & FILE_READ) {
@@ -1015,7 +1026,7 @@ static int File_check_fds(uint_t seconds)
if (client->flags & FILE_WRITE)
FD_SET (client->sh->fd_out, &write_set);
}
- MSG("Watching %d fds:", dList_length(Clients) + 1);
+ MSG("Watching %d fds\n", dList_length(Clients) + 1);
/* Initialize the timeout data structure. */
timeout.tv_sec = seconds;
@@ -1024,7 +1035,7 @@ static int File_check_fds(uint_t seconds)
do {
st = select(FD_SETSIZE, &read_set, &write_set, NULL, &timeout);
} while (st == -1 && errno == EINTR);
-
+/*
MSG_RAW(" (%d%s%s)", STDIN_FILENO,
FD_ISSET(STDIN_FILENO, &read_set) ? "R" : "",
FD_ISSET(STDIN_FILENO, &write_set) ? "W" : "");
@@ -1034,7 +1045,7 @@ static int File_check_fds(uint_t seconds)
FD_ISSET(client->sh->fd_out, &write_set) ? "W" : "");
}
MSG_RAW("\n");
-
+*/
return st;
}
@@ -1087,6 +1098,7 @@ int main(void)
break;
} else {
/* Create and initialize a new client */
+ MSG(" accept() fd=%d\n", tmp_fd);
File_add_client(tmp_fd);
}
continue;