Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
liblongpath-rsync
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
liblongpath
liblongpath-rsync
Commits
cbc63a09
Commit
cbc63a09
authored
Oct 24, 2009
by
Wayne Davison
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed a couple iconv loops to properly handle incomplete chars
that span two reads.
parent
a0a88e0e
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
77 additions
and
34 deletions
+77
-34
io.c
io.c
+77
-34
No files found.
io.c
View file @
cbc63a09
...
...
@@ -95,6 +95,7 @@ static int write_batch_monitor_out = -1;
static
int
ff_forward_fd
=
-
1
;
static
char
ff_lastchar
;
static
xbuf
ff_xb
=
EMPTY_XBUF
;
#ifdef ICONV_OPTION
static
xbuf
iconv_buf
=
EMPTY_XBUF
;
#endif
...
...
@@ -338,18 +339,15 @@ static void safe_write(int fd, const char *buf, size_t len)
* a chunk of data and put it into the output buffer. */
static
void
forward_filesfrom_data
(
void
)
{
char
buf
[
FILESFROM_BUFLEN
];
int
len
;
xbuf
x
;
INIT_CONST_XBUF
(
x
,
buf
);
len
=
read
(
ff_forward_fd
,
x
.
buf
,
x
.
size
);
len
=
read
(
ff_forward_fd
,
ff_xb
.
buf
+
ff_xb
.
len
,
ff_xb
.
size
-
ff_xb
.
len
);
if
(
len
<=
0
)
{
if
(
len
==
0
||
errno
!=
EINTR
)
{
/* Send end-of-file marker */
write_buf
(
iobuf
.
out_fd
,
"
\0\0
"
,
ff_lastchar
?
2
:
1
);
ff_forward_fd
=
-
1
;
write_buf
(
iobuf
.
out_fd
,
"
\0\0
"
,
ff_lastchar
?
2
:
1
);
free_xbuf
(
&
ff_xb
);
if
(
protocol_version
<
31
)
io_start_multiplex_out
(
iobuf
.
out_fd
);
}
...
...
@@ -359,47 +357,84 @@ static void forward_filesfrom_data(void)
if
(
DEBUG_GTE
(
IO
,
2
))
rprintf
(
FINFO
,
"[%s] files-from read=%ld
\n
"
,
who_am_i
(),
(
long
)
len
);
#ifdef ICONV_OPTION
len
+=
ff_xb
.
len
;
#endif
if
(
!
eol_nulls
)
{
char
*
s
=
x
.
buf
+
len
;
char
*
s
=
ff_xb
.
buf
+
len
;
/* Transform CR and/or LF into '\0' */
while
(
s
--
>
x
.
buf
)
{
while
(
s
--
>
ff_xb
.
buf
)
{
if
(
*
s
==
'\n'
||
*
s
==
'\r'
)
*
s
=
'\0'
;
}
}
if
(
ff_lastchar
)
x
.
pos
=
0
;
ff_xb
.
pos
=
0
;
else
{
char
*
s
=
x
.
buf
;
char
*
s
=
ff_xb
.
buf
;
/* Last buf ended with a '\0', so don't let this buf start with one. */
while
(
len
&&
*
s
==
'\0'
)
s
++
,
len
--
;
x
.
pos
=
s
-
x
.
buf
;
ff_xb
.
pos
=
s
-
ff_xb
.
buf
;
}
#ifdef ICONV_OPTION
if
(
filesfrom_convert
&&
len
)
{
char
*
sob
=
ff_xb
.
buf
+
ff_xb
.
pos
,
*
s
=
sob
;
char
*
eob
=
sob
+
len
;
int
flags
=
ICB_INCLUDE_BAD
|
ICB_INCLUDE_INCOMPLETE
|
ICB_CIRCULAR_OUT
;
if
(
ff_lastchar
==
'\0'
)
flags
|=
ICB_INIT
;
/* Convert/send each null-terminated string separately, skipping empties. */
while
(
s
!=
eob
)
{
if
(
*
s
++
==
'\0'
)
{
ff_xb
.
len
=
s
-
sob
-
1
;
if
(
iconvbufs
(
ic_send
,
&
ff_xb
,
&
iobuf
.
out
,
flags
)
<
0
)
exit_cleanup
(
RERR_PROTOCOL
);
/* impossible? */
write_buf
(
iobuf
.
out_fd
,
s
-
1
,
1
);
/* Send the '\0'. */
while
(
s
!=
eob
&&
*
s
==
'\0'
)
s
++
;
sob
=
s
;
ff_xb
.
pos
=
sob
-
ff_xb
.
buf
;
flags
|=
ICB_INIT
;
}
}
if
((
ff_xb
.
len
=
s
-
sob
)
==
0
)
ff_lastchar
=
'\0'
;
else
{
/* Handle a partial string specially, saving any incomplete chars. */
flags
&=
~
ICB_INCLUDE_INCOMPLETE
;
if
(
iconvbufs
(
ic_send
,
&
ff_xb
,
&
iobuf
.
out
,
flags
)
<
0
)
{
if
(
errno
==
E2BIG
)
exit_cleanup
(
RERR_PROTOCOL
);
/* impossible? */
if
(
ff_xb
.
pos
)
memmove
(
ff_xb
.
buf
,
ff_xb
.
buf
+
ff_xb
.
pos
,
ff_xb
.
len
);
}
ff_lastchar
=
'x'
;
/* Anything non-zero. */
}
}
else
#endif
if
(
len
)
{
char
*
f
=
x
.
buf
+
x
.
pos
;
char
*
t
=
x
.
buf
;
char
*
f
=
ff_xb
.
buf
+
ff_xb
.
pos
;
char
*
t
=
ff_xb
.
buf
;
char
*
eob
=
f
+
len
;
/* Eliminate any multi-'\0' runs. */
while
(
f
!=
eob
)
{
if
(
!
(
*
t
++
=
*
f
++
))
{
while
(
f
!=
eob
&&
!*
f
)
f
++
,
len
--
;
while
(
f
!=
eob
&&
*
f
==
'\0'
)
f
++
;
}
}
ff_lastchar
=
f
[
-
1
];
}
#ifdef ICONV_OPTION
if
(
filesfrom_convert
)
{
/* TODO would it help to translate each string between nulls separately? */
x
.
len
=
len
;
iconvbufs
(
ic_send
,
&
x
,
&
iobuf
.
out
,
ICB_INCLUDE_BAD
|
ICB_INCLUDE_INCOMPLETE
|
ICB_CIRCULAR_OUT
|
ICB_INIT
);
}
else
#endif
if
(
len
)
{
/* This will not circle back to perform_io() because we only get
* called when there is plenty of room in the output buffer. */
write_buf
(
iobuf
.
out_fd
,
x
.
buf
,
len
);
if
((
len
=
t
-
ff_xb
.
buf
)
!=
0
)
{
/* This will not circle back to perform_io() because we only get
* called when there is plenty of room in the output buffer. */
write_buf
(
iobuf
.
out_fd
,
ff_xb
.
buf
,
len
);
}
}
}
...
...
@@ -993,6 +1028,8 @@ void start_filesfrom_forwarding(int fd)
io_end_multiplex_out
(
False
);
iobuf
.
out_fd
=
save_fd
;
}
alloc_xbuf
(
&
ff_xb
,
FILESFROM_BUFLEN
);
}
/* Read a line into the "buf" buffer. */
...
...
@@ -1289,20 +1326,26 @@ static void read_a_msg(void)
xbuf
outbuf
,
inbuf
;
char
ibuf
[
512
];
int
add_null
=
0
;
int
flags
=
ICB_INCLUDE_BAD
|
ICB_INIT
;
INIT_CONST_XBUF
(
outbuf
,
line
);
INIT_XBUF
(
inbuf
,
ibuf
,
0
,
(
size_t
)
-
1
);
while
(
msg_bytes
)
{
size_t
len
=
msg_bytes
>
sizeof
ibuf
-
inbuf
.
len
?
sizeof
ibuf
-
inbuf
.
len
:
msg_bytes
;
memcpy
(
ibuf
+
inbuf
.
len
,
perform_io
(
len
,
PIO_INPUT_AND_CONSUME
),
len
);
inbuf
.
pos
=
0
;
inbuf
.
len
=
msg_bytes
>
sizeof
ibuf
?
sizeof
ibuf
:
msg_bytes
;
memcpy
(
inbuf
.
buf
,
perform_io
(
inbuf
.
len
,
PIO_INPUT_AND_CONSUME
),
inbuf
.
len
);
if
(
!
(
msg_bytes
-=
inbuf
.
len
)
&&
!
ibuf
[
inbuf
.
len
-
1
])
inbuf
.
len
+=
len
;
if
(
!
(
msg_bytes
-=
len
)
&&
!
ibuf
[
inbuf
.
len
-
1
])
inbuf
.
len
--
,
add_null
=
1
;
if
(
iconvbufs
(
ic_send
,
&
inbuf
,
&
outbuf
,
ICB_INCLUDE_BAD
|
ICB_INCLUDE_INCOMPLETE
|
ICB_INIT
)
<
0
)
goto
overflow
;
if
(
iconvbufs
(
ic_send
,
&
inbuf
,
&
outbuf
,
flags
)
<
0
)
{
if
(
errno
==
E2BIG
)
goto
overflow
;
/* Buffer ended with an incomplete char, so move the
* bytes to the start of the buffer and continue. */
memmove
(
ibuf
,
ibuf
+
inbuf
.
pos
,
inbuf
.
len
);
}
flags
&=
~
ICB_INIT
;
}
if
(
add_null
)
{
if
(
outbuf
.
len
==
outbuf
.
size
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment