/** * strscpy - Copy a C-string into a sized buffer * @dest: Where to copy the string to * @src: Where to copy the string from * @count: Size of destination buffer * * Copy the string, or as much of it as fits, into the dest buffer. * The routine returns the number of characters copied (not including * the trailing NUL) or -E2BIG if the destination buffer wasn't big enough. * The behavior is undefined if the string buffers overlap. * The destination buffer is always NUL terminated, unless it's zero-sized. * * Preferred to strlcpy() since the API doesn't require reading memory * from the src string beyond the specified "count" bytes, and since * the return value is easier to error-check than strlcpy()'s. * In addition, the implementation is robust to the string changing out * from underneath it, unlike the current strlcpy() implementation. * * Preferred to strncpy() since it always returns a valid string, and * doesn't unnecessarily force the tail of the destination buffer to be * zeroed. If the zeroing is desired, it's likely cleaner to use strscpy() * with an overflow test, then just memset() the tail of the dest buffer. */ ssize_t strscpy(char *dest, const char *src, size_t count) { const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; size_t max = count; long res = 0; if (count == 0) return -E2BIG; #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS /* * If src is unaligned, don't cross a page boundary, * since we don't know if the next page is mapped. */ if ((long)src & (sizeof(long) - 1)) { size_t limit = PAGE_SIZE - ((long)src & (PAGE_SIZE - 1)); if (limit < max) max = limit; } #else /* If src or dest is unaligned, don't do word-at-a-time. */ if (((long) dest | (long) src) & (sizeof(long) - 1)) max = 0; #endif while (max >= sizeof(unsigned long)) { unsigned long c, data; c = read_word_at_a_time(src+res); if (has_zero(c, &data, &constants)) { data = prep_zero_mask(c, data, &constants); data = create_zero_mask(data); *(unsigned long *)(dest+res) = c & zero_bytemask(data); return res + find_zero(data); } *(unsigned long *)(dest+res) = c; res += sizeof(unsigned long); count -= sizeof(unsigned long); max -= sizeof(unsigned long); } while (count) { char c; c = src[res]; dest[res] = c; if (!c) return res; res++; count--; } /* Hit buffer length without finding a NUL; force NUL-termination. */ if (res) dest[res-1] = '\0'; return -E2BIG; }
/* * Do a strncpy, return length of string without final '\0'. * 'count' is the user-supplied count (return 'count' if we * hit it), 'max' is the address space maximum (and we return * -EFAULT if we hit it). */ static inline long do_strncpy_from_user(char *dst, const char __user *src, long count, unsigned long max) { static const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; long res = 0; /* * Truncate 'max' to the user-specified limit, so that * we only have one limit we need to check in the loop */ if (max > count) max = count; if (IS_UNALIGNED(src, dst)) goto byte_at_a_time; while (max >= sizeof(unsigned long)) { unsigned long c, data; /* Fall back to byte-at-a-time if we get a page fault */ if (unlikely(__get_user(c,(unsigned long __user *)(src+res)))) break; *(unsigned long *)(dst+res) = c; if (has_zero(c, &data, &constants)) { data = prep_zero_mask(c, data, &constants); data = create_zero_mask(data); return res + find_zero(data); } res += sizeof(unsigned long); max -= sizeof(unsigned long); } byte_at_a_time: while (max) { char c; if (unlikely(__get_user(c,src+res))) return -EFAULT; dst[res] = c; if (!c) return res; res++; max--; } /* * Uhhuh. We hit 'max'. But was that the user-specified maximum * too? If so, that's ok - we got as much as the user asked for. */ if (res >= count) return res; /* * Nope: we hit the address space limit, and we still had more * characters the caller would have wanted. That's an EFAULT. */ return -EFAULT; }
/* * Do a strnlen, return length of string *with* final '\0'. * 'count' is the user-supplied count, while 'max' is the * address space maximum. * * Return 0 for exceptions (which includes hitting the address * space maximum), or 'count+1' if hitting the user-supplied * maximum count. * * NOTE! We can sometimes overshoot the user-supplied maximum * if it fits in a aligned 'long'. The caller needs to check * the return value against "> max". */ static inline long do_strnlen_user(const char __user *src, unsigned long count, unsigned long max) { const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; long align, res = 0; unsigned long c; /* * Truncate 'max' to the user-specified limit, so that * we only have one limit we need to check in the loop */ if (max > count) max = count; /* * Do everything aligned. But that means that we * need to also expand the maximum.. */ align = (sizeof(long) - 1) & (unsigned long)src; src -= align; max += align; if (unlikely(__get_user(c,(unsigned long __user *)src))) return 0; c |= aligned_byte_mask(align); for (;;) { unsigned long data; if (has_zero(c, &data, &constants)) { data = prep_zero_mask(c, data, &constants); data = create_zero_mask(data); return res + find_zero(data) + 1 - align; } res += sizeof(unsigned long); if (unlikely(max < sizeof(unsigned long))) break; max -= sizeof(unsigned long); if (unlikely(__get_user(c,(unsigned long __user *)(src+res)))) return 0; } res -= align; /* * Uhhuh. We hit 'max'. But was that the user-specified maximum * too? If so, return the marker for "too long". */ if (res >= count) return count+1; /* * Nope: we hit the address space limit, and we still had more * characters the caller would have wanted. That's 0. */ return 0; }
/* * Do a strncpy, return length of string without final '\0'. * 'count' is the user-supplied count (return 'count' if we * hit it), 'max' is the address space maximum (and we return * -EFAULT if we hit it). */ static inline long do_strncpy_from_user(char *dst, const char __user *src, long count, unsigned long max) { long res = 0; /* * Truncate 'max' to the user-specified limit, so that * we only have one limit we need to check in the loop */ if (max > count) max = count; while (max >= sizeof(unsigned long)) { unsigned long c; /* Fall back to byte-at-a-time if we get a page fault */ if (unlikely(__get_user(c,(unsigned long __user *)(src+res)))) break; /* This can write a few bytes past the NUL character, but that's ok */ *(unsigned long *)(dst+res) = c; c = has_zero(c); if (c) return res + count_bytes(c); res += sizeof(unsigned long); max -= sizeof(unsigned long); } while (max) { char c; if (unlikely(__get_user(c,src+res))) return -EFAULT; dst[res] = c; if (!c) return res; res++; max--; } /* * Uhhuh. We hit 'max'. But was that the user-specified maximum * too? If so, that's ok - we got as much as the user asked for. */ if (res >= count) return res; /* * Nope: we hit the address space limit, and we still had more * characters the caller would have wanted. That's an EFAULT. */ return -EFAULT; }
int main(void) { int a[LEN] = {-1, 0, 1}; int b[LEN] = {1, 2, 3}; printf("a[] ="); for (int i = 0; i < LEN; i++) { printf(" %d", a[i]); } printf("\n"); printf("b[] ="); for (int i = 0; i < LEN; i++) { printf(" %d", b[i]); } printf("\n"); printf("has_zero(a, 3) => %s\n", (has_zero(a, 3) == 1) ? "true" : "false"); printf("has_zero(b, 3) => %s\n", (has_zero(b, 3) == 1) ? "true" : "false"); return 0; }
int main( ) { int n = 1000000; int num = 0; while( n-- ) { if( !is_prime( n ) ) continue; if( has_zero( n ) ) continue; int r = n; int circular = 1; while( (r = rotate(r)) != n ) { if( !is_prime( r ) ) { circular = 0; break; } } if( circular ) { num++; } } printf( "Answer: %d\n", num ); }
int main(void) { int offset = 0, pos = 0; u64 largest = 0; while(offset <= (1000 - 13)){ if((pos = has_zero(offset))){ offset += pos; continue; } u64 current = 1LL; for(int i = 0; i < 13; i++) current *= (u64) (number[offset + i] - '0'); if(current > largest) largest = current; offset++; } printf("%llu\n", largest); }
const char *fgets2(FILE *stream) { static char buffer[FGETS2_BUFSIZE + 5]; static char *end = buffer; static char *line = buffer; char *next; int ret; next = line; while (1) { /* this is a speed-up, we read 32 bits at once and check for an * LF character there. We stop if found then continue one at a * time. */ while (next < end && (((unsigned long)next) & 3) && *next != '\n') next++; /* now next is multiple of 4 or equal to end */ while (next <= (end-32)) { if (has_zero(*(unsigned int *)next ^ 0x0A0A0A0A)) break; next += 4; if (has_zero(*(unsigned int *)next ^ 0x0A0A0A0A)) break; next += 4; if (has_zero(*(unsigned int *)next ^ 0x0A0A0A0A)) break; next += 4; if (has_zero(*(unsigned int *)next ^ 0x0A0A0A0A)) break; next += 4; if (has_zero(*(unsigned int *)next ^ 0x0A0A0A0A)) break; next += 4; if (has_zero(*(unsigned int *)next ^ 0x0A0A0A0A)) break; next += 4; if (has_zero(*(unsigned int *)next ^ 0x0A0A0A0A)) break; next += 4; if (has_zero(*(unsigned int *)next ^ 0x0A0A0A0A)) break; next += 4; } /* we finish if needed. Note that next might be slightly higher * than end here because we might have gone past it above. */ while (next < end) { if (*next == '\n') { const char *start = line; *next = '\0'; line = next + 1; return start; } next++; } /* we found an incomplete line. First, let's move the * remaining part of the buffer to the beginning, then * try to complete the buffer with a new read. */ if (line > buffer) { if (end != line) memmove(buffer, line, end - line); end = buffer + (end - line); next = end; line = buffer; } else { if (end == buffer + FGETS2_BUFSIZE) return NULL; } ret = read(fileno(stream), end, buffer + FGETS2_BUFSIZE - end); if (ret <= 0) { if (end == line) return NULL; *end = '\0'; end = line; /* ensure we stop next time */ return line; } end += ret; /* search for '\n' again */ } }
const char *fgets2(FILE *stream) { static char buffer[FGETS2_BUFSIZE + 68]; static char *end = buffer; static char *line = buffer; char *next; int ret; next = line; while (1) { /* this is a speed-up, we read 64 bits at once and check for an * LF character there. We stop if found then continue one at a * time. */ if (next <= end) { /* max 3 bytes tested here */ while ((((unsigned long)next) & 3) && *next != '\n') next++; /* maybe we have can skip 4 more bytes */ if ((((unsigned long)next) & 4) && !has_zero(*(unsigned int *)next ^ 0x0A0A0A0AU)) next += 4; } /* now next is multiple of 8 or equal to end */ while (next <= (end-68)) { if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) break; next += 8; if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) break; next += 8; if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) break; next += 8; if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) break; next += 8; if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) break; next += 8; if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) break; next += 8; if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) break; next += 8; if (has_zero64(*(unsigned long long *)next ^ 0x0A0A0A0A0A0A0A0AULL)) break; next += 8; } /* maybe we can skip 4 more bytes */ if (!has_zero(*(unsigned int *)next ^ 0x0A0A0A0AU)) next += 4; /* We finish if needed : if <next> is below <end>, it means we * found an LF in one of the 4 following bytes. */ while (next < end) { if (*next == '\n') { const char *start = line; *next = '\0'; line = next + 1; return start; } next++; } /* we found an incomplete line. First, let's move the * remaining part of the buffer to the beginning, then * try to complete the buffer with a new read. We can't * rely on <next> anymore because it went past <end>. */ if (line > buffer) { if (end != line) memmove(buffer, line, end - line); end = buffer + (end - line); next = end; line = buffer; } else { if (end == buffer + FGETS2_BUFSIZE) return NULL; } ret = read(fileno(stream), end, buffer + FGETS2_BUFSIZE - end); if (ret <= 0) { if (end == line) return NULL; *end = '\0'; end = line; /* ensure we stop next time */ return line; } end += ret; *end = '\n'; /* make parser stop ASAP */ /* search for '\n' again */ } }