sys_unix.c

Go to the documentation of this file.
00001 /*
00002  * This handles abstract system level calls.
00003  *
00004  * MUSCLE SmartCard Development ( http://www.linuxnet.com )
00005  *
00006  * Copyright (C) 1999
00007  *  David Corcoran <corcoran@linuxnet.com>
00008  *
00009  * $Id: sys_unix.c 3259 2009-01-02 14:32:44Z rousseau $
00010  */
00011 
00017 #include "config.h"
00018 #include <sys/types.h>
00019 #include <sys/mman.h>
00020 #include <sys/stat.h>
00021 #include <sys/wait.h>
00022 #include <sys/time.h>
00023 #include <sys/file.h>
00024 #include <fcntl.h>
00025 #include <errno.h>
00026 #include <unistd.h>
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 #include <signal.h>
00031 #include <time.h>
00032 
00033 #include "misc.h"
00034 #include "sys_generic.h"
00035 #include "debug.h"
00036 
00043 INTERNAL int SYS_Initialize(void)
00044 {
00045     /*
00046      * Nothing special
00047      */
00048     return 0;
00049 }
00050 
00061 INTERNAL int SYS_Mkdir(const char *path, int perms)
00062 {
00063     return mkdir(path, perms);
00064 }
00065 
00071 INTERNAL int SYS_GetPID(void)
00072 {
00073     return getpid();
00074 }
00075 
00081 INTERNAL int SYS_Sleep(int iTimeVal)
00082 {
00083 #ifdef HAVE_NANOSLEEP
00084     struct timespec mrqtp;
00085     mrqtp.tv_sec = iTimeVal;
00086     mrqtp.tv_nsec = 0;
00087 
00088     return nanosleep(&mrqtp, NULL);
00089 #else
00090     return sleep(iTimeVal);
00091 #endif
00092 }
00093 
00099 INTERNAL int SYS_USleep(int iTimeVal)
00100 {
00101 #ifdef HAVE_NANOSLEEP
00102     struct timespec mrqtp;
00103     mrqtp.tv_sec = iTimeVal/1000000;
00104     mrqtp.tv_nsec = (iTimeVal - (mrqtp.tv_sec * 1000000)) * 1000;
00105 
00106     return nanosleep(&mrqtp, NULL);
00107 #else
00108     struct timeval tv;
00109     tv.tv_sec  = iTimeVal/1000000;
00110     tv.tv_usec = iTimeVal - (tv.tv_sec * 1000000);
00111     return select(0, NULL, NULL, NULL, &tv);
00112 #endif
00113 }
00114 
00127 INTERNAL int SYS_OpenFile(const char *pcFile, int flags, int mode)
00128 {
00129     int fd = open(pcFile, flags, mode);
00130     fcntl(fd, F_SETFD, FD_CLOEXEC);
00131     return fd;
00132 }
00133 
00143 INTERNAL int SYS_CloseFile(int iHandle)
00144 {
00145     return close(iHandle);
00146 }
00147 
00157 INTERNAL int SYS_RemoveFile(const char *pcFile)
00158 {
00159     return remove(pcFile);
00160 }
00161 
00162 INTERNAL int SYS_Chmod(const char *path, int mode)
00163 {
00164     return chmod(path, mode);
00165 }
00166 
00167 INTERNAL int SYS_Chdir(const char *path)
00168 {
00169     return chdir(path);
00170 }
00171 
00172 INTERNAL int SYS_GetUID(void)
00173 {
00174     return getuid();
00175 }
00176 
00177 INTERNAL int SYS_GetGID(void)
00178 {
00179     return getgid();
00180 }
00181 
00182 INTERNAL int SYS_SeekFile(int iHandle, int iSeekLength)
00183 {
00184     int iOffset;
00185     iOffset = lseek(iHandle, iSeekLength, SEEK_SET);
00186     return iOffset;
00187 }
00188 
00189 INTERNAL int SYS_ReadFile(int iHandle, char *pcBuffer, int iLength)
00190 {
00191     return read(iHandle, pcBuffer, iLength);
00192 }
00193 
00194 INTERNAL int SYS_WriteFile(int iHandle, const char *pcBuffer, int iLength)
00195 {
00196     return write(iHandle, pcBuffer, iLength);
00197 }
00198 
00207 INTERNAL int SYS_GetPageSize(void)
00208 {
00209     static int size = -1;
00210 
00211     /* we use a cache to avoid a system call and improve perfs */
00212     if (-1 == size)
00213         size = getpagesize();
00214     return size;
00215 }
00216 
00227 INTERNAL void *SYS_MemoryMap(int iSize, int iFid, int iOffset)
00228 {
00229 
00230     void *vAddress;
00231 
00232     vAddress = 0;
00233     vAddress = mmap(0, iSize, PROT_READ | PROT_WRITE,
00234         MAP_SHARED, iFid, iOffset);
00235 
00236     /*
00237      * Here are some common error types: switch( errno ) { case EINVAL:
00238      * printf("EINVAL"); case EBADF: printf("EBADF"); break; case EACCES:
00239      * printf("EACCES"); break; case EAGAIN: printf("EAGAIN"); break; case
00240      * ENOMEM: printf("ENOMEM"); break; }
00241      */
00242 
00243     return vAddress;
00244 }
00245 
00255 /*@null@*/ INTERNAL void *SYS_PublicMemoryMap(int iSize, int iFid, int iOffset)
00256 {
00257 
00258     void *vAddress;
00259 
00260     vAddress = 0;
00261     vAddress = mmap(0, iSize, PROT_READ, MAP_SHARED, iFid, iOffset);
00262     if (vAddress == (void*)-1) /* mmap returns -1 on error */
00263     {
00264         Log2(PCSC_LOG_CRITICAL, "SYS_PublicMemoryMap() failed: %s",
00265             strerror(errno));
00266         vAddress = NULL;
00267     }
00268 
00269     return vAddress;
00270 }
00271 
00278 INTERNAL void SYS_PublicMemoryUnmap(void * ptr, int iSize)
00279 {
00280     (void)munmap(ptr, iSize);
00281 }
00282 
00293 INTERNAL int SYS_MMapSynchronize(void *begin, int length)
00294 {
00295     int flags = 0;
00296 
00297 #ifdef MS_INVALIDATE
00298     flags |= MS_INVALIDATE;
00299 #endif
00300     return msync(begin, length, MS_SYNC | flags);
00301 }
00302 
00303 INTERNAL int SYS_Fork(void)
00304 {
00305     return fork();
00306 }
00307 
00318 INTERNAL int SYS_Daemon(int nochdir, int noclose)
00319 {
00320 #ifdef HAVE_DAEMON
00321     return daemon(nochdir, noclose);
00322 #else
00323 
00324 #if defined(__SVR4) && defined(__sun)
00325     pid_t pid;
00326 
00327     pid = SYS_Fork();
00328     if (-1 == pid)
00329     {
00330         Log2(PCSC_LOG_CRITICAL, "main: SYS_Fork() failed: %s", strerror(errno));
00331         return -1;
00332     }
00333     else
00334     {
00335         if (pid != 0)
00336             /* the father exits */
00337             exit(0);
00338     }
00339 
00340     setsid();
00341 
00342     pid = SYS_Fork();
00343     if (-1 == pid)
00344     {
00345         Log2(PCSC_LOG_CRITICAL, "main: SYS_Fork() failed: %s", strerror(errno));
00346         exit(1);
00347     }
00348     else
00349     {
00350         if (pid != 0)
00351             /* the father exits */
00352             exit(0);
00353     }
00354 #else
00355     switch (SYS_Fork())
00356     {
00357     case -1:
00358         return (-1);
00359     case 0:
00360         break;
00361     default:
00362         return (0);
00363     }
00364 #endif
00365 
00366     if (!noclose) {
00367         if (SYS_CloseFile(0))
00368             Log2(PCSC_LOG_ERROR, "SYS_CloseFile(0) failed: %s",
00369                 strerror(errno));
00370 
00371         if (SYS_CloseFile(1))
00372             Log2(PCSC_LOG_ERROR, "SYS_CloseFile(1) failed: %s",
00373                 strerror(errno));
00374 
00375         if (SYS_CloseFile(2))
00376             Log2(PCSC_LOG_ERROR, "SYS_CloseFile(2) failed: %s",
00377                 strerror(errno));
00378     }
00379     if (!nochdir) {
00380         if (SYS_Chdir("/"))
00381             Log2(PCSC_LOG_ERROR, "SYS_Chdir() failed: %s", strerror(errno));
00382     }
00383     return 0;
00384 #endif
00385 }
00386 
00387 INTERNAL int SYS_Stat(const char *pcFile, struct stat *psStatus)
00388 {
00389     return stat(pcFile, psStatus);
00390 }
00391 
00392 INTERNAL int SYS_RandomInt(int fStart, int fEnd)
00393 {
00394     static int iInitialized = 0;
00395     int iRandNum = 0;
00396 
00397     if (0 == iInitialized)
00398     {
00399         srand(SYS_GetSeed());
00400         iInitialized = 1;
00401     }
00402 
00403     iRandNum = ((rand()+0.0)/RAND_MAX * (fEnd - fStart)) + fStart;
00404 
00405     return iRandNum;
00406 }
00407 
00408 INTERNAL int SYS_GetSeed(void)
00409 {
00410     struct timeval tv;
00411     struct timezone tz;
00412     long myseed = 0;
00413 
00414     tz.tz_minuteswest = 0;
00415     tz.tz_dsttime = 0;
00416     if (gettimeofday(&tv, &tz) == 0)
00417     {
00418         myseed = tv.tv_usec;
00419     } else
00420     {
00421         myseed = (long) time(NULL);
00422     }
00423     return myseed;
00424 }
00425 
00426 INTERNAL void SYS_Exit(int iRetVal)
00427 {
00428     _exit(iRetVal);
00429 }
00430 

Generated on Mon Aug 17 01:00:11 2009 for pcsc-lite by  doxygen 1.5.9