CPP expands macros in %-lines in rpcgen source file - rpc

Lines starting with sign '%' should be passed as is in output file,
but is such lines have some CPP macros, those macros are expanded as well:
Source (test.x):
#ifdef ONE
#warning "ONE is defined"
#else
#warning "NO ONE!!!!!1111"
#endif
%
% hello, ONE
%
Running rpcgen:
# rpcgen test.x -DONE
test.x:2:2: warning: #warning "ONE is defined" [-Wcpp]
test.x:2:2: warning: #warning "ONE is defined" [-Wcpp]
test.x:2:2: warning: #warning "ONE is defined" [-Wcpp]
test.x:2:2: warning: #warning "ONE is defined" [-Wcpp]
Result (test.h):
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#ifndef _TEST_H_RPCGEN
#define _TEST_H_RPCGEN
#include <rpc/rpc.h>
#ifdef __cplusplus
extern "C" {
#endif
hello, 1
#ifdef __cplusplus
}
#endif
#endif /* !_TEST_H_RPCGEN */
So "ONE" is replaced with "1", but it is desirable leave it as is
(consider "#ifdef ONE" in resulting test.h)
It there any way to aviod it?

So, I have a workaroud with CPP wrapper:
somedir/cpp <- wrapped which undefines problematic macros. For example:
#!/bin/sh
exec /usr/bin/cpp -U_LP64
Run rpcgen as rpcgen -Y somedir

Related

How to force g++ to respect #define _POSIX_C_SOURCE 200809L

I need to use strerror_r to translate error numbers into human readable messages compiled with g++ on Linux Debian Bullseye. The man page notes:
int strerror_r(int errnum, char *buf, size_t buflen);
/* XSI-compliant */
char *strerror_r(int errnum, char *buf, size_t buflen);
/* GNU-specific */
strerror_r():
The XSI-compliant version is provided if:
(_POSIX_C_SOURCE >= 200112L) && ! _GNU_SOURCE
Otherwise, the GNU-specific version is provided.
We have two different types of the return value: int or char* depending on the version defined by _POSIX_C_SOURCE. I have this small test program:
~$ cat strerror_r.c
#include <string.h>
#include <stdio.h>
// #define _POSIX_C_SOURCE 200112L
// #undef _GNU_SOURCE
#define ERROR_BUFFER_LEN (size_t)256
int main(int argc, char **argv)
{
#if _POSIX_C_SOURCE < 200112L
char* ret;
#else
int ret;
#endif
char errorBuffer[ERROR_BUFFER_LEN];
int errno;
errno = 0;
ret = strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
fprintf(stderr, "Error message by pointer = '%s'\n", ret);
fprintf(stderr, "Content of errorBuffer = '%s'\n", errorBuffer);
return 0;
}
If I compile it with gcc everything is as expected:
$ gcc strerror_r.c && ./a.out; rm a.out
Error message by pointer = '(null)'
Content of errorBuffer = 'Success'
If I compile it with g++ I get this:
$ g++ strerror_r.c && ./a.out; rm a.out
strerror_r.c: In function ‘int main(int, char**)’:
strerror_r.c:24:21: error: invalid conversion from ‘char*’ to ‘int’ [-fpermissive]
24 | ret = strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
| ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| char*
rm: cannot remove 'a.out': No such file or directory
If I try to force the needed version by uncommenting
#define _POSIX_C_SOURCE 200112L
#undef _GNU_SOURCE
I get:
$ g++ strerror_r.c && ./a.out; rm a.out
strerror_r.c:7: warning: "_POSIX_C_SOURCE" redefined
7 | #define _POSIX_C_SOURCE 200112L
|
In file included from /usr/include/x86_64-linux-gnu/bits/libc-header-start.h:33,
from /usr/include/string.h:26,
from strerror_r.c:3:
/usr/include/features.h:281: note: this is the location of the previous definition
281 | # define _POSIX_C_SOURCE 200809L
|
strerror_r.c: In function ‘int main(int, char**)’:
strerror_r.c:24:21: error: invalid conversion from ‘char*’ to ‘int’ [-fpermissive]
24 | ret = strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
| ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| char*
rm: cannot remove 'a.out': No such file or directory
What I'm missing here? Why g++ does not compile the default thread save version of strerror_r? I need that version. How can I fix it?
Reference
Feature Test Macros
You need to specify the #define and #undef directives before you include any header files, so the first few lines should look like this:
#define _POSIX_C_SOURCE 200112L
#undef _GNU_SOURCE
#include <string.h>
#include <stdio.h>
That's because those header files or internal header files they include need those values defined to choose the proper variant. If you define them after including the headers, the headers don't see the right values and they don't include the version you want.
Often people specify these values on the command like with the -D and -U arguments so they are always specified before header files are included.

Where is the serial port flag CRTSXOFF on Linux?

