-
Notifications
You must be signed in to change notification settings - Fork 172
Os.exec win32 #1089
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Os.exec win32 #1089
Conversation
I put this back like it was. Changes will be split into smaller parts and I've gotten confused when permissions went back and forth
Update test_std.js
getting back to original codebase
tests on win32: os.exec os.pipe (fd version) os.kill os.watchpid maintains test on linux: os.exec os.kill os.waitpid os.watchpid os.pipe
just modified comments and changed name. I do plan to test watchpid on non-win32.
managed to also verify execution of .exe, return values of exe, and stderr handle. verifies watchpid in non-win32 for compatible scripting. the only non-compatible issue left I see is that getline() pulls from windows needing \r to be trimmed from <eol>
jscheck issue fixed. I did move the functions around to minimize code differences. env in win32 is one big zero-delimited buffer; I now double its size and copy on overflow.
os.exec branch is updated and tested. |
it's semantics. I just tested it. my compiler is not liking size_t addition to char* and for some reason even code editor seems to think it's typecasting crazy. so I'm comparing references to keep it clean enough looking.
needed to free the memory when I re-cache.
tested again ... I had comments and printf functions to remove. I just keep reviewing and expanding my test environment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a bunch of style issues, like inconsistent whitespace, non-idiomatic (for this project) if/else style, etc. Can you fix those first?
Rule of thumb: new code should look like the existing code that surrounds it.
Sure. I don't want to trample over everyone else's projects. In fact, I believe Mr Bellard likely ran into the same issues (that windows doesn't play nice with FDs and PIDs) and just skipped all of this. The quickjs-ng team added worker pipes for win32 (in quickjs-libc.c), but they use HND types in a piece of code that users won't see in the script. The quickjs documentation, the current std and os module, the c standard, and all of linux use and prefer PIDs and FDs. I haven't had a chance to test things like passing the FD down a pipe to another .exe or to a worker thread. Passing out HNDs in script would guarantee that flexibility, but it would be a documentation nightmare. So this works, it does what I need it to do as a scripting tool, and it function simply enough. I've created one replacement function that can be used in linux and windows without testing the environment, but the user needs to understand what that function does. Windows doesn't have waitpid. Do I just leave it in the tests.js folder and let them figure it out? Leave my comments above the c code and test.js code? Or put a comment in the documentation section for watchpid next to waitpid? Is everyone okay with the way I split those functions up in test_os_exec.js? I am just trying to make the use clear. Is everyone happy with the way I've left that? I appreciate the feedback so far, I don't expect anyone to take up all their time on this. I just know what any windows user or admin needs, and I'm trying to complete it. |
removed the majority of flags. Only left flags that seemed necessary. I had a combined js_os_pipe with several #ifdefs inside to separate the OSs. I later restored the non-WIN32 version so that it would not be out of order from the code before. The logic was that a) the export list is maintained in the order of the function calls. and b) the code compare was less of a mess to keep that chunk intact. I realized there were useless #ifdefs and removed them. I did retest both WIN32 and GNU.
I think I got everything! mostly comments and reordering of if statements. I'm not the only programmer in the world to put my then branches on the same line following an if statement. But I'm genX, I used 640x480 CRTs. It looks clearer, I do admit that. But this is definitely a 21st century practice, in the old days we couldn't afford the Tabs or the printer paper.
nothing functional, just tweaking the comments. I'm not happy leaving this undocumented function in the wild. and it's trivial! but there it is! it at least deserved 2 lines of description. It is more concise now .... just like Bellard would have wanted ... tidy and such.
Yes, I found a few things that needed cleaning up. Hopefully that's sufficient. |
quickjs-libc.c
Outdated
int pid; | ||
HANDLE ph; | ||
int block = 0, ret; | ||
DWORD options = 0, flags = PROCESS_QUERY_INFORMATION | SYNCHRONIZE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably should be:
DWORD options = 0, flags = PROCESS_QUERY_INFORMATION | SYNCHRONIZE; | |
DWORD options = 0, flags = PROCESS_QUERY_LIMITED_INFORMATION | SYNCHRONIZE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tested and works fine like that. I'll put that in. There's better chances of it not tripping security checkpoints in someone else's random section of code with LTD INFO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
apparently you close PID HNDS. Unlike FDs to HND casts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tested this a good bit over here. I think the handle numbers are recycling, just not immediately. Everything works.
PROCESS_QUERY_LIMITED_INFORMATION
CloseHandle after OpenProcess. The documentation wasn't so clear, but this works as it should, and I read that it wastes resources not to. Don't close HNDs to FDs, let them get closed by the user. But close HNDs from PIDs. Besides, this is a kill and an exit return value. It's stopped!
If you guys want to take some time reviewing this, I'm trying to pass these handles down pipes through stdin see if the child permissions work. |
You may want to take a look at: https://learn.microsoft.com/en-us/windows/win32/sysinfo/handle-inheritance |
thanks! |
I think I just need to fix the test script, to truncate the name from the path and append "qjs". But I have to get test262 to actually run to fully verify that. |
also I'm working on this and remembering, do you want to just combine this back into test_std.js? or keep this file separate? it's becoming sort of misplaced as test_std does some os module tests. |
recombined the functions tested against: (linux) true exit 2 bad command -> 127 good command ->0 watchpid blocking environment inherited pipe waitpid blocking watchpid nonblocking pid running kill watchpid nonblocking pid ended waitpid WNOHANG I have uncovered that linux echoes to the stdout and I am going to revert my flags for win32, but that change isn't tested yet in this file.
don't sleep on blocking, moved comment too
For things like |
"shell commands come through" split the os_exec function back in half between the 2 versions. fixed the way handles inherit and text buffers FROM SHELLS! text does not buffer from system commands, especially bad ones. Error messages are not the same. verifying 7 permutations are the same between the two OSs
7 permutations of direct commands and shell commands firing error codes and text through console. shells inherit stdio unless you pass a pipe. this is exec, bad programs don't execute. echo doesn't execute! there's text output now. it may be to set a flag to disable text output for testing, or else execute a script and verify the pipe text.
Done! functions separated between the operating systems and code cleaned up. There were bugs. The test script now goes through 7 permutations to show and explain that echo is not a process. Besides the return values being different and the text from shells, the behavior of those 7 permutations is identical. The error code for a bad program is not the same as cmd /c not finding a command. Shells inherit the handles by default if you don't pass a pipe. That's the way it was set up. But that's why the text program outputs "bad" and "shell commands come through". It's a change to the way test scripts work, but it needed verifying. Now, these 2 things can be changed! I started creating a flag that is not in the linux code when passing the stdio handles to CreateProcess. I think that shutting off the pipes and just reading the exit status from processes would be the more desired option, so a flag should be implemented. I was calling it 'inherit', and we can do this either way, because we pass stdio 1,2,3 by default. I think it should not be by default, silence should be default. It's less intrusive than creating 2 pipes to silence the output. I think a flag in test_os_exec.js for demonstrating the output text is more fitting. But now you have the option to execute "qjs test_os_exec.js" from test_std.js and just silently assert that shell text was there (similar to how you have test_worker and test_worker_module but only execute the master, the other is the slave). |
expanded 2 more functions and improved the test on file and inherit. nothing is yet tested on cwd.
added inherit flag it became more obvious that stdio should default to silent. set the inherit flag or pass one pipe, and the child will inherit the stdio of the parent (except the pipe you set). I believe this includes stdin!
silent by default, set inherit: true to pass stdio to the child, seems like the right thing to do. |
test_os_exec_child.js - executes the 8 basic permutative shell tests and verifies that only inherited handle text passes through stdout and stderr. test_os_exec.js - now builds the test folder path and executes test_os_exec_child.js; verifies that stderr sees 'bad' and stdout only sees the proper echo string. tests.conf will need update for all of this. It comes to my attention there is no return value when doing asynchronous shell commands.
test_os_exec_child.js added to exclusions. there's no other way to silently verify stdout and stderr inheritance.
amended child execution to test cwd parameter of os.exec
updated scripts to work with test262. Verifying 8 permutations is offloaded to test_os_exec_child.js. this verifies:
|
I was building the script path, but I needed to test cwd. test262 is usually called from the make folder. manually I'm going into tests/ and calling from there so that assert.js is there. now I look and see if 'tests' is the end of the path, if not I insert it, and I use 'cwd: dir,' If someone executes test262 from a build folder, I don't know how they get assert.js, but this will then break.
I need the cwd, and it needs testing. detects if you're in 'build' detects if you're in 'scripts' otherwise adds 'scripts' then it builds the cwd to use and test.
test_os_exec moved to other js
I need some eyes on this in case it won't work for you. I assume everything is fine, I can run-test262 without complaint. also, after sleeping on this, I've added a 'inherit' flag to make stdio pass through from the child to the console executing qjs. After I've slept on it and gotten familiar with how fork and execvpe function, I'm not happy with it. Inherited is default with a fork, it's not with Windows, but it should default to the linux standard. I think it should be a 'silent' flag. |
I think I have this figured out, minimized changes for win32 functionality and testing of os.exec.
someone should test on a real linux machine .. and you're doing mac?
I had to change several #ifdef (wasi) lines. I wasn't expecting to just change the codebase. I'm sorry about going back and forth, but someone changed permissions while I was in the middle of uploading files and it's created a huge mess that I can't seem to fix!
downloaded compiled and tests run with MING64/Clang64 Msys2, Debian on WSL, MSVC 2022, Clang for MSVC