I'm using the luajit ffi library to call into the C library function waitpid.
However I can't find a proper specification for the encoding of the status result. The only documentation I've found are C macro functions I'd prefer to write in pure lua.
I had a brief look at the header files defining these macro's and would you know it, they are not simple but refer to other macros which refer to still other macros.
Can you help?
One way is to wrap the macros in little functions:
#include <sys/types.h>
#include <sys/wait.h>
int wifexited(int status) {
return WIFEXITED(status);
}
int wifexitstatus(int status) {
return WEXITSTATUS(status);
}
Now build a DLL (you didn't mention OS, so you'll have to work that out yourself).
Load the DLL ffi.load(...) and finally:
waitpidlib = ffi.cdef[[
int wifexited(int status);
int wifexitstatus(int status);
]]
...
local ans = waidpidlib.wifexited(42)
Related
I'm tasked with creating a popen() function using Pipes, which I have already completed. The catch is that the function must ALSO be named popen, not mypopen or popen2 etc.
I'm looking for someone to guide me in the right direction as to how I can accomplish this.
Currently I have a header file popen.h and another filed popen.c that I have created.
popen.h just has
void popen(char *arr[]);
While popen.c has the actual popen function code (Which works, just not when the function name is popen).
Currently I'm getting a previous declaration error upon compilation when my function is called popen.
How can I let the compiler choose between the two different popen functions, mine and stdio.h version.
Just #define popen my_popen before declaring, defining and using your function, but after including <stdio.h>.
popen.h
#define popen my_popen
void popen(char *arr[]);
popen.c
#include <stdio.h>
#include "popen.h"
void popen(char *arr[]){ printf("that's NOT the stdio's popen\n"); }
main.c
#include <stdio.h>
#include "popen.h"
int main(void){
popen(0); printf("done\n");
}
Similarly, you can hide the stdio's popen by defining popen to stdio_popen before including <stdio.h> and undefining it afterwards, if you really want to have a symbol named popen:
#define popen stdio_popen
#include <stdio.h>
#undef popen
void popen(char *arr[]){ printf("that's NOT the stdio's popen\n"); }
int main(void){
popen(0); printf("done\n");
}
$ nm a.out | grep popen
0000000000001160 T popen
Such nasty tricks are only useful when having to combine ornery source codes which pollute each other's namespace. There's zero reason to name a function you just wrote popen() and not something else, unless it's a drop-in replacement, with the same interface as the standard one.
If you want to have popen safely you must also make sure that you aren’t using <stdio.h>as this is where the normal popen is located, and your linker will not like it if there are two identical symbols named popen.
Let's look at the gettid system call as an example:
http://man7.org/linux/man-pages/man2/gettid.2.html
I know gettid is not implemented in libc and I need to make a system call directly in order to use it (syscall(SYS_gettid)). I have verified this myself with this C code:
#include <stdio.h>
#include <sys/types.h>
int main(){
pid_t a = gettid();
return 0;
}
which doesn't link and gives this warning when compiling: warning: implicit declaration of function 'gettid'; did you mean 'getline'.
Now my question is, why has the Linux documentation documented it as if this function actually exists?
SYNOPSIS
#include <sys/types.h>
pid_t gettid(void);
They have no example of how to make a direct system call and instead they have the above code snippet which doesn't exist and can't be used. Is there something I'm missing?
The syscall doesn't have a wrapper in the GNU C library (before 2.30), this is just a prototype of how the function would look if it did.
As noted in the man page:
NOTES
Glibc does not provide a wrapper for this system call; call it using syscall(2).
Here's an example of the gettid wrapper:
#define _GNU_SOURCE
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
pid_t gettid(void)
{
pid_t tid = (pid_t)syscall(SYS_gettid);
return tid;
}
As you can see, this is the same prototype as described in the man-page. The prototype in the man-page is just for reference, so you can create a wrapper around the system call if you (or the libc developers) so choose.
If you're just starting to learn C, I suggest you stop trying to understand system calls and their wrappers in the C library until you have more experience in the language. The difference will then be clear.
I have a version of a program that used to compile to a *.o file, but now it does not, and gives a compiler error.
I have tried to compile my code with gcc compiler on Linux, and the compile fails.
#include <stdio.h>
int isatty();
long isatty_(lio_number)
long *lio_number;
{
int file_desc;
if ((*lio_number)==5)
{
file_desc = stdin->_file;
return isatty(file_desc);
}
else
return 0;
}
I expect the command gcc -c isatty.c to yield isatty.o but it does not. Instead, I get this message:
isatty.c: In function ‘isatty_’:
isatty.c:11: error: ‘struct _IO_FILE’ has no member named ‘_file’
Never use any members of the FILE structure.
Use fileno(stdin) instead of stdin->_file.
The member _file is a MinGW-specific name for the file descriptor, while fileno is a widely-supported POSIX-compliant function.
Along with that, you may want to #include <unistd.h> instead of defining isatty explicitly.
If you're limited to writing your code this way for some reason, don't expect it to be portable. Otherwise, this should work:
#include <stdio.h>
#include <unistd.h>
long isatty_(long *lio_number)
{
int file_desc;
if (*lio_number == 5)
{
file_desc = fileno(stdin);
return isatty(file_desc);
}
else
{
return 0;
}
}
What this changes is that it includes unistd.h which provides a declaration for isatty, it includes the types of the arguments within the function definition, and it uses fileno(stdin) instead of stdin->_file, of which the former is much more portable. It also improves the formatting so others can read your code if they need to.
Modernize the code. The original seems to be targeting some ancient Unix. This should work on more recent POSIX-compliant systems, since virtually every such system should provide the fileno() function. Changing the code to standard C is also a good idea.
So use fileno(), include <unistd.h> instead of forward declaring isatty(), and use standard C function parameter declarations:
#include <stdio.h>
#include <unistd.h>
long isatty_(long *lio_number)
{
if (*lio_number == 5)
{
return isatty(fileno(stdin));
}
return 0;
}
I am learning C.
In this program
I use sleep function to slowdown a count down.
My text book doesn't specify a library I should include to use the sleep function.
So I use it without including any special library for it and it works.
But it gives me this warning message in codeblocks.
I tried to include <windows.h> but still the same warning message appears.
warning D:\Project\C language\trial8\trial8.c|19|warning: implicit
declaration of function `sleep'|
And here is my code.
#include <stdio.h>
int main()
{
int start;
do
{
printf("Please enter the number to start\n");
printf("the countdown (1 to 100):");
scanf("%d",&start);
}
while(start<1 || start>100);
do
{
printf("T-minus %d\n",start);
start--;
sleep(3000);
}
while(start>0);
printf("Zero!\n Go!\n");
return(0);
}
I want to know what does the warning message mean? How important is it? Is there anything that I should do about it? Note that the program works anyway.
The issue is in the libraries (header files):
on Windows:
#include <windows.h> and Sleep(1000); => 1000 milliseconds
on Linux:
#include <unistd.h> and sleep(1); => 1 second
The function sleep is not part of C programming language. So, C compiler needs a declaration/prototype of it so that it can get to know about about number of arguments and their data types and return data type of the function. When it doesn't find it, it creates an Implicit Declaration of that function.
In Linux, sleep has a prototype in <unistd.h> and in windows, there is another function Sleep which has a prototype in <windows.h> or <synchapi.h>.
You can always get away with including header, if you explicitly supply the prototype of the function before using it. It is useful when you need only few functions from a header file.
The prototype of Sleep function in C on windows is:
VOID WINAPI Sleep(_In_ DWORD dwMilliseconds);
Remember, it is always a good practice to supply the prototype of the function being used either by including the appropriate header file or by explicitly writing it. Even, if you don't supply it, compiler will just throw a warning most of the time and it will make an assumption which in most cases will be something that you don't want. It is better to include the header file as API might change in future versions of the Library.
Windows doesn't have the sleep function. Instead, it has Sleep, which takes the number of milliseconds to sleep:
VOID WINAPI Sleep(
_In_ DWORD dwMilliseconds
);
You'll need to either #include <windows.h> or #include <synchapi.h>, depending on the version of Windows you're running. See MSDN for more details.
Update in 2022:
As it is stated on the Linux man page here we need to include unistd.h and should do fine for all OS.
#include <stdio.h>
#include <unistd.h>
int main()
{
sleep(1); /* sleep for 1 second*/
printf("END\n");
return 0;
}
To make it more cross-platform, try this:
#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif
Folks, Assuming I have a c++ application / library running which implements say
/* Alloc API */
void* my_alloc(int size) {
return malloc(sizeof(size));
}
This is not under "extern c".
I have a C dynamic library from which I need to call my_alloc, can I directly call that API?
Like,
int test_my_alloc (int size) {
int *x;
x = (int*)my_alloc(size);
if (x == NULL) {
return 0;
} else {
return 1;
}
}
You need to create a stub, e.g.
Stub header:
// stub.h
#ifdef __cplusplus
extern "C" {
#endif
void* my_alloc_c(int size);
#ifdef __cplusplus
}
#endif
Stub implementation:
// stub.cpp
#include "stub.h"
#include "header_where_my_alloc_is_declared.h"
void* my_alloc_c(int size)
{
return my_alloc(size);
}
Your C code (example):
// my_code.c
#include "stub.h"
int main()
{
void * p = my_alloc_c(42);
return 0;
}
Then compile your stub and link it with your C code:
g++ -Wall -c stub.cpp # compile stub.cpp
gcc -Wall my_code.c stub.o # compile your C code and link with stub.o
As Paul R. answered, you need a stub code. also, you'll better be sure that your C++ function does not throw exceptions (I guess that a C++ function, called from a C program and main, which throws an uncaught exception is having some undefined behavior). BTW, you should be sure that the constructor of static C++ data (like std::cout) is called "conceptually" before your main in C (so you better link your program with a C++ compiler, not a C one). See the GCC __attribute__(constructor)
In practice, at least on Linux with C++ code compiled by GCC (g++) or by Clang/LLVM (clang++), a C++ function has some mangled name.
You might use some ugly and non-portable trick to call a function by its mangled name. You could dare coding:
int main(int argc, char**argv) {
extern void* _Z10my_alloc_ci(int size);
void * p = _Z10my_alloc_ci(42);
return 0;
}
but I am a bit ashamed of giving such silly advice. You could even use asm labels e.g.
extern void*f(int) asm ("_Z10my_alloc_ci");
p = f(42);
However, I feel that you should not have any such approaches, and I am surprized why you need to call a C++ function which is not wrapped around extern "C".
Notice that in theory, C++ functions (without extern "C") could even have a different -and incompatible- calling convention than C functions. I don't know any implementation doing that. So to be safe you should wrap your C++ function with some C++ wrapping using extern "C"
To avoid uncaught exceptions, you might catch all of them in your C++ wrapper:
#include <cstdio>
#include <cstdlib>
extern "C" void* my_alloc_c(int size) {
extern void* my_alloc(int);
try {
return my_alloc(size);
} catch (...) {
::fprintf(::stderr, "got uncaught C++ exception for my_alloc(%d)\n",
size);
::fflush(nullptr);
::abort();
}
}
BTW, if your C++ library is large, you might perhaps try to automatize the generation of the glue code. For example, you could customize GCC using MELT (a Lispy domain specific language to extend GCC) by coding an extension in MELT which would generate the glue code when compiling the C++ header files.
You might be interested in libffi which enables you to (portably) call any (C and probably C++) function of arbitrary signature.
From what I gathered:
You have a C++ library you have no control over (you can't add the extern "C")
You have a C library that must call the C++ library
You can modify your C library to accommodate a solution (you can change the makefile and change the name of the function you want to call)
So, one alternative solution would be to compile your C library with the very same C++ compiler used for that C++ library, if that's acceptable for you.
Note: with C89, you'll possibly need to modify bits of your code (e.g. void * to T * conversions are not implicit anymore in C++), but it would probably be easier than 100+ wrappers.
Note 2: If you're using some C99 features (e.g. the VLAs), then that code will not compile in C++.