]> git.ipfire.org Git - pakfire.git/commitdiff
pty: Replace any CRNL with NL when capturing the output
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 19 Oct 2024 12:32:28 +0000 (12:32 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 19 Oct 2024 12:33:16 +0000 (12:33 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/pty.c
tests/libpakfire/jail.c

index 11d03a3bcac279d7b0c938f2d1369f08bf974481..3307b6d40cb8b6a38d1f2b2c035be38400be09c4 100644 (file)
@@ -53,6 +53,7 @@ struct pakfire_pty_stdio {
                PAKFIRE_PTY_READY_TO_WRITE = (1 << 1),
                PAKFIRE_PTY_HANGUP         = (1 << 2),
                PAKFIRE_PTY_EOF            = (1 << 3),
+               PAKFIRE_PTY_MAP_CRNL       = (1 << 4),
        } io;
 
        // Event Source
@@ -359,6 +360,33 @@ static int pakfire_pty_buffer_has_data(struct pakfire_pty* pty, const struct pak
        return 0;
 }
 
+/*
+       Maps any CRNL in the buffer to just NL
+*/
+static void pakfire_pty_map_crnl(struct pakfire_pty_stdio* stdio) {
+       char* cr = NULL;
+
+       // Walk through the entire buffer...
+       for (char* p = stdio->buffer; p <= stdio->buffer + stdio->buffered; p++) {
+               switch (*p) {
+                       // Remember the position of the last CR
+                       case '\r':
+                               cr = p;
+                               continue;
+
+                       // Check if have have found a NL
+                       case '\n':
+                               // CR is only set if the previous character was CR
+                               if (cr)
+                                       memmove(cr, p, stdio->buffered-- - (cr - stdio->buffer));
+                               break;
+               }
+
+               // Reset
+               cr = NULL;
+       }
+}
+
 /*
        Reads as much data as possible into the buffer
 */
@@ -396,6 +424,10 @@ static int pakfire_pty_drain_buffer(struct pakfire_pty* pty, int fd, struct pakf
        ssize_t bytes_written = 0;
        char* eol = NULL;
 
+       // Map any CRNL to just NL
+       if (stdio->io & PAKFIRE_PTY_MAP_CRNL)
+               pakfire_pty_map_crnl(stdio);
+
        // Call the callback if possible
        if (stdio->callbacks.stdout_callback) {
                // Try finding the end of a line
@@ -863,6 +895,9 @@ static int pakfire_pty_setup_forwarding(struct pakfire_pty* pty) {
                        return -errno;
                }
 
+               // Map any CRNL to NL
+               pty->stdout.io |= PAKFIRE_PTY_MAP_CRNL;
+
                // Close the buffer in the end
                pty->stdout.close_fd = 1;
 
index 6b058ca5a51573358b91241bb3d1a13a8aa4c26f..e5b71fc0caa1858a29347f0489eefe11b8eca5d1 100644 (file)
@@ -143,7 +143,7 @@ static int test_exec(const struct test* t) {
        ASSERT_SUCCESS(pakfire_jail_exec(jail, cmd_hello_world, 0, &output));
 
        // We should have some output
-       ASSERT_STRING_EQUALS(output, "Hello World!\r\n");
+       ASSERT_STRING_EQUALS(output, "Hello World!\n");
 
        // Destroy it
        ASSERT_NULL(pakfire_jail_unref(jail));
@@ -205,7 +205,7 @@ static int test_nice(const struct test* t) {
 
        // Check if the nice level has been set
        ASSERT_SUCCESS(pakfire_jail_exec(jail, argv, 0, &output));
-       ASSERT_STRING_EQUALS(output, "5\r\n");
+       ASSERT_STRING_EQUALS(output, "5\n");
 
        // Success
        r = EXIT_SUCCESS;