The 2024 Wheel Reinvention Jam just concluded. See the results.

furry-succotash - Jam Submission

My Jam project was to make a utility that I can see myself using for a long time.

I decided to recreate a simple utility program I made in Go before that re-runs specified command whenever any content in target directory changes, since I couldn't (or didn't try to) find a tool that does the same thing just like I wanted to.

after starting to work on my project I quickly realized that this isn't going well as I thought it would be. after struggling to transfer what I've wrote before into a C code for a week, this was the end result.

20211010_122252.mp4

through this jam project now I realized that I don't really know how to organize the code, and identify/decide what feature is crucial and should be implemented first.

I initially went to make it multi-threading but I totally forgot that multi-threading came in late when I wrote Go version before.

I didn't know that you cannot capture stdout concurrently without a workaround, since apparently a process created by CreateProcess with redirecting stdout to Pipe uses block buffering instead of line buffering (may be misunderstanding a bit).

I made several other mistake that can be boiled down into a lack of pre-planning or organizing. this experience made me realize that how un-organized I am while writing the code, and taught me what to pay attention for next time.

https://github.com/komugi1211s/furry-succotash

(project name was randomly generated)

I didn't know that you cannot capture stdout concurrently

You do that by using overlapped reads - call ReadFile with OVERLAPPED structure in argument and it will do read in background. Then either periodically check completion result, or simply wait on it to finish it. Then you can process data and issue next read

since apparently a process created by CreateProcess with redirecting stdout to Pipe uses block buffering instead of line buffering (may be misunderstanding a bit).

This is not problem with process creation or pipes. This is purely choice of target application. It can decide when to do buffering or when not to do. Some applications will do line buffering when outputting to screen, and no buffering when to pipe. Some applications will always do buffering. Some will never do buffering. You (as somebody who creates process) does not control that. Application itself controls that. That's why, for example, python has extra argument you can pass when you want it to not buffer python -u script.py (u means unbuffered). This way it allows whoever called it to decide buffer or not.


Edited by Mārtiņš Možeiko on

thank you for feedback!

call ReadFile with OVERLAPPED structure in argument and it will do read in background. Then either periodically check completion result, or simply wait on it to finish it. Then you can process data and issue next read

I learned about overlapping read after I started working on project, but couldn't wrap my head around the concept within the time limit. I will try to make it work correctly in the future.

This is not problem with process creation or pipes. This is purely choice of target application. It can decide when to do buffering or when not to do.

you are right, thank you for correction. I was misunderstanding that part. the article that I read was talking about this specific step (create process, connect a pipe, output gets delayed) and didn't mention how it's working under the hood, but I somehow just took what's written at face value and assumed that's how it works. I should've researched to clarify it.


Replying to mmozeiko (#25368)