Skip to content
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

Using janet_dobytes or janet_dostring with os/ commands causes block to fail to evaluate/return #926

Closed
ahungry opened this issue Mar 1, 2022 · 3 comments

Comments

@ahungry
Copy link
Contributor

ahungry commented Mar 1, 2022

Related to: janet-lang/circlet#17 - I have found a similar issue in my bespoke web server implementation - however, it can be distilled down to the following small snippet fail case:

// gcc -Wall -I./amalg ./amalg/janet.c ./src/janet-os-fail.c -o test.bin -lm
#include <janet.h>
#include <string.h>

char *
janet_stuff ()
{
  JanetTable *env;

  janet_init ();
  env = janet_core_env (NULL);

  Janet ret;
  int h = janet_gclock ();

  // This will fail
  // janet_dostring (env, "(do (os/shell \"whoami\") \"bob\")", "fake", &ret);

  // This will succeed
  janet_dostring (env, "(do \"bob\")", "fake", &ret);

  const unsigned char *result;

  if (janet_checktype (ret, JANET_STRING))
    {
      result = janet_unwrap_string (ret);
    }
  else
    {
      fprintf (stderr, "The string was not returned, woops.");
      result = (uint8_t *) "FAILURE";
    }

  janet_gcunlock (h);
  janet_deinit ();

  return (char *) result;
}

int
main (int argc, char *argv[])
{
  char *res = janet_stuff ();

  fprintf (stdout, res);

  return 0;
}

// Sample output
/* ❯ gcc -Wall -I./amalg ./amalg/janet.c ./src/janet-os-fail.c -o test.bin -lm */
/* ❯ ./test.bin */
/* The string was not returned, woops.FAILURE% */
/* mcarter */
/* ❯ gcc -Wall -I./amalg ./amalg/janet.c ./src/janet-os-fail.c -o test.bin -lm */
/* ❯ ./test.bin */
/* bob% */

To reproduce the failure, simply swap the janet_dostring() lines so you execute the one with the os/shell call in it. It will not finish block evaluation and return the string "bob" as it should.

Compare to a valid Janet in the REPL, which will reproduce the behavior as expected.

(do (os/shell "whoami") "bob")
mcarter
"bob"

FWIW, this is under Janet 1.20 built from the tag

@ahungry
Copy link
Contributor Author

ahungry commented Mar 1, 2022

Also - it occurs with or without the gclock, so it doesn't appear to be some obscure issue with having gc locked while os/ is executed.

@ahungry
Copy link
Contributor Author

ahungry commented Mar 1, 2022

Interestingly enough, if I wrap the os/ call in an (ev/spawn-thread), the problem goes away.

@bakpakin
Copy link
Member

bakpakin commented Mar 5, 2022

Functions that use the event loop must have a call to janet_loop to run the event loop to completion. I guess the next question would be, should janet_dobytes and janet_dostring call janet_loop under the hood - they predate the event loop so currently they don't.

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

No branches or pull requests

2 participants