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;
}
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.
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)
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
As clang-format is a tool to only reformat code, is it possible that such formatting can break working code or at least change how it works? Is there some kind of contract that it will/can not change how code works?
We have a lot of code that we want to format with clang-format. This means, many lines of code will change. Not having to review every single line of code that only changed due to a clang-format would be a big simplification of this process.
I would say that clang-format will not change how code works. On the other hand I am not 100% sure, if this can be guaranteed.
Short answer: YES.
The clang-format tool has a -sort-includes option. Changing the order of #include directives can definitely change the behavior of existing code, and may break existing code.
Since the corresponding SortIncludes option is set to true by several of the built-in styles, it might not be obvious that clang-format is going to reorder your includes.
MyStruct.h:
struct MyStruct {
uint8_t value;
};
original.c:
#include <stdint.h>
#include <stddef.h>
#include "MyStruct.h"
int main (int argc, char **argv) {
struct MyStruct s = { 0 };
return s.value;
}
Now let's say we run clang-format -style=llvm original.c > restyled.c.
restyled.c:
#include "MyStruct.h"
#include <stddef.h>
#include <stdint.h>
int main(int argc, char **argv) {
struct MyStruct s = {0};
return s.value;
}
Due to the reordering of the header files, I get the following error when compiling restyled.c:
In file included from restyled.c:1:
./MyStruct.h:2:5: error: unknown type name 'uint8_t'
uint8_t value;
^
1 error generated.
However, this issue should be easy to work around. It's unlikely that you have order-dependent includes like this, but if you do, you can fix the problem by putting a blank line between groups of headers that require a specific order, since apparently clang-format only sorts groups of #include directives with no non-#include lines in between.
fixed-original.c:
#include <stdint.h>
#include <stddef.h>
#include "MyStruct.h"
int main (int argc, char **argv) {
struct MyStruct s = { 0 };
return s.value;
}
fixed-restyled.c:
#include <stddef.h>
#include <stdint.h>
#include "MyStruct.h"
int main(int argc, char **argv) {
struct MyStruct s = {0};
return s.value;
}
Note that stdint.h and stddef.h were still reordered since their includes are still "grouped", but that the new blank line prevented MyStruct.h from being moved before the standard library includes.
However...
If reordering your #include directives breaks your code, you should probably do one of the following anyway:
Explicitly include the dependencies for each header in the header file. In my example, I'd need to include stdint.h in MyStruct.h.
Add a comment line between the include groups that explicitly states the ordering dependency. Remember that any non-#include line should break up a group, so comment lines work as well. The comment line in the following code also prevents clang-format from including MyStruct.h before the standard library headers.
alternate-original.c:
#include <stdint.h>
#include <stddef.h>
// must come after stdint.h
#include "MyStruct.h"
int main (int argc, char **argv) {
struct MyStruct s = { 0 };
return s.value;
}
For sure it can change how your code works. And the reason is C program can view some properties of its source code. What I'm thinking about is __LINE__ macro, but I'm not sure there are no other ways.
Consider 1.c:
#include <stdio.h>
int main(){printf("%d\n", __LINE__);}
Then:
> clang 1.c -o 1.exe & 1.exe
2
Now do some clang-format:
> clang-format -style=Chromium 1.c >2.c
And 2.c is:
#include <stdio.h>
int main() {
printf("%d\n", __LINE__);
}
And, of course, output has changed:
> clang 2.c -o 2.exe & 2.exe
3
Since clang-format affects only whitespace characters, you can check that files before and after clang-formating are identical up to whitespaces. In Linux/BSD/OS X you can use diff and tr for that:
$ diff --ignore-all-space <(tr '\n' ' ' < 2.c ) <(tr '\n' ' ' < 1.c)
1.c:
#include <stdio.h>
int main() {printf("Hello, world!\n"); return 0;}
2.c:
#include <stdio.h>
int main() {
printf("Hello, world!\n");
return 0;
}
Output of diff command is empty, meaning that files 1.c and 2.c are identical up to whitespaces.
As Karoly mentioned in his comment, note that in ideal conditions you still have to check spaces that matters, e.g. string literals. But in the real world I believe this test is more than enough.
clang-format reformatted ASM code in a project because we effectively did this:
#define ASM _asm
ASM {
...
}
yes
it will not break the working flow
the system has the config switch:
"C_Cpp.clang_format_sortIncludes": false,
but it not work, i don't know what is wrong...
my version is:ms-vscode.cpptools-0.13.1
this is my solution:
for the stable working flow ,use the grammar:
// clang-format off
...here is your code
// clang-format on
It can break your code, if you use special constructs in your code and your settings for formatting.
Inline Assembler
If you normally compile your code with gcc and make use of gcc-style inline assembler, clang-format will very likely break the naming of register variables, as it sees the %-character as an operator.
asm_movq(%[val2], %%mm0)
will be reformatted as
asm_movq(% [val2], % % mm0)
which will no longer compile.
Constructing a Path in a macro
If you build up a path using macros without using strings, clang-format again will see the '/' character as an operator and will put spaces around it.
Boost e.g. uses a construct like this:
# define AUX778076_PREPROCESSED_HEADER \
BOOST_MPL_CFG_COMPILER_DIR/BOOST_MPL_PREPROCESSED_HEADER
to construct a path to a header file. The '/' is not an operator here, but as it is not inside a string, clang-format treats it as an operator and puts spaces around it, creating a different path.
The include of the header file will obviously fail.
Conclusion
Yes, clang-format can break your code. If you are using very specific constructs that are edge cases or outside of the language standard or simply extensions of your very specific compiler (which is not clang), then you will need to check the changes made by clang-format. Otherwise you risk getting hidden errors.
I imagine it would not, given that it is built on clang's static analysis, and therefore has knowledge of the structure of code itself, rather than just a dumb source code formatter that operates on the text alone(one of the boons of being able to use a compiler library). Given that the formatter uses the same parser and lexer as the compiler itself, I'd feel safe enough that it wouldn't have any issue spitting out code that behaves the same as what you feed it.
You can see the source code for the C++ formatter here: http://clang.llvm.org/doxygen/Format_8cpp_source.html
I am working out of the 2nd edition of Jon Erickson's "Hacking: The Art of Exploitation" using a VM (virutalbox) to run the LiveCD it came with (Ubuntu 7.04). In section 0x281 "File Access", the author explains accessing files through file descriptors, as well as the open() close() read() and write() functions, using an example on pages 82-84.
The code for the simplenote.c is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
void usage(char *prog_name,char *filename){
printf("Usage: %s < data to add to %s>\n",prog_name,filename);
exit(0);
}
void fatal(char *);
void *ec_malloc(unsigned int );
int main(int argc,char *argv[]){
int fd; //file descriptor
char *buffer,*datafile;
buffer = (char *)ec_malloc(100);
datafile = (char *)ec_malloc(20);
strcpy(datafile,"/tmp/notes");
if(argc < 2)
usage(argv[0],datafile);
strcpy(buffer,argv[1]);
printf("[DEBUG] buffer # %p:\'%s'\n",buffer,buffer);
printf("[DEBUG] datafile # %p:\'%s'\n",datafile,datafile);
strncat(buffer,"\n",1);//Add a newline on the end.
fd = open(datafile,O_WRONLY|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR);
if(fd == -1)
fatal("in main() while opening file");
printf("[DEBUG] file descriptor is %d\n",fd);
//Writing data
if(write(fd,buffer,strlen(buffer)) == -1)
fatal("in main() while writing buffer to file");
//Closing file
if(close(fd) == -1)
fatal("in main() while closing file");
printf("Note has been saved.\n");
free(buffer);
free(datafile);
}
//A function to display an error message and then exit
void fatal(char *message){
char error_message[100];
strcpy(error_message,"[!!]Fatal Error");
strncat(error_message,message,83);
perror(error_message);
exit(-1);
}
//An error-checked malloc() wrapper function
void *ec_malloc(unsigned int size){
void *ptr;
ptr = malloc(size);
if(ptr == NULL)
fatal("in ec_malloc() on memory allocation");
return ptr;
}
However, when I type the following instructions stated in the book into my terminal window, it returns the following error message:
reader#hacking:~/booksrc $ gcc -o simplenote simplenote.c
In file included from /usr/include/sys/stat.h:105, from simplenote.c:6:
/usr/include/bits/stat.h:70: error: field 'st_atim' has incomplete type
/usr/include/bits/stat.h:71: error: field 'st_mtim' has incomplete type
/usr/include/bits/stat.h:72: error: field 'st_ctim' has incomplete type
simplenote.c: In function 'main':
simplenote.c:35: error: 'O-WRONLY' undeclared (first use in this function)
simplenote.c:35: error: (Each undeclared identifier is reported only once
simplenote.c:35: error: for each function it appears in.)
simplenote.c:35: error: 'O_CREAT' undeclared (first use in this function)
simplenote.c:35: error: 'O_APPEND' undeclared (first use in this function)
Here is sys/stat.h line 105:
#include <bits/stat.h>
And here is bits/stat.h lines 63-83:
#ifdef __USE_MISC
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
identifier 'timespec' to appear in the <sys/stat.h> header.
Therefore we have to handle the use of this header in strictly
standard-compliant sources special. */
struct timespec st_atim; /* Time of last access. */
struct timespec st_mtim; /* Time of last modification. */
struct timespec st_ctim; /* Time of last status change. */
# define st_atime st_atim.tv_sec /* Backward compatibility */
# define st_mtime st_mtim.tv_sec
# define st_ctime st_ctim.tv_sec
#else
__time_t st_atime; /* Time of last access. */
unsigned long int st_atimensec; /* Nscecs of last access. */
__time_t st_mtime; /* Time of last modification. */
unsigned long int st_mtimensec; /* Nsecs of last modification. */
__time_t st_ctime; /* Time of last status change. */
unsigned long int st_ctimensec; /* Nsecs of last status change. */
#endif
I suppose this might be of some use for the first set of issues:
C++ system file bits/stat.h suddenly breaks with "error: field ‘st_atim’ has incomplete type"
/usr/include/time.h
cat time.h
doesn't do anything in my terminal window.
And here is the simplenote.c main function lines 1-6, 34-35:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
// Opening the file
fd = open(datafile, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
I'm guessing the open function problems stem from fcntl.h ?
I seem to keep running into issues because of faulty code the author provided. I don't want to constantly depend on the stackoverflow community for help, so what suggestions do you have for a novice about examining and fixing these problems in the future?
Thanks.
Transferring a selection of comments into a semi-coherent answer.
You should probably explicitly enable POSIX definitions. Add -D_XOPEN_SOURCE=700 to the command line, or #define _XOPEN_SOURCE 700 before the first #include and see if that solves anything. You should not be running into the problem though; the header should be self-contained.
Oh, but Ubuntu 7.04 is archaic…you may need to use 600 instead of 700. When was it released (when was the book published)? If it was 2009 or before, you probably need the older version (600). It's still surprising that you're seeing the error. The command line you specify doesn't contain the options that normally cause trouble (-ansi -pedantic, for example, or -std=c99 -pedantic). You could try using -std=gnu99 too; it might work better.
You had a similar problem recently (gcc -o stdlib.h syntax error c Hacking the Art of Exploitation). Did you get that resolved? It sounds as if the compilation system on the Live CD is not self-coherent, or the way you're able to use it means that it is not behaving self-coherently. Are you sure the compilation system works? It appears to be semi-defunct. Is it using the wrong headers, somehow?
I was able to resolve the previous problem by inserting #include <stdint.h> before #include <stdlib.h>
I will try the -D_XOPEN_SOURCE=600 and get back to you. Something must be wrong with the compilation system.
Well, you might need to include <time.h> (or possibly <sys/time.h>) before <sys/stat.h>, but the <sys/stat.h> header is broken if that works. And the <stdlib.h> header is broken if you have to include <stdint.h> before including it. I suppose Ubuntu 7.04 could be so old that you're supposed to #include <sys/types.h> before many of these headers, but that's still not an excuse for <stdlib.h>; that should be self-contained. POSIX 1997 required #include <sys/types.h> before <sys/stat.h>; POSIX 2004 did not. And I don't think Ubuntu 7.04 is quite that old.
Note, though, that the st_atim member is new; it was added to POSIX 2008 (and hence is in POSIX 2013). It was just st_atime before (and st_atime is now a macro for st_atim.tv_sec).
Including the -D_XOPEN_SOURCE=600 dealt with the bits stat issue. Ubuntu 7.04 was released in 2007 and the 2nd edition of the book that I am using came out in 2008. Also, not sure if this is of use, but in another previous example that included both <stdio.h> and <string.h> (as opposed to only <stdio.h>), the code would run fine without any intervention.
Interesting…it is going to make life interesting for you, in a way that life should not need to be interesting. (Chinese curses like "May you live in interesting times" spring to mind.) Use the -DXOPEN_SOURCE=600 option in all your compilations and keep your fingers crossed; that may well resolve most of your problems. Consider using -std=gnu99 as well, or instead. With luck, either or both of those should get you around most problems.
In case someone else is having the same issue with this book, I downloaded the iso file from hacking-live-1.0.iso.
Created a bootable usb and all works just fine without corrupted headers or anything.