Я написал новый "fprintf ()", но он не работает должным образом, в то время как "fopen ()" и "fclose ()" работают нормально.Мои собственные "fopen ()" и "fclose ()" вызываются вместо оригинальных.
команды:
gcc -fpic -c -ldl file_io_operation_interception.c
gcc -shared -lc -ldl -o file_io_operation_interception.so file_io_operation_interception.o
LD_PRELOAD =. / file_io_operation_interception.so gcc -o file_operations_test file_operations_test.c
* 1010_ .o./ file_operations_test
file_io_operation_interception.c
#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>
#include <errno.h>
// Client side implementation of UDP client-server model
//#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
// for fprintf
#include <stdarg.h>
//#include <libioP.h>
#define PORT 8080
#define MAXLINE 1024
static FILE *(*real_fopen)(const char *filename, const char *mode) = NULL;
static int (*real_fclose)(FILE *fp) = NULL;
static int (*real_fprintf)(FILE *stream, const char *format, ...) = NULL;
static size_t (*real_fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream) = NULL;
static ssize_t (*real_write)(int fd,const void *buf,size_t len) = NULL;
static int (*real_remove)(const char *filename) = NULL;
static int (*real_close)(int fd) = NULL;
static ssize_t (*real_read)(int fildes, void *buf, size_t nbyte) = NULL;
__attribute__((constructor))
void
my_lib_init(void)
{
real_fopen = dlsym(RTLD_NEXT,"fopen");
real_fclose = dlsym(RTLD_NEXT, "fclose");
real_fprintf = dlsym(RTLD_NEXT, "fprintf");
real_fwrite = dlsym(RTLD_NEXT, "fwrite");
real_remove = dlsym(RTLD_NEXT,"remove");
}
FILE *fopen(const char *filename, const char *mode)
{
FILE *fp;
// do whatever special stuff ...
fp = real_fopen(filename, mode);
printf("fopen worked!\n");
char message[200];
char fidString[10];
sprintf(fidString, "fopen %d ", fp);
strcat(message, fidString);
strcat(message, filename);
sendMessage(message);
// do whatever special stuff ...
return fp;
}
int
fclose(FILE *fp)
{
int i;
char message[200];
i = real_fclose(fp);
printf("fclose worked!\n");
sprintf(message, "fclose %d", fp);
sendMessage(message);
return i;
}
int
fprintf(FILE *stream, const char *format, ...)
{
va_list arg;
int done;
va_start (arg, format);
done = vfprintf(stream, format, arg);
va_end (arg);
char message[200];
printf("fprintf worked!\n");
sprintf(message, "fprintf %d", stream);
sendMessage(message);
return done;
}
int
remove(const char *filename)
{
int ret;
char message[200];
// do whatever special stuff ...
printf("remove worked!\n");
sprintf(message, "remove %s", filename);
sendMessage(message);
ret = real_remove(filename);
// do whatever special stuff ...
return ret;
}
int
sendMessage(char *message)
{
int sockfd;
struct sockaddr_in servaddr;
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = INADDR_ANY;
int n, len;
sendto(sockfd, (const char *)message, strlen(message),
MSG_CONFIRM, (const struct sockaddr *) &servaddr,
sizeof(servaddr));
printf("message sent\n");
close(sockfd);
return 0;
}
file_operation_test.c
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("\n\nProgram Begins:\n");
FILE *fr;
char str[10];
fr = fopen("testFile", "w");
fprintf(fr, "%s", "Papa Don't Preach");
fclose(fr);
fr = fopen("testFile", "r");
if(fr == NULL) {
perror("Error opening file");
return(-1);
}
fgets(str, 20, fr);
printf("%s\n", str);
fclose(fr);
remove("testFile");
return 0;
}
Вывод после выполнения вышеуказанных команд:
Program Begins:
fopen worked!
message sent
fclose worked!
message sent
fopen worked!
message sent
Papa Don't Preach
fclose worked!
message sent
remove worked!
message sent
Стандартный вывод должен иметь "fprintf работал!"но это не так.