50ssize_t
safe_read(
int filedes,
void *buffer,
size_t size)
53 ssize_t p = read(filedes, buffer, size);
54 if (p < 0 && errno == EINTR) {
55 dsyslog(
"EINTR while reading from file handle %d - retrying", filedes);
62ssize_t
safe_write(
int filedes,
const void *buffer,
size_t size)
65 ssize_t written = size;
66 const unsigned char *ptr = (
const unsigned char *)buffer;
68 p = write(filedes, ptr, size);
71 dsyslog(
"EINTR while writing to file handle %d - retrying", filedes);
79 return p < 0 ? p : written;
91 int w = write(fd, Data + written, Length);
100 Poller.
Poll(RetryMs);
101 if (TimeoutMs > 0 && (TimeoutMs -= t.
Elapsed()) <= 0)
114 int l =
max(dest ? strlen(dest) : 0, strlen(src)) + 1;
115 dest = (
char *)realloc(dest, l);
119 esyslog(
"ERROR: out of memory");
128char *
strn0cpy(
char *dest,
const char *src,
size_t n)
133 for ( ; --n && (*dest = *src) != 0; dest++, src++) ;
154 if (!s || !s1 || !*s1 || !s2 || strcmp(s1, s2) == 0)
157 if (
char *p = strstr(s, s1)) {
164 if (
char *NewBuffer = (
char *)realloc(s, l + l2 - l1 + 1))
167 esyslog(
"ERROR: out of memory");
173 memmove(sof + l2, sof + l1, l - of - l1 + 1);
178 }
while (p = strstr(q, s1));
183const char *
strchrn(
const char *s,
char c,
size_t n)
189 if (*s == c && --n == 0)
210 const char *p = strrchr(s, 0);
212 if (*p == c && --n == 0)
220 const char *p = strrchr(s, c);
221 return p ? p + 1 : s;
227 for (
char *p = s + strlen(s) - 1; p >= s; p--) {
250 memmove(s, b, e - b + 1);
256 else if ((
uchar)*p >
' ') {
279 memmove(p + 1, q, strlen(q) + 1);
297 else if (t != s && n == 0) {
316 if (strchr(chars, *p)) {
318 buffer =
MALLOC(
char, 2 * strlen(s) + 1);
319 t = buffer + (p - s);
320 s = strcpy(buffer, s);
336 int l = strlen(name);
338 while (
const char *p = strstr(t, name)) {
340 if (p == s || *(p - 1) <=
' ') {
360 memmove(s, s + n, l - n + 1);
378 const char *se = s + strlen(s) - 1;
379 const char *pe = p + strlen(p) - 1;
381 if (*pe-- != *se-- || (se < s && pe >= p))
416 int64_t n = strtoll(s, &t, 10);
432 if (strcmp(*a, s) == 0)
447 if (*FileName ==
'/')
449 return cString::sprintf(
"%s/%s", DirName && *DirName ? DirName :
".", FileName);
452#define DECIMAL_POINT_C '.'
456 static lconv *loc = localeconv();
458 char buf[strlen(s) + 1];
462 *p = *loc->decimal_point;
477 static lconv *loc = localeconv();
479 snprintf(buf,
sizeof(buf), Format, d);
488 snprintf(buf,
sizeof(buf),
"%d", n);
495 if (stat(File1, &st) == 0) {
496 dev_t dev1 = st.st_dev;
497 if (stat(File2, &st) == 0)
498 return st.st_dev == dev1;
512 struct statfs statFs;
513 if (statfs(Directory, &statFs) == 0) {
514 double blocksPerMeg = 1024.0 * 1024.0 / statFs.f_bsize;
516 *UsedMB = int((statFs.f_blocks - statFs.f_bfree) / blocksPerMeg);
517 Free = int(statFs.f_bavail / blocksPerMeg);
527 if (stat(DirName, &ds) == 0) {
528 if (S_ISDIR(ds.st_mode)) {
529 if (access(DirName, R_OK | W_OK | X_OK) == 0)
532 esyslog(
"ERROR: can't access %s", DirName);
535 esyslog(
"ERROR: %s is not a directory", DirName);
542bool MakeDirs(
const char *FileName,
bool IsDirectory)
545 char *s = strdup(FileName);
549 while ((p = strchr(p,
'/')) != NULL || IsDirectory) {
553 if (stat(s, &fs) != 0 || !S_ISDIR(fs.st_mode)) {
554 dsyslog(
"creating directory %s", s);
555 if (mkdir(s, ACCESSPERMS) == -1) {
573 if (stat(FileName, &st) == 0) {
574 if (S_ISDIR(st.st_mode)) {
578 while ((e = d.
Next()) != NULL) {
580 if (FollowSymlinks) {
582 if (lstat(buffer, &st2) == 0) {
583 if (S_ISLNK(st2.st_mode)) {
584 int size = st2.st_size + 1;
585 char *l =
MALLOC(
char, size);
586 int n = readlink(buffer, l, size - 1);
600 else if (errno != ENOENT) {
605 dsyslog(
"removing %s", *buffer);
606 if (remove(buffer) < 0)
615 dsyslog(
"removing %s", FileName);
616 if (remove(FileName) < 0) {
621 else if (errno != ENOENT) {
630 bool HasIgnoredFiles =
false;
635 while ((e = d.
Next()) != NULL) {
636 if (strcmp(e->d_name,
"lost+found")) {
639 if (stat(buffer, &st) == 0) {
640 if (S_ISDIR(st.st_mode)) {
644 else if (RemoveThis && IgnoreFiles &&
StrInArray(IgnoreFiles, e->d_name))
645 HasIgnoredFiles =
true;
655 if (RemoveThis && empty) {
656 if (HasIgnoredFiles) {
657 while (*IgnoreFiles) {
659 if (access(buffer, F_OK) == 0) {
660 dsyslog(
"removing %s", *buffer);
661 if (remove(buffer) < 0) {
669 dsyslog(
"removing %s", DirName);
670 if (remove(DirName) < 0) {
688 while (size >= 0 && (e = d.
Next()) != NULL) {
691 if (stat(buffer, &st) == 0) {
692 if (S_ISDIR(st.st_mode)) {
709 else if (errno != ENOENT)
718 char *TargetName = canonicalize_file_name(FileName);
721 TargetName = strdup(FileName);
730 for (
int n = 0; n < 10; n++) {
736 if (access(buf, F_OK) != 0) {
738 gettimeofday(&tp1, NULL);
739 int f = open(buf, O_WRONLY | O_CREAT, DEFFILEMODE);
742 if (fdatasync(f) < 0)
746 gettimeofday(&tp2, NULL);
747 double seconds = (((
long long)tp2.tv_sec * 1000000 + tp2.tv_usec) - ((
long long)tp1.tv_sec * 1000000 + tp1.tv_usec)) / 1000000.0;
749 dsyslog(
"SpinUpDisk took %.2f seconds", seconds);
756 esyslog(
"ERROR: SpinUpDisk failed");
762 if (Create && access(FileName, F_OK) != 0) {
763 isyslog(
"creating file '%s'", FileName);
764 int f = open(FileName, O_WRONLY | O_CREAT, DEFFILEMODE);
770 if (utime(FileName, NULL) == -1 && errno != ENOENT)
777 if (stat(FileName, &fs) == 0)
785 if (stat(FileName, &fs) == 0)
801#if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK)
802#define MIN_RESOLUTION 5
803 static bool initialized =
false;
804 static bool monotonic =
false;
808 if (clock_getres(CLOCK_MONOTONIC, &tp) == 0) {
809 long Resolution = tp.tv_nsec;
811 if (tp.tv_sec == 0 && tp.tv_nsec <= MIN_RESOLUTION * 1000000) {
812 if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
813 dsyslog(
"cTimeMs: using monotonic clock (resolution is %ld ns)", Resolution);
817 esyslog(
"cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed");
820 dsyslog(
"cTimeMs: not using monotonic clock - resolution is too bad (%jd s %ld ns)", intmax_t(tp.tv_sec), tp.tv_nsec);
823 esyslog(
"cTimeMs: clock_getres(CLOCK_MONOTONIC) failed");
827 if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
828 return (uint64_t(tp.tv_sec)) * 1000 + tp.tv_nsec / 1000000;
829 esyslog(
"cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed");
834# warning Posix monotonic clock not available
837 if (gettimeofday(&t, NULL) == 0)
838 return (uint64_t(t.tv_sec)) * 1000 + t.tv_usec / 1000;
878#define MT(s, m, v) ((*(s) & (m)) == (v))
879 if (
MT(s, 0xE0, 0xC0) &&
MT(s + 1, 0xC0, 0x80))
881 if (
MT(s, 0xF0, 0xE0) &&
MT(s + 1, 0xC0, 0x80) &&
MT(s + 2, 0xC0, 0x80))
883 if (
MT(s, 0xF8, 0xF0) &&
MT(s + 1, 0xC0, 0x80) &&
MT(s + 2, 0xC0, 0x80) &&
MT(s + 3, 0xC0, 0x80))
895 case 2:
return ((*s & 0x1F) << 6) | (*(s + 1) & 0x3F);
896 case 3:
return ((*s & 0x0F) << 12) | ((*(s + 1) & 0x3F) << 6) | (*(s + 2) & 0x3F);
897 case 4:
return ((*s & 0x07) << 18) | ((*(s + 1) & 0x3F) << 12) | ((*(s + 2) & 0x3F) << 6) | (*(s + 3) & 0x3F);
912 *s++ = ((c >> 6) & 0x1F) | 0xC0;
913 *s = (c & 0x3F) | 0x80;
919 *s++ = ((c >> 12) & 0x0F) | 0xE0;
920 *s++ = ((c >> 6) & 0x3F) | 0x80;
921 *s = (c & 0x3F) | 0x80;
927 *s++ = ((c >> 18) & 0x07) | 0xF0;
928 *s++ = ((c >> 12) & 0x3F) | 0x80;
929 *s++ = ((c >> 6) & 0x3F) | 0x80;
930 *s = (c & 0x3F) | 0x80;
942 while (*s && Symbols--) {
988 while (*s && --Size > 0) {
990 *a++ = (
uchar)(*s++);
1007 while (*a && NumChars < Size) {
1008 if (Max >= 0 && NumSyms++ >= Max)
1016 if (NumChars + sl <= Size) {
1026 if (NumChars < Size)
1041 cd = iconv_open(ToCode, FromCode);
1049 if (
cd != (iconv_t)-1)
1057 if (!strcasestr(CharacterTable,
"UTF-8")) {
1060 for (
int i = 0; i < 128; i++)
1064 const char *s = csc.
Convert(buf);
1078 if (
cd != (iconv_t)-1 && From && *From) {
1079 char *FromPtr = (
char *)From;
1080 size_t FromLength = strlen(From);
1083 int NewLength =
max(
length, FromLength * 2);
1084 if (
char *NewBuffer = (
char *)realloc(
result, NewLength)) {
1089 esyslog(
"ERROR: out of memory");
1098 char *Converted = ToPtr;
1099 while (FromLength > 0) {
1100 if (iconv(
cd, &FromPtr, &FromLength, &ToPtr, &ToLength) ==
size_t(-1)) {
1101 if (errno == E2BIG || errno == EILSEQ && ToLength < 1) {
1105 size_t d = ToPtr -
result;
1107 int NewLength =
length + r;
1108 if (
char *NewBuffer = (
char *)realloc(
result, NewLength)) {
1110 Converted =
result = NewBuffer;
1113 esyslog(
"ERROR: out of memory");
1119 if (errno == EILSEQ) {
1126 else if (errno != E2BIG)
1140 s = TakePointer ? (
char *)S : S ? strdup(S) : NULL;
1159 s = String.
s ? strdup(String.
s) : NULL;
1169 if (
this == &String)
1172 s = String.
s ? strdup(String.
s) : NULL;
1178 if (
this != &String) {
1191 s = String ? strdup(String) : NULL;
1198 int l1 =
s ? strlen(
s) : 0;
1199 int l2 = strlen(String);
1200 if (
char *p = (
char *)realloc(
s, l1 + l2 + 1)) {
1202 strcpy(
s + l1, String);
1205 esyslog(
"ERROR: out of memory");
1213 int l1 =
s ? strlen(
s) : 0;
1215 if (
char *p = (
char *)realloc(
s, l1 + l2 + 1)) {
1221 esyslog(
"ERROR: out of memory");
1231 if (Index >= 0 && Index < l)
1247 if (!fmt || vasprintf(&buffer, fmt, ap) < 0) {
1248 esyslog(
"error in vasprintf('%s', ...)", fmt);
1249 buffer = strdup(
"???");
1258 if (!fmt || vasprintf(&buffer, fmt, ap) < 0) {
1259 esyslog(
"error in vasprintf('%s', ...)", fmt);
1260 buffer = strdup(
"???");
1268 WeekDay = WeekDay == 0 ? 6 : WeekDay - 1;
1269 if (0 <= WeekDay && WeekDay <= 6) {
1271 const char *day =
tr(
"MonTueWedThuFriSatSun");
1283 return WeekDayName(localtime_r(&t, &tm_r)->tm_wday);
1288 WeekDay = WeekDay == 0 ? 6 : WeekDay - 1;
1290 case 0:
return tr(
"Monday");
1291 case 1:
return tr(
"Tuesday");
1292 case 2:
return tr(
"Wednesday");
1293 case 3:
return tr(
"Thursday");
1294 case 4:
return tr(
"Friday");
1295 case 5:
return tr(
"Saturday");
1296 case 6:
return tr(
"Sunday");
1297 default:
return "???";
1313 tm *tm = localtime_r(&t, &tm_r);
1314 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);
1321 if (ctime_r(&t, buffer)) {
1322 buffer[strlen(buffer) - 1] = 0;
1332 tm *tm = localtime_r(&t, &tm_r);
1335 strftime(p,
sizeof(buf) - (p - buf),
"%d.%m.%Y", tm);
1343 tm *tm = localtime_r(&t, &tm_r);
1344 strftime(buf,
sizeof(buf),
"%d.%m.%y", tm);
1352 strftime(buf,
sizeof(buf),
"%R", localtime_r(&t, &tm_r));
1358#define JPEGCOMPRESSMEM 500000
1378 int Used = jcd->
size;
1380 if (
uchar *NewBuffer = (
uchar *)realloc(jcd->
mem, NewSize)) {
1381 jcd->
size = NewSize;
1382 jcd->
mem = NewBuffer;
1385 esyslog(
"ERROR: out of memory");
1389 cinfo->dest->next_output_byte = jcd->
mem + Used;
1390 cinfo->dest->free_in_buffer = jcd->
size - Used;
1401 int Used = cinfo->dest->next_output_byte - jcd->
mem;
1402 if (Used < jcd->size) {
1405 jcd->
mem = NewBuffer;
1408 esyslog(
"ERROR: out of memory");
1417 else if (Quality > 100)
1420 jpeg_destination_mgr jdm;
1426 struct jpeg_compress_struct cinfo;
1427 struct jpeg_error_mgr jerr;
1428 cinfo.err = jpeg_std_error(&jerr);
1429 jpeg_create_compress(&cinfo);
1432 cinfo.client_data = &jcd;
1433 cinfo.image_width = Width;
1434 cinfo.image_height = Height;
1435 cinfo.input_components = 3;
1436 cinfo.in_color_space = JCS_RGB;
1438 jpeg_set_defaults(&cinfo);
1439 jpeg_set_quality(&cinfo, Quality, TRUE);
1440 jpeg_start_compress(&cinfo, TRUE);
1443 JSAMPROW rp[Height];
1444 for (
int k = 0; k < Height; k++)
1445 rp[k] = &Mem[rs * k];
1446 jpeg_write_scanlines(&cinfo, rp, Height);
1447 jpeg_finish_compress(&cinfo);
1448 jpeg_destroy_compress(&cinfo);
1458 static char buffer[HOST_NAME_MAX] =
"";
1460 if (gethostname(buffer,
sizeof(buffer)) < 0) {
1462 strcpy(buffer,
"vdr");
1470const char *
cBase64Encoder::b64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1493 c |= (
data[
i] >> 4) & 0x0F;
1496 c = (
data[
i] << 2) & 0x3F;
1498 c |= (
data[
i] >> 6) & 0x03;
1597 Add(FileHandle, Out);
1602 if (FileHandle >= 0) {
1604 if (
pfd[i].fd == FileHandle &&
pfd[i].events == (Out ? POLLOUT : POLLIN))
1614 esyslog(
"ERROR: too many file handles in cPoller");
1621 if (FileHandle >= 0) {
1623 if (
pfd[i].fd == FileHandle &&
pfd[i].events == (Out ? POLLOUT : POLLIN)) {
1660#if !__GLIBC_PREREQ(2, 24)
1665 if (strcmp(
result->d_name,
".") && strcmp(
result->d_name,
".."))
1681 for (
int i = 0; i <
Size(); i++) {
1682 if (!strcmp(s,
At(i)))
1690 for (
int i = 0; i <
Size(); i++)
1700 Load(Directory, DirsOnly);
1710 while ((e = d.
Next()) != NULL) {
1713 if (stat(
AddDirectory(Directory, e->d_name), &ds) == 0) {
1714 if (!S_ISDIR(ds.st_mode))
1718 Append(strdup(e->d_name));
1745 return Open(open(FileName, Flags, Mode));
1746 esyslog(
"ERROR: attempt to re-open %s", FileName);
1758 esyslog(
"ERROR: attempt to re-open file descriptor %d", FileDes);
1780 struct timeval timeout;
1782 FD_SET(FileDes, &set);
1783 if (TimeoutMs >= 0) {
1784 if (TimeoutMs < 100)
1786 timeout.tv_sec = TimeoutMs / 1000;
1787 timeout.tv_usec = (TimeoutMs % 1000) * 1000;
1789 return select(FD_SETSIZE, &set, NULL, NULL, (TimeoutMs >= 0) ? &timeout : NULL) > 0 && FD_ISSET(FileDes, &set);
1826 if (ferror(
f) != 0) {
1832 if (fclose(
f) < 0) {
1849#ifndef USE_FADVISE_READ
1850#define USE_FADVISE_READ 0
1852#ifndef USE_FADVISE_WRITE
1853#define USE_FADVISE_WRITE 1
1856#define WRITE_BUFFER KILOBYTE(800)
1871 fd = open(FileName, Flags, Mode);
1873#if USE_FADVISE_READ || USE_FADVISE_WRITE
1881 posix_fadvise(
fd, 0, 0, POSIX_FADV_RANDOM);
1889#if USE_FADVISE_READ || USE_FADVISE_WRITE
1892 posix_fadvise(
fd, 0, 0, POSIX_FADV_DONTNEED);
1896 return close(OldFd);
1907#define FADVGRAN KILOBYTE(4)
1908#define READCHUNK MEGABYTE(8)
1918 return posix_fadvise(
fd, Offset - (
FADVGRAN - 1), Len + (
FADVGRAN - 1) * 2, POSIX_FADV_DONTNEED);
1923 if (Whence == SEEK_SET && Offset ==
curpos)
1925 curpos = lseek(
fd, Offset, Whence);
1943 if (bytesRead > 0) {
1950 if (jumped >= 0 && jumped <= (off_t)
readahead) {
1991#if USE_FADVISE_WRITE
1992 if (bytesWritten > 0) {
2033 return bytesWritten;
2041 if (File->
Open(FileName, Flags, Mode) < 0) {
2050#define LOCKFILENAME ".lock-vdr"
2051#define LOCKFILESTALETIME 600
2070 time_t Timeout = time(NULL) + WaitSeconds;
2072 f = open(
fileName, O_WRONLY | O_CREAT | O_EXCL, DEFFILEMODE);
2074 if (errno == EEXIST) {
2086 else if (errno != ENOENT) {
2093 if (errno == ENOSPC) {
2094 esyslog(
"ERROR: can't create lock file '%s' - assuming lock anyway!",
fileName);
2102 }
while (
f < 0 && time(NULL) < Timeout);
2130 Object->
prev =
this;
2136 Object->
next =
this;
2162#define LIST_GARBAGE_COLLECTOR_TIMEOUT 5
2175 esyslog(
"ERROR: ListGarbageCollector destroyed without prior Purge()!");
2224 esyslog(
"ERROR: cListBase::Lock() called for a list that doesn't require locking");
2246 if (Before && Before !=
objects) {
2283 if (From && To && From != To) {
2340 while (
object && Index-- > 0)
2341 object =
object->
Next();
2360 while (
object && i < n) {
2362 object =
object->
Next();
2366 for (i = 0; i < n; i++) {
2390 if (
size < NewSize) {
2397 esyslog(
"ERROR: out of memory");
2429 unsigned int hash =
hashfn(Id);
2440 if (hob->object == Object) {
2450 for (
int i = 0; i <
size; i++) {
cBase64Encoder(const uchar *Data, int Length, int MaxResult=64)
Sets up a new base 64 encoder for the given Data, with the given Length.
const char * NextLine(void)
Returns the next line of encoded data (terminated by '\0'), or NULL if there is no more encoded data.
bool SetLength(int Length)
cCharSetConv(const char *FromCode=NULL, const char *ToCode=NULL)
Sets up a character set converter to convert from FromCode to ToCode.
static const char * SystemCharacterTable(void)
static void SetSystemCharacterTable(const char *CharacterTable)
static char * systemCharacterTable
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).
static void SleepMs(int TimeoutMs)
Creates a cCondWait object and uses it to sleep for TimeoutMs milliseconds, immediately giving up the...
cDynamicBuffer(int InitialSize=1024)
bool Realloc(int NewSize)
void Append(const uchar *Data, int Length)
bool Load(const char *Directory, bool DirsOnly=false)
cFileNameList(const char *Directory=NULL, bool DirsOnly=false)
static bool FileReady(int FileDes, int TimeoutMs=1000)
bool Ready(bool Wait=true)
bool Open(const char *FileName, int Flags, mode_t Mode=DEFFILEMODE)
void Del(cListObject *Object, unsigned int Id)
cListObject * Get(unsigned int Id) const
cList< cHashObject > ** hashTable
cList< cHashObject > * GetList(unsigned int Id) const
cHashBase(int Size, bool OwnObjects)
Creates a new hash of the given Size.
void Add(cListObject *Object, unsigned int Id)
unsigned int hashfn(unsigned int Id) const
cHashObject(cListObject *Object, unsigned int Id)
void Ins(cListObject *Object, cListObject *Before=NULL)
bool Contains(const cListObject *Object) const
If a pointer to an object contained in this list has been obtained while holding a lock,...
void Del(cListObject *Object, bool DeleteObject=true)
virtual void Move(int From, int To)
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 SetModified(void)
Unconditionally marks this list as modified.
bool Lock(cStateKey &StateKey, bool Write=false, int TimeoutMs=0) const
Tries to get a lock on this list and returns true if successful.
const char * needsLocking
cListBase(const char *NeedsLocking=NULL)
const cListObject * Get(int Index) const
void Add(cListObject *Object, cListObject *After=NULL)
void Purge(bool Force=false)
cListGarbageCollector(void)
void Put(cListObject *Object)
cListObject(const cListObject &ListObject)
cListObject * Prev(void) const
virtual int Compare(const cListObject &ListObject) const
Must return 0 if this object is equal to ListObject, a positive value if it is "greater",...
void Insert(cListObject *Object)
cListObject * Next(void) const
void Append(cListObject *Object)
const T * First(void) const
Returns the first element in this list, or NULL if the list is empty.
const T * Next(const T *Object) const
< Returns the element immediately before Object in this list, or NULL if Object is the first element ...
bool Lock(int WaitSeconds=0)
cLockFile(const char *Directory)
cPoller(int FileHandle=-1, bool Out=false)
bool Add(int FileHandle, bool Out)
bool Poll(int TimeoutMs=0)
void Del(int FileHandle, bool Out)
cReadDir(const char *Directory)
struct dirent * Next(void)
union cReadDir::@177011034140060070152007220245225125302245142357 u
cSafeFile(const char *FileName)
void SetExplicitModify(void)
If you have obtained a write lock on this lock, and you don't want its state to be automatically incr...
void SetModified(void)
Sets this lock to have its state incremented when the current write lock state key is removed.
bool Lock(cStateKey &StateKey, bool Write=false, int TimeoutMs=0)
Tries to get a lock and returns true if successful.
void Sort(bool IgnoreCase=false)
virtual void Clear(void) override
int Find(const char *s) const
virtual ~cStringList() override
cString & CompactChars(char c)
Compact any sequence of characters 'c' to a single character, and strip all of them from the beginnin...
static cString static cString vsprintf(const char *fmt, va_list &ap)
cString(const char *S=NULL, bool TakePointer=false)
static cString sprintf(const char *fmt,...) __attribute__((format(printf
cString & operator=(const cString &String)
cString & Append(const char *String)
cString & Truncate(int Index)
Truncate the string at the given Index (if Index is < 0 it is counted from the end of the string).
static tThreadId ThreadId(void)
uint64_t Elapsed(void) const
Returns the number of milliseconds that have elapsed since the last call to Set().
void Set(int Ms=0)
Sets the timer.
bool TimedOut(void) const
Returns true if the number of milliseconds given in the last call to Set() have passed.
cTimeMs(int Ms=0)
Creates a timer with ms resolution and an initial timeout of Ms.
void Reset(void)
Resets the timer to the same timeout as given in the last call to Set().
static uint64_t Now(void)
uint64_t Remaining(void) const
Returns the number of milliseconds remaining until the timer times out.
static cUnbufferedFile * Create(const char *FileName, int Flags, mode_t Mode=DEFFILEMODE)
void SetReadAhead(size_t ra)
ssize_t Write(const void *Data, size_t Size)
int Open(const char *FileName, int Flags, mode_t Mode=DEFFILEMODE)
ssize_t Read(void *Data, size_t Size)
int FadviseDrop(off_t Offset, off_t Len)
off_t Seek(off_t Offset, int Whence)
virtual void Append(char *Data)
char *& At(int Index) const