[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[FDclone-users:00508] Re: FDclone でファイルサイズが 0 と表示される
- Subject: [FDclone-users:00508] Re: FDclone でファイルサイズが 0 と表示される
- From: Takashi SHIRAI <shirai@unixusers.net>
- Date: Sat, 22 Apr 2006 02:44:19 +0900
しらいです。
In Message-Id <OF9212CAA1.2282A43A-ON49257157.00069E68@tky.lightwell.co.jp>
SHIOTA Shoichi <Shoichi.Shiota@lightwell.co.jp>さんwrites:
> 潮田です。
> va_dcl の後ろのセミコロンを外したもので、以下の様に
> なりました。
あ、「va_dcl」のところ直すの忘れてました。
> 直前にある
>
> else {
> mask >>= 1;
> if (n >= 0) {
> if ((u_long_t)n & ~mask) s = NULL;
> }
> else if (((u_long_t)n & ~mask) != ~mask) s = NULL;
> if (!s) break;
> memcpy(&u, &n, sizeof(u));
> }
>
> の break に該当しているようです。
ほぅ。こんなところで引っかかるとは、ひょっとして mask の値
がおかしいんじゃないでしょうかね。
ここで mask の値は sizeof(long long) - sizeof(off_t) bytes
分だけシフトして得られるんですが、AIX 環境ではこれが負数にな
るんですね。
負数回数分だけシフトさせた場合、多くの CPU では無視される
んですが、多分 AIX の場合 2 の補数表現で正数化した上で、その
回数分シフトしてしまうんだと思います。
理屈はともかく、そういう特性を鑑みて [FDclone-users:00495]
の patch を作り直すとこんな感じになるんじゃないでしょうか?
---- Cut Here ----
diff -u ../old/FD-2.08b/parse.c ./parse.c
--- ../old/FD-2.08b/parse.c Thu Mar 30 00:00:00 2006
+++ ./parse.c Sat Apr 22 02:33:54 2006
@@ -256,8 +256,12 @@
break;
}
+#ifndef HAVELONGLONG
+ if (len > (int)sizeof(u_long_t)) mask = MAXUTYPE(u_long_t);
+ else
+#endif
mask = (MAXUTYPE(u_long_t)
- >> (((int)sizeof(long_t) - len) * BITSPERBYTE));
+ >> (((int)sizeof(u_long_t) - len) * BITSPERBYTE));
if (flags & VF_UNSIGNED) {
if (u & ~mask) {
s = NULL;
@@ -274,6 +278,27 @@
memcpy(&u, &n, sizeof(u));
}
+#ifndef HAVELONGLONG
+ if (len > (int)sizeof(u_long_t)) {
+ char *buf;
+ u_long_t tmp;
+ int hi;
+
+ hi = 0;
+ if (!(flags & VF_UNSIGNED)) {
+ mask = (MAXUTYPE(u_long_t) >> 1);
+ if (u & ~mask) hi = 0xff;
+ }
+ buf = va_arg(args, char *);
+ memset(buf, hi, len);
+
+ tmp = 0x5a;
+ cp = (char *)(&tmp);
+ if (*cp != 0x5a) buf += len - sizeof(u_long_t);
+ memcpy(buf, (char *)(&u), sizeof(u));
+ }
+ else
+#endif /* !HAVELONGLONG */
if (len == (int)sizeof(u_long_t))
*(va_arg(args, u_long_t *)) = u;
#ifdef HAVELONGLONG
diff -u ../old/FD-2.08b/printf.c ./printf.c
--- ../old/FD-2.08b/printf.c Thu Mar 30 00:00:00 2006
+++ ./printf.c Sat Apr 22 02:32:05 2006
@@ -496,29 +496,37 @@
}
if (base) {
- if (len == (int)sizeof(u_long_t))
- u = va_arg(args, u_long_t);
-#ifdef HAVELONGLONG
- else if (len == (int)sizeof(u_long))
- u = va_arg(args, u_long);
-#endif
- else u = va_arg(args, u_int);
-
#ifndef HAVELONGLONG
if (len > (int)sizeof(u_long_t)) {
- u_long_t hi, tmp;
-
- while (len > (int)sizeof(u_int)) {
- hi = va_arg(args, u_int);
- len -= (int)sizeof(u_int);
- }
+ u_long_t tmp;
+ int hi;
+# ifndef HPUX
+ /*
+ * HP-UX always pushes arguments from lowest to uppermost,
+ * in spite of the CPU endien.
+ */
tmp = 0x5a;
cp = (char *)(&tmp);
if (*cp != 0x5a) {
- tmp = hi;
- hi = u;
- u = tmp;
+ hi = va_arg(args, u_int);
+ len -= (int)sizeof(u_int);
+ while (len > (int)sizeof(u_long_t)) {
+ tmp = va_arg(args, u_int);
+ len -= (int)sizeof(u_int);
+ }
+ u = va_arg(args, u_long_t);
+ }
+ else
+# endif /* !HPUX */
+ {
+ hi = 0;
+ u = va_arg(args, u_long_t);
+ len -= (int)sizeof(u_long_t);
+ while (len > 0) {
+ hi = va_arg(args, u_int);
+ len -= (int)sizeof(u_int);
+ }
}
if (pbufp -> flags & VF_UNSIGNED) {
@@ -526,7 +534,7 @@
}
else {
mask = (MAXUTYPE(u_long_t) >> 1);
- if (hi & ~mask) {
+ if (hi < 0) {
if (++hi || !(u & ~mask))
u = ~mask;
}
@@ -538,9 +546,21 @@
}
else
#endif /* !HAVELONGLONG */
+ if (len == (int)sizeof(u_long_t))
+ u = va_arg(args, u_long_t);
+#ifdef HAVELONGLONG
+ else if (len == (int)sizeof(u_long))
+ u = va_arg(args, u_long);
+#endif
+ else u = va_arg(args, u_int);
+
+#ifndef HAVELONGLONG
+ if (len > (int)sizeof(u_long_t)) /*EMPTY*/;
+ else
+#endif
if (!(pbufp -> flags & VF_UNSIGNED)) {
mask = (MAXUTYPE(u_long_t)
- >> (((int)sizeof(long_t) - len)
+ >> (((int)sizeof(u_long_t) - len)
* BITSPERBYTE + 1));
if (u & ~mask) u |= ~mask;
}
---- Cut Here ----
しらい たかし