Truncate file on Linux with c99 - c

I would like to open a file and set its size so that I can then use mmap to write to it.
I found that I can use function truncate or ftruncate. Unfortunately, when I include <unistd.h> I got error:
error: implicit declaration of function ‘truncate’
I read on Internet that I should use gnu or something like that but this is for school project and we have to compile with -std=c99.
Are there any alternatives?

When you use -std=c99 the C library makes sure that the headers do not declare any symbols that are not reserved/are not defined in the C standard library. Since ftruncate does not belong to the C standard library, being a POSIX extension instead, it is not defined by default.
A POSIX program must, for maximal compatibility, define the _POSIX_C_SOURCE feature test macro, or _XOPEN_SOURCE, with appropriate values, before including the headers.
The feature test macros are listed conveniently on for example Linux manual pages; for ftruncate these would be:
ftruncate():
_XOPEN_SOURCE >= 500
|| /* Since glibc 2.3.5: */ _POSIX_C_SOURCE >= 200112L
|| /* Glibc versions <= 2.19: */ _BSD_SOURCE
i.e. use
#define _XOPEN_SOURCE 500 // (or greater; current is 700)
#include <unistd.h>
or
#define _POSIX_C_SOURCE 200112L // (or greater)
#include <unistd.h>

Related

implicit declaration error even after including required header

I get the following error when I run my code:
error: implicit declaration of function ‘mkdtemp’ [-Werror=implicit-function-declaration]
This occurs even after including the correct header files for mkdtemp():
#include <stdlib.h>
Any ideas why this might be occurring?
The <stdlib.h> header is mandated by the C standard. The C standard makes no reference to a mkdtemp() function. If you're using gcc -std=c11 or some similar option, only the definitions provided by the C standard are exposed. If you compile using gcc -std=gnu11, then you'll get an indeterminate set of extension features enabled (and mkdtemp() would be one of them).
Since mkdtemp() is a POSIX function, you can explicitly request it by defining the appropriate enabling macro before including any standard header. A command-line option -D_XOPEN_SOURCE=700 would (probably) do the job, for example; there's also the option of using -D_POSIX_C_SOURCE=200809 but remembering the correct number is harder (it is the date of the POSIX 2008 standard as year and month).
Or you can place the appropriate #define at the top of the file:
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 700
#endif
or:
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L
#endif
These stanzas allow you to override the POSIX version on the command line. Simply writing the #define without the conditional around it would generate a warning (or error) for a non-benign redefinition of the macro.
There used to be major differences between the POSIX and X/Open functionality — X/Open included some things that POSIX doesn't. This distinction is smaller these days, and generally, you'll not get into trouble using the X/Open macro.
There are other enabling macros for other platforms, but one of these two will enable the declaration of mkdtemp(). On Linux (RHEL 7.x), /usr/include/features.h) documents these enabling macros:
/* These are defined by the user (or the compiler)
to specify the desired environment:
__STRICT_ANSI__ ISO Standard C.
_ISOC99_SOURCE Extensions to ISO C89 from ISO C99.
_ISOC11_SOURCE Extensions to ISO C99 from ISO C11.
_POSIX_SOURCE IEEE Std 1003.1.
_POSIX_C_SOURCE If ==1, like _POSIX_SOURCE; if >=2 add IEEE Std 1003.2;
if >=199309L, add IEEE Std 1003.1b-1993;
if >=199506L, add IEEE Std 1003.1c-1995;
if >=200112L, all of IEEE 1003.1-2004
if >=200809L, all of IEEE 1003.1-2008
_XOPEN_SOURCE Includes POSIX and XPG things. Set to 500 if
Single Unix conformance is wanted, to 600 for the
sixth revision, to 700 for the seventh revision.
_XOPEN_SOURCE_EXTENDED XPG things and X/Open Unix extensions.
_LARGEFILE_SOURCE Some more functions for correct standard I/O.
_LARGEFILE64_SOURCE Additional functionality from LFS for large files.
_FILE_OFFSET_BITS=N Select default filesystem interface.
_BSD_SOURCE ISO C, POSIX, and 4.3BSD things.
_SVID_SOURCE ISO C, POSIX, and SVID things.
_ATFILE_SOURCE Additional *at interfaces.
_GNU_SOURCE All of the above, plus GNU extensions.
_REENTRANT Select additionally reentrant object.
_THREAD_SAFE Same as _REENTRANT, often used by other systems.
_FORTIFY_SOURCE If set to numeric value > 0 additional security
measures are defined, according to level.
Note, too, that the manual page for mkdtemp() shows what is needed:
NAME
mkdtemp - create a unique temporary directory
SYNOPSIS
#include <stdlib.h>
char *mkdtemp(char *template);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
mkdtemp():
_BSD_SOURCE
|| /* Since glibc 2.10: */
(_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)
What I called 'enabling macros' are also known as 'Feature Test' macros.
See also POSIX System Interfaces: General Information: The Compilation Environment.

