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