]> git.ipfire.org Git - pakfire.git/commitdiff
jail: Implement sending data into standard input
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 19 Dec 2023 17:04:35 +0000 (17:04 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 19 Dec 2023 17:04:35 +0000 (17:04 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/jail.c
tests/libpakfire/jail.c

index a8c2bf48e3a0c097208efe28a3aee609d9de36e1..9aac4962b10a938206cd1e0ecfe895c0ebbbae7c 100644 (file)
@@ -725,45 +725,43 @@ static int pakfire_jail_handle_log(struct pakfire_jail* jail, struct pakfire_jai
        return 0;
 }
 
-#if 0
 static int pakfire_jail_stream_stdin(struct pakfire_jail* jail,
                struct pakfire_jail_exec* ctx, const int fd) {
+       const char eof = 0x04;
        int r;
 
-       // Nothing to do if there is no stdin callback set
-       if (!ctx->communicate.in) {
-               DEBUG(jail->pakfire, "Callback for standard input is not set\n");
-               return 0;
-       }
-
        // Skip if the writing pipe has already been closed
-       if (ctx->pipes.stdin[1] < 0)
+       if (fd < 0)
                return 0;
 
-       DEBUG(jail->pakfire, "Streaming standard input...\n");
+       CTX_DEBUG(jail->ctx, "Streaming standard input...\n");
 
        // Calling the callback
        r = ctx->communicate.in(jail->pakfire, ctx->communicate.data, fd);
 
-       DEBUG(jail->pakfire, "Standard input callback finished: %d\n", r);
+       switch (r) {
+               case EOF:
+                       // The callback signaled that it has written everything
+                       CTX_DEBUG(jail->ctx, "Closing standard input pipe\n");
 
-       // The callback signaled that it has written everything
-       if (r == EOF) {
-               DEBUG(jail->pakfire, "Closing standard input pipe\n");
+                       // Send EOF (Ctrl-D)
+                       r = write(fd, &eof, sizeof(eof));
+                       if (r < 0) {
+                               CTX_ERROR(jail->ctx, "Could not write EOF: %s\n", strerror(errno));
+                               return -errno;
+                       }
 
-               // Close the file-descriptor
-               close(fd);
+                       return 0;
 
-               // Reset the file-descriptor so it won't be closed again later
-               ctx->pipes.stdin[1] = -1;
+               case 0:
+                       CTX_DEBUG(jail->ctx, "Standard input callback finished\n");
+                       return 0;
 
-               // Report success
-               r = 0;
+               default:
+                       CTX_ERROR(jail->ctx, "Standard input callback failed: %s\n", strerror(-r));
+                       return r;
        }
-
-       return r;
 }
-#endif
 
 static int pakfire_jail_recv_fd(struct pakfire_jail* jail, int socket, int* fd) {
        const size_t payload_length = sizeof(fd);
@@ -1075,8 +1073,6 @@ static int pakfire_jail_forward_pty(struct pakfire_jail* jail, struct pakfire_ja
                                return r;
                        }
 
-                       printf("BUFFER %.*s\n", (int)ctx->pty.stdin.buffer.used, ctx->pty.stdin.buffer.data);
-
                        // We are done reading for now
                        ctx->pty.stdin.flags &= ~PAKFIRE_JAIL_PTY_READY_TO_READ;
 
@@ -1087,10 +1083,17 @@ static int pakfire_jail_forward_pty(struct pakfire_jail* jail, struct pakfire_ja
 
                // Write to the master
                if (ctx->pty.master.flags & PAKFIRE_JAIL_PTY_READY_TO_WRITE) {
-                       r = pakfire_jail_drain_buffer(jail, ctx->pty.master.fd, &ctx->pty.stdin.buffer);
-                       if (r) {
-                               CTX_ERROR(jail->ctx, "Failed writing to the PTY: %s\n", strerror(-r));
-                               return r;
+                       if (ctx->communicate.in) {
+                               r = pakfire_jail_stream_stdin(jail, ctx, ctx->pty.master.fd);
+                               if (r)
+                                       return r;
+
+                       } else {
+                               r = pakfire_jail_drain_buffer(jail, ctx->pty.master.fd, &ctx->pty.stdin.buffer);
+                               if (r) {
+                                       CTX_ERROR(jail->ctx, "Failed writing to the PTY: %s\n", strerror(-r));
+                                       return r;
+                               }
                        }
 
                        // We are done writing for now
index 2993448ca255e3877379592c1f18a811ef55ec9f..d49795a94680604107d074265390b3f2ca5d5095 100644 (file)
@@ -350,9 +350,14 @@ static int callback_stdin(struct pakfire* pakfire, void* data, int fd) {
        while (*lines > 0) {
                r = dprintf(fd, "LINE %d\n", *lines);
                if (r < 0) {
-                       LOG_ERROR("Could not write line (%u) to stdin: %m\n", *lines);
-
-                       return 1;
+                       switch (errno) {
+                               case EAGAIN:
+                                       return 0;
+
+                               default:
+                                       LOG_ERROR("Could not write line (%u) to stdin: %m\n", *lines);
+                                       return -errno;
+                       }
                }
 
                // Decrement the lines counter