How to use ftruncate in c99 without warning

I want to use ftruncate function in my code. I have to compile with option std=c99. I get warning:
In function ‘test’:
warning: implicit declaration of function ‘ftruncate’ [-Wimplicit-function-declaration]
I tied to find on the Internet any solution which can solve this problem but I don't succeeded in.
I use ftrucnate because I want to clear content of an opened file after I get lock (flock).
Since ftruncate() isn't a standard C function, and you've asked for standards enforcement, you need to define the appropriate feature test macros (see feature_test_macros(7)).
From the ftruncate(2) manpage:
ftruncate():
_BSD_SOURCE || _XOPEN_SOURCE >= 500 ||
_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
|| /* Since glibc 2.3.5: */ _POSIX_C_SOURCE >= 200112L
In other words, to expose the ftruncate() function you must define one of these macros, for example:
gcc -c -std=c99 -D_XOPEN_SOURCE=500 myfile.c
FatalError's answer did not work for me. Mostly all you have to do for it to work is:
#include <unistd.h>

Compiler doesn't recognize lstat even with the #include's

#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
...
lstat(name, &st);
...
I am using CodeBlocks to write a C program. All the other includes work fine. I checked online and lstat requires the three includes listed at the top of the code, but I still get the error message warning: implicit declaration of function 'lstat' when I try to compile. I do not know what is wrong. If I need to include any extra information to get help, please say.
According to lstat(2):
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
lstat():
_BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
|| /* Since glibc 2.10: */ _POSIX_C_SOURCE >= 200112L
This means you need to define one of these feature test macros to use lstat(2).
So choose one of those feature test macros that makes sense to your code, such as _BSD_SOURCE, and define it in the very beginning (before you include any header file) of your source file, or you could define it on the compiler command line, such as -D_BSD_SOURCE for gcc.
lstat() is not compliant with strict ANSI standard.You should use your compiler flags from
-std=c99 to -std=gnu99 . This would include all the Unix based system.

Which macro is being used with strdup on Linux?

I have seen strdup used in code samples on StackOverflow and have just tried to use it on Linux (3.0.0-21-generic x86_64).
The compiler (clang) knew it was in string.h, but still complained about not having a prototype even with string.h included. It turns out that strdup is wrapped in a #if defined, in string.h. I searched this site and found a post that said that strdup is a POSIX routine, not a C standard library routine.
The possible macros that will expose it are
__USE_SVID
__USE_BSD
__USE_XOPEN_EXTENDED
__USE_XOPEN2K8
Each one of those is undefined in features.h which is included by stdlib.h.
Why isn't a POSIX macro in that list and which macro/compiler switch are people using to expose strdup in string.h?
Edit: per Jim's comment below I found that
#define _POSIX_SOURCE 1
or
#define _POSIX_C_SOURCE 1
above
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
do not expose strdup on my system.
But these do:
#define _BSD_SOURCE 1
#define _SVID_SOURCE 1
Edit 2: Per Keith's comment, I found that this also works:
#define _POSIX_C_SOURCE 200809L
Edit 3: Per Jonathan's comment these also work
#define _XOPEN_SOURCE 500
#define _XOPEN_SOURCE 600
#define _XOPEN_SOURCE 700
The __USE... macros are for internal use. You should define _POSIX_SOURCE, or possibly one of the other feature macros as described in the comments in your feature.h ... for example, from a version I just grabbed off the web (apparently an old and somewhat obsolete version),
__STRICT_ANSI__ ANSI Standard C.
_POSIX_SOURCE IEEE Std 1003.1.
_POSIX_C_SOURCE If ==1, like _POSIX_SOURCE; if ==2 add IEEE Std 1003.2.
_BSD_SOURCE ANSI, POSIX, and 4.3BSD things.
_SVID_SOURCE ANSI, POSIX, and SVID things.
_GNU_SOURCE All of the above, plus GNU extensions.
So defining _GNU_SOURCE would get you everything.
Edit: from the comment by Keith Thompson, you need
#define _POSIX_C_SOURCE 200809L
for strdup.

