X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilcfdstream.c;h=1ae8d413ca730fd7c67880522ea7604052edcd69;hb=929798ea2747657e5834da459d4abb9bb41d71b0;hp=cbd837aa9c07f4a7d5289cc8733b91bd431f1406;hpb=690216574e05c9dcc1e78d6677d4cc82c3d8baa8;p=silc.git diff --git a/lib/silcutil/silcfdstream.c b/lib/silcutil/silcfdstream.c index cbd837aa..1ae8d413 100644 --- a/lib/silcutil/silcfdstream.c +++ b/lib/silcutil/silcfdstream.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2005 - 2006 Pekka Riikonen + Copyright (C) 2005 - 2008 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,7 +21,7 @@ /************************** Types and definitions ***************************/ -#define SILC_IS_FD_STREAM(s) (s->ops == &silc_fd_stream_ops) +#define SILC_IS_FD_STREAM(s) (s && s->ops == &silc_fd_stream_ops) const SilcStreamOps silc_fd_stream_ops; @@ -80,9 +80,6 @@ SilcStream silc_fd_stream_create2(int read_fd, int write_fd) { SilcFDStream stream; - if (read_fd < 1) - return NULL; - stream = silc_calloc(1, sizeof(*stream)); if (!stream) return NULL; @@ -98,26 +95,54 @@ SilcStream silc_fd_stream_create2(int read_fd, int write_fd) /* Create by opening file */ -SilcStream silc_fd_stream_file(const char *filename, - SilcBool reading, SilcBool writing) +SilcStream silc_fd_stream_file(const char *filename, SilcBool reading, + SilcBool writing) { - int fd, flags = 0; + const char *read_file = NULL, *write_file = NULL; if (!filename) return NULL; - if (reading) - flags |= O_RDONLY; if (writing) - flags |= O_CREAT | O_WRONLY; - if (reading && writing) - flags = O_CREAT | O_RDWR; + write_file = filename; + if (reading) + read_file = filename; - fd = silc_file_open(filename, flags); - if (fd < 0) - return NULL; + return silc_fd_stream_file2(read_file, write_file); +} + +/* Create by opening two files */ - return silc_fd_stream_create(fd); +SilcStream silc_fd_stream_file2(const char *read_file, const char *write_file) +{ + SilcStream stream; + int fd1 = 0, fd2 = 0; + + SILC_LOG_DEBUG(("Creating new fd stream for reading `%s' and writing `%s'", + read_file ? read_file : "(none)", + write_file ? write_file : "(none)")); + + if (write_file) { + fd2 = silc_file_open(write_file, O_CREAT | O_WRONLY); + if (fd2 < 0) { + silc_file_close(fd1); + return NULL; + } + } + + if (read_file) { + fd1 = silc_file_open(read_file, O_RDONLY); + if (fd1 < 0) + return NULL; + } + + stream = silc_fd_stream_create2(fd1, fd2); + if (!stream) { + silc_file_close(fd1); + silc_file_close(fd2); + } + + return stream; } /* Return fds */ @@ -232,11 +257,17 @@ SilcBool silc_fd_stream_close(SilcStream stream) if (fd_stream->fd1 > 0) { silc_file_close(fd_stream->fd1); - silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd1); + if (fd_stream->schedule) { + silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd1); + silc_schedule_task_del_by_fd(fd_stream->schedule, fd_stream->fd1); + } } if (fd_stream->fd2 > 0 && fd_stream->fd2 != fd_stream->fd1) { silc_file_close(fd_stream->fd2); - silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd2); + if (fd_stream->schedule) { + silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd2); + silc_schedule_task_del_by_fd(fd_stream->schedule, fd_stream->fd2); + } } return TRUE; @@ -246,20 +277,16 @@ SilcBool silc_fd_stream_close(SilcStream stream) void silc_fd_stream_destroy(SilcStream stream) { - SilcFDStream fd_stream = stream; - silc_fd_stream_close(stream); - silc_schedule_task_del_by_fd(fd_stream->schedule, fd_stream->fd1); - silc_schedule_task_del_by_fd(fd_stream->schedule, fd_stream->fd2); silc_free(stream); } /* Sets stream notification callback for the stream */ -void silc_fd_stream_notifier(SilcStream stream, - SilcSchedule schedule, - SilcStreamNotifier callback, - void *context) +SilcBool silc_fd_stream_notifier(SilcStream stream, + SilcSchedule schedule, + SilcStreamNotifier callback, + void *context) { SilcFDStream fd_stream = stream; @@ -281,14 +308,20 @@ void silc_fd_stream_notifier(SilcStream stream, silc_fd_stream_io, stream); silc_schedule_set_listen_fd(schedule, fd_stream->fd1, SILC_TASK_READ, FALSE); - silc_file_set_nonblock(fd_stream->fd1);; + silc_file_set_nonblock(fd_stream->fd1); if (fd_stream->fd2 < 1) fd_stream->fd2 = fd_stream->fd1; } } else { - silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd1); - silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd2); + if (fd_stream->schedule) { + silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd1); + silc_schedule_unset_listen_fd(fd_stream->schedule, fd_stream->fd2); + silc_schedule_task_del_by_fd(fd_stream->schedule, fd_stream->fd1); + silc_schedule_task_del_by_fd(fd_stream->schedule, fd_stream->fd2); + } } + + return TRUE; } /* Return schedule */