aboutsummaryrefslogtreecommitdiffhomepage
path: root/common.cpp
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2012-02-29 11:27:14 -0800
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2012-02-29 16:14:51 -0800
commit8ada404c5f1ec068a8bad144b63878d9962aa1f0 (patch)
tree6964537047cec6e4b09d0744a01c3208b26dbfea /common.cpp
parentebba30d67157cf0dee46edfa5f47a216b1f35ae6 (diff)
More work towards improving relationship between multithreading and fork
Diffstat (limited to 'common.cpp')
-rw-r--r--common.cpp185
1 files changed, 177 insertions, 8 deletions
diff --git a/common.cpp b/common.cpp
index 049cdf34..d76b7a46 100644
--- a/common.cpp
+++ b/common.cpp
@@ -635,7 +635,7 @@ int read_blocked(int fd, void *buf, size_t count)
ssize_t write_loop(int fd, const char *buff, size_t count)
{
- size_t out=0;
+ ssize_t out=0;
size_t out_cum=0;
while( 1 )
{
@@ -644,12 +644,12 @@ ssize_t write_loop(int fd, const char *buff, size_t count)
count - out_cum );
if (out < 0)
{
- if( errno != EAGAIN &&
- errno != EINTR )
+ if(errno != EAGAIN && errno != EINTR)
{
return -1;
}
- } else
+ }
+ else
{
out_cum += (size_t)out;
}
@@ -686,6 +686,79 @@ void debug( int level, const wchar_t *msg, ... )
errno = errno_old;
}
+void debug_safe(int level, const char *msg, const char *param1, const char *param2, const char *param3)
+{
+ if (! msg)
+ return;
+
+ /* Can't call printf, that may allocate memory Just call write() over and over. */
+ if (level > debug_level)
+ return;
+ int errno_old = errno;
+
+ size_t param_idx = 0;
+ const char *cursor = msg;
+ while (*cursor != '\0') {
+ const char *end = strchr(cursor, '%');
+ if (end == NULL)
+ end = cursor + strlen(cursor);
+
+ write(STDERR_FILENO, cursor, end - cursor);
+
+ if (end[0] == '%' && end[1] == 's') {
+ /* Handle a format string */
+ const char *format = NULL;
+ switch (param_idx++) {
+ case 0: format = param1; break;
+ case 1: format = param2; break;
+ case 2: format = param3; break;
+ }
+ if (! format)
+ format = "(null)";
+ write(STDERR_FILENO, format, strlen(format));
+ cursor = end + 2;
+ } else if (end[0] == '\0') {
+ /* Must be at the end of the string */
+ cursor = end;
+ } else {
+ /* Some other format specifier, just skip it */
+ cursor = end + 1;
+ }
+ }
+
+ // We always append a newline
+ write(STDERR_FILENO, "\n", 1);
+
+ errno = errno_old;
+}
+
+void format_int_safe(char buff[128], int val) {
+ if (val == 0) {
+ strcpy(buff, "0");
+ } else {
+ /* Generate the string in reverse */
+ size_t idx = 0;
+ bool negative = (val < 0);
+ if (negative)
+ val = -val;
+
+ while (val > 0) {
+ buff[idx++] = val % 10;
+ val /= 10;
+ }
+ if (negative)
+ buff[idx++] = '-';
+ buff[idx++] = 0;
+
+ size_t left = 0, right = idx - 1;
+ while (left < right) {
+ char tmp = buff[left];
+ buff[left++] = buff[right];
+ buff[right--] = tmp;
+ }
+ }
+}
+
void write_screen( const wcstring &msg, wcstring &buff )
{
const wchar_t *start, *pos;
@@ -1979,10 +2052,9 @@ void sb_format_size( string_buffer_t *sb,
wcstring format_size(long long sz)
{
wcstring result;
- const wchar_t *sz_name[]=
- {
+ const wchar_t *sz_name[]= {
L"kB", L"MB", L"GB", L"TB", L"PB", L"EB", L"ZB", L"YB", 0
- };
+ };
if( sz < 0 )
{
@@ -2015,10 +2087,90 @@ wcstring format_size(long long sz)
}
}
-
return result;
}
+/* Crappy function to extract the most significant digit of an unsigned long long value */
+static char extract_most_significant_digit(unsigned long long *xp) {
+ unsigned long long place_value = 1;
+ unsigned long long x = *xp;
+ while (x >= 10) {
+ x /= 10;
+ place_value *= 10;
+ }
+ *xp -= (place_value * x);
+ return x + '0';
+}
+
+void append_ull(char *buff, unsigned long long val, size_t *inout_idx, size_t max_len) {
+ size_t idx = *inout_idx;
+ while (val > 0 && idx < max_len)
+ buff[idx++] = extract_most_significant_digit(&val);
+ *inout_idx = idx;
+}
+
+void append_str(char *buff, const char *str, size_t *inout_idx, size_t max_len) {
+ size_t idx = *inout_idx;
+ while (*str && idx < max_len)
+ buff[idx++] = *str++;
+ *inout_idx = idx;
+}
+
+void format_size_safe(char buff[128], unsigned long long sz) {
+ const size_t buff_size = 128;
+ const size_t max_len = buff_size - 1; //need to leave room for a null terminator
+ bzero(buff, buff_size);
+ size_t idx = 0;
+ const char * const sz_name[]= {
+ "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", NULL
+ };
+ if (sz < 1)
+ {
+ strncpy(buff, "empty", buff_size);
+ }
+ else if (sz < 1024)
+ {
+ append_ull(buff, sz, &idx, max_len);
+ append_str(buff, "B", &idx, max_len);
+ }
+ else
+ {
+ for( size_t i=0; sz_name[i]; i++ )
+ {
+ if( sz < (1024*1024) || !sz_name[i+1] )
+ {
+ unsigned long long isz = sz/1024;
+ if( isz > 9 )
+ {
+ append_ull(buff, isz, &idx, max_len);
+ }
+ else
+ {
+ if (isz == 0)
+ {
+ append_str(buff, "0", &idx, max_len);
+ }
+ else
+ {
+ append_ull(buff, isz, &idx, max_len);
+ }
+
+ // Maybe append a single fraction digit
+ unsigned long long remainder = sz % 1024;
+ if (remainder > 0)
+ {
+ char tmp[3] = {'.', extract_most_significant_digit(&remainder), 0};
+ append_str(buff, tmp, &idx, max_len);
+ }
+ }
+ append_str(buff, sz_name[i], &idx, max_len);
+ break;
+ }
+ sz /= 1024;
+ }
+ }
+}
+
double timef()
{
int time_res;
@@ -2045,6 +2197,19 @@ void exit_without_destructors(int code) {
_exit(code);
}
+/* Helper function to convert from a null_terminated_array_t<wchar_t> to a null_terminated_array_t<char_t> */
+null_terminated_array_t<char> convert_wide_array_to_narrow(const null_terminated_array_t<wchar_t> &wide_arr) {
+ const wchar_t *const *arr = wide_arr.get();
+ if (! arr)
+ return null_terminated_array_t<char>();
+
+ std::vector<std::string> list;
+ for (size_t i=0; arr[i]; i++) {
+ list.push_back(wcs2string(arr[i]));
+ }
+ return null_terminated_array_t<char>(list);
+}
+
void append_path_component(wcstring &path, const wcstring &component)
{
size_t len = path.size();
@@ -2076,6 +2241,10 @@ static void child_note_forked(void) {
}
bool is_forked_child(void) {
+ if (is_child_of_fork) {
+ printf("Uh-oh: %d\n", getpid());
+ while (1) sleep(10000);
+ }
return is_child_of_fork;
}