Compiling C and sqlite3 - c

I'm having some trouble incorporating sqlite3 into a program I'm writing. I've been scouring the internet over the past few days attempting to find a solution. I'm using the MinGW compiler and have already tried:
Ensuring the C:\MinGW\bin directory is included in both the user and system environment Path variables with no spaces and separated with a semi-colon
Using the command prompt and entering "C:\MinGW\bin\gcc shell.c sqlite3.c -lpthread -ldl" in the same directory of all related files which returns the result "c:/mingw/bin/../lib/gcc/mingw32/5.3.0/../../../../mingw32/bin/ld.exe: cannot find -ldl
collect2.exe: error: ld returned 1 exit status"
Fresh install of MinGW and eclipse
If it helps this is the code I'm testing this with, I can't get the includes to show up as code but they are all in carets in order, iostream, stdio.h, and sqlite3.h
It returns the error "fatal error: sqlite3.h: No such file or directory". I have all of the include files in the same directory as the .cpp source as well.
int main(int argc, char* argv[])
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
rc = sqlite3_open("text.db", &db);
return 0;
}

#include <stdio.h>
#include "sqlite3.h"
int main(int argc, char* argv[])
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
rc = sqlite3_open("text.db", &db);
return 0;
}
Compile and test result:
w00343520#wuhy1w001184171 MINGW64 /d/Download/sqlite-amalgamation-3190200/sqlite-amalgamation-3190200
$ mingw32-gcc -o test main.c sqlite3.c -I./
w00343520#wuhy1w001184171 MINGW64 /d/Download/sqlite-amalgamation-3190200/sqlite-amalgamation-3190200
$ ll
total 8485
-rw-r--r-- 1 w00343520 1049089 192 六月 8 10:38 main.c
-rw-r--r-- 1 w00343520 1049089 236938 五月 26 00:15 shell.c
-rw-r--r-- 1 w00343520 1049089 7130198 五月 26 00:15 sqlite3.c
-rw-r--r-- 1 w00343520 1049089 498184 五月 26 00:15 sqlite3.h
-rw-r--r-- 1 w00343520 1049089 30199 五月 26 00:15 sqlite3ext.h
-rwxr-xr-x 1 w00343520 1049089 785640 六月 8 10:38 test.exe*
w00343520#wuhy1w001184171 MINGW64 /d/Download/sqlite-amalgamation-3190200/sqlite-amalgamation-3190200
$ ./test.exe
w00343520#wuhy1w001184171 MINGW64 /d/Download/sqlite-amalgamation-3190200/sqlite-amalgamation-3190200
$ ll
total 8485
-rw-r--r-- 1 w00343520 1049089 192 六月 8 10:38 main.c
-rw-r--r-- 1 w00343520 1049089 236938 五月 26 00:15 shell.c
-rw-r--r-- 1 w00343520 1049089 7130198 五月 26 00:15 sqlite3.c
-rw-r--r-- 1 w00343520 1049089 498184 五月 26 00:15 sqlite3.h
-rw-r--r-- 1 w00343520 1049089 30199 五月 26 00:15 sqlite3ext.h
-rwxr-xr-x 1 w00343520 1049089 785640 六月 8 10:38 test.exe*
-rw-r--r-- 1 w00343520 1049089 0 六月 8 10:41 text.db
w00343520#wuhy1w001184171 MINGW64 /d/Download/sqlite-amalgamation-3190200/sqlite-amalgamation-3190200
$
The test result for shell.c:
w00343520#wuhy1w001184171 MINGW64 /d/Download/sqlite-amalgamation-3190200/sqlite-amalgamation-3190200
$ mingw32-gcc -o sqlite shell.c sqlite3.c -I./
w00343520#wuhy1w001184171 MINGW64 /d/Download/sqlite-amalgamation-3190200/sqlite-amalgamation-3190200
$ ./sqlite.exe
w00343520#wuhy1w001184171 MINGW64 /d/Download/sqlite-amalgamation-3190200/sqlite-amalgamation-3190200
$ ./sqlite.exe --help
Usage: D:\Download\sqlite-amalgamation-3190200\sqlite-amalgamation-3190200\sqlite.exe [OPTIONS] FILENAME [SQL]
FILENAME is the name of an SQLite database. A new database is created
if the file does not previously exist.
OPTIONS include:
-ascii set output mode to 'ascii'
-bail stop after hitting an error
-batch force batch I/O
-column set output mode to 'column'
-cmd COMMAND run "COMMAND" before reading stdin
-csv set output mode to 'csv'
-echo print commands before execution
-init FILENAME read/process named file
-[no]header turn headers on or off
-help show this message
-html set output mode to HTML
-interactive force interactive I/O
-line set output mode to 'line'
-list set output mode to 'list'
-lookaside SIZE N use N entries of SZ bytes for lookaside memory
-mmap N default mmap size set to N
-newline SEP set output row separator. Default: '\n'
-nullvalue TEXT set text string for NULL values. Default ''
-pagecache SIZE N use N slots of SZ bytes each for page cache memory
-scratch SIZE N use N slots of SZ bytes each for scratch memory
-separator SEP set output column separator. Default: '|'
-stats print memory stats before each finalize
-version show SQLite version
-vfs NAME use NAME as the default VFS
w00343520#wuhy1w001184171 MINGW64 /d/Download/sqlite-amalgamation-3190200/sqlite-amalgamation-3190200
$

