Skip to content
/ src Public

Commit 3aba417

Browse files
author
downsj
committed
New mmap(2)-using send_data() from FreeBSD.
1 parent 35e9b97 commit 3aba417

File tree

1 file changed

+45
-8
lines changed

1 file changed

+45
-8
lines changed

libexec/ftpd/ftpd.c

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: ftpd.c,v 1.3 1996/07/27 07:26:39 joshd Exp $ */
1+
/* $OpenBSD: ftpd.c,v 1.4 1996/07/28 19:45:36 downsj Exp $ */
22
/* $NetBSD: ftpd.c,v 1.15 1995/06/03 22:46:47 mycroft Exp $ */
33

44
/*
@@ -56,6 +56,7 @@ static char rcsid[] = "$NetBSD: ftpd.c,v 1.15 1995/06/03 22:46:47 mycroft Exp $"
5656
#include <sys/ioctl.h>
5757
#include <sys/socket.h>
5858
#include <sys/wait.h>
59+
#include <sys/mman.h>
5960

6061
#include <netinet/in.h>
6162
#include <netinet/in_systm.h>
@@ -187,7 +188,7 @@ static FILE *getdatasock __P((char *));
187188
static char *gunique __P((char *));
188189
static void lostconn __P((int));
189190
static int receive_data __P((FILE *, FILE *));
190-
static void send_data __P((FILE *, FILE *, off_t));
191+
static void send_data __P((FILE *, FILE *, off_t, off_t, int));
191192
static struct passwd *
192193
sgetpwnam __P((char *));
193194
static char *sgetsave __P((char *));
@@ -750,7 +751,8 @@ retrieve(cmd, name)
750751
dout = dataconn(name, st.st_size, "w");
751752
if (dout == NULL)
752753
goto done;
753-
send_data(fin, dout, st.st_blksize);
754+
send_data(fin, dout, st.st_blksize, st.st_size,
755+
(restart_point == 0 && cmd == 0 && S_ISREG(st.st_mode)));
754756
(void) fclose(dout);
755757
data = -1;
756758
pdata = -1;
@@ -980,17 +982,20 @@ dataconn(name, size, mode)
980982

981983
/*
982984
* Tranfer the contents of "instr" to "outstr" peer using the appropriate
983-
* encapsulation of the data subject * to Mode, Structure, and Type.
985+
* encapsulation of the data subject to Mode, Structure, and Type.
984986
*
985987
* NB: Form isn't handled.
986988
*/
987989
static void
988-
send_data(instr, outstr, blksize)
990+
send_data(instr, outstr, blksize, filesize, isreg)
989991
FILE *instr, *outstr;
990992
off_t blksize;
993+
off_t filesize;
994+
int isreg;
991995
{
992996
int c, cnt, filefd, netfd;
993-
char *buf;
997+
char *buf, *bp;
998+
size_t len;
994999

9951000
transflag++;
9961001
if (setjmp(urgcatch)) {
@@ -1020,13 +1025,45 @@ send_data(instr, outstr, blksize)
10201025

10211026
case TYPE_I:
10221027
case TYPE_L:
1028+
/*
1029+
* isreg is only set if we are not doing restart and we
1030+
* are sending a regular file
1031+
*/
1032+
netfd = fileno(outstr);
1033+
filefd = fileno(instr);
1034+
1035+
if (isreg && filesize < (off_t)16 * 1024 * 1024) {
1036+
buf = mmap(0, filesize, PROT_READ, MAP_SHARED, filefd,
1037+
(off_t)0);
1038+
if (!buf) {
1039+
syslog(LOG_WARNING, "mmap(%lu): %m",
1040+
(unsigned long)filesize);
1041+
goto oldway;
1042+
}
1043+
bp = buf;
1044+
len = filesize;
1045+
do {
1046+
cnt = write(netfd, bp, len);
1047+
len -= cnt;
1048+
bp += cnt;
1049+
if (cnt > 0) byte_count += cnt;
1050+
} while(cnt > 0 && len > 0);
1051+
1052+
transflag = 0;
1053+
munmap(buf, (size_t)filesize);
1054+
if (cnt < 0)
1055+
goto data_err;
1056+
reply(226, "Transfer complete.");
1057+
return;
1058+
}
1059+
1060+
oldway:
10231061
if ((buf = malloc((u_int)blksize)) == NULL) {
10241062
transflag = 0;
10251063
perror_reply(451, "Local resource failure: malloc");
10261064
return;
10271065
}
1028-
netfd = fileno(outstr);
1029-
filefd = fileno(instr);
1066+
10301067
while ((cnt = read(filefd, buf, (u_int)blksize)) > 0 &&
10311068
write(netfd, buf, cnt) == cnt)
10321069
byte_count += cnt;

0 commit comments

Comments
 (0)