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

Custom mg_set_non_blocking_mode() implementation #1411

Closed
dmitry-kandiner opened this issue Nov 23, 2021 Discussed in #1410 · 7 comments
Closed

Custom mg_set_non_blocking_mode() implementation #1411

dmitry-kandiner opened this issue Nov 23, 2021 Discussed in #1410 · 7 comments

Comments

@dmitry-kandiner
Copy link

It would be nice to have an option for custom mg_set_non_blocking_mode() implementation - some architectures have non-standard way for doing so. For instance, Cyclone TCP stack implementation of fcntl() requires three parameters: a socket, a command and a pointer to the command parameters.

@cpq
Copy link
Member

cpq commented Nov 23, 2021

@dmitry-kandiner thank you!

Do you get a build error about it? If yes, could you share it please?

@dmitry-kandiner
Copy link
Author

dmitry-kandiner commented Nov 23, 2021

@cpq sure, here is the snippet from the build log:

...../mongoose.c: In function 'mg_set_non_blocking_mode':
...../mongoose.c:2981:22: error: too few arguments to function 'fcntl'
2981 | fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); // Set non-blocking mode
| ^~~~~
In file included from ...../mongoose_custom.h:6,
from ...../mongoose.h:134,
from ...../mongoose.c:18:
...../core/bsd_socket.h:320:7: note: declared here
320 | int_t fcntl(int_t s, int_t cmd, void *arg);
| ^~~~~
...../mongoose.c:2982:13: error: 'F_SETFD' undeclared (first use in this function); did you mean 'F_SETFL'?
2982 | fcntl(fd, F_SETFD, FD_CLOEXEC); // Set close-on-exec
| ^~~~~~~
| F_SETFL
...../mongoose.c:2982:13: note: each undeclared identifier is reported only once for each function it appears in
...../mongoose.c:2982:22: error: 'FD_CLOEXEC' undeclared (first use in this function)
2982 | fcntl(fd, F_SETFD, FD_CLOEXEC); // Set close-on-exec
| ^~~~~~~~~~
Besides, Cyclone TCP stack does not define F_SETFD and FD_CLOEXEC.

Actually, my solution for this was like this:

2977: fcntl(fd, F_SETFL, O_NONBLOCK);
2978: #elif defined(mg_custom_set_non_blocking_mode)
2979: mg_custom_set_non_blocking_mode(fd);
2980: #else
2981: fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); // Set non-blocking mode

Plus the following code in mongoose_cusom.h:

static inline void set_non_blocking_mode(int_t socket) {
uint32_t opt = O_NONBLOCK;
fcntl(socket, F_SETFL, &opt);
}
#define mg_custom_set_non_blocking_mode(fd) set_non_blocking_mode(fd)

Best regards,
Dmitry

@cpq
Copy link
Member

cpq commented Nov 23, 2021

Thank you.

Maybe a way to go is to create your own custom fcntl and define dummy values for F_SETFL and FD_CLOEXEC. Like, in your mongoose_custom.h, you can do something like this:

#define fcntl sys_fcntl

.....includes....


// Here make our own fcntl()
#define F_SETFD 12345
#define FD_CLOEXEC 0

#undef fcntl

static inline int fcntl(int fd, int cmd, ...) {
  if (cmd == F_GETFL) return sys_fcntl(fd, cmd);
  if (cmd == F_SETFL) {
    va_list ap;
    va_start(ap, cmd);
    uint32_t opt = va_arg(ap, int);
    int result = sys_fcntl(fd, cmd, &opt);
    va_end(ap);
    return result;
  }
  return 0;
}

@dmitry-kandiner
Copy link
Author

Unfortunately, it didn't work for me. I tried to add the following code to the mogoose_custom.h, but was not able to link it.

#define fcntl sys_fcntl

#include <core/bsd_socket.h>

static inline int_t mg_fcntl(int_t fd, int_t cmd, void* opt)
{
	return sys_fcntl(fd, cmd, opt);
}

#define F_SETFD 12345
#define FD_CLOEXEC 0

#undef fcntl

static inline int fcntl(int fd, int cmd, ...) {
	if (cmd == F_GETFL) 
	{
		uint32_t opt;
		mg_fcntl(fd, cmd, &opt);
		return opt;
	}
	if (cmd == F_SETFL)
	{
		va_list ap;
		va_start(ap, cmd);
		uint32_t opt = va_arg(ap, int);
		int result = mg_fcntl(fd, cmd, &opt);
		va_end(ap);
		return result;
	}
	return 0;
}

Unfortunately linker fails with undefined reference to 'sys_fcntl'

@dmitry-kandiner
Copy link
Author

Maybe the best way will be to use mg_fcntl() instead of fcntl() in case of MG_ARCH_CUSTOM, and let the user define it in mogoose_custom.h? Also, it is possible to use fcntl() as the fallback option if mg_fcntl() is not defined.

@cpq
Copy link
Member

cpq commented Nov 24, 2021

I still think it is possible to inject a custom fcntl() without code modification. How about this mongoose_custom.h:

#include <core/bsd_socket.h>

#define F_SETFD 12345
#define FD_CLOEXEC 0

static inline int mg_fcntl(int fd, int cmd, ...) {
  if (cmd == F_GETFL) { uint32_t opt; fcntl(fd, cmd, &opt); return opt; }
  ...
}

#define fcntl mg_fcntl

@dmitry-kandiner
Copy link
Author

Thank you, @cpq , this solution worked for me!

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