After fiddling around a bit I realized all I had to do was #include "sqlite3.h" with the sqlite.h file in the source file directory and include the sqlite3.c file in the project tree. I'm using DevC++ and I went to project > add to project and select the sqlite3.c file. Then project > project options > files and select sqlite3.c then uncheck "compile file as C++".

Related

execvp behaves weirdly with ls

Here is a minimal reproducible example of my issue
#include <unistd.h>
int main (int argc, char *argv[])
{
char *a[] = {"ls", "-l", "~", "..", "-A", NULL};
execvp(a[0], a);
return 0;
}
I expected this to work as it would when I run ls -l ~ .. -A in the shell, but on running the executable after compiling I get the following output
❯ clang main.c -o a
❯ ./a
ls: -A: No such file or directory
ls: ~: No such file or directory
..:
total 0
drwxr-xr-x 3 me staff 96 Sep 1 11:56 test

I am trying to use safec lib function's but facing linking issue

#include <stdio.h>
#include <string.h>
int main(){
char * ch = "THISISsometest";
char out[10] ;
strcpy_s(out,ch);
printf(" out : %s its len is %d \n ", out , strlen(out));
return 0;
}
Tried installing the lib source code from the git
https://github.com/rurban/safeclib.git
root#DESKTOP-RUVNU9H:~/sample_C_safe# ls -l
total 3
-rw-r--r-- 1 root root 194 Jun 22 16:00 sscanf.c
-rw-r--r-- 1 root root 2008 Jun 22 16:01 sscanf.o
root#DESKTOP-RUVNU9H:~/sample_C_safe# gcc -o out.exe sscanf.o -lsafec-3.5.1
/usr/bin/ld: sscanf.o: in function `main':
sscanf.c:(.text+0x3a): undefined reference to `strcpy_s'
collect2: error: ld returned 1 exit status
root#DESKTOP-RUVNU9H:~/sample_C_safe#
root#DESKTOP-RUVNU9H:~/sample_C_safe# echo $LD_LIBRARY_PATH
:/usr/lib:/usr/local/lib
root#DESKTOP-RUVNU9H:~/sample_C_safe# ls -l /usr/local/lib/
total 932
-rw-r--r-- 1 root root 625344 Jun 22 13:14 libsafec-3.5.1.a
-rwxr-xr-x 1 root root 981 Jun 22 13:14 libsafec-3.5.1.la
lrwxrwxrwx 1 root root 23 Jun 22 13:14 libsafec-3.5.1.so -> libsafec-3.5.1.so.3.0.6
lrwxrwxrwx 1 root root 23 Jun 22 13:14 libsafec-3.5.1.so.3 -> libsafec-3.5.1.so.3.0.6
-rwxr-xr-x 1 root root 322080 Jun 22 13:14 libsafec-3.5.1.so.3.0.6
drwxr-xr-x 1 root root 4096 Jun 22 13:14 pkgconfig
drwxrwxr-x 1 root staff 4096 Jun 22 12:56 python2.7
drwxrwsr-x 1 root staff 4096 Apr 23 12:10 python3.8
root#DESKTOP-RUVNU9H:~/sample_C_safe#
root#DESKTOP-RUVNU9H:~/sample_C_safe#
root#DESKTOP-RUVNU9H:~/sample_C_safe#
root#DESKTOP-RUVNU9H:~/sample_C_safe# ldconfig -p | grep -i safec
libsafec-3.5.1.so.3 (libc6,x86-64) => /usr/local/lib/libsafec-3.5.1.so.3
libsafec-3.5.1.so (libc6,x86-64) => /usr/local/lib/libsafec-3.5.1.so
root#DESKTOP-RUVNU9H:~/sample_C_safe#
So... this shows ld is able load our shared obj files
root#DESKTOP-RUVNU9H:~/sample_C_safe# nm -D /usr/local/lib/libsafec-3.5.1.so | grep -i printf_s
0000000000010870 T _snwprintf_s_chk
00000000000083d0 T _sprintf_s_chk
000000000000f2c0 T _swprintf_s_chk
0000000000009b90 T _vsnprintf_s_chk
0000000000010cd0 T _vsnwprintf_s_chk
0000000000009930 T _vsprintf_s_chk
000000000000ef70 T _vswprintf_s_chk
000000000000ab00 T fprintf_s
000000000000fba0 T fwprintf_s
000000000000a900 T printf_s
000000000000ae50 T vfprintf_s
000000000000f6d0 T vfwprintf_s
000000000000afe0 T vprintf_s
000000000000f860 T vwprintf_s
000000000000f9b0 T wprintf_s
root#DESKTOP-RUVNU9H:~/sample_C_safe#
and libsafec-3.5.1.so contains printf_s .
But still i am getting the error
/usr/bin/ld: /tmp/ccUBo9E9.o: in function main': check2.c:(.text+0x2b): undefined reference to printf_s'
collect2: error: ld returned 1 exit status
#include <stdio.h>
#include <string.h>
#include <safe_str_lib.h>
int main(){
char * ch = "THISISTEST2";
char out[10] ;
strcpy_s(out,10,ch);
printf(" out : %s its len is %d \n ", out , strlen(out));
return 0;
}
root#DESKTOP-RUVNU9H:~/sample_C_safe#
root#DESKTOP-RUVNU9H:~/sample_C_safe# gcc sscanf.c -I /usr/lib/safeclib/include/ -lsafec-3.5.1
root#DESKTOP-RUVNU9H:~/sample_C_safe#
root#DESKTOP-RUVNU9H:~/sample_C_safe#
root#DESKTOP-RUVNU9H:~/sample_C_safe#
root#DESKTOP-RUVNU9H:~/sample_C_safe# ./a.out
out : its len is 0
root#DESKTOP-RUVNU9H:~/sample_C_safe#
Now the input to < 10 bits size
root#DESKTOP-RUVNU9H:~/sample_C_safe# vim sscanf.c
#include <stdio.h>
#include <string.h>
#include <safe_str_lib.h>
int main(){
char * ch = "THISISTE";
char out[10] ;
strcpy_s(out,10,ch);
printf(" out : %s its len is %d \n ", out , strlen(out));
return 0;
}
root#DESKTOP-RUVNU9H:~/sample_C_safe# gcc sscanf.c -I /usr/lib/safeclib/include/ -lsafec-3.5.1
root#DESKTOP-RUVNU9H:~/sample_C_safe#
root#DESKTOP-RUVNU9H:~/sample_C_safe#
root#DESKTOP-RUVNU9H:~/sample_C_safe# ./a.out
out : THISISTE its len is 8
root#DESKTOP-RUVNU9H:~/sample_C_safe#

