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