pcsc-lite 1.5.5
|
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