When a C library is statically linked does the whole library get added to the executable?

Background info: I am trying to compare the memory requirements for two pieces of code which perform some numerical computations. For this, I am comparing the size of compiled C codes with the math library statically linked.
However, I am finding some strange results which seem to indicate that the whole library is being added. I'm describing an MWE below
// Program ex1.c
# include<math.h>
void main (void)
{
float a = exp(2);
}
And
// Program ex2.c
# include <math.h>
void main(void)
{
float a = exp(2);
float b = pow(3,4);
float c = sin(3.14159);
}
I compile the files as follows:
gcc -static -o ex1static.out ex1.c -lm
gcc -static -o ex2static.out ex2.c -lm
If the compiled object for program 1 contained the code only for exp() and that for compiled object for program 2 contained the code for exp(), pow() and sin(), then the second one would be larger than the first. But both objects have the same size of 912.6 kB.
Why is this happening and is there any way to make sure that only the required parts of code get added to the objects?
Static libs are archives of object files, and linking in a static lib adds only those object file members of the archive that resolve at least one undefined reference.
To make sure only the required code gets added, the static lib needs to be made up of small object files, preferably with one exported global in each.
Other than that, you can achieve a similar effect if the library is compiled with -ffunction-sections/-fdata-sections and you then pass --gc-sections to the linker.
The -ffunction-sections -fdata-sections approach is basically equivalent to one-global-per-source approach, but using source files to establish the boundaries is more flexible as sometimes grouping things together may be desirable (larger translation units may lead to more compact and more optimized code).
Anyway, in your case (the lib isn't under your control), all you can try is -Wl,--gc-sections (the -Wl option to gcc prefixes what gcc should pass to the linker)
With your example and glibc, I was able to shed about about 41KiB from an original 849KiB.
Not very impressive, but glibc isn't build with static linking in mind anyway.
You can get much better results with a libc library that is, such as musl-libc.
for ex in ex{1,2}.c; do for flg in '' -Wl,--gc-sections; do echo "$ex $flg"; musl-gcc -O0 $ex -static -lm $flg call.c && \ls -l a.out ; done ; done
ex1.c
-rwxrwx--- 1 pjmp pjmp 8064 Jun 29 19:11 a.out
ex1.c -Wl,--gc-sections
-rwxrwx--- 1 pjmp pjmp 7744 Jun 29 19:11 a.out
ex2.c
-rwxrwx--- 1 pjmp pjmp 8064 Jun 29 19:11 a.out
ex2.c -Wl,--gc-sections
-rwxrwx--- 1 pjmp pjmp 7744 Jun 29 19:11 a.out
Now this is better, but you may be wondering why same sizes for example 1 and 2.
If you add -Wl,--print-map, you'll find that the relevant object files from musl-libc aren't being included at all
in either case. The reason is, gcc knows about these standard functions and it cheats by inserting opcodes instead of generated function calls. You can somewhat defeat gcc's cheating by adding a layer of indirection facilitated by another translation unit.
call.c:
double call1(double(*X)(double A), double A) { return X(A); }
double call2(double(*X)(double A,double B), double A, double B){ return X(A,B); }
Ex1.c
# include<math.h>
double call1(double(*X)(double A), double A);
double call2(double(*X)(double A,double B), double A, double B);
int main (void)
{
float a = call1(exp,2);
}
Ex2.c
# include <math.h>
double call1(double(*X)(double A), double A);
double call2(double(*X)(double A,double B), double A, double B);
int main(void)
{
float a = call1(exp,(2));
float b = call2(pow,3,4);
float c = call1(sin,(3.14159));
}
Now this gives me:
Ex1.c
-rwxrwx--- 1 pjmp pjmp 8216 Jun 29 19:15 a.out
Ex1.c -Wl,--gc-sections
-rwxrwx--- 1 pjmp pjmp 7984 Jun 29 19:15 a.out
Ex2.c
-rwxrwx--- 1 pjmp pjmp 17088 Jun 29 19:15 a.out
Ex2.c -Wl,--gc-sections
-rwxrwx--- 1 pjmp pjmp 16856 Jun 29 19:15 a.out
—a noticable difference between the two examples, which is possible thanks to how musl is made up of
many small source/object files so that no more (or not much more) than the relevant referenced code gets added when linking statically.

Executable with set-user-ID-on-execution option doesn't set effective uid

Here is a program which shows euid:
$ cat main.c
#include <stdio.h>
#include <unistd.h>
int main(int argc, char** argv) {
printf("euid: %d\n", geteuid());
return 0;
}
$ gcc main.c -o main
$ ls -l main
-rwxr-xr-x 1 scdmb scdmb 6425 Mar 30 14:07 main
Let's set set-user-ID-on-execution option:
$ chmod u+s main
$ ls -l main
-rwsr-xr-x 1 scdmb scdmb 6425 Mar 30 14:07 main
Program executed as user scdmb shows right euid:
$ ./main
euid: 1000
$ id -u scdmb
1000
Let's execute program as other user:
$ id -u jakisuser
1001
$ su jakisuser
Password:
Now euid is the same as uid of user jakisuser:
$ ./main
euid: 1001
Why this set-user-ID-on-execution option doesn't cause that second time effective user id is not 1000 (as file owner) but 1001 (as the one who executes program)? Shouldn't it be the same as owner of file main?
I've just tried this here and your program works perfectly.
What I suspect is happening is that you have apparmor or selinux or something else in the way which is preventing your SUID bit from taking effect. I suggest you disable those and try again.

Fread on Lion does not read when length > 2G

Since Macosx Lion fread does not read file with length > 2G (int size, 2'147'483'648 bytes).
It worked for years with macosx snow leopard.
I wrote a program to test it :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
FILE *fin = NULL, *fout = NULL;
char *ptr = NULL;
size_t len;
fpos_t flen;
if (!(fin = fopen(argv[1], "rb")))
{
printf("The input file: %s could not be opened\n", argv[1]);
return -1;
}
if ((fout = fopen(argv[2], "rb")))
{
printf("The output file %s already exist\n", argv[2]);
fclose(fin);
return -1;
}
if (!(fout = fopen(argv[2],"wb")))
{
printf("Cannot write on output file %s\n", argv[2]);
fclose(fin);
return -1;
}
fseek(fin, 0, SEEK_END);
fgetpos(fin, &flen);
len = flen;
printf("Input file length : %zd\n", len);
fseek(fin, 0, SEEK_SET);
if (!(ptr = malloc(len)))
{
printf("Canot allocate %zd bytes\n", len);
fclose(fin);
fclose(fout);
return -1;
}
if (fread(ptr, sizeof(char), len, fin) != len)
{
printf("Cannot read file\n");
fclose(fin);
fclose(fout);
free(ptr);
return -1;
}
fclose(fin);
if (fwrite(ptr, sizeof(char), len, fout) != len)
{
printf("Cannot write file\n");
fclose(fout);
free(ptr);
return -1;
}
free(ptr);
fclose(fout);
return 1;
}
just run :
./pgm inputfile outputfile
openssl sha inputfile
openssl sha outputfile
There is no error.
The length of the 2 files are the same.
The two fingerprints are not the same.
(The pointer is well allocated and write in the outputfile)
Its only with fread, not fwrite.
i don't understand the problem.
I just see this program (i don't know if apple use this one on Lion) and
r variable is defined as int.
http://www.opensource.apple.com/source/Libc/Libc-186/stdio.subproj/fread.c
Thanks for answers
Sounds like you're not compiling in 64 bit mode. Look for a command line argument or an option to whatever compiler you're using. To make sure you're compiling in the right mode, printf("%d\n", sizeof(int)); and see if it shows you what you expected.
Works fine for me on MacOS X Lion (10.7.2) with XCode 4.2. The executable is a 64-bit program. You should ensure yours is too.
$ make 2gb
/usr/bin/gcc -g -std=c99 -Wall -Wextra 2gb.c -o 2gb
2gb.c:5: warning: unused parameter ‘argc’
$ file 2gb
2gb: Mach-O 64-bit executable x86_64
$ dd if=/dev/zero of=input bs=1m count=3072
./2g3072+0 records in
3072+0 records out
3221225472 bytes transferred in 42.940363 secs (75016261 bytes/sec)
$ ls -l input
./2gb -rw-r--r-- 1 jleffler staff 3221225472 Oct 29 00:48 input
$ ./2gb input output
Input file length : 3221225472
$ openssl sha input
SHA(input)= c93bf6713a90e34554311f0a9e43cfd1f153475a
$ openssl sha output
SHA(output)= c93bf6713a90e34554311f0a9e43cfd1f153475a
$ ls -l input output
-rw-r--r-- 1 jleffler staff 3221225472 Oct 29 00:48 input
-rw-r--r-- 1 jleffler staff 3221225472 Oct 29 00:49 output
$ rm input output
$ /usr/bin/gcc --version
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$
And, when forced into 32-bit compilation:
$ rm 2gb
$ make CC='/usr/bin/gcc -m32' 2gb
/usr/bin/gcc -m32 -g -std=c99 -Wall -Wextra 2gb.c -o 2gb
2gb.c:5: warning: unused parameter ‘argc’
$ dd if=/dev/zero of=input bs=1m count=3072
3072+0 records in
3072+0 records out
3221225472 bytes transferred in 38.326753 secs (84046397 bytes/sec)
$ ./2gb input output
Input file length : 0
$ ls -l input
-rw-r--r-- 1 jleffler staff 3221225472 Oct 29 00:57 input
$
printf("%d\n", sizeof(int));
gcc -Wall Typ.c -o Typ
warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long unsigned int’
warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long
--> 4
Thank you Jonathan.
i am on 10.7.2 and xcode 4.2
gcc --version
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)
i do gcc TestFile.c -o TestFile.o
and even exactly as you did :
/usr/bin/gcc -g -std=c99 -Wall -Wextra 2gb.c -o 2gb
and i add -m64 after
and i have again 2 differents fingerprint.
xcode 3.6.2 was removed using sudo /Library/uninstall-devtools --mode=all
and xcode 4.2 install after.
i run the pgm on another user newly created (cause of $path maybe) and its the same.
i don't understand.
Apple team answer after reporting this bug
Hello Stéphane,
This is a follow up to Bug ID# 10376104. After further investigation it has been determined that this is a known issue, which is currently being investigated by engineering. This issue has been filed in our bug database under the original Bug ID# 6434977. The original bug number being used to track this duplicate issue can be found in the Related Problem section of your bug report's Problem Detail view.
Thank you for submitting this bug report. We truly appreciate your assistance in helping us discover and isolate bugs.
Best Regards,
Developer Bug Reporting Team
Apple Worldwide Developer Relations

Resources