Is the crypt() function declared in unistd.h or crypt.h?

I'm using GCC 4.6.0 (on an otherwise unidentified platform).
I am using the crypt() function to encrypt a password.
I have never used that function before so I checked out the main page:
man 3 crypt
And it says to include the unistd.h header.
However, when I did that, I got an implicit warning for the crypt function.
warning: implicit declaration of function ‘crypt’ [-Wimplicit-function-declaration]
I did a bit of searching and I found that you have to include the crypt.h. However, how come it doesn't say that in the man page?
It also says #define _XOPEN_SOURCE (before including unistd.h) in my man page. So you should probably add it to expose the declaration of crypt.
EDIT
I just tried it. Including unistd.h and #define _XOPEN_SOURCE before it does the trick. Including it alone isn't enough.
Using
gcc version 4.6.0 20110429
GNU C Library stable release version 2.13
Looking into unistd.h:
/* XPG4.2 specifies that prototypes for the encryption functions must
be defined here. */
#ifdef __USE_XOPEN
/* Encrypt at most 8 characters from KEY using salt to perturb DES. */
extern char *crypt (__const char *__key, __const char *__salt)
__THROW __nonnull ((1, 2));
The POSIX standard for crypt() says that it should be declared in <unistd.h>, so that's what you need to include.
However, depending on what other compiler options you specify, you may or may not see it.
I currently use a header I call "posixver.h" which contains the code:
#ifndef JLSS_ID_POSIXVER_H
#define JLSS_ID_POSIXVER_H
/*
** Include this file before including system headers. By default, with
** C99 support from the compiler, it requests POSIX 2001 support. With
** C89 support only, it requests POSIX 1997 support. Override the
** default behaviour by setting either _XOPEN_SOURCE or _POSIX_C_SOURCE.
*/
/* _XOPEN_SOURCE 700 is loosely equivalent to _POSIX_C_SOURCE 200809L */
/* _XOPEN_SOURCE 600 is loosely equivalent to _POSIX_C_SOURCE 200112L */
/* _XOPEN_SOURCE 500 is loosely equivalent to _POSIX_C_SOURCE 199506L */
#if !defined(_XOPEN_SOURCE) && !defined(_POSIX_C_SOURCE)
#if __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 600 /* SUS v3, POSIX 1003.1 2004 (POSIX 2001 + Corrigenda) */
#else
#define _XOPEN_SOURCE 500 /* SUS v2, POSIX 1003.1 1997 */
#endif /* __STDC_VERSION__ */
#endif /* !_XOPEN_SOURCE && !_POSIX_C_SOURCE */
#endif /* JLSS_ID_POSIXVER_H */
On the systems where I work, setting _XOPEN_SOURCE to 700 would be an exercise in frustration and futility, however much I'd like to be able to do so. But these options normally make my code work correctly on Linux, HP-UX, MacOS X, AIX and Solaris - the Unix-like platforms I normally work on.
And this works when I set GCC into -std=c99 mode. If you use -std=gnu99, you probably don't need the header at all; it automatically enables C99 standard plus extensions.
Incidentally, I used to have this stanza at the top of individual source files. As the number of files containing the stanza grew (encroaching on hundreds of files), I realized that when I needed to adjust the settings, I had a monstrous editing job ahead of me. Now I have the one header and I'm retrofitting it into the files that have the stanza so I change one file (the header) to effect a change for all my code - once I've finished undoing the damage I did.

Resources