Go to the documentation of this file.
33 #define MAXSYSLOGBUF 256
41 vsyslog(priority, fmt, ap);
53 ssize_t
safe_read(
int filedes,
void *buffer,
size_t size)
56 ssize_t p = read(filedes, buffer, size);
57 if (p < 0 && errno == EINTR) {
58 dsyslog(
"EINTR while reading from file handle %d - retrying", filedes);
65 ssize_t
safe_write(
int filedes,
const void *buffer,
size_t size)
68 ssize_t written = size;
69 const unsigned char *ptr = (
const unsigned char *)buffer;
71 p = write(filedes, ptr, size);
74 dsyslog(
"EINTR while writing to file handle %d - retrying", filedes);
82 return p < 0 ? p : written;
94 int w = write(fd, Data + written, Length);
103 Poller.
Poll(RetryMs);
104 if (TimeoutMs > 0 && (TimeoutMs -= t.
Elapsed()) <= 0)
117 int l =
max(dest ? strlen(dest) : 0, strlen(src)) + 1;
118 dest = (
char *)realloc(dest, l);
122 esyslog(
"ERROR: out of memory");
131 char *
strn0cpy(
char *dest,
const char *src,
size_t n)
134 for ( ; --n && (*dest = *src) != 0; dest++, src++) ;
154 char *p = strstr(s, s1);
161 if (
char *NewBuffer = (
char *)realloc(s, l + l2 - l1 + 1))
164 esyslog(
"ERROR: out of memory");
170 memmove(sof + l2, sof + l1, l - of - l1 + 1);
171 strncpy(sof, s2, l2);
176 const char *
strchrn(
const char *s,
char c,
size_t n)
182 if (*s == c && --n == 0)
204 for (
char *p = s + strlen(s) - 1; p >= s; p--) {
221 memmove(p + 1, q, strlen(q) + 1);
225 memmove(s, t, strlen(t) + 1);
241 else if (t != s && n == 0) {
260 if (strchr(chars, *p)) {
262 buffer =
MALLOC(
char, 2 * strlen(s) + 1);
263 t = buffer + (p - s);
264 s = strcpy(buffer, s);
280 int l = strlen(name);
282 while (
const char *p = strstr(t, name)) {
284 if (p == s || *(p - 1) <=
' ') {
304 memmove(s, s + n, l - n + 1);
322 const char *se = s + strlen(s) - 1;
323 const char *pe = p + strlen(p) - 1;
325 if (*pe-- != *se-- || (se < s && pe >= p))
360 int64_t n = strtoll(s, &t, 10);
376 if (strcmp(*a, s) == 0)
386 if (*FileName ==
'/')
388 return cString::sprintf(
"%s/%s", DirName && *DirName ? DirName :
".", FileName);
391 #define DECIMAL_POINT_C '.'
395 static lconv *loc = localeconv();
397 char buf[strlen(s) + 1];
401 *p = *loc->decimal_point;
416 static lconv *loc = localeconv();
418 snprintf(buf,
sizeof(buf), Format, d);
427 snprintf(buf,
sizeof(buf),
"%d", n);
434 if (stat(File1, &st) == 0) {
435 dev_t dev1 = st.st_dev;
436 if (stat(File2, &st) == 0)
437 return st.st_dev == dev1;
451 struct statfs statFs;
452 if (statfs(Directory, &statFs) == 0) {
453 double blocksPerMeg = 1024.0 * 1024.0 / statFs.f_bsize;
455 *UsedMB = int((statFs.f_blocks - statFs.f_bfree) / blocksPerMeg);
456 Free = int(statFs.f_bavail / blocksPerMeg);
466 if (stat(DirName, &ds) == 0) {
467 if (S_ISDIR(ds.st_mode)) {
468 if (access(DirName, R_OK | W_OK | X_OK) == 0)
471 esyslog(
"ERROR: can't access %s", DirName);
474 esyslog(
"ERROR: %s is not a directory", DirName);
481 bool MakeDirs(
const char *FileName,
bool IsDirectory)
484 char *s = strdup(FileName);
488 while ((p = strchr(p,
'/')) != NULL || IsDirectory) {
492 if (stat(s, &fs) != 0 || !S_ISDIR(fs.st_mode)) {
493 dsyslog(
"creating directory %s", s);
494 if (mkdir(s, ACCESSPERMS) == -1) {
512 if (stat(FileName, &st) == 0) {
513 if (S_ISDIR(st.st_mode)) {
517 while ((e = d.
Next()) != NULL) {
519 if (FollowSymlinks) {
521 if (lstat(buffer, &st2) == 0) {
522 if (S_ISLNK(st2.st_mode)) {
523 int size = st2.st_size + 1;
524 char *l =
MALLOC(
char, size);
525 int n = readlink(buffer, l, size - 1);
539 else if (errno != ENOENT) {
544 dsyslog(
"removing %s", *buffer);
545 if (remove(buffer) < 0)
554 dsyslog(
"removing %s", FileName);
555 if (remove(FileName) < 0) {
560 else if (errno != ENOENT) {
569 bool HasIgnoredFiles =
false;
574 while ((e = d.
Next()) != NULL) {
575 if (strcmp(e->d_name,
"lost+found")) {
578 if (stat(buffer, &st) == 0) {
579 if (S_ISDIR(st.st_mode)) {
583 else if (RemoveThis && IgnoreFiles &&
StrInArray(IgnoreFiles, e->d_name))
584 HasIgnoredFiles =
true;
594 if (RemoveThis && empty) {
595 if (HasIgnoredFiles) {
596 while (*IgnoreFiles) {
598 if (access(buffer, F_OK) == 0) {
599 dsyslog(
"removing %s", *buffer);
600 if (remove(buffer) < 0) {
608 dsyslog(
"removing %s", DirName);
609 if (remove(DirName) < 0) {
627 while (size >= 0 && (e = d.
Next()) != NULL) {
630 if (stat(buffer, &st) == 0) {
631 if (S_ISDIR(st.st_mode)) {
648 else if (errno != ENOENT)
657 char *TargetName = canonicalize_file_name(FileName);
660 TargetName = strdup(FileName);
669 for (
int n = 0; n < 10; n++) {
675 if (access(buf, F_OK) != 0) {
677 gettimeofday(&tp1, NULL);
678 int f = open(buf, O_WRONLY | O_CREAT, DEFFILEMODE);
681 if (fdatasync(f) < 0)
685 gettimeofday(&tp2, NULL);
686 double seconds = (((
long long)tp2.tv_sec * 1000000 + tp2.tv_usec) - ((
long long)tp1.tv_sec * 1000000 + tp1.tv_usec)) / 1000000.0;
688 dsyslog(
"SpinUpDisk took %.2f seconds", seconds);
695 esyslog(
"ERROR: SpinUpDisk failed");
701 if (utime(FileName, NULL) == -1 && errno != ENOENT)
708 if (stat(FileName, &fs) == 0)
716 if (stat(FileName, &fs) == 0)
733 #if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK)
734 #define MIN_RESOLUTION 5 // ms
735 static bool initialized =
false;
736 static bool monotonic =
false;
740 if (clock_getres(CLOCK_MONOTONIC, &tp) == 0) {
741 long Resolution = tp.tv_nsec;
743 if (tp.tv_sec == 0 && tp.tv_nsec <= MIN_RESOLUTION * 1000000) {
744 if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
745 dsyslog(
"cTimeMs: using monotonic clock (resolution is %ld ns)", Resolution);
749 esyslog(
"cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed");
752 dsyslog(
"cTimeMs: not using monotonic clock - resolution is too bad (%ld s %ld ns)", tp.tv_sec, tp.tv_nsec);
755 esyslog(
"cTimeMs: clock_getres(CLOCK_MONOTONIC) failed");
759 if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
760 return (uint64_t(tp.tv_sec)) * 1000 + tp.tv_nsec / 1000000;
761 esyslog(
"cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed");
766 # warning Posix monotonic clock not available
769 if (gettimeofday(&t, NULL) == 0)
770 return (uint64_t(t.tv_sec)) * 1000 + t.tv_usec / 1000;
797 #define MT(s, m, v) ((*(s) & (m)) == (v)) // Mask Test
798 if (
MT(s, 0xE0, 0xC0) &&
MT(s + 1, 0xC0, 0x80))
800 if (
MT(s, 0xF0, 0xE0) &&
MT(s + 1, 0xC0, 0x80) &&
MT(s + 2, 0xC0, 0x80))
802 if (
MT(s, 0xF8, 0xF0) &&
MT(s + 1, 0xC0, 0x80) &&
MT(s + 2, 0xC0, 0x80) &&
MT(s + 3, 0xC0, 0x80))
814 case 2:
return ((*s & 0x1F) << 6) | (*(s + 1) & 0x3F);
815 case 3:
return ((*s & 0x0F) << 12) | ((*(s + 1) & 0x3F) << 6) | (*(s + 2) & 0x3F);
816 case 4:
return ((*s & 0x07) << 18) | ((*(s + 1) & 0x3F) << 12) | ((*(s + 2) & 0x3F) << 6) | (*(s + 3) & 0x3F);
831 *s++ = ((c >> 6) & 0x1F) | 0xC0;
832 *s = (c & 0x3F) | 0x80;
838 *s++ = ((c >> 12) & 0x0F) | 0xE0;
839 *s++ = ((c >> 6) & 0x3F) | 0x80;
840 *s = (c & 0x3F) | 0x80;
846 *s++ = ((c >> 18) & 0x07) | 0xF0;
847 *s++ = ((c >> 12) & 0x3F) | 0x80;
848 *s++ = ((c >> 6) & 0x3F) | 0x80;
849 *s = (c & 0x3F) | 0x80;
861 while (*s && Symbols--) {
903 while (*s && --Size > 0) {
905 *a++ = (
uchar)(*s++);
922 while (*a && NumChars < Size) {
923 if (Max >= 0 && NumSyms++ >= Max)
931 if (NumChars + sl <= Size) {
956 cd = iconv_open(ToCode, FromCode);
964 if (
cd != (iconv_t)-1)
972 if (!strcasestr(CharacterTable,
"UTF-8")) {
975 for (
int i = 0; i < 128; i++)
979 const char *s = csc.
Convert(buf);
993 if (
cd != (iconv_t)-1 && From && *From) {
994 char *FromPtr = (
char *)From;
995 size_t FromLength = strlen(From);
998 int NewLength =
max(
length, FromLength * 2);
999 if (
char *NewBuffer = (
char *)realloc(
result, NewLength)) {
1004 esyslog(
"ERROR: out of memory");
1013 char *Converted = ToPtr;
1014 while (FromLength > 0) {
1015 if (iconv(
cd, &FromPtr, &FromLength, &ToPtr, &ToLength) ==
size_t(-1)) {
1016 if (errno == E2BIG || errno == EILSEQ && ToLength < 1) {
1020 size_t d = ToPtr -
result;
1022 int NewLength =
length + r;
1023 if (
char *NewBuffer = (
char *)realloc(
result, NewLength)) {
1025 Converted =
result = NewBuffer;
1028 esyslog(
"ERROR: out of memory");
1034 if (errno == EILSEQ) {
1041 else if (errno != E2BIG)
1055 s = TakePointer ? (
char *)S : S ? strdup(S) : NULL;
1074 s = String.
s ? strdup(String.
s) : NULL;
1084 if (
this == &String)
1087 s = String.
s ? strdup(String.
s) : NULL;
1096 s = String ? strdup(String) : NULL;
1103 int l2 = strlen(String);
1104 char *p = (
char *)realloc(
s, l1 + l2 + 1);
1107 strcpy(p + l1, String);
1116 if (Index >= 0 && Index < l)
1132 if (!fmt || vasprintf(&buffer, fmt, ap) < 0) {
1133 esyslog(
"error in vasprintf('%s', ...)", fmt);
1134 buffer = strdup(
"???");
1143 if (!fmt || vasprintf(&buffer, fmt, ap) < 0) {
1144 esyslog(
"error in vasprintf('%s', ...)", fmt);
1145 buffer = strdup(
"???");
1153 WeekDay = WeekDay == 0 ? 6 : WeekDay - 1;
1154 if (0 <= WeekDay && WeekDay <= 6) {
1156 const char *day =
tr(
"MonTueWedThuFriSatSun");
1168 return WeekDayName(localtime_r(&t, &tm_r)->tm_wday);
1173 WeekDay = WeekDay == 0 ? 6 : WeekDay - 1;
1175 case 0:
return tr(
"Monday");
1176 case 1:
return tr(
"Tuesday");
1177 case 2:
return tr(
"Wednesday");
1178 case 3:
return tr(
"Thursday");
1179 case 4:
return tr(
"Friday");
1180 case 5:
return tr(
"Saturday");
1181 case 6:
return tr(
"Sunday");
1182 default:
return "???";
1198 tm *tm = localtime_r(&t, &tm_r);
1199 snprintf(buffer,
sizeof(buffer),
"%s %02d.%02d. %02d:%02d", *
WeekDayName(tm->tm_wday), tm->tm_mday, tm->tm_mon + 1, tm->tm_hour, tm->tm_min);
1206 if (ctime_r(&t, buffer)) {
1207 buffer[strlen(buffer) - 1] = 0;
1217 tm *tm = localtime_r(&t, &tm_r);
1220 strftime(p,
sizeof(buf) - (p - buf),
"%d.%m.%Y", tm);
1228 tm *tm = localtime_r(&t, &tm_r);
1229 strftime(buf,
sizeof(buf),
"%d.%m.%y", tm);
1237 strftime(buf,
sizeof(buf),
"%R", localtime_r(&t, &tm_r));
1243 #define JPEGCOMPRESSMEM 500000
1263 int Used = jcd->
size;
1265 if (
uchar *NewBuffer = (
uchar *)realloc(jcd->
mem, NewSize)) {
1266 jcd->
size = NewSize;
1267 jcd->
mem = NewBuffer;
1270 esyslog(
"ERROR: out of memory");
1274 cinfo->dest->next_output_byte = jcd->
mem + Used;
1275 cinfo->dest->free_in_buffer = jcd->
size - Used;
1286 int Used = cinfo->dest->next_output_byte - jcd->
mem;
1287 if (Used < jcd->size) {
1290 jcd->
mem = NewBuffer;
1293 esyslog(
"ERROR: out of memory");
1302 else if (Quality > 100)
1305 jpeg_destination_mgr jdm;
1311 struct jpeg_compress_struct cinfo;
1312 struct jpeg_error_mgr jerr;
1313 cinfo.err = jpeg_std_error(&jerr);
1314 jpeg_create_compress(&cinfo);
1317 cinfo.client_data = &jcd;
1318 cinfo.image_width = Width;
1319 cinfo.image_height = Height;
1320 cinfo.input_components = 3;
1321 cinfo.in_color_space = JCS_RGB;
1323 jpeg_set_defaults(&cinfo);
1324 jpeg_set_quality(&cinfo, Quality,
true);
1325 jpeg_start_compress(&cinfo,
true);
1328 JSAMPROW rp[Height];
1329 for (
int k = 0; k < Height; k++)
1330 rp[k] = &Mem[rs * k];
1331 jpeg_write_scanlines(&cinfo, rp, Height);
1332 jpeg_finish_compress(&cinfo);
1333 jpeg_destroy_compress(&cinfo);
1343 static char buffer[HOST_NAME_MAX] =
"";
1345 if (gethostname(buffer,
sizeof(buffer)) < 0) {
1347 strcpy(buffer,
"vdr");
1355 const char *
cBase64Encoder::b64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1378 c |= (
data[
i] >> 4) & 0x0F;
1381 c = (
data[
i] << 2) & 0x3F;
1383 c |= (
data[
i] >> 6) & 0x03;
1482 Add(FileHandle, Out);
1487 if (FileHandle >= 0) {
1489 if (
pfd[i].fd == FileHandle &&
pfd[i].events == (Out ? POLLOUT : POLLIN))
1499 esyslog(
"ERROR: too many file handles in cPoller");
1506 if (FileHandle >= 0) {
1508 if (
pfd[i].fd == FileHandle &&
pfd[i].events == (Out ? POLLOUT : POLLIN)) {
1543 #if !__GLIBC_PREREQ(2, 24) // readdir_r() is deprecated as of GLIBC 2.24
1548 if (strcmp(
result->d_name,
".") && strcmp(
result->d_name,
".."))
1564 for (
int i = 0; i < Size(); i++) {
1565 if (!strcmp(s, At(i)))
1573 for (
int i = 0; i < Size(); i++)
1583 Load(Directory, DirsOnly);
1593 while ((e =
d.Next()) != NULL) {
1596 if (stat(
AddDirectory(Directory, e->d_name), &ds) == 0) {
1597 if (!S_ISDIR(ds.st_mode))
1601 Append(strdup(e->d_name));
1630 return Open(open(FileName, Flags, Mode));
1631 esyslog(
"ERROR: attempt to re-open %s", FileName);
1641 if (f < FD_SETSIZE) {
1647 esyslog(
"ERROR: file descriptor %d already in files[]", f);
1651 esyslog(
"ERROR: file descriptor %d is larger than FD_SETSIZE (%d)", f, FD_SETSIZE);
1655 esyslog(
"ERROR: attempt to re-open file descriptor %d", FileDes);
1671 return f >= 0 && AnyFileReady(f, Wait ? 1000 : 0);
1678 for (
int i = 0; i < maxFiles; i++) {
1682 if (0 <= FileDes && FileDes < FD_SETSIZE && !files[FileDes])
1683 FD_SET(FileDes, &set);
1686 struct timeval timeout;
1687 timeout.tv_sec = TimeoutMs / 1000;
1688 timeout.tv_usec = (TimeoutMs % 1000) * 1000;
1689 return select(FD_SETSIZE, &set, NULL, NULL, &timeout) > 0 && (FileDes < 0 || FD_ISSET(FileDes, &set));
1695 struct timeval timeout;
1697 FD_SET(FileDes, &set);
1698 if (TimeoutMs >= 0) {
1699 if (TimeoutMs < 100)
1701 timeout.tv_sec = TimeoutMs / 1000;
1702 timeout.tv_usec = (TimeoutMs % 1000) * 1000;
1704 return select(FD_SETSIZE, &set, NULL, NULL, (TimeoutMs >= 0) ? &timeout : NULL) > 0 && FD_ISSET(FileDes, &set);
1710 struct timeval timeout;
1712 FD_SET(FileDes, &set);
1713 if (TimeoutMs < 100)
1716 timeout.tv_usec = TimeoutMs * 1000;
1717 return select(FD_SETSIZE, NULL, &set, NULL, &timeout) > 0 && FD_ISSET(FileDes, &set);
1726 tempName = fileName ?
MALLOC(
char, strlen(fileName) + 5) : NULL;
1728 strcat(strcpy(tempName, fileName),
".$$$");
1742 if (!f && fileName && tempName) {
1743 f = fopen(tempName,
"w");
1754 if (ferror(f) != 0) {
1760 if (fclose(f) < 0) {
1765 if (
result && rename(tempName, fileName) < 0) {
1777 #ifndef USE_FADVISE_READ
1778 #define USE_FADVISE_READ 0
1780 #ifndef USE_FADVISE_WRITE
1781 #define USE_FADVISE_WRITE 1
1784 #define WRITE_BUFFER KILOBYTE(800)
1799 fd = open(FileName, Flags, Mode);
1801 #if USE_FADVISE_READ || USE_FADVISE_WRITE
1802 begin = lastpos = ahead = 0;
1809 posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM);
1817 #if USE_FADVISE_READ || USE_FADVISE_WRITE
1820 posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
1824 return close(OldFd);
1835 #define FADVGRAN KILOBYTE(4) // AKA fadvise-chunk-size; PAGE_SIZE or getpagesize(2) would also work.
1836 #define READCHUNK MEGABYTE(8)
1846 return posix_fadvise(fd, Offset - (
FADVGRAN - 1), Len + (
FADVGRAN - 1) * 2, POSIX_FADV_DONTNEED);
1851 if (Whence == SEEK_SET && Offset == curpos)
1853 curpos = lseek(fd, Offset, Whence);
1860 #if USE_FADVISE_READ
1861 off_t jumped = curpos-lastpos;
1862 if ((cachedstart < cachedend) && (curpos < cachedstart || curpos > cachedend)) {
1864 FadviseDrop(cachedstart, cachedend-cachedstart);
1865 cachedstart = curpos;
1868 cachedstart =
min(cachedstart, curpos);
1870 ssize_t bytesRead =
safe_read(fd, Data, Size);
1871 if (bytesRead > 0) {
1872 curpos += bytesRead;
1873 #if USE_FADVISE_READ
1874 cachedend =
max(cachedend, curpos);
1878 if (jumped >= 0 && jumped <= (off_t)readahead) {
1882 if (ahead - curpos < (off_t)(readahead / 2)) {
1883 posix_fadvise(fd, curpos, readahead, POSIX_FADV_WILLNEED);
1884 ahead = curpos + readahead;
1885 cachedend =
max(cachedend, ahead);
1887 if (readahead < Size * 32) {
1888 readahead = Size * 32;
1895 #if USE_FADVISE_READ
1896 if (cachedstart < cachedend) {
1897 if (curpos - cachedstart >
READCHUNK * 2) {
1899 FadviseDrop(cachedstart, curpos -
READCHUNK - cachedstart);
1902 else if (cachedend > ahead && cachedend - curpos >
READCHUNK * 2) {
1918 ssize_t bytesWritten =
safe_write(fd, Data, Size);
1919 #if USE_FADVISE_WRITE
1920 if (bytesWritten > 0) {
1921 begin =
min(begin, curpos);
1922 curpos += bytesWritten;
1923 written += bytesWritten;
1924 lastpos =
max(lastpos, curpos);
1926 if (lastpos > begin) {
1936 posix_fadvise(fd, begin - headdrop, lastpos - begin + headdrop, POSIX_FADV_DONTNEED);
1938 begin = lastpos = curpos;
1939 totwritten += written;
1954 off_t headdrop =
min(off_t(curpos - totwritten), off_t(totwritten * 2));
1955 posix_fadvise(fd, curpos - totwritten - headdrop, totwritten + headdrop, POSIX_FADV_DONTNEED);
1961 return bytesWritten;
1969 if (File->
Open(FileName, Flags, Mode) < 0) {
1978 #define LOCKFILENAME ".lock-vdr"
1979 #define LOCKFILESTALETIME 600 // seconds before considering a lock file "stale"
1997 if (f < 0 && fileName) {
1998 time_t Timeout = time(NULL) + WaitSeconds;
2000 f = open(fileName, O_WRONLY | O_CREAT | O_EXCL, DEFFILEMODE);
2002 if (errno == EEXIST) {
2004 if (stat(fileName, &fs) == 0) {
2006 esyslog(
"ERROR: removing stale lock file '%s'", fileName);
2007 if (remove(fileName) < 0) {
2014 else if (errno != ENOENT) {
2026 }
while (f < 0 && time(NULL) < Timeout);
2054 Object->
prev =
this;
2060 Object->
next =
this;
2086 #define LIST_GARBAGE_COLLECTOR_TIMEOUT 5 // seconds
2099 esyslog(
"ERROR: ListGarbageCollector destroyed without prior Purge()!");
2105 Object->
next = objects;
2107 lastPut = time(NULL);
2120 objects = Object->next;
2130 :stateLock(NeedsLocking)
2148 esyslog(
"ERROR: cListBase::Lock() called for a list that doesn't require locking");
2170 if (Before && Before !=
objects) {
2207 if (From && To && From != To) {
2264 while (
object && Index-- > 0)
2265 object =
object->
Next();
2284 while (
object && i < n) {
2286 object =
object->
Next();
2290 for (i = 0; i < n; i++) {
2314 if (
size < NewSize) {
2321 esyslog(
"ERROR: out of memory");
2353 unsigned int hash =
hashfn(Id);
2364 if (hob->object == Object) {
2374 for (
int i = 0; i <
size; i++) {
bool SetLength(int Length)
static const char * SystemCharacterTable(void)
bool Poll(int TimeoutMs=0)
int Open(const char *FileName, int Flags, mode_t Mode=DEFFILEMODE)
static cString sprintf(const char *fmt,...) __attribute__((format(printf
cString & Truncate(int Index)
Truncate the string at the given Index (if Index is < 0 it is counted from the end of the string).
cPoller(int FileHandle=-1, bool Out=false)
struct dirent * Next(void)
static bool FileReady(int FileDes, int TimeoutMs=1000)
bool Ready(bool Wait=true)
static uint64_t Now(void)
bool Contains(const cListObject *Object) const
If a pointer to an object contained in this list has been obtained while holding a lock,...
cCharSetConv(const char *FromCode=NULL, const char *ToCode=NULL)
Sets up a character set converter to convert from FromCode to ToCode.
void Put(cListObject *Object)
cTimeMs(int Ms=0)
Creates a timer with ms resolution and an initial timeout of Ms.
void Append(cListObject *Object)
void Add(cListObject *Object, cListObject *After=NULL)
ssize_t Read(void *Data, size_t Size)
cSafeFile(const char *FileName)
void Del(cListObject *Object, unsigned int Id)
cListObject * Prev(void) const
cListObject * Get(unsigned int Id) const
cFileNameList(const char *Directory=NULL, bool DirsOnly=false)
void SetModified(void)
Sets this lock to have its state incremented when the current write lock state key is removed.
cUnbufferedFile is used for large files that are mainly written or read in a streaming manner,...
static tThreadId ThreadId(void)
cString & operator=(const cString &String)
void Del(cListObject *Object, bool DeleteObject=true)
void Ins(cListObject *Object, cListObject *Before=NULL)
void Add(cListObject *Object, unsigned int Id)
const char * needsLocking
cLockFile(const char *Directory)
cHashBase(int Size, bool OwnObjects)
Creates a new hash of the given Size.
bool Load(const char *Directory, bool DirsOnly=false)
static cString static cString vsprintf(const char *fmt, va_list &ap)
const char * Convert(const char *From, char *To=NULL, size_t ToLength=0)
Converts the given Text from FromCode to ToCode (as set in the constructor).
bool Lock(cStateKey &StateKey, bool Write=false, int TimeoutMs=0) const
Tries to get a lock on this list and returns true if successful.
bool Open(const char *FileName, int Flags, mode_t Mode=DEFFILEMODE)
static cUnbufferedFile * Create(const char *FileName, int Flags, mode_t Mode=DEFFILEMODE)
cString & CompactChars(char c)
Compact any sequence of characters 'c' to a single character, and strip all of them from the beginnin...
void SetExplicitModify(void)
If you have obtained a write lock on this list, and you don't want it to be automatically marked as m...
void Purge(bool Force=false)
cList< cHashObject > * GetList(unsigned int Id) const
const T * First(void) const
Returns the first element in this list, or NULL if the list is empty.
static bool FileReadyForWriting(int FileDes, int TimeoutMs=1000)
bool Lock(cStateKey &StateKey, bool Write=false, int TimeoutMs=0)
Tries to get a lock and returns true if successful.
const char * NextLine(void)
Returns the next line of encoded data (terminated by '\0'), or NULL if there is no more encoded data.
unsigned int hashfn(unsigned int Id) const
int Find(const char *s) const
virtual void Move(int From, int To)
cBase64Encoder(const uchar *Data, int Length, int MaxResult=64)
Sets up a new base 64 encoder for the given Data, with the given Length.
bool Realloc(int NewSize)
cString(const char *S=NULL, bool TakePointer=false)
virtual int Compare(const cListObject &ListObject) const
Must return 0 if this object is equal to ListObject, a positive value if it is "greater",...
cListGarbageCollector(void)
const cListObject * Get(int Index) const
bool Lock(int WaitSeconds=0)
cListObject * Next(void) const
static void SleepMs(int TimeoutMs)
Creates a cCondWait object and uses it to sleep for TimeoutMs milliseconds, immediately giving up the...
ssize_t Write(const void *Data, size_t Size)
void SetExplicitModify(void)
If you have obtained a write lock on this lock, and you don't want its state to be automatically incr...
cString & Append(const char *String)
bool TimedOut(void) const
static void SetSystemCharacterTable(const char *CharacterTable)
int FadviseDrop(off_t Offset, off_t Len)
void SetReadAhead(size_t ra)
void Del(int FileHandle, bool Out)
void Insert(cListObject *Object)
void SetModified(void)
Unconditionally marks this list as modified.
const T * Next(const T *Object) const
< Returns the element immediately before Object in this list, or NULL if Object is the first element ...
static bool AnyFileReady(int FileDes=-1, int TimeoutMs=1000)
off_t Seek(off_t Offset, int Whence)
cListBase(const char *NeedsLocking=NULL)
bool Add(int FileHandle, bool Out)
static char * systemCharacterTable
cDynamicBuffer(int InitialSize=1024)
void Append(const uchar *Data, int Length)
cList< cHashObject > ** hashTable
uint64_t Elapsed(void) const
cReadDir(const char *Directory)