From the official documentation we have the following signature for uv_fs_open:
int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb);
And it is said that it is equivalent to open(2).
From the most accredited tutorial I've found on the web, we have this (emphasis mine):
flags and mode are standard Unix flags. libuv takes care of converting to the appropriate Windows flags.
Because of that, I thought that the following statement would have worked both on Linux and Windows:
uv_fs_open(my_loop, my_req, my_filename, O_RDWR | O_CREAT, S_IRWXU, my_callback);
Actually, it works just fine on Linux.
Anyway, on Windows I receive the following errors:
'O_RDWR': undeclared identifier
'O_CREAT': undeclared identifier
'S_IRWXU': undeclared identifier
Is it the expected result (and thus the tutorial is wrong)?
What should I do to have a call to uv_fs_open that just works on both the platforms?
What are the values for flags and mode to be used on Windows?
To be able to use uv_fs_open on Windows, users have to:
include fcntl.h explicitly, because uv-win.h doesn't include it (see this issue for further details)
use _O_CREAT, _O_RDWR_ and so on instead of O_CREAT, O_RDWR and the others (see the official documentation for further details)
Something similar applies to the mode and details on the available constants can be found in the linked documentation.
Related
I use GNU-EFI to develop UEFI apps. I have some trouble getting a protocol (EFI_SHELL_PROTOCOL) working under GNU-EFI. My compiler says that it is undefined. Should I include something? I already included efi.h and efilib.h. Do I need more?
Code that I tried:
EFI_SHELL_PROTOCOL shell;
The error that I got:
error: unknown type name ‘EFI_SHELL_PROTOCOL’; did you mean ‘EFI_OPEN_PROTOCOL’?
161 | EFI_SHELL_PROTOCOL shell;
The EFI_SHELL_PROTOCOL isn't part of the main UEFI interface, and is therefore not included in the main header files (e.g. efi.h) and not included in the main UEFI standard.
Instead, EFI_SHELL_PROTOCOL is just an optional extension (that may not exist, and I'd assume is only likely to exist when a shell is being used and provides it), with its own separate standard and its own separate header file.
Assuming you're using GNU's tools; the right files to include are probably efishellintf.h and efishellparm.h.
Currently, GNU-EFI does not support EFI_SHELL_PROTOCOL. It doesn't contain any related definitions about it.
If you want to use it with GNU-EFI, you can use this header file from edk2 (put it in inc folder, for example, inc/efishell.h). Then include this header file in inc/efi.h and add these lines:
lib/data.c:
EFI_GUID ShellProtocol = EFI_SHELL_PROTOCOL_GUID;
inc/efilib.h:
extern EFI_GUID ShellProtocol;
Rebuild your GNU-EFI and now you can use EFI_SHELL_PROTOCOL by locating it first.
EFI_SHELL_PROTOCOL *SP;
uefi_call_wrapper(BS->LocateProtocol, 3, &ShellProtocol, NULL, &SP);
The EFI_SHELL_PROTOCOL is fully documented in the UEFI Shell Specification (currently v2.2) which can be downloaded at https://uefi.org/specifications
GNU EFI does not currently implement EFI_SHELL_PROTOCOL or, indeed, all of the current UEFI Specification. For a reference implementation of the UEFI Shell Specification look at the EDK11 ShellPkg source code.
This question already has answers here:
Why does open() create my file with the wrong permissions?
(7 answers)
Closed 5 years ago.
I made a little project some weeks ago, but it somehow didn't work anymore recently (or at least, not like it previously worked).
It had to create a file with open(), and fill it with some content.
[...]
int fd=open(filename, O_RDWR | O_CREAT);
/* write content */
close(fd);
[...]
The problem was just that it recently didn't create the file with the right permissions anymore (it was created with 0110 when the problem was occurring)
I now know that I just have to specify the permissions like this :
int fd=open(filename, O_RDWR | O_CREAT, 0700); /* (for instance) */
But the project still worked on some computers (Didn't work on OSX, but did work on a Linux, on which it was created with 0640, so it still worked because I still had reading permission).
So here is my question:
How are those default permissions defined for open() function at file creation?
(If I don't explicitly pass it to my open() call as a parameter.)
There is no default. You must specify them when you use O_CREAT.
According to the documentation on my system,
[The mode] argument must be supplied when O_CREAT is specified in flags
(Emphasis mine)
This makes it sound like it's undefined behaviour when you don't, and I do indeed get junk when I omit it (--wS--S--T).
You need to specify the mode arguments as an integer containing a set of bit flags. Something like:
int fd=open(filename, O_RDWR | O_CREAT, S_IRWXU | S_IRWXG);
See the man page for chmod. The call also uses the process umask to limit things.
I have a link error when trying to use sctp_get_no_strms function. I am running Slackware 14.1 and have lksctp-tools installed.
# ls /var/log/packages | grep sctp
lksctp-tools-1.0.16-x86_64-1_SBo
However libsctp symbol list does not include this function.
# nm -D /usr/lib64/libsctp.so | grep sctp_get
0000000000001100 T sctp_getaddrlen
00000000000010e0 T sctp_getladdrs
00000000000010c0 T sctp_getpaddrs
Is sctp_get_no_strms not supported by lksctp-tools?
The compilation command is as follows:
gcc -o srv sctpserv01.o sctp_wrapper.o -L../lib -lsock -lsctp
When using functions from a library, the appropriate header file needs to be #include'd — for example #include "unp.h" since the function sctp_get_no_strms() is described in Stevens Unix Network Programming, Volume 1: The Sockets API, 3rd Edn and is specific to that book.
Note that unp.h is not a standard system header, which is why I used "unp.h" rather than <unp.h> (with angle brackets around the header file name).
It turns out that function is defined in the source code available for the book. Confusingly it is not declared in the header file unp.h. It is defined in sctp/sctp_getnostrms.c.
I am using IAR EWARM 7.4
I have followed the instructions here: http://www.safetycritical.info/library/static/pc-lint/ewb-pclint-v2.pdf
I have created a header full of compiler definitions using the --predef_macros compiler option
--predef_macros C:\lint\lnt\iar-ewarm-predefined_macros_for_PC-lint.h
In iar-co-arm-v6.lnt I've added the following:
//
// EWARM extended defines
//
-header(C:/lint/lnt/iar-ewarm-predefined_macros_for_PC-lint.h)
Lint it gryping about a ton of MISRA violations from within that file.
Edit:
I tried adding the line
+libh(C:/lint/lnt/iar-ewarm-predefined_macros_for_PC-lint.h)
This cuts down on many of many of the MISRA violations, but I am still getting a few, e.g:
#define __CODE_MEMORY_LIST1__() __CODE_MEM_HELPER1__(__code, 0)
^
"LINT: C:\lint\lnt\iar-ewarm-predefined_macros_for_PC-lint.h (150, 9) Note 9026: Function-like macro, '__CODE_MEMORY_LIST1__', defined [MISRA 2012
Directive 4.9, advisory]"
#define __CODE_MEMORY_LIST2__(_P1) __CODE_MEM_HELPER2__(__code, 0, _P1)
^
"LINT: C:\lint\lnt\iar-ewarm-predefined_macros_for_PC-lint.h (151, 9) Note 9026: Function-like macro, '__CODE_MEMORY_LIST2__', defined [MISRA 2012
Directive 4.9, advisory]"
All of these messages were being explicitly turned on using the +elib() argument in the au-misra3.lnt file. That is why they were not being enabled by default.
Also, it did not work when I used -elib() to suppress them because when I included the au-misra3.lnt file they were reenabled.
So the answer is, include the au-misra3.lnt file and then manually suppress all of the messages I don't care to see about library files because that's more transparent then modifying the file that ships with lint or supplying my own file for MISRA.
It’s said that the error numbers like EINVAL, ENOMEM, etc. are defined in errno.h, but I can’t find them in errno.h, I also searched some directories under /usr/include, still can’t find them. I can use these macros without any issue in my C code. Anyone can tell me where are them?
It is defined either directly in errno.h or in a file included (directly or indirectly) by errno.h.
I searched for it using the following command:
find /usr/include | xargs grep ENOMEM | grep '#define'
and I found a match in /usr/include/asm-generic/errno-base.h in my linux (RHEL 6).
It's up to the implementation of the standard C library.
All that is certain is that <errno.h> is the top-level header that application code should use.
One way of figuring out is to trace an invocation of the compiler.
You can run locate errno.h | xargs grep EINVAL to find the location
On my Ubuntu 12.04 machine, its in /usr/lib/syslinux/com32/include/errno.h