Here is my simple program
#include <SDL2/SDL.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
SDL_Window *window = NULL;
if(SDL_Init(SDL_INIT_VIDEO) != 0)
{
SDL_Log("ERROR : SDL Initialization > %s\n", SDL_GetError());
exit(EXIT_FAILURE);
}
//Program
window = SDL_CreateWindow("My Viewer",SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN);
if(window == NULL)
{
SDL_Log("ERROR : SDL Window creation > %s\n", SDL_GetError());
exit(EXIT_FAILURE);
}
SDL_Delay(5000);
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}
When running the command line :
gcc main.c -o prog $(sdl2-config --cflags --libs) && ./prog
it display :
error: XDG_RUNTIME_DIR not set in the environment.
INFO: ERROR : SDL Initialization > No available video device
I search many forum and tried what they told us to do but nothing work.
I uninstall and re install (manually and also with command line) SDL2, change the env var "export DISPLAY=:0.0" or "export DISPLAY=:1", tried this forum but nothing seems to change.
I'm running this code in bash Ubuntu with WSL2.
Thank you everyone I manage to run my program with this solution :
Install Windows 11 (because Windows 10 is not able to run graphical app).
At This point, the following is run in the bash.exe
Install Xming and run Xming. (you can try running xeyes by installing xterm to check if it's working)
For SDL, just install sdl normally (sudo apt-get install libsdl2-2.0)
Run your program.
I didn't change any env var or any other library.
Related
My application is unable to handle time operations like time(2) when it runs in alpine docker container on an arm device.
What I have:
I am building a native c application which is statically linked to musl with toolchain from musl.cc (arm-linux-musleabihf-gcc). I am using latest alpine container (without image tag).
How it behaves:
Running binary directly on arm device works as expected
Running in alpine container on x64 device works as expected
Running in alpine container on arm device does not work
What's going wrong:
time(NULL); returns ((time_t) -1) and error=1: "Operation not permitted"
The timestamps in the log outputs have cranked timestamps
SSH handshake fails because the validity of the remote certificate is in the future.
However, if I execute date in container's ash the output is valid. Thus, there seems to be a problem that only occurs in alpine containers on the ARM architecture. Funnily enough, I'm switching from Ubuntu to Alpine as we had similar problems there.
Does anyone have any idea what I am doing wrong?
Update #1:
Same problem on ubuntu. So the problem seems to be on any docker basis image but only on arm devices.
Update #2: Here is a minimal example
TimeTest.c
#include <stdio.h>
#include <string.h>
#include "time.h"
#include "errno.h"
int main()
{
printf("hallo\n");
time_t myTime;
time_t result = time(&myTime);
printf("result: %lld\n", result);
if ((long)result < 0)
{
printf("time() error=%d: %s\n", errno, strerror(errno));
}
else
{
struct tm* tm_info = localtime(&myTime);
printf("Current local time and date: %s\n", asctime(tm_info));
}
return 0;
}
CMakeLists.txt
cmake_minimum_required (VERSION 3.8)
project ("TimeTest")
if(BUILD_TARGET STREQUAL "ARM_MUSL")
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER /usr/bin/arm-linux-musleabi-gcc)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-stack-protector -mfloat-abi=softfp -static --static")
set(CMAKE_LINK_SEARCH_END_STATIC TRUE)
endif()
add_executable (TimeTest "TimeTest.c")
Output on arm device
pi#raspberrypi:/tmp $ docker run --rm -it -v /tmp/TimeTest:/TimeTest alpine ash
/ # /TimeTest
hallo
result: -4696377169665647048
time() error=1: Operation not permitted
I am able to reproduce this exactly as described in the question. On my particular ARM hardware:
$ docker --version
Docker version 19.03.6, build 369ce74a3c [released approx. 2020-02-12]
$ file demo
demo: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV),
statically linked, with debug_info, not stripped
Using strace we can observe this behavior inside a container launched as reported:
...
clock_gettime64(CLOCK_REALTIME, 0xbe9c5e10) = -1 EPERM (Operation not permitted)
...
However, if we add the --privileged flag to the Docker command, it works:
# ./demo
hallo
result: 1608983884
Current local time and date: Sat Dec 26 11:58:04 2020
This behavior is caused by a Docker issue: https://gitlab.alpinelinux.org/alpine/aports/-/issues/11774, which is fixed in this commit and rolled into Docker version 19.03.12 (?) and up.
ionFish has solved the puzzle. I will mark his post as answer. However, I would like to post a possible work around that I think should work in all cases. What do you guys think?
I created a wrapper for __clock_gettime and always fallback to gettime32.
DockerFix.c
#include <time.h>
#include <errno.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/syscall.h>
static bool __wrap___clock_gettime_fallback = false;
int __wrap___clock_gettime(clockid_t clk, struct timespec* ts)
{
int r;
if (!__wrap___clock_gettime_fallback)
{
r = __real___clock_gettime(clk, ts);
if (!r) return r;
if (errno == EPERM || errno == EINVAL)
{
printf("WARN: clock_gettime() faulted with '%s'. Using SYS_clock_gettime32 as permanent fallback. Possible cause could be a faulty Docker version!\n", strerror(errno));
__wrap___clock_gettime_fallback = true; // skip in future
}
}
long ts32[2];
r = syscall(SYS_clock_gettime32, clk, ts32);
if (r == -ENOSYS && clk == CLOCK_REALTIME) {
r = syscall(SYS_gettimeofday_time32, ts32, 0);
ts32[1] *= 1000;
}
if (!r) {
ts->tv_sec = ts32[0];
ts->tv_nsec = ts32[1];
}
return r;
}
int __attribute__((weak, alias("__wrap___clock_gettime"))) clock_gettime(clockid_t clk, struct timespec* ts);
CMakeLists.txt
set(CMAKE_EXE_LINKER_FLAGS -Wl,--wrap=__clock_gettime")
add_executable (TimeTest "TimeTest.c" "DockerFix.c")
for me in Raspbian SO, works correctly in a redmine image.
These is the error that it reports:
Operation not permitted - clock_gettime (Errno::EPERM)
I use privileged:true in my docker compose file
I was trying to play around a bit with SDL on macOS (High Sierra 10.13.2) and I stumbled on what seems to be a rather incomprehensible mistake involving SDL windows not responding to keystrokes. I tried to construct two minimally different examples demarcating when this problem occurs: in fact, the examples do differ so minimally that it seems bizarre that their behaviour differs at all.
I have version 1.2.15 of the SDL libraries installed, and they were installed using the 'brew install sdl' command.
The first example (the one that does work correctly) is as follows:
/* sdl1.c */
#include "SDL/SDL.h"
SDL_Surface *screen;
SDL_Event event;
void initsdl (void) {
SDL_Init (SDL_INIT_EVERYTHING);
screen = SDL_SetVideoMode (500, 250, 32, SDL_SWSURFACE);
SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
while (1)
if (SDL_PollEvent(&event))
if (event.type == SDL_KEYDOWN)
if (event.key.keysym.sym == SDLK_ESCAPE)
break;
SDL_Quit ();
}
int main (int argc, char **argv) {
initsdl ();
return 0;
}
The other example is almost identical, but is spread over two files.
/* sdl2a.c */
#include "SDL/SDL.h"
SDL_Surface *screen;
SDL_Event event;
void initsdl (void) {
SDL_Init (SDL_INIT_EVERYTHING);
screen = SDL_SetVideoMode (500, 250, 32, SDL_SWSURFACE);
SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
while (1)
if (SDL_PollEvent(&event))
if (event.type == SDL_KEYDOWN)
if (event.key.keysym.sym == SDLK_ESCAPE)
break;
SDL_Quit ();
}
With the second file being:
/* sdl2b.c */
void initsdl(void);
int main (int argc, char **argv) {
initsdl ();
return (0);
}
As you can see, these programs are close to identical, with the only real difference being the fact that one of them is spread out over two files.
Now, I compile these files with the commands
cc -Wall -o sdl1 sdl1.c `sdl-config --libs` # (1)
and
cc -Wall -o sdl2 sdl2a.c sdl2b.c `sdl-config --libs` # (2)
I get two differences in the resulting behaviour.
First of all, the first example does not give any warnings whatsoever, whereas the second example gives the following warning:
ld: warning: object file (/usr/local/lib/libSDLmain.a(SDLMain.o)) was built for newer OSX version (10.13) than being linked (10.12)
The second difference is more problematic, however. Whereas the first example (the one who does give a compiler warning) behaves as it should, with a window appearing on screen, which correctly responds to the pressing of the ESC key before quitting, the second example simply does not respond to keystrokes at all, even after clicking on the window to make it active. This result is obtained by executing the binary resulting from the compilation directly from the terminal.
WebkitGTK+ API Reference
What I'm trying to do is run my HTML5 app on Linux that way I and my users can still use my app without relying on an internet connection.
My problem is when I go to download say a zip file. The download doesn't execute because there isn't an adequate url for the file to save to (like the desktop). Therefore it doesn't download.
Thus my question relies onto how am I suppose to get an adequate url to download this file when it's executed dynamically via JSZip. (It works fine in Chrome, just not in my app). Terminal says...
source.c:35:3: warning: ‘return’ with a value, in function returning
void [enabled by default] return TRUE; ^
Here's my code:
/*
Save this file as main.c and compile it using this command
(those are backticks, not single quotes):
gcc -Wall -g -o source source.c `pkg-config --cflags --libs gtk+-2.0 webkit-1.0` -export-dynamic
Then execute it using:
./source
If you can't compile chances are you don't have gcc installed.
Install gcc/c with the following terminal command. (This command is for Debian based Linux distros)
sudo apt-get install libgtk2.0-dev libgtk2.0-doc libglib2.0-doc
WebKit requires libraries to successfully aquire, configure, and compile. You can get libraries by issuing the following command in your terminal:
sudo apt-get install subversion gtk-doc-tools autoconf automake libtool libgtk2.0-dev libpango1.0-dev libicu-dev libxslt-dev libsoup2.4-dev libsqlite3-dev gperf bison flex libjpeg62-dev libpng12-dev libxt-dev autotools-dev libgstreamer-plugins-base0.10-dev libenchant-dev libgail-dev
WebkitGTK+ API Reference: http://webkitgtk.org/reference/webkitgtk/stable/webkitgtk-webkitdownload.html
Ubuntu Webkit information - https://help.ubuntu.com/community/WebKit
sudo apt-get install libwebkitgtk-dev python-webkit-dev python-webkit
Required dependencies for this build: (If you installed all the above this is not needed)
sudo apt-get install libgtk2.0-dev libgtk2.0-doc libglib2.0-doc subversion gtk-doc-tools autoconf automake libtool libgtk2.0-dev libpango1.0-dev libicu-dev libxslt-dev libsoup2.4-dev libsqlite3-dev gperf bison flex libjpeg62-dev libpng12-dev libxt-dev autotools-dev libgstreamer-plugins-base0.10-dev libenchant-dev libgail-dev libwebkitgtk-dev
*/
#include <gtk/gtk.h>
#include <webkit/webkit.h>
static void destroy_cb(GtkWidget* widget, gpointer data) {
gtk_main_quit();
}
static void download_requested_cb(WebKitWebView *web_view, WebKitDownload *download) {
const gchar* dest = g_strdup_printf("%s", "file:///home/michael/Downloads/test.zip");
//set the destination uri (eg, send the file to a downloads folder)
webkit_download_set_destination_uri(download, dest);
webkit_download_start();
return TRUE;
}
int main(int argc, char* argv[]) {
GtkWidget* window;
WebKitWebView* web_view;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_name (window, "AppName");
gtk_window_set_default_size(GTK_WINDOW(window), 600, 600);
//gtk_window_set_icon_from_file(window, "app/logo.png", NULL);
g_signal_connect(window, "destroy", G_CALLBACK(destroy_cb), NULL);
web_view = WEBKIT_WEB_VIEW(webkit_web_view_new());
/* Register a callback that gets invoked each time a download is requested */
g_object_connect(web_view, "download-requested", G_CALLBACK(download_requested_cb), NULL);
char uri[PATH_MAX];
char cwd[PATH_MAX];
getcwd(cwd, sizeof(cwd));
if (argc > 1)
snprintf(uri, sizeof(uri), "%s", argv[1]);
else
snprintf(uri, sizeof(uri), "file://%s/app/index.html", cwd);
webkit_web_view_open (web_view, uri);
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(web_view));
gtk_widget_grab_focus(GTK_WIDGET(web_view));
gtk_widget_show_all(window);
gtk_main();
return 0;
}
1) Your basic premise is sound:
file:///home/michael/Downloads/test.zip // This syntax should allow you to "upload" a local file on your hard drve
2) This is a compile warning (not an error). In theory, you could ignore it:
source.c:35:3: warning: ‘return’ with a value, in function returning void [enabled by default] return TRUE; ^
3) This is the problem:
static void download_requested_cb(WebKitWebView *web_view, ...
...
return TRUE; // Delete this line. You can't return anything from a "void" function!
}
Resently I'm installed Opencv in my machine. Its working in python well(I just checked it by some eg programs). But due to the lack of tutorials in python I decided to move to c. I just run an Hello world program from http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/
My program is
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>
int main(int argc, char *argv[])
{
IplImage* img = 0;
int height,width,step,channels;
uchar *data;
int i,j,k;
if(argc<2){
printf("Usage: main <image-file-name>\n\7");
exit(0);
}
// load an image
img=cvLoadImage(argv[1]);
if(!img){
printf("Could not load image file: %s\n",argv[1]);
exit(0);
}
// get the image data
height = img->height;
width = img->width;
step = img->widthStep;
channels = img->nChannels;
data = (uchar *)img->imageData;
printf("Processing a %dx%d image with %d channels\n",height,width,channels);
// create a window
cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);
cvMoveWindow("mainWin", 100, 100);
// invert the image
for(i=0;i<height;i++) for(j=0;j<width;j++) for(k=0;k<channels;k++)
data[i*step+j*channels+k]=255-data[i*step+j*channels+k];
// show the image
cvShowImage("mainWin", img );
// wait for a key
cvWaitKey(0);
// release the image
cvReleaseImage(&img );
return 0;
}
first while compiling I got the following error
hello-world.c:4:16: fatal error: cv.h: No such file or directory
compilation terminated.
and I rectify this error by compiling like this
gcc -I/usr/lib/perl/5.12.4/CORE -o hello-world hello-world.c
But now the error is
In file included from hello-world.c:4:0:
/usr/lib/perl/5.12.4/CORE/cv.h:14:5: error: expected specifier-qualifier-list before ‘_XPV_HEAD’
hello-world.c:5:21: fatal error: highgui.h: No such file or directory
compilation terminated.
Qns :
Is it this header is not installed in my system? While I'm using this command find /usr -name "highgui.h" I'm not find anything
If this header is not in my sysytem hoew I install this?
Please help me . I'm new in opencv
First check if highgui.h exists on your machine:
sudo find /usr/include -name "highgui.h"
If you find it on path lets say "/usr/include/opencv/highgui.h"
then use:
#include <opencv/highgui.h> in your c file.
or
while compiling you could add
-I/usr/include/opencv in gcc line
but then your include line in c file should become:
#include "highgui.h"
if, your first command fails that is you don't "find" highgui.h on your machine. Then clearly you are missing some package. To figure out that package name, use apt-find command:
sudo apt-find search highgui.h
on my machine, it gave me this:
libhighgui-dev: /usr/include/opencv/highgui.h
libhighgui-dev: /usr/include/opencv/highgui.hpp
if you don't have apt-find then install it first, using:
sudo apt-get install apt-find
So, now you know the package name, then issue:
sudo apt-get install libhighgui-dev
once this is done, use the find command to see where exactly, headers been installed and then use then change include path accordingly
I have the following headers in my project:
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/features2d/features2d.hpp>
The version of OpenCV 2.4.2
I set up Allegro 5, and could compile the following code with success:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <allegro5/allegro.h>
void error(char *msg)
{
fprintf(stderr,"%s : %s\n", msg, strerror(errno));
exit(1);
}
int main(int argc, char **argv)
{
ALLEGRO_DISPLAY *display = NULL;
if(!al_init())
error("Could not initailize allegro");
display = al_create_display(640, 480);
if(!display)
error("fail to display");
al_clear_to_color(al_map_rgb(0,0,0));
al_flip_display();
al_rest(10.0);
al_destroy_display(display);
return 0;
}
But after running it, it failed with the error message:
Could not initailize allegro : No such file or directory.
I don't know what is wrong. My OS is Ubuntu, I'd compiled the code successfully with:
gcc try.c -lallegro
But could not run it with:
./a.out
Allegro needs a configuration file and possibly other files to operate. From your comment, that is probably why it is not working. From the readme:
"
Normally the setup program and allegro.cfg will go in the same directory as the Allegro program they are controlling. This is fine for the end user, but it can be a pain for a programmer using Allegro because you may have several programs in different directories and want to use a single allegro.cfg for all of them. If this is the case you can set the environment variable ALLEGRO to the directory containing your allegro.cfg, and Allegro will look there if there is no allegro.cfg in the current directory.
...
Under Unix, BeOS and MacOS X, the config file routines also check for ~/allegro.cfg, ~/.allegrorc, /etc/allegro.cfg, and /etc/allegrorc, in that order, and the keyboard and language files can be stored in your home directory or in /etc/.
See more:
http://alleg.sourceforge.net/stabledocs/en/readme.html#configuration