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 
00126 INTERNAL int SYS_OpenFile(const char *pcFile, int flags, int mode)
00127 {
00128     return open(pcFile, flags, mode);
00129 }
00130 
00140 INTERNAL int SYS_CloseFile(int iHandle)
00141 {
00142     return close(iHandle);
00143 }
00144 
00154 INTERNAL int SYS_RemoveFile(const char *pcFile)
00155 {
00156     return remove(pcFile);
00157 }
00158 
00159 INTERNAL int SYS_Chmod(const char *path, int mode)
00160 {
00161     return chmod(path, mode);
00162 }
00163 
00164 INTERNAL int SYS_Chdir(const char *path)
00165 {
00166     return chdir(path);
00167 }
00168 
00169 INTERNAL int SYS_GetUID(void)
00170 {
00171     return getuid();
00172 }
00173 
00174 INTERNAL int SYS_GetGID(void)
00175 {
00176     return getgid();
00177 }
00178 
00179 INTERNAL int SYS_SeekFile(int iHandle, int iSeekLength)
00180 {
00181     int iOffset;
00182     iOffset = lseek(iHandle, iSeekLength, SEEK_SET);
00183     return iOffset;
00184 }
00185 
00186 INTERNAL int SYS_ReadFile(int iHandle, char *pcBuffer, int iLength)
00187 {
00188     return read(iHandle, pcBuffer, iLength);
00189 }
00190 
00191 INTERNAL int SYS_WriteFile(int iHandle, const char *pcBuffer, int iLength)
00192 {
00193     return write(iHandle, pcBuffer, iLength);
00194 }
00195 
00204 INTERNAL int SYS_GetPageSize(void)
00205 {
00206     static int size = -1;
00207 
00208     /* we use a cache to avoid a system call and improve perfs */
00209     if (-1 == size)
00210         size = getpagesize();
00211     return size;
00212 }
00213 
00224 INTERNAL void *SYS_MemoryMap(int iSize, int iFid, int iOffset)
00225 {
00226 
00227     void *vAddress;
00228 
00229     vAddress = 0;
00230     vAddress = mmap(0, iSize, PROT_READ | PROT_WRITE,
00231         MAP_SHARED, iFid, iOffset);
00232 
00233     /*
00234      * Here are some common error types: switch( errno ) { case EINVAL:
00235      * printf("EINVAL"); case EBADF: printf("EBADF"); break; case EACCES:
00236      * printf("EACCES"); break; case EAGAIN: printf("EAGAIN"); break; case
00237      * ENOMEM: printf("ENOMEM"); break; }
00238      */
00239 
00240     return vAddress;
00241 }
00242 
00252 /*@null@*/ INTERNAL void *SYS_PublicMemoryMap(int iSize, int iFid, int iOffset)
00253 {
00254 
00255     void *vAddress;
00256 
00257     vAddress = 0;
00258     vAddress = mmap(0, iSize, PROT_READ, MAP_SHARED, iFid, iOffset);
00259     if (vAddress == (void*)-1) /* mmap returns -1 on error */
00260     {
00261         Log2(PCSC_LOG_CRITICAL, "SYS_PublicMemoryMap() failed: %s",
00262             strerror(errno));
00263         vAddress = NULL;
00264     }
00265 
00266     return vAddress;
00267 }
00268 
00275 INTERNAL void SYS_PublicMemoryUnmap(void * ptr, int iSize)
00276 {
00277     (void)munmap(ptr, iSize);
00278 }
00279 
00290 INTERNAL int SYS_MMapSynchronize(void *begin, int length)
00291 {
00292     int flags = 0;
00293 
00294 #ifdef MS_INVALIDATE
00295     flags |= MS_INVALIDATE;
00296 #endif
00297     return msync(begin, length, MS_SYNC | flags);
00298 }
00299 
00300 INTERNAL int SYS_Fork(void)
00301 {
00302     return fork();
00303 }
00304 
00315 INTERNAL int SYS_Daemon(int nochdir, int noclose)
00316 {
00317 #ifdef HAVE_DAEMON
00318     return daemon(nochdir, noclose);
00319 #else
00320 
00321 #if defined(__SVR4) && defined(__sun)
00322     pid_t pid;
00323 
00324     pid = SYS_Fork();
00325     if (-1 == pid)
00326     {
00327         Log2(PCSC_LOG_CRITICAL, "main: SYS_Fork() failed: %s", strerror(errno));
00328         return -1;
00329     }
00330     else
00331     {
00332         if (pid != 0)
00333             /* the father exits */
00334             exit(0);
00335     }
00336 
00337     setsid();
00338 
00339     pid = SYS_Fork();
00340     if (-1 == pid)
00341     {
00342         Log2(PCSC_LOG_CRITICAL, "main: SYS_Fork() failed: %s", strerror(errno));
00343         exit(1);
00344     }
00345     else
00346     {
00347         if (pid != 0)
00348             /* the father exits */
00349             exit(0);
00350     }
00351 #else
00352     switch (SYS_Fork())
00353     {
00354     case -1:
00355         return (-1);
00356     case 0:
00357         break;
00358     default:
00359         return (0);
00360     }
00361 #endif
00362 
00363     if (!noclose) {
00364         if (SYS_CloseFile(0))
00365             Log2(PCSC_LOG_ERROR, "SYS_CloseFile(0) failed: %s",
00366                 strerror(errno));
00367 
00368         if (SYS_CloseFile(1))
00369             Log2(PCSC_LOG_ERROR, "SYS_CloseFile(1) failed: %s",
00370                 strerror(errno));
00371 
00372         if (SYS_CloseFile(2))
00373             Log2(PCSC_LOG_ERROR, "SYS_CloseFile(2) failed: %s",
00374                 strerror(errno));
00375     }
00376     if (!nochdir) {
00377         if (SYS_Chdir("/"))
00378             Log2(PCSC_LOG_ERROR, "SYS_Chdir() failed: %s", strerror(errno));
00379     }
00380     return 0;
00381 #endif
00382 }
00383 
00384 INTERNAL int SYS_Stat(const char *pcFile, struct stat *psStatus)
00385 {
00386     return stat(pcFile, psStatus);
00387 }
00388 
00389 INTERNAL int SYS_RandomInt(int fStart, int fEnd)
00390 {
00391     static int iInitialized = 0;
00392     int iRandNum = 0;
00393 
00394     if (0 == iInitialized)
00395     {
00396         srand(SYS_GetSeed());
00397         iInitialized = 1;
00398     }
00399 
00400     iRandNum = ((rand()+0.0)/RAND_MAX * (fEnd - fStart)) + fStart;
00401 
00402     return iRandNum;
00403 }
00404 
00405 INTERNAL int SYS_GetSeed(void)
00406 {
00407     struct timeval tv;
00408     struct timezone tz;
00409     long myseed = 0;
00410 
00411     tz.tz_minuteswest = 0;
00412     tz.tz_dsttime = 0;
00413     if (gettimeofday(&tv, &tz) == 0)
00414     {
00415         myseed = tv.tv_usec;
00416     } else
00417     {
00418         myseed = (long) time(NULL);
00419     }
00420     return myseed;
00421 }
00422 
00423 INTERNAL void SYS_Exit(int iRetVal)
00424 {
00425     _exit(iRetVal);
00426 }
00427 

Generated on Wed Jul 22 21:08:11 2009 for pcsc-lite by  doxygen 1.5.8