From owner-freebsd-hackers@freebsd.org Thu Aug 22 16:24:29 2019 Return-Path: Delivered-To: freebsd-hackers@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 5ECD0CC1C9 for ; Thu, 22 Aug 2019 16:24:29 +0000 (UTC) (envelope-from farhan@farhan.codes) Received: from mail.farhan.codes (mail.farhan.codes [155.138.165.43]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 46DqcD3whFz4c86 for ; Thu, 22 Aug 2019 16:24:28 +0000 (UTC) (envelope-from farhan@farhan.codes) Received: from mail.farhan.codes (rainloop [172.16.0.4]) by mail.farhan.codes (Postfix) with ESMTPSA id 9399516427 for ; Thu, 22 Aug 2019 12:24:19 -0400 (EDT) MIME-Version: 1.0 Date: Thu, 22 Aug 2019 16:24:19 +0000 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Mailer: RainLoop/1.12.1 From: "Farhan Khan" Message-ID: <519c2fce85fe0db1cd189d2060f09a0f@farhan.codes> Subject: Trouble using and understanding funopen(3) To: freebsd-hackers@freebsd.org X-Rspamd-Queue-Id: 46DqcD3whFz4c86 X-Spamd-Bar: ------- X-Spamd-Result: default: False [-7.05 / 15.00]; ARC_NA(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; R_DKIM_ALLOW(-0.20)[farhan.codes:s=mail]; NEURAL_HAM_MEDIUM(-1.00)[-1.000,0]; FROM_HAS_DN(0.00)[]; R_SPF_ALLOW(-0.20)[+mx]; TO_MATCH_ENVRCPT_ALL(0.00)[]; MIME_GOOD(-0.10)[text/plain]; PREVIOUSLY_DELIVERED(0.00)[freebsd-hackers@freebsd.org]; TO_DN_NONE(0.00)[]; RCPT_COUNT_ONE(0.00)[1]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; DKIM_TRACE(0.00)[farhan.codes:+]; DMARC_POLICY_ALLOW(-0.50)[farhan.codes,reject]; NEURAL_HAM_SHORT(-0.99)[-0.991,0]; FROM_EQ_ENVFROM(0.00)[]; MIME_TRACE(0.00)[0:+]; IP_SCORE(-3.06)[ip: (-9.86), ipnet: 155.138.160.0/20(-4.93), asn: 20473(-0.44), country: US(-0.05)]; ASN(0.00)[asn:20473, ipnet:155.138.160.0/20, country:US]; MID_RHS_MATCH_FROM(0.00)[]; RCVD_TLS_ALL(0.00)[]; RCVD_COUNT_TWO(0.00)[2] X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 Aug 2019 16:24:29 -0000 Hi all,=0A=0AI am having trouble understanding how funopen(3)'s read func= tion works. Specifically, how do I have the readfn return with less than = the requested amount of bytes.=0A=0AMy understanding: I believe that funo= pen(3) allows you to assign the read, write and close methods to a FILE s= tream. When a program runs fread(3) on a FILE stream opened by funopen(3)= , the program will run the readfn handler in a loop until it returns eith= er returns the requested number of bytes, 0 or -1 (error).=0A=0AQuestion:= How do I structure the code so that readfn returns with less than the nu= mbe of requested bytes? For example, what if the calling fread() function= requests 100 bytes, but the readfn can only return 10 bytes? What mechan= ism do I need to implement so that the fread(3) returns "10" bytes rather= than the readfn handler running 10 times? This results in the fread()'s = return value as 100, even though only 10 bytes were *actually* read.=0A= =0AI have looked at a few examples from the src tree. Clearly they have t= o use buffering and append the bytes they read to the memory object they = were initially passed. Somehow they return with the number of bytes they = actually read, not necessarily the requested amount. But it is not clear = to me how they make this distinction and avoid having their respective re= adfn function re-rerun. Also, in the examples I did look up there does no= t appear to be any use of setvbuf().=0A=0ABelow is a very simple test cas= e to illustrate the issue.=0A=0A------=0A#include =0A#include =0A#include =0A=0Astatic int=0Assh_readfn(void *v, char= *buf, int len)=0A{=0A printf("Running readfn handler\n");=0A memcpy(buf,= "AAAAAAAAAA", 10);=0A return 10;=0A}=0A=0Astatic int=0Assh_writefn(void = *v, const char *buf, int len)=0A{=0A return 0;=0A}=0A=0Aint=0Amain()=0A{= =0A int x;=0A char buf[1000];=0A FILE *f;=0A=0A f =3D funopen(NULL, ssh_r= eadfn, ssh_writefn, NULL, NULL);=0A if (f =3D=3D NULL) {=0A printf("funo= pen failed, exiting.\n");=0A exit(0);=0A }=0A=0A x =3D fread(buf, 1, 100= , f);=0A printf("Bytes read: %d\n", x);=0A}=0A------=0A=0AThis displays 1= 0 "Running readfn handler" lines fllowed by "Bytes read: 100" even though= I am explicitly returning 10 in ssh_readfn. Please advise what the mecha= nism is only return with less than the requested number of bytes.=0A=0ATh= anks!=0A---=0AFarhan Khan=0APGP Fingerprint: 1312 89CE 663E 1EB2 179C 1C8= 3 C41D 2281 F8DA C0DE