Skip to content

Allow lisp programs to read a process's stdout and stderr either separately or together.#32

Open
ethanxxxl wants to merge 16 commits intolem-project:masterfrom
ethanxxxl:master
Open

Allow lisp programs to read a process's stdout and stderr either separately or together.#32
ethanxxxl wants to merge 16 commits intolem-project:masterfrom
ethanxxxl:master

Conversation

@ethanxxxl
Copy link
Copy Markdown

I was trying to get a language server running in lem (clangd) but it was not starting. After some investigation I found that clangd was outputing error messages to stderr, which were being piped to stdout via the PTY in async-process.

I ended up having to rewrite all of async-process.c in order to add this ability in. Apparently PTYs only have in input stream and an output stream. My solution was to add a second PTY into the process just for stderr. This should work fine as long as programs don't try to set terminal settings on stderr, as these settings will not be mirrored to the PTY running stdout and stdin.

These changes still need some testing before they can be merged. I need to ensure that there are no memory leaks, either in the C code or in the CL interface. One of the changes I made was to use dynamically allocated buffers for read. This way a single call through the CFFI will read as much data as it can. We can revisit this decision if a thinner C API is desired. I am marking this PR as a draft for the time being.

also note, that I changed the load path for libasyncprocess.so to where it is saved to on my local machine for testing

@cxxxr
Copy link
Copy Markdown
Member

cxxxr commented Jan 14, 2026

That's great.
If it doesn't break the behavior of existing lem features, I'd like to merge it.

@ethanxxxl
Copy link
Copy Markdown
Author

currently chasing a bug with process_write, for large inputs (greater than ~11.7k bytes) the program will fail to transfer all the data, and then lock up, with a "Resource temporarily unavailable" error.

@ethanxxxl
Copy link
Copy Markdown
Author

after a bit of a hiatus, I have gotten back to this finally. I often found myself working on this during long flights. Having the C compilation dependency was giving me a headache when trying to get qlot/Lem to use/find the library. After some digging, I discovered I can just import all the C posix functions and constants I was using with CFFI. I decided to rewrite my (mostly) working C code in CL to remove this C dependency and simplify the build process a little bit.

I'm still working on the translation, I can currently open/close, and I am currently working on testing the process creation functions.

@ethanxxxl
Copy link
Copy Markdown
Author

I consider this a 95% solution, the only thing that doesn't work with this implementation is the PTY support. I think that being a PTY should be a toggle-able option. Most of the time, I think we want the scripting output of programs rather than their interactive output.

Sometimes we do want the interactive output though, like when we are putting a terminal in a buffer. Currently, this breaks that. It looks like there are tools such as script, unbuffer, and socat which would be able to handle this for us easily, but that would introduce an installation dependency. I'm not sure how well this would transfer over to windows either.

@ethanxxxl
Copy link
Copy Markdown
Author

@cxxxr I am going to mark this as ready for review. We can revert back to a draft if we want to incorporate a solution to provide a PTY facility before merging.

In that case, I would recommend breaking the API and making piped output be the default, with PTY facilities selectable upon creation with a keyword argument.

@ethanxxxl ethanxxxl marked this pull request as ready for review April 18, 2026 04:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants