From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Maxim Cournoyer Newsgroups: gmane.lisp.guile.user Subject: Lost input when using suspendable read-line Date: Mon, 23 Aug 2021 00:04:46 -0400 Message-ID: <87mtp8vmap.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="32181"; mail-complaints-to="usenet@ciao.gmane.io" To: guile-user@gnu.org Original-X-From: guile-user-bounces+guile-user=m.gmane-mx.org@gnu.org Mon Aug 23 06:05:05 2021 Return-path: Envelope-to: guile-user@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mI1Cr-0008Ea-DH for guile-user@m.gmane-mx.org; Mon, 23 Aug 2021 06:05:05 +0200 Original-Received: from localhost ([::1]:41792 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mI1Cp-00034M-RU for guile-user@m.gmane-mx.org; Mon, 23 Aug 2021 00:05:03 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:43012) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mI1Cd-00034E-J9 for guile-user@gnu.org; Mon, 23 Aug 2021 00:04:51 -0400 Original-Received: from mail-qt1-x82a.google.com ([2607:f8b0:4864:20::82a]:40913) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mI1Cb-0003Ve-Uy for guile-user@gnu.org; Mon, 23 Aug 2021 00:04:51 -0400 Original-Received: by mail-qt1-x82a.google.com with SMTP id c19so1934465qte.7 for ; Sun, 22 Aug 2021 21:04:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:mime-version; bh=SfldNYmFOpDqDqjXuSBuEEONz58mqtngzO7EyG/Meao=; b=lYb4e3ZlPGz6j9ZBGHXAuq5XJnqEPs3upwQdq6UDipViTfTP9pk8srEOzPNLwJk0B1 tXtavbYfZEnWPKIvW7vMpvS/GIpHUuM94aY/C+WwywkaLJJHQEmCnUcVcitd/48MNnt+ RWEFV6KKVk2OeY72lphQaksdGMG936MfMJ9aJwNiwQliGKTgKXGfGHMULqe4mf6oExeO yPUnd723qAxURKVObK5jO0oW/j1DzJuETlVSs2QYbIOeSDxCe2g3rPIzbVhcpJbMiLLQ DjWNpg6R6QpGsuUj+6rNWZQ/V8jZVJkfEQjugEODpwDOQlq2r4NSlLg9bHa28F6mQasw 0tFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version; bh=SfldNYmFOpDqDqjXuSBuEEONz58mqtngzO7EyG/Meao=; b=r6IX0PZr1qO325Hn8nM3D8ybXno5r8lAZLsYTj6bRjlO/1zwa5i4rA8jOMFPtWGNMK jGd/aEOSLTlJ/yoxiFweFmSiWt2cfxOx7rsPnFNJTQBxlgYgu/+Kn276zWsgBYMNIyBK rZNMxzwglIA4928Cd7N8alzJ6SL3rFbSNSaoIPpa6vGXw6+Ml4ZySjolcuGvXPnPAoRW W3pfzBebOoNHv8e120YWx9xW9GtiYlHs5uY84A8HxvF5Jbo6uxpmHx1wIA7WLjhiaaRA x78CNU75l9o5bBbFDcfX1XEH7ui6kmReHfZ1vcw/JcF32QSNlQ6AvGyrFB3oaGwQ/DvO MEXQ== X-Gm-Message-State: AOAM530A5zTPhNn4fY/BY/5WoJzJ//Ia7WrfK1ckMNN9p5MXrZb0BN8B Wln9q1sHJ0I9U0tVrUqiUod+0AOoswE= X-Google-Smtp-Source: ABdhPJxfBG7yNNYSHNgC/IuE0CjoeroL/aIqfQeUWDPc4KpNuVrbs+m7VN2RcedzLgNYRjtWFA7Y6w== X-Received: by 2002:ac8:5f52:: with SMTP id y18mr17064599qta.379.1629691488352; Sun, 22 Aug 2021 21:04:48 -0700 (PDT) Original-Received: from hurd (dsl-150-192.b2b2c.ca. [66.158.150.192]) by smtp.gmail.com with ESMTPSA id y15sm7797081qko.78.2021.08.22.21.04.47 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 22 Aug 2021 21:04:47 -0700 (PDT) Received-SPF: pass client-ip=2607:f8b0:4864:20::82a; envelope-from=maxim.cournoyer@gmail.com; helo=mail-qt1-x82a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane-mx.org@gnu.org Original-Sender: "guile-user" Xref: news.gmane.io gmane.lisp.guile.user:17688 Archived-At: Hello, I'm pretty new to this, so hopefully I'm doing something wrong, but when using a suspendable read-line with the following "minimal" program: --8<---------------cut here---------------start------------->8--- (use-modules (ice-9 match) (ice-9 rdelim) (ice-9 suspendable-ports)) (install-suspendable-ports!) (define (read-line* port cont) ;; Return, as a pair, the line and the terminated delimiter or end-of-file ;; object. When a line cannot be read, return the '(suspended ;; . partial-continuation) pair, where partial-continuation can be ;; evaluated in the future when the port is ready to be read. (call-with-prompt 'continue (lambda () (parameterize ((current-read-waiter (lambda (_) (abort-to-prompt 'continue)))) (if cont (cont) (read-line port 'split)))) (lambda (partial-continuation) (cons 'suspended partial-continuation)))) (define (main) ;; Create a pipe, and set its read side to non-blocking mode. (define child->parent-pipe (pipe)) (let ((flags (fcntl (car child->parent-pipe) F_GETFL))) (fcntl (car child->parent-pipe) F_SETFL (logior O_NONBLOCK flags))) ;; Empty buffers to avoid duplicated output. (flush-all-ports) (match (primitive-fork) (0 ;child ;; Connect the stdout and stderr outputs of the child process to the ;; pipe established in the parent. (close (car child->parent-pipe)) ;unused input pipe (dup2 (port->fdes (cdr child->parent-pipe)) 1) (dup2 1 2) (set-current-output-port (cdr child->parent-pipe)) (set-current-error-port (cdr child->parent-pipe)) (while #t (format #t "Line 1\n") (format #t "Line 2\nLine 3\n") (display "Done!\n") (force-output) (sleep 5))) (child-pid ;parent (close (cdr child->parent-pipe)) ;disconnect the write end of the pipe (define port (car child->parent-pipe)) (let loop ((cont #f)) (match (select (list (port->fdes port)) '() '()) (((fdes ..1) () ()) (let next-line ((line+delim (read-line* port cont))) (match line+delim (('suspended . partial-continuation) (loop partial-continuation)) ((line . _) (format #t "~a~%" line) (next-line (read-line* port cont))))))))))) (main) --8<---------------cut here---------------end--------------->8--- The output looks like this (non-deterministic it seems): --8<---------------cut here---------------start------------->8--- $ guile repro.scm Line 1 Line 2 Line 3 Done! Line 1 Line 2 Line 3 Done! Line 1 Line 1 Line 1 [...] --8<---------------cut here---------------end--------------->8--- And strace shows that more than a single line is buffered on each read-line, but that it only returns the first line of such buffered input: --8<---------------cut here---------------start------------->8--- read(8, 0x7fcd06bfc020, 4096) = -1 EAGAIN (Resource temporarily unavailable) rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0 select(9, [3 8], [], [], NULL) = 1 (in [8]) read(8, "Line 1\nLine 2\nLine 3\nDone!\n", 4096) = 27 write(1, "Line 1", 6Line 1) = 6 write(1, "\n", 1 ) = 1 read(8, 0x7fcd06bfc020, 4096) = -1 EAGAIN (Resource temporarily unavailable) rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0 select(9, [3 8], [], [], NULL) = 1 (in [8]) read(8, "Line 1\nLine 2\nLine 3\nDone!\n", 4096) = 27 write(1, "Line 1", 6Line 1) = 6 write(1, "\n", 1 ) = 1 [...] --8<---------------cut here---------------end--------------->8--- Bug? PEBCAK? I'm interested to know :-). Thanks, Maxim