I'm trying to port some Solaris serial port code to Linux, however the XOn / XOff symbol typically found in termios.h seems to be missing.
// ...
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
// ...
int config_port(int fd, int timeout)
{
struct termios options; /* Holds the port option flags */
int status; /* Holds return value of system calls */
int min_chars; /* Holds the minimum number of characters to read
* before returning. */
// ...
options.c_cflag &= ~( CRTSXOFF | CRTSCTS ); // <<-- HERE
Of course, Linux GCC doesn't know CRTSXOFF:
# gcc -c -g serial.c
serial.c: In function ‘config_port’:
serial.c:125:25: error: ‘CRTSXOFF’ undeclared (first use in this function)
125 | options.c_cflag &= ~( CRTSXOFF | CRTSCTS );
On Solaris, this symbol is certainly defined in termios.h:
# find /usr/include -iname \*.h -exec grep CRTSXOFF {} /dev/null \;
/usr/include/sys/termios.h:#define CRTSXOFF 010000000000
But on Linux the same command finds me nothing.
Is this symbol called something else on Linux?
Found it: under Linux CRTSXOFF is implemented as IXOFF.

Inno Setup string concatenation in #define directive

Did the Inno Setup website fail to document the #define directives or did I miss that somewhere? Is it permissible to define using defined strings and concatenate them?
#define MyApp ABC
#define MyAppVersion 1.2.1
#define MyFolder ? ; what is the right syntax here to concatenate
; the two previously defined strings?
Here is the section of help concerning defines:
http://www.jrsoftware.org/ispphelp/index.php?topic=define
Regarding your example:
#define MyApp "ABC"
#define MyAppVersion "1.2.1"
#define MyFolder MyApp + MyAppVersion
#define MyFolder1 MyApp + "Some other string"

Testing a parameter passed through the /D command line switch fails in Inno Setup

I call ISCC /DENABLE_SIGNING=1 MyFile.iss, and in MyFile.iss I have:
#if ENABLE_SIGNING == 1
SignedUninstaller=yes
SignTool=mysigntool
#endif
ISPP fails with an error exactly at the line with #if ENABLE_SIGNING == 1:
[ISPP] Operator not applicable to this operand type.
But if I've defined ENABLE_SIGNING in the MyFile.iss instead, it goes fine. This code passes without errors:
#define ENABLE_SIGNING 1
#if ENABLE_SIGNING == 1
SignedUninstaller=yes
SignTool=mysigntool
#endif
Edit
Also, there is another problem, when I use /DENABLE_SIGNING=0, testing #if ENABLE_SIGNING succeeds, while if I use #define ENABLE_SIGNING 0, the check fails (meaning evaluates to false), as it should.
From some tests I've ran right now it seems the command line interpreted preprocessor takes the define default values as strings. So when you modify your condition this way, it will work properly:
; just for case when you wouldn't run ISCC from command line
#ifndef ENABLE_SIGNING
#define ENABLE_SIGNING "1"
#endif
[Setup]
AppName=My Program 1
AppVersion=1.5
DefaultDirName={pf}\My Program
#if ENABLE_SIGNING == "1"
SignedUninstaller=yes
SignTool=mysigntool
#endif

Problems on injecting into printf using LD_PRELOAD method

I was hacking printf() of glibc in one of my project and encountered some problem. Could you please give some clues? And one of my concern is why the same solution for malloc/free works perfect!
As attached, “PrintfHank.c” contains my own solution of printf() which will be preloaded before standard library; and “main.c” just outputs a sentence using printf(). After editing two files, I issued following commands:
compile main.c
gcc –Wall –o main main.c
create my own library
gcc –Wall –fPIC –shared –o PrintfHank.so PrintfHank.c –ldl
test the new library
LD_PRELOAD=”$mypath/PrintfHank.so” $mypath/main
But I received “hello world” instead of “within my own printf” in the console. When hacking malloc/free functions, it’s okay.
I log in my system as “root” and am using 2.6.23.1-42.fc8-i686. Any comments will be highly appreciated!!
main.c
#include <stdio.h>
int main(void)
{
printf("hello world\n");
return 0;
}
PrintfHank.c
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <dlfcn.h>
static int (*orig_printf)(const char *format, ...) = NULL;
int printf(const char *format, ...)
{
if (orig_printf == NULL)
{
orig_printf = (int (*)(const char *format, ...))dlsym(RTLD_NEXT, "printf");
}
// TODO: print desired message from caller.
return orig_printf("within my own printf\n");
}
This question is ancient, however:
In your main.c, you've got a newline at the end and aren't using any of the formatting capability of printf.
If I look at the output of LD_DEBUG=all LD_PRELOAD=./printhack.so hello 2>&1 (I've renamed your files somewhat), then near the bottom I can see
17246: transferring control: ./hello
17246:
17246: symbol=puts; lookup in file=./hello [0]
17246: symbol=puts; lookup in file=./printhack.so [0]
17246: symbol=puts; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0]
17246: binding file ./hello [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `puts' [GLIBC_2.2.5]
and no actual mention of printf. puts is basically printf without the formatting and with an automatic line break at the end, so this evidently the result of gcc being "helpful" by replacing the printf with a puts.
To make your example work, I removed the \n from the printf, which gives me output like:
17114: transferring control: ./hello
17114:
17114: symbol=printf; lookup in file=./hello [0]
17114: symbol=printf; lookup in file=./printhack.so [0]
17114: binding file ./hello [0] to ./printhack.so [0]: normal symbol `printf' [GLIBC_2.2.5]
Now I can see that printhack.so is indeed being dragged in with its custom printf.
Alternatively, you can define a custom puts function as well:
static int (*orig_puts)(const char *str) = NULL;
int puts(const char *str)
{
if (orig_puts == NULL)
{
orig_puts = (int (*)(const char *str))dlsym(RTLD_NEXT, "puts");
}
// TODO: print desired message from caller.
return orig_puts("within my own puts");
}
Check
1) preprocessor output. printf can be changed to smth else
gcc -E main.c
2) ld_debug info about printf symbol and preloading
LD_DEBUG=help LD_PRELOAD=”$mypath/PrintfHank.so” $mypath/main
LD_DEBUG=all LD_PRELOAD=”$mypath/PrintfHank.so” $mypath/main
Change
return orig_printf("within my own printf\n");
to
return (*orig_printf)("within my own printf\n");

Resources