summaryrefslogtreecommitdiff
path: root/AK/printf.cpp
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-01-29 04:55:08 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-01-29 04:55:08 +0100
commitc30e2c8d440de7a8abbc1935cb5fb79b82d3421f (patch)
tree6ddae2118d2eec002f0327ff30d5a792828f3002 /AK/printf.cpp
parentad53f6afd3de86fa927a2f8cdacdcbf5134af916 (diff)
downloadserenity-c30e2c8d440de7a8abbc1935cb5fb79b82d3421f.zip
Implement basic chmod() syscall and /bin/chmod helper.
Only raw octal modes are supported right now. This patch also changes mode_t from 32-bit to 16-bit to match the on-disk type used by Ext2FS. I also ran into EPERM being errno=0 which was confusing, so I inserted an ESUCCESS in its place.
Diffstat (limited to 'AK/printf.cpp')
-rw-r--r--AK/printf.cpp45
1 files changed, 45 insertions, 0 deletions
diff --git a/AK/printf.cpp b/AK/printf.cpp
index 4b8cf89172..63a028cefc 100644
--- a/AK/printf.cpp
+++ b/AK/printf.cpp
@@ -67,6 +67,47 @@ ALWAYS_INLINE int printNumber(PutChFunc putch, char*& bufptr, dword number, bool
}
template<typename PutChFunc>
+ALWAYS_INLINE int print_octal_number(PutChFunc putch, char*& bufptr, dword number, bool leftPad, bool zeroPad, dword fieldWidth)
+{
+ dword divisor = 134217728;
+ char ch;
+ char padding = 1;
+ char buf[32];
+ char* p = buf;
+
+ for (;;) {
+ ch = '0' + (number / divisor);
+ number %= divisor;
+ if (ch != '0')
+ padding = 0;
+ if (!padding || divisor == 1)
+ *(p++) = ch;
+ if (divisor == 1)
+ break;
+ divisor /= 8;
+ }
+
+ size_t numlen = p - buf;
+ if (!fieldWidth || fieldWidth < numlen)
+ fieldWidth = numlen;
+ if (!leftPad) {
+ for (unsigned i = 0; i < fieldWidth - numlen; ++i) {
+ putch(bufptr, zeroPad ? '0' : ' ');
+ }
+ }
+ for (unsigned i = 0; i < numlen; ++i) {
+ putch(bufptr, buf[i]);
+ }
+ if (leftPad) {
+ for (unsigned i = 0; i < fieldWidth - numlen; ++i) {
+ putch(bufptr, ' ');
+ }
+ }
+
+ return fieldWidth;
+}
+
+template<typename PutChFunc>
ALWAYS_INLINE int printString(PutChFunc putch, char*& bufptr, const char* str, bool leftPad, dword fieldWidth)
{
size_t len = strlen(str);
@@ -145,6 +186,10 @@ one_more:
ret += printNumber(putch, bufptr, va_arg(ap, dword), leftPad, zeroPad, fieldWidth);
break;
+ case 'o':
+ ret += print_octal_number(putch, bufptr, va_arg(ap, dword), leftPad, zeroPad, fieldWidth);
+ break;
+
case 'x':
ret += printHex(putch, bufptr, va_arg(ap, dword), 8);
break;