1 | #undef G_DISABLE_ASSERT |
2 | #undef G_LOG_DOMAIN |
3 | |
4 | #include <sys/types.h> |
5 | #include <sys/stat.h> |
6 | #include <fcntl.h> |
7 | #include <glib.h> |
8 | #include <string.h> |
9 | #include <stdio.h> |
10 | #include <stdlib.h> |
11 | |
12 | #define BUFFER_SIZE 1024 |
13 | |
14 | static void |
15 | test_small_writes (void) |
16 | { |
17 | GIOChannel *io; |
18 | GIOStatus status = G_IO_STATUS_ERROR; |
19 | guint cnt; |
20 | gchar tmp; |
21 | GError *error = NULL; |
22 | |
23 | io = g_io_channel_new_file (filename: "iochannel-test-outfile" , mode: "w" , error: &error); |
24 | if (error) |
25 | { |
26 | g_warning ("Unable to open file %s: %s" , |
27 | "iochannel-test-outfile" , |
28 | error->message); |
29 | g_clear_error (err: &error); |
30 | |
31 | exit (status: 1); |
32 | } |
33 | |
34 | g_io_channel_set_encoding (channel: io, NULL, NULL); |
35 | g_io_channel_set_buffer_size (channel: io, size: 1022); |
36 | |
37 | cnt = 2 * g_io_channel_get_buffer_size (channel: io); |
38 | tmp = 0; |
39 | |
40 | while (cnt) |
41 | { |
42 | status = g_io_channel_write_chars (channel: io, buf: &tmp, count: 1, NULL, NULL); |
43 | if (status == G_IO_STATUS_ERROR) |
44 | break; |
45 | if (status == G_IO_STATUS_NORMAL) |
46 | cnt--; |
47 | } |
48 | |
49 | g_assert (status == G_IO_STATUS_NORMAL); |
50 | |
51 | g_io_channel_unref (channel: io); |
52 | } |
53 | |
54 | |
55 | gint main (gint argc, gchar * argv[]) |
56 | { |
57 | GIOChannel *gio_r, *gio_w ; |
58 | GError *gerr = NULL; |
59 | GString *buffer; |
60 | char *filename; |
61 | gint rlength = 0; |
62 | glong wlength = 0; |
63 | gsize length_out; |
64 | const gchar encoding[] = "EUC-JP" ; |
65 | GIOStatus status; |
66 | |
67 | g_test_init (argc: &argc, argv: &argv, NULL); |
68 | |
69 | filename = g_test_build_filename (file_type: G_TEST_DIST, first_path: "iochannel-test-infile" , NULL); |
70 | |
71 | setbuf (stdout, NULL); /* For debugging */ |
72 | |
73 | gio_r = g_io_channel_new_file (filename, mode: "r" , error: &gerr); |
74 | if (gerr) |
75 | { |
76 | g_warning ("Unable to open file %s: %s" , filename, gerr->message); |
77 | g_clear_error (err: &gerr); |
78 | return 1; |
79 | } |
80 | gio_w = g_io_channel_new_file (filename: "iochannel-test-outfile" , mode: "w" , error: &gerr); |
81 | if (gerr) |
82 | { |
83 | g_warning ("Unable to open file %s: %s" , "iochannel-test-outfile" , gerr->message); |
84 | g_clear_error (err: &gerr); |
85 | return 1; |
86 | } |
87 | |
88 | g_io_channel_set_encoding (channel: gio_r, encoding, error: &gerr); |
89 | if (gerr) |
90 | { |
91 | g_warning ("%s" , gerr->message); |
92 | /* Keep going if this is just a case of iconv not supporting EUC-JP, see bug 428048 */ |
93 | if (gerr->code != G_CONVERT_ERROR_NO_CONVERSION) |
94 | return 1; |
95 | g_clear_error (err: &gerr); |
96 | } |
97 | |
98 | g_io_channel_set_buffer_size (channel: gio_r, BUFFER_SIZE); |
99 | |
100 | status = g_io_channel_set_flags (channel: gio_r, flags: G_IO_FLAG_NONBLOCK, error: &gerr); |
101 | if (status == G_IO_STATUS_ERROR) |
102 | { |
103 | g_warning ("%s" , gerr->message); |
104 | g_clear_error (err: &gerr); |
105 | } |
106 | buffer = g_string_sized_new (BUFFER_SIZE); |
107 | |
108 | while (TRUE) |
109 | { |
110 | do |
111 | status = g_io_channel_read_line_string (channel: gio_r, buffer, NULL, error: &gerr); |
112 | while (status == G_IO_STATUS_AGAIN); |
113 | if (status != G_IO_STATUS_NORMAL) |
114 | break; |
115 | |
116 | rlength += buffer->len; |
117 | |
118 | do |
119 | status = g_io_channel_write_chars (channel: gio_w, buf: buffer->str, count: buffer->len, |
120 | bytes_written: &length_out, error: &gerr); |
121 | while (status == G_IO_STATUS_AGAIN); |
122 | if (status != G_IO_STATUS_NORMAL) |
123 | break; |
124 | |
125 | wlength += length_out; |
126 | |
127 | if (length_out < buffer->len) |
128 | g_warning ("Only wrote part of the line." ); |
129 | |
130 | #ifdef VERBOSE |
131 | g_print ("%s" , buffer->str); |
132 | #endif |
133 | g_string_truncate (string: buffer, len: 0); |
134 | } |
135 | |
136 | switch (status) |
137 | { |
138 | case G_IO_STATUS_EOF: |
139 | break; |
140 | case G_IO_STATUS_ERROR: |
141 | g_warning ("%s" , gerr->message); |
142 | g_clear_error (err: &gerr); |
143 | break; |
144 | default: |
145 | g_warning ("Abnormal exit from write loop." ); |
146 | break; |
147 | } |
148 | |
149 | do |
150 | status = g_io_channel_flush (channel: gio_w, error: &gerr); |
151 | while (status == G_IO_STATUS_AGAIN); |
152 | |
153 | if (status == G_IO_STATUS_ERROR) |
154 | { |
155 | g_warning ("%s" , gerr->message); |
156 | g_clear_error (err: &gerr); |
157 | } |
158 | |
159 | #ifdef VERBOSE |
160 | g_print ("read %d bytes, wrote %ld bytes\n" , rlength, wlength); |
161 | #endif |
162 | |
163 | g_io_channel_unref(channel: gio_r); |
164 | g_io_channel_unref(channel: gio_w); |
165 | |
166 | test_small_writes (); |
167 | |
168 | g_free (mem: filename); |
169 | g_string_free (string: buffer, TRUE); |
170 | |
171 | return 0; |
172 | } |
173 | |