sync with OpenBSD -current
This commit is contained in:
parent
0f27a61c5c
commit
38dbdec412
46 changed files with 425 additions and 338 deletions
|
@ -1,4 +1,4 @@
|
|||
# $OpenBSD: files,v 1.726 2023/11/21 14:00:13 bluhm Exp $
|
||||
# $OpenBSD: files,v 1.727 2023/12/21 02:57:14 jsg Exp $
|
||||
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
|
||||
|
||||
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
|
||||
|
@ -1075,6 +1075,7 @@ file lib/libkern/arch/${MACHINE_ARCH}/strlen.S | lib/libkern/strlen.c
|
|||
file lib/libkern/arch/${MACHINE_ARCH}/strncmp.S | lib/libkern/strncmp.c
|
||||
file lib/libkern/arch/${MACHINE_ARCH}/strncpy.S | lib/libkern/strncpy.c
|
||||
file lib/libkern/arch/${MACHINE_ARCH}/strnlen.S | lib/libkern/strnlen.c
|
||||
file lib/libkern/arch/${MACHINE_ARCH}/strnstr.S | lib/libkern/strnstr.c
|
||||
file lib/libkern/arch/${MACHINE_ARCH}/scanc.S | lib/libkern/scanc.c
|
||||
file lib/libkern/arch/${MACHINE_ARCH}/skpc.S | lib/libkern/skpc.c
|
||||
file lib/libkern/arch/${MACHINE_ARCH}/htonl.S | lib/libkern/htonl.c
|
||||
|
|
|
@ -53,7 +53,6 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
|
|||
*/
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA20:
|
||||
#ifdef notyet
|
||||
/* D161 and D163 are the VG20 server SKUs */
|
||||
if (strnstr(atom_ctx->vbios_version, "D161",
|
||||
sizeof(atom_ctx->vbios_version)) ||
|
||||
|
@ -61,13 +60,11 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
|
|||
sizeof(atom_ctx->vbios_version)))
|
||||
return true;
|
||||
else
|
||||
#endif
|
||||
return false;
|
||||
case CHIP_ALDEBARAN:
|
||||
/* All Aldebaran SKUs have the FRU */
|
||||
return true;
|
||||
case CHIP_SIENNA_CICHLID:
|
||||
#ifdef notyet
|
||||
if (strnstr(atom_ctx->vbios_version, "D603",
|
||||
sizeof(atom_ctx->vbios_version))) {
|
||||
if (strnstr(atom_ctx->vbios_version, "D603GLXE",
|
||||
|
@ -78,9 +75,6 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev)
|
|||
} else {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -2327,13 +2327,11 @@ static void amdgpu_ras_get_quirks(struct amdgpu_device *adev)
|
|||
if (!ctx)
|
||||
return;
|
||||
|
||||
#ifdef notyet
|
||||
if (strnstr(ctx->vbios_version, "D16406",
|
||||
sizeof(ctx->vbios_version)) ||
|
||||
strnstr(ctx->vbios_version, "D36002",
|
||||
sizeof(ctx->vbios_version)))
|
||||
adev->ras_hw_enabled |= (1 << AMDGPU_RAS_BLOCK__GFX);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -149,44 +149,29 @@ static bool __get_eeprom_i2c_addr(struct amdgpu_device *adev,
|
|||
/* VEGA20 and ARCTURUS */
|
||||
if (adev->asic_type == CHIP_VEGA20)
|
||||
control->i2c_address = EEPROM_I2C_MADDR_0;
|
||||
#ifdef notyet
|
||||
else if (strnstr(atom_ctx->vbios_version,
|
||||
"D342",
|
||||
sizeof(atom_ctx->vbios_version)))
|
||||
control->i2c_address = EEPROM_I2C_MADDR_0;
|
||||
else
|
||||
control->i2c_address = EEPROM_I2C_MADDR_4;
|
||||
#else
|
||||
STUB();
|
||||
control->i2c_address = EEPROM_I2C_MADDR_4;
|
||||
#endif
|
||||
return true;
|
||||
case IP_VERSION(11, 0, 7):
|
||||
control->i2c_address = EEPROM_I2C_MADDR_0;
|
||||
return true;
|
||||
case IP_VERSION(13, 0, 2):
|
||||
#ifdef notyet
|
||||
if (strnstr(atom_ctx->vbios_version, "D673",
|
||||
sizeof(atom_ctx->vbios_version)))
|
||||
control->i2c_address = EEPROM_I2C_MADDR_4;
|
||||
else
|
||||
control->i2c_address = EEPROM_I2C_MADDR_0;
|
||||
#else
|
||||
STUB();
|
||||
control->i2c_address = EEPROM_I2C_MADDR_0;
|
||||
#endif
|
||||
return true;
|
||||
case IP_VERSION(13, 0, 0):
|
||||
#ifdef notyet
|
||||
if (strnstr(atom_ctx->vbios_pn, "D707",
|
||||
sizeof(atom_ctx->vbios_pn)))
|
||||
control->i2c_address = EEPROM_I2C_MADDR_0;
|
||||
else
|
||||
control->i2c_address = EEPROM_I2C_MADDR_4;
|
||||
#else
|
||||
STUB();
|
||||
control->i2c_address = EEPROM_I2C_MADDR_4;
|
||||
#endif
|
||||
return true;
|
||||
case IP_VERSION(13, 0, 6):
|
||||
case IP_VERSION(13, 0, 10):
|
||||
|
|
|
@ -631,13 +631,14 @@ static void amdgpu_vm_pt_free(struct amdgpu_vm_bo_base *entry)
|
|||
|
||||
if (!entry->bo)
|
||||
return;
|
||||
|
||||
entry->bo->vm_bo = NULL;
|
||||
shadow = amdgpu_bo_shadowed(entry->bo);
|
||||
if (shadow) {
|
||||
ttm_bo_set_bulk_move(&shadow->tbo, NULL);
|
||||
amdgpu_bo_unref(&shadow);
|
||||
}
|
||||
ttm_bo_set_bulk_move(&entry->bo->tbo, NULL);
|
||||
entry->bo->vm_bo = NULL;
|
||||
|
||||
spin_lock(&entry->vm->status_lock);
|
||||
list_del(&entry->vm_status);
|
||||
|
|
|
@ -1690,6 +1690,32 @@ static void sdma_v5_2_get_clockgating_state(void *handle, u64 *flags)
|
|||
*flags |= AMD_CG_SUPPORT_SDMA_LS;
|
||||
}
|
||||
|
||||
static void sdma_v5_2_ring_begin_use(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
|
||||
/* SDMA 5.2.3 (RMB) FW doesn't seem to properly
|
||||
* disallow GFXOFF in some cases leading to
|
||||
* hangs in SDMA. Disallow GFXOFF while SDMA is active.
|
||||
* We can probably just limit this to 5.2.3,
|
||||
* but it shouldn't hurt for other parts since
|
||||
* this GFXOFF will be disallowed anyway when SDMA is
|
||||
* active, this just makes it explicit.
|
||||
*/
|
||||
amdgpu_gfx_off_ctrl(adev, false);
|
||||
}
|
||||
|
||||
static void sdma_v5_2_ring_end_use(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
|
||||
/* SDMA 5.2.3 (RMB) FW doesn't seem to properly
|
||||
* disallow GFXOFF in some cases leading to
|
||||
* hangs in SDMA. Allow GFXOFF when SDMA is complete.
|
||||
*/
|
||||
amdgpu_gfx_off_ctrl(adev, true);
|
||||
}
|
||||
|
||||
const struct amd_ip_funcs sdma_v5_2_ip_funcs = {
|
||||
.name = "sdma_v5_2",
|
||||
.early_init = sdma_v5_2_early_init,
|
||||
|
@ -1738,6 +1764,8 @@ static const struct amdgpu_ring_funcs sdma_v5_2_ring_funcs = {
|
|||
.test_ib = sdma_v5_2_ring_test_ib,
|
||||
.insert_nop = sdma_v5_2_ring_insert_nop,
|
||||
.pad_ib = sdma_v5_2_ring_pad_ib,
|
||||
.begin_use = sdma_v5_2_ring_begin_use,
|
||||
.end_use = sdma_v5_2_ring_end_use,
|
||||
.emit_wreg = sdma_v5_2_ring_emit_wreg,
|
||||
.emit_reg_wait = sdma_v5_2_ring_emit_reg_wait,
|
||||
.emit_reg_write_reg_wait = sdma_v5_2_ring_emit_reg_write_reg_wait,
|
||||
|
|
|
@ -816,6 +816,8 @@ bool is_psr_su_specific_panel(struct dc_link *link)
|
|||
((dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x08) ||
|
||||
(dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x07)))
|
||||
isPSRSUSupported = false;
|
||||
else if (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x03)
|
||||
isPSRSUSupported = false;
|
||||
else if (dpcd_caps->psr_info.force_psrsu_cap == 0x1)
|
||||
isPSRSUSupported = true;
|
||||
}
|
||||
|
|
|
@ -1441,8 +1441,20 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p
|
|||
|
||||
size += remap_info->size;
|
||||
} else {
|
||||
unsigned int dst_stride = plane_view_dst_stride_tiles(fb, color_plane,
|
||||
remap_info->width);
|
||||
unsigned int dst_stride;
|
||||
|
||||
/*
|
||||
* The hardware automagically calculates the CCS AUX surface
|
||||
* stride from the main surface stride so can't really remap a
|
||||
* smaller subset (unless we'd remap in whole AUX page units).
|
||||
*/
|
||||
if (intel_fb_needs_pot_stride_remap(fb) &&
|
||||
intel_fb_is_ccs_modifier(fb->base.modifier))
|
||||
dst_stride = remap_info->src_stride;
|
||||
else
|
||||
dst_stride = remap_info->width;
|
||||
|
||||
dst_stride = plane_view_dst_stride_tiles(fb, color_plane, dst_stride);
|
||||
|
||||
assign_chk_ovf(i915, remap_info->dst_stride, dst_stride);
|
||||
color_plane_info->mapping_stride = dst_stride *
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ugold.c,v 1.26 2023/12/10 19:03:37 miod Exp $ */
|
||||
/* $OpenBSD: ugold.c,v 1.27 2023/12/21 19:40:47 miod Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 Takayoshi SASANO <uaa@openbsd.org>
|
||||
|
@ -498,8 +498,14 @@ ugold_si700x_type(struct ugold_softc *sc)
|
|||
/* TEMPerGold prefix */
|
||||
if (sc->sc_model_len >= 11 &&
|
||||
memcmp(sc->sc_model, "TEMPerGold_", 11) == 0) {
|
||||
/*
|
||||
* All V3.something models ought to work, but better be
|
||||
* safe than sorry, and TEMPerHum models have been known
|
||||
* to use slightly different sensors between models.
|
||||
*/
|
||||
if (memcmp(sc->sc_model + 11, "V3.1 ", 16 - 11) == 0 ||
|
||||
memcmp(sc->sc_model + 11, "V3.4 ", 16 - 11) == 0) {
|
||||
memcmp(sc->sc_model + 11, "V3.4 ", 16 - 11) == 0 ||
|
||||
memcmp(sc->sc_model + 11, "V3.5 ", 16 - 11) == 0) {
|
||||
sc->sc_type = UGOLD_TYPE_GOLD;
|
||||
sc->sc_num_sensors = 1;
|
||||
descr = "gold (temperature only)";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /bin/sh -
|
||||
# $OpenBSD: makesyscalls.sh,v 1.20 2023/04/07 09:43:38 tb Exp $
|
||||
# $OpenBSD: makesyscalls.sh,v 1.21 2023/12/21 19:34:07 miod Exp $
|
||||
# $NetBSD: makesyscalls.sh,v 1.26 1998/01/09 06:17:51 thorpej Exp $
|
||||
#
|
||||
# Copyright (c) 1994,1996 Christopher G. Demetriou
|
||||
|
@ -296,10 +296,6 @@ function parseline() {
|
|||
# arguments, they must still have arguments specified for
|
||||
# the remaining argument "positions," because of the way the
|
||||
# kernel system call argument handling works.
|
||||
#
|
||||
# Indirect system calls, e.g. syscall(), are exceptions to this
|
||||
# rule, since they are handled entirely by machine-dependent code
|
||||
# and do not need argument structures built.
|
||||
|
||||
isvarargs = 0;
|
||||
while (f <= end) {
|
||||
|
@ -326,59 +322,50 @@ function parseline() {
|
|||
}
|
||||
# must see another argument after varargs notice.
|
||||
if (isvarargs) {
|
||||
if (argc == varargc && $2 != "INDIR")
|
||||
if (argc == varargc)
|
||||
parserr($f, "argument definition")
|
||||
} else
|
||||
varargc = argc;
|
||||
}
|
||||
function putent(nodefs, compatwrap) {
|
||||
# output syscall declaration for switch table. INDIR functions
|
||||
# get none, since they always have sys_nosys() for their table
|
||||
# entries.
|
||||
if (nodefs != "INDIR") {
|
||||
prototype = "(struct proc *, void *, register_t *)"
|
||||
if (compatwrap == "")
|
||||
printf("int\t%s%s;\n", funcname,
|
||||
prototype) > sysprotos
|
||||
else
|
||||
printf("int\t%s_%s%s;\n", compatwrap, funcname,
|
||||
prototype) > sysprotos
|
||||
}
|
||||
# output syscall declaration for switch table.
|
||||
prototype = "(struct proc *, void *, register_t *)"
|
||||
if (compatwrap == "")
|
||||
printf("int\t%s%s;\n", funcname,
|
||||
prototype) > sysprotos
|
||||
else
|
||||
printf("int\t%s_%s%s;\n", compatwrap, funcname,
|
||||
prototype) > sysprotos
|
||||
|
||||
# output syscall switch entry
|
||||
if (nodefs == "INDIR") {
|
||||
printf("\t{ 0, 0, %s,\n\t sys_nosys },\t\t\t/* %d = %s (indir) */\n", \
|
||||
sycall_flags, syscall, funcalias) > sysent
|
||||
} else {
|
||||
# printf("\t{ { %d", argc) > sysent
|
||||
# for (i = 1; i <= argc; i++) {
|
||||
# if (i == 5) # wrap the line
|
||||
# printf(",\n\t ") > sysent
|
||||
# else
|
||||
# printf(", ") > sysent
|
||||
# printf("s(%s)", argtypenospc[i]) > sysent
|
||||
# }
|
||||
printf("\t{ %d, ", argc) > sysent
|
||||
if (argc == 0)
|
||||
printf("0") > sysent
|
||||
else if (compatwrap == "")
|
||||
printf("s(struct %s_args)", funcname) > sysent
|
||||
else
|
||||
printf("s(struct %s_%s_args)", compatwrap,
|
||||
funcname) > sysent
|
||||
if (compatwrap == "")
|
||||
wfn = sprintf("%s", funcname);
|
||||
else
|
||||
wfn = sprintf("%s(%s)", compatwrap, funcname);
|
||||
printf(", %s,\n\t %s },", sycall_flags, wfn) > sysent
|
||||
for (i = 0; i < (33 - length(wfn)) / 8; i++)
|
||||
printf("\t") > sysent
|
||||
if (compatwrap == "")
|
||||
printf("/* %d = %s */\n", syscall, funcalias) > sysent
|
||||
else
|
||||
printf("/* %d = %s %s */\n", syscall, compatwrap,
|
||||
funcalias) > sysent
|
||||
}
|
||||
# printf("\t{ { %d", argc) > sysent
|
||||
# for (i = 1; i <= argc; i++) {
|
||||
# if (i == 5) # wrap the line
|
||||
# printf(",\n\t ") > sysent
|
||||
# else
|
||||
# printf(", ") > sysent
|
||||
# printf("s(%s)", argtypenospc[i]) > sysent
|
||||
# }
|
||||
printf("\t{ %d, ", argc) > sysent
|
||||
if (argc == 0)
|
||||
printf("0") > sysent
|
||||
else if (compatwrap == "")
|
||||
printf("s(struct %s_args)", funcname) > sysent
|
||||
else
|
||||
printf("s(struct %s_%s_args)", compatwrap,
|
||||
funcname) > sysent
|
||||
if (compatwrap == "")
|
||||
wfn = sprintf("%s", funcname);
|
||||
else
|
||||
wfn = sprintf("%s(%s)", compatwrap, funcname);
|
||||
printf(", %s,\n\t %s },", sycall_flags, wfn) > sysent
|
||||
for (i = 0; i < (33 - length(wfn)) / 8; i++)
|
||||
printf("\t") > sysent
|
||||
if (compatwrap == "")
|
||||
printf("/* %d = %s */\n", syscall, funcalias) > sysent
|
||||
else
|
||||
printf("/* %d = %s %s */\n", syscall, compatwrap,
|
||||
funcalias) > sysent
|
||||
|
||||
# output syscall name for names table
|
||||
if (compatwrap == "")
|
||||
|
@ -389,7 +376,7 @@ function putent(nodefs, compatwrap) {
|
|||
funcalias, syscall, compatwrap, funcalias) > sysnames
|
||||
|
||||
# output syscall number of header, if appropriate
|
||||
if (nodefs == "" || nodefs == "NOARGS" || nodefs == "INDIR") {
|
||||
if (nodefs == "" || nodefs == "NOARGS") {
|
||||
# output a prototype, to be used to generate lint stubs in
|
||||
# libc.
|
||||
printf("/* syscall: \"%s\" ret: \"%s\" args:", funcalias,
|
||||
|
@ -410,7 +397,7 @@ function putent(nodefs, compatwrap) {
|
|||
compatwrap, funcalias) > sysnumhdr
|
||||
|
||||
# output syscall argument structure, if it has arguments
|
||||
if (argc != 0 && nodefs != "NOARGS" && nodefs != "INDIR") {
|
||||
if (argc != 0 && nodefs != "NOARGS") {
|
||||
if (compatwrap == "")
|
||||
printf("\nstruct %s_args {\n", funcname) > sysarghdr
|
||||
else
|
||||
|
@ -428,7 +415,7 @@ $2 == "STD" {
|
|||
syscall++
|
||||
next
|
||||
}
|
||||
$2 == "NODEF" || $2 == "NOARGS" || $2 == "INDIR" {
|
||||
$2 == "NODEF" || $2 == "NOARGS" {
|
||||
parseline()
|
||||
putent($2, "")
|
||||
syscall++
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $OpenBSD: syscalls.master,v 1.255 2023/12/19 06:58:36 deraadt Exp $
|
||||
; $OpenBSD: syscalls.master,v 1.256 2023/12/21 19:34:07 miod Exp $
|
||||
; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $
|
||||
|
||||
; @(#)syscalls.master 8.2 (Berkeley) 1/13/94
|
||||
|
@ -12,8 +12,6 @@
|
|||
; compatibility options defined in syscalls.conf
|
||||
;
|
||||
; types:
|
||||
; INDIR included, but don't define the syscall args structure,
|
||||
; and allow it to be "really" varargs
|
||||
; NOARGS included, but don't define the syscall args structure
|
||||
; NODEF included, but don't define the syscall number
|
||||
; NOLOCK don't acquire the kernel lock when calling this syscall
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: libkern.h,v 1.36 2020/02/26 14:23:15 visa Exp $ */
|
||||
/* $OpenBSD: libkern.h,v 1.37 2023/12/21 02:57:14 jsg Exp $ */
|
||||
/* $NetBSD: libkern.h,v 1.7 1996/03/14 18:52:08 christos Exp $ */
|
||||
|
||||
/*-
|
||||
|
@ -167,5 +167,6 @@ size_t getsn(char *, size_t)
|
|||
char *strchr(const char *, int);
|
||||
char *strrchr(const char *, int);
|
||||
int timingsafe_bcmp(const void *, const void *, size_t);
|
||||
char *strnstr(const char *, const char *, size_t);
|
||||
|
||||
#endif /* __LIBKERN_H__ */
|
||||
|
|
62
sys/lib/libkern/strnstr.c
Normal file
62
sys/lib/libkern/strnstr.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/* $OpenBSD: strnstr.c,v 1.1 2023/12/21 02:57:14 jsg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Chris Torek.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <lib/libkern/libkern.h>
|
||||
|
||||
/*
|
||||
* Find the first occurrence of find in s, where the search is limited to the
|
||||
* first slen characters of s.
|
||||
*/
|
||||
char *
|
||||
strnstr(const char *s, const char *find, size_t slen)
|
||||
{
|
||||
char c, sc;
|
||||
size_t len;
|
||||
|
||||
if ((c = *find++) != '\0') {
|
||||
len = strlen(find);
|
||||
do {
|
||||
do {
|
||||
if (slen-- < 1 || (sc = *s++) == '\0')
|
||||
return (NULL);
|
||||
} while (sc != c);
|
||||
if (len > slen)
|
||||
return (NULL);
|
||||
} while (strncmp(s, find, len) != 0);
|
||||
s--;
|
||||
}
|
||||
return ((char *)s);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue