00001 #ifndef _COPY_C_
00002 #define _COPY_C_
00003
00004 #include "string.c"
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 long _stp_strncpy_from_user(char *dst, const char __user *src, long count);
00019
00020
00021 #if defined (__i386__)
00022 #define __stp_strncpy_from_user(dst,src,count,res) \
00023 do { \
00024 int __d0, __d1, __d2; \
00025 __asm__ __volatile__( \
00026 " testl %1,%1\n" \
00027 " jz 2f\n" \
00028 "0: lodsb\n" \
00029 " stosb\n" \
00030 " testb %%al,%%al\n" \
00031 " jz 1f\n" \
00032 " decl %1\n" \
00033 " jnz 0b\n" \
00034 "1: subl %1,%0\n" \
00035 "2:\n" \
00036 ".section .fixup,\"ax\"\n" \
00037 "3: movl %5,%0\n" \
00038 " jmp 2b\n" \
00039 ".previous\n" \
00040 ".section __ex_table,\"a\"\n" \
00041 " .align 4\n" \
00042 " .long 0b,3b\n" \
00043 ".previous" \
00044 : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
00045 "=&D" (__d2) \
00046 : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
00047 : "memory"); \
00048 } while (0)
00049 #elif defined (__x86_64__)
00050 #define __stp_strncpy_from_user(dst,src,count,res) \
00051 do { \
00052 long __d0, __d1, __d2; \
00053 __asm__ __volatile__( \
00054 " testq %1,%1\n" \
00055 " jz 2f\n" \
00056 "0: lodsb\n" \
00057 " stosb\n" \
00058 " testb %%al,%%al\n" \
00059 " jz 1f\n" \
00060 " decq %1\n" \
00061 " jnz 0b\n" \
00062 "1: subq %1,%0\n" \
00063 "2:\n" \
00064 ".section .fixup,\"ax\"\n" \
00065 "3: movq %5,%0\n" \
00066 " jmp 2b\n" \
00067 ".previous\n" \
00068 ".section __ex_table,\"a\"\n" \
00069 " .align 8\n" \
00070 " .quad 0b,3b\n" \
00071 ".previous" \
00072 : "=r"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
00073 "=&D" (__d2) \
00074 : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
00075 : "memory"); \
00076 } while (0)
00077 #endif
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 long
00096 _stp_strncpy_from_user(char *dst, const char __user *src, long count)
00097 {
00098 long res;
00099 __stp_strncpy_from_user(dst, src, count, res);
00100 return res;
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 void _stp_string_from_user (String str, const char __user *src, long count)
00114 {
00115 long res;
00116 if (count > STP_STRING_SIZE - str->len - 1)
00117 count = STP_STRING_SIZE - str->len - 1;
00118 __stp_strncpy_from_user(str->buf + str->len, src, count, res);
00119 if (res > 0) {
00120 str->len += res;
00121 str->buf[str->len] = '\0';
00122 }
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 unsigned long
00139 _stp_copy_from_user (char *dst, const char __user *src, unsigned long count)
00140 {
00141 return __copy_from_user_inatomic(dst, src, count);
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 int _stp_copy_argv_from_user (MAP list, char __user *__user *argv)
00155 {
00156 char str[128];
00157 char __user *vstr;
00158 int len;
00159
00160 if (argv)
00161 argv++;
00162
00163 while (argv != NULL) {
00164 if (get_user (vstr, argv))
00165 break;
00166
00167 if (vstr == NULL)
00168 break;
00169
00170 len = _stp_strncpy_from_user(str, vstr, 128);
00171 str[len] = 0;
00172 _stp_list_add_str (list, str);
00173 argv++;
00174 }
00175 return list->num;
00176 }
00177
00178 #endif