*/
-#include "silcincludes.h"
+#include "silc.h"
#define SILC_IS_FD_STREAM(s) (s->ops == &silc_fd_stream_ops)
/* Create file descriptor stream */
-SilcStream silc_fd_stream_create(int fd, SilcSchedule schedule)
+SilcStream silc_fd_stream_create(int fd)
{
if (fd < 1)
return NULL;
- return silc_fd_stream_create2(fd, 0, schedule);
+ return silc_fd_stream_create2(fd, 0);
}
/* Create stream with two file descriptors */
-SilcStream silc_fd_stream_create2(int read_fd, int write_fd,
- SilcSchedule schedule)
+SilcStream silc_fd_stream_create2(int read_fd, int write_fd)
{
SilcFDStream stream;
- if (read_fd < 1 && write_fd < 1)
+ if (read_fd < 1)
return NULL;
stream = silc_calloc(1, sizeof(*stream));
SILC_LOG_DEBUG(("Creating new fd stream %p", stream));
stream->ops = &silc_fd_stream_ops;
- stream->schedule = schedule;
stream->fd1 = read_fd;
- stream->fd1 = write_fd;
-
- /* Schedule the file descriptors */
- if (write_fd > 0) {
- silc_schedule_task_add_fd(schedule, write_fd, silc_fd_stream_io, stream);
- silc_net_set_socket_nonblock(write_fd);
- }
- if (read_fd > 0) {
- silc_schedule_task_add_fd(schedule, read_fd, silc_fd_stream_io, stream);
- silc_schedule_set_listen_fd(schedule, read_fd, SILC_TASK_READ, FALSE);
- silc_net_set_socket_nonblock(read_fd);
- if (write_fd < 1)
- write_fd = read_fd;
- }
+ stream->fd2 = write_fd;
return stream;
}
+/* Create by opening file */
+
+SilcStream silc_fd_stream_file(const char *filename,
+ SilcBool reading, SilcBool writing)
+{
+ int fd, flags = 0;
+
+ if (!filename)
+ return NULL;
+
+ if (reading)
+ flags |= O_RDONLY;
+ if (writing)
+ flags |= O_CREAT | O_WRONLY;
+ if (reading && writing)
+ flags |= O_CREAT | O_RDWR;
+
+ fd = silc_file_open(filename, flags);
+ if (fd < 0)
+ return NULL;
+
+ return silc_fd_stream_create(fd);
+}
+
/* Return fds */
-SilcBool silc_fd_stream_get_info(SilcStream stream, int *read_fd, int *write_fd)
+SilcBool silc_fd_stream_get_info(SilcStream stream, int *read_fd,
+ int *write_fd)
{
SilcFDStream fd_stream = stream;
if (!SILC_IS_FD_STREAM(fd_stream))
return -2;
+ if (!fd_stream->notifier)
+ return -2;
SILC_LOG_DEBUG(("Reading data from fd %d", fd_stream->fd1));
if (!SILC_IS_FD_STREAM(fd_stream))
return -2;
+ if (!fd_stream->notifier)
+ return -2;
SILC_LOG_DEBUG(("Writing data to fd %d", fd_stream->fd2));
if (!SILC_IS_FD_STREAM(fd_stream))
return FALSE;
- if (fd_stream->fd1 > 0)
+ if (fd_stream->fd1 > 0) {
silc_file_close(fd_stream->fd1);
- if (fd_stream->fd2 > 0 && fd_stream->fd2 != fd_stream->fd1)
+ silc_schedule_unset_listen_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);
+ }
return TRUE;
}
return;
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)
{
fd_stream->notifier = callback;
fd_stream->notifier_context = context;
+ fd_stream->schedule = schedule;
+
+ /* Schedule the file descriptors */
+ if (schedule) {
+ if (fd_stream->fd2 > 0) {
+ silc_schedule_task_add_fd(schedule, fd_stream->fd2,
+ silc_fd_stream_io, stream);
+ silc_file_set_nonblock(fd_stream->fd2);
+ }
+ if (fd_stream->fd1 > 0) {
+ silc_schedule_task_add_fd(schedule, fd_stream->fd1,
+ 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);;
+ 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);
+ }
+}
+
+/* Return schedule */
+
+SilcSchedule silc_fd_stream_get_schedule(SilcStream stream)
+{
+ SilcFDStream fd_stream = stream;
+
+ if (!SILC_IS_FD_STREAM(fd_stream))
+ return NULL;
+
+ return fd_stream->schedule;
}
/* File descriptor stream operations */
silc_fd_stream_close,
silc_fd_stream_destroy,
silc_fd_stream_notifier,
+ silc_fd_stream_get_schedule
};