Files
foc/l4/tool/gendep/syscall.c
2013-01-11 17:00:47 +01:00

195 lines
4.8 KiB
C

/*
syscall.c -- override open(2)
(c) Han-Wen Nienhuys <hanwen@cs.uu.nl> 1998
(c) Jork Loeser <jork.loeser@inf.tu-dresden.de> 2002
(c) Michael Roitzsch <mroi@os.inf.tu-dresden.de> 2007
*/
#include <stdio.h>
#include <fcntl.h>
#include <stdarg.h>
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <unistd.h>
/* Assume GNU as target platform. We need this in dlfcn.h */
#define __USE_GNU
#include <dlfcn.h>
#include "gendep.h"
#ifdef __ELF__
# define OPEN __open
# define OPEN64 __open64
# define FOPEN __fopen
# define FOPEN64 __fopen64
# define UNLINK __unlink
#else
# define OPEN open
# define OPEN64 open64
# define FOPEN fopen
# define FOPEN64 fopen64
# define UNLINK unlink
#endif
#define VERBOSE 0 /* set to 1 to log open/unlink calls */
/* ----------------------------------------------------------------------- */
/*
This breaks if we hook gendep onto another library that overrides open(2).
(zlibc comes to mind)
*/
static int real_open (const char *fn, int flags, int mode)
{
if(VERBOSE) printf("real_open(%s)\n", fn);
return (syscall(SYS_open, (fn), (flags), (mode)));
}
int OPEN(const char *fn, int flags, ...)
{
int rv ;
va_list p;
va_start (p,flags);
if(VERBOSE) printf("open(%s) called\n", fn);
rv = real_open (fn, flags, va_arg (p, int));
if (rv >=0)
gendep__register_open (fn, flags);
return rv;
}
/* ----------------------------------------------------------------------- */
typedef int(*open64_type)(const char*, int flag, int mode);
static int real_open64(const char*path, int flag, int mode){
static open64_type f_open64;
if(VERBOSE) printf("real_open64(%s)\n", path);
if(f_open64==0){
*(void**)(&f_open64) = dlsym(RTLD_NEXT, "open64");
if(!f_open64){
fprintf(stderr, "gendep: Cannot resolve open64()\n");
errno=ENOENT;
return 0;
}
}
return f_open64(path, flag, mode);
}
int OPEN64(const char*path, int flag, int mode){
int f;
if(VERBOSE) printf("open64(%s)\n", path);
f = real_open64(path, flag, mode);
if(f>=0){
gendep__register_open(path, flag);
}
return f;
}
/* ----------------------------------------------------------------------- */
typedef FILE* (*fopen_type)(const char*, const char*);
static FILE* real_fopen(const char*path, const char*mode){
static fopen_type f_fopen;
if(VERBOSE) printf("real_fopen(%s)\n", path);
if(f_fopen==0){
*(void**)(&f_fopen) = dlsym(RTLD_NEXT, "fopen");
if(!f_fopen){
fprintf(stderr, "gendep: Cannot resolve fopen()\n");
errno=ENOENT;
return 0;
}
}
return f_fopen(path, mode);
}
FILE* FOPEN(const char*path, const char*mode){
FILE *f;
int binmode;
if(VERBOSE) printf("fopen(%s)\n", path);
f = real_fopen(path, mode);
if(f){
if(strchr(mode, 'w') || strchr(mode, 'a')){
binmode=O_WRONLY;
} else {
binmode=O_RDONLY;
}
gendep__register_open(path, binmode);
}
return f;
}
/* ----------------------------------------------------------------------- */
typedef FILE* (*fopen64_type)(const char*, const char*);
static FILE* real_fopen64(const char*path, const char*mode){
static fopen64_type f_fopen64;
if(VERBOSE) printf("real_fopen64(%s)\n", path);
if(f_fopen64==0){
*(void**)(&f_fopen64) = dlsym(RTLD_NEXT, "fopen64");
if(!f_fopen64){
fprintf(stderr, "gendep: Cannot resolve fopen64()\n");
errno=ENOENT;
return 0;
}
}
return f_fopen64(path, mode);
}
FILE* FOPEN64(const char*path, const char*mode){
FILE *f;
int binmode;
if(VERBOSE) printf("fopen64(%s)\n", path);
f = real_fopen64(path, mode);
if(f){
if(strchr(mode, 'w') || strchr(mode, 'a')){
binmode=O_WRONLY;
} else {
binmode=O_RDONLY;
}
gendep__register_open(path, binmode);
}
return f;
}
/* ----------------------------------------------------------------------- */
static int real_unlink (const char *fn)
{
if(VERBOSE) printf("real_unlink(%s)\n", fn);
return syscall(SYS_unlink, (fn));
}
int UNLINK(const char *fn)
{
int rv ;
if(VERBOSE) printf("unlink(%s)\n", fn);
rv = real_unlink (fn);
if (rv >=0)
gendep__register_unlink (fn);
return rv;
}
/* ----------------------------------------------------------------------- */
#ifdef __ELF__
int open (const char *fn, int flags, ...) __attribute__ ((alias ("__open")));
int open64 (const char *fn, int flags, ...) __attribute__ ((alias ("__open64")));
int unlink(const char *fn) __attribute__ ((alias ("__unlink")));
FILE *fopen (const char *path, const char *mode) __attribute__ ((alias ("__fopen")));
FILE *fopen64 (const char *path, const char *mode) __attribute__ ((alias ("__fopen64")));
#endif