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