From c9604b47adf545c431be866d833bb7167a3b6f1e Mon Sep 17 00:00:00 2001 From: Alistair Thomas Date: Mon, 25 Jun 2018 10:06:10 +0100 Subject: [PATCH] posix: Add CommandPipe as a sub-type of FILE A FILE opened with popen() should be closed with pclose() This is enabled by adding CommandPipe as a sub-class of FILE Fixes https://gitlab.gnome.org/GNOME/vala/issues/645 --- tests/Makefile.am | 1 + tests/posix/file-commandpipe.vala | 10 +++++++ vapi/posix.vapi | 45 ++++++++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 tests/posix/file-commandpipe.vala diff --git a/tests/Makefile.am b/tests/Makefile.am index 4ac9b94dc..39745e8c8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -644,6 +644,7 @@ NON_NULL_TESTS = \ LINUX_TESTS = \ linux/bug793444.vala \ + posix/file-commandpipe.vala \ $(NULL) check-TESTS: $(TESTS) $(NON_NULL_TESTS) diff --git a/tests/posix/file-commandpipe.vala b/tests/posix/file-commandpipe.vala new file mode 100644 index 000000000..90ef10c0a --- /dev/null +++ b/tests/posix/file-commandpipe.vala @@ -0,0 +1,10 @@ +void main () { + { + var pipe = Posix.FILE.popen ("sleep 0", "r"); + var result = pipe.close (); + assert (result == 0); + } + { + new Posix.CommandPipe ("ls *"); + } +} diff --git a/vapi/posix.vapi b/vapi/posix.vapi index 93eb80b70..118e96d87 100644 --- a/vapi/posix.vapi +++ b/vapi/posix.vapi @@ -3074,8 +3074,11 @@ namespace Posix { [CCode (cname = "fdopen")] public static FILE? fdopen (int fildes, string mode); [CCode (cname = "popen")] - public static FILE? popen (string command, string mode); + public static CommandPipe? popen (string command, string mode); + [CCode (cname = "fclose")] + [DestroysInstance] + public int close (); [CCode (cname = "fprintf")] [PrintfFormat ()] public int printf (string format, ...); @@ -3115,6 +3118,46 @@ namespace Posix { public static FILE stdout; public static FILE stdin; + /** + * A pipe to the given command run in a child process + * + * This is a binding to popen () and pclose (). popen () is the equivalent + * of pipe (), fork (), dup2 () and then exec () in a single operation + */ + [Compact] + [CCode (cname = "FILE", free_function = "pclose", cheader_filename = "stdio.h")] + [Version (since = "vala-0.44")] + public class CommandPipe : FILE { + /** + * A pipe to the given command run in a child process + * + * @param command The command to run + * @param mode Either 'r' or 'w'. 'r' creates a pipe to the command's + * STDOUT, the command's STDIN is the same as the parent process. + * 'w' creates a pipe to the command's STDIN, the command's STDOUT is + * the same as the parent process + */ + [CCode (cname = "popen")] + public CommandPipe (string command, string mode = "r"); + /** + * Explicitly close the pipe + * + * Explicitly closing the pipe is only necessary when checking the + * termination status of the command language interpreter. Normally + * Vala will generate code to automatically close the pipe when the + * CommandPipe instance goes out of scope + * + * CommandPipe.close () is synchronous and will return when the child + * process has terminated + * + * @return The termination status of the command language interpreter + * or -1 if status could not be obtained. errno will be set if -1 + */ + [CCode (cname = "pclose")] + [DestroysInstance] + public int close (); + } + [CCode (cheader_filename = "stdio.h")] public void perror (string s); -- 2.47.2