Path: blob/main/vendor/golang.org/x/sys/unix/bpxsvc_zos.go
2880 views
// Copyright 2024 The Go Authors. All rights reserved.1// Use of this source code is governed by a BSD-style2// license that can be found in the LICENSE file.34//go:build zos56package unix78import (9"bytes"10"fmt"11"unsafe"12)1314//go:noescape15func bpxcall(plist []unsafe.Pointer, bpx_offset int64)1617//go:noescape18func A2e([]byte)1920//go:noescape21func E2a([]byte)2223const (24BPX4STA = 192 // stat25BPX4FST = 104 // fstat26BPX4LST = 132 // lstat27BPX4OPN = 156 // open28BPX4CLO = 72 // close29BPX4CHR = 500 // chattr30BPX4FCR = 504 // fchattr31BPX4LCR = 1180 // lchattr32BPX4CTW = 492 // cond_timed_wait33BPX4GTH = 1056 // __getthent34BPX4PTQ = 412 // pthread_quiesc35BPX4PTR = 320 // ptrace36)3738const (39//options40//byte141BPX_OPNFHIGH = 0x8042//byte243BPX_OPNFEXEC = 0x8044//byte345BPX_O_NOLARGEFILE = 0x0846BPX_O_LARGEFILE = 0x0447BPX_O_ASYNCSIG = 0x0248BPX_O_SYNC = 0x0149//byte450BPX_O_CREXCL = 0xc051BPX_O_CREAT = 0x8052BPX_O_EXCL = 0x4053BPX_O_NOCTTY = 0x2054BPX_O_TRUNC = 0x1055BPX_O_APPEND = 0x0856BPX_O_NONBLOCK = 0x0457BPX_FNDELAY = 0x0458BPX_O_RDWR = 0x0359BPX_O_RDONLY = 0x0260BPX_O_WRONLY = 0x0161BPX_O_ACCMODE = 0x0362BPX_O_GETFL = 0x0f6364//mode65// byte1 (file type)66BPX_FT_DIR = 167BPX_FT_CHARSPEC = 268BPX_FT_REGFILE = 369BPX_FT_FIFO = 470BPX_FT_SYMLINK = 571BPX_FT_SOCKET = 672//byte373BPX_S_ISUID = 0x0874BPX_S_ISGID = 0x0475BPX_S_ISVTX = 0x0276BPX_S_IRWXU1 = 0x0177BPX_S_IRUSR = 0x0178//byte479BPX_S_IRWXU2 = 0xc080BPX_S_IWUSR = 0x8081BPX_S_IXUSR = 0x4082BPX_S_IRWXG = 0x3883BPX_S_IRGRP = 0x2084BPX_S_IWGRP = 0x1085BPX_S_IXGRP = 0x0886BPX_S_IRWXOX = 0x0787BPX_S_IROTH = 0x0488BPX_S_IWOTH = 0x0289BPX_S_IXOTH = 0x019091CW_INTRPT = 192CW_CONDVAR = 3293CW_TIMEOUT = 649495PGTHA_NEXT = 296PGTHA_CURRENT = 197PGTHA_FIRST = 098PGTHA_LAST = 399PGTHA_PROCESS = 0x80100PGTHA_CONTTY = 0x40101PGTHA_PATH = 0x20102PGTHA_COMMAND = 0x10103PGTHA_FILEDATA = 0x08104PGTHA_THREAD = 0x04105PGTHA_PTAG = 0x02106PGTHA_COMMANDLONG = 0x01107PGTHA_THREADFAST = 0x80108PGTHA_FILEPATH = 0x40109PGTHA_THDSIGMASK = 0x20110// thread quiece mode111QUIESCE_TERM int32 = 1112QUIESCE_FORCE int32 = 2113QUIESCE_QUERY int32 = 3114QUIESCE_FREEZE int32 = 4115QUIESCE_UNFREEZE int32 = 5116FREEZE_THIS_THREAD int32 = 6117FREEZE_EXIT int32 = 8118QUIESCE_SRB int32 = 9119)120121type Pgtha struct {122Pid uint32 // 0123Tid0 uint32 // 4124Tid1 uint32125Accesspid byte // C126Accesstid byte // D127Accessasid uint16 // E128Loginname [8]byte // 10129Flag1 byte // 18130Flag1b2 byte // 19131}132133type Bpxystat_t struct { // DSECT BPXYSTAT134St_id [4]uint8 // 0135St_length uint16 // 0x4136St_version uint16 // 0x6137St_mode uint32 // 0x8138St_ino uint32 // 0xc139St_dev uint32 // 0x10140St_nlink uint32 // 0x14141St_uid uint32 // 0x18142St_gid uint32 // 0x1c143St_size uint64 // 0x20144St_atime uint32 // 0x28145St_mtime uint32 // 0x2c146St_ctime uint32 // 0x30147St_rdev uint32 // 0x34148St_auditoraudit uint32 // 0x38149St_useraudit uint32 // 0x3c150St_blksize uint32 // 0x40151St_createtime uint32 // 0x44152St_auditid [4]uint32 // 0x48153St_res01 uint32 // 0x58154Ft_ccsid uint16 // 0x5c155Ft_flags uint16 // 0x5e156St_res01a [2]uint32 // 0x60157St_res02 uint32 // 0x68158St_blocks uint32 // 0x6c159St_opaque [3]uint8 // 0x70160St_visible uint8 // 0x73161St_reftime uint32 // 0x74162St_fid uint64 // 0x78163St_filefmt uint8 // 0x80164St_fspflag2 uint8 // 0x81165St_res03 [2]uint8 // 0x82166St_ctimemsec uint32 // 0x84167St_seclabel [8]uint8 // 0x88168St_res04 [4]uint8 // 0x90169// end of version 1170_ uint32 // 0x94171St_atime64 uint64 // 0x98172St_mtime64 uint64 // 0xa0173St_ctime64 uint64 // 0xa8174St_createtime64 uint64 // 0xb0175St_reftime64 uint64 // 0xb8176_ uint64 // 0xc0177St_res05 [16]uint8 // 0xc8178// end of version 2179}180181type BpxFilestatus struct {182Oflag1 byte183Oflag2 byte184Oflag3 byte185Oflag4 byte186}187188type BpxMode struct {189Ftype byte190Mode1 byte191Mode2 byte192Mode3 byte193}194195// Thr attribute structure for extended attributes196type Bpxyatt_t struct { // DSECT BPXYATT197Att_id [4]uint8198Att_version uint16199Att_res01 [2]uint8200Att_setflags1 uint8201Att_setflags2 uint8202Att_setflags3 uint8203Att_setflags4 uint8204Att_mode uint32205Att_uid uint32206Att_gid uint32207Att_opaquemask [3]uint8208Att_visblmaskres uint8209Att_opaque [3]uint8210Att_visibleres uint8211Att_size_h uint32212Att_size_l uint32213Att_atime uint32214Att_mtime uint32215Att_auditoraudit uint32216Att_useraudit uint32217Att_ctime uint32218Att_reftime uint32219// end of version 1220Att_filefmt uint8221Att_res02 [3]uint8222Att_filetag uint32223Att_res03 [8]uint8224// end of version 2225Att_atime64 uint64226Att_mtime64 uint64227Att_ctime64 uint64228Att_reftime64 uint64229Att_seclabel [8]uint8230Att_ver3res02 [8]uint8231// end of version 3232}233234func BpxOpen(name string, options *BpxFilestatus, mode *BpxMode) (rv int32, rc int32, rn int32) {235if len(name) < 1024 {236var namebuf [1024]byte237sz := int32(copy(namebuf[:], name))238A2e(namebuf[:sz])239var parms [7]unsafe.Pointer240parms[0] = unsafe.Pointer(&sz)241parms[1] = unsafe.Pointer(&namebuf[0])242parms[2] = unsafe.Pointer(options)243parms[3] = unsafe.Pointer(mode)244parms[4] = unsafe.Pointer(&rv)245parms[5] = unsafe.Pointer(&rc)246parms[6] = unsafe.Pointer(&rn)247bpxcall(parms[:], BPX4OPN)248return rv, rc, rn249}250return -1, -1, -1251}252253func BpxClose(fd int32) (rv int32, rc int32, rn int32) {254var parms [4]unsafe.Pointer255parms[0] = unsafe.Pointer(&fd)256parms[1] = unsafe.Pointer(&rv)257parms[2] = unsafe.Pointer(&rc)258parms[3] = unsafe.Pointer(&rn)259bpxcall(parms[:], BPX4CLO)260return rv, rc, rn261}262263func BpxFileFStat(fd int32, st *Bpxystat_t) (rv int32, rc int32, rn int32) {264st.St_id = [4]uint8{0xe2, 0xe3, 0xc1, 0xe3}265st.St_version = 2266stat_sz := uint32(unsafe.Sizeof(*st))267var parms [6]unsafe.Pointer268parms[0] = unsafe.Pointer(&fd)269parms[1] = unsafe.Pointer(&stat_sz)270parms[2] = unsafe.Pointer(st)271parms[3] = unsafe.Pointer(&rv)272parms[4] = unsafe.Pointer(&rc)273parms[5] = unsafe.Pointer(&rn)274bpxcall(parms[:], BPX4FST)275return rv, rc, rn276}277278func BpxFileStat(name string, st *Bpxystat_t) (rv int32, rc int32, rn int32) {279if len(name) < 1024 {280var namebuf [1024]byte281sz := int32(copy(namebuf[:], name))282A2e(namebuf[:sz])283st.St_id = [4]uint8{0xe2, 0xe3, 0xc1, 0xe3}284st.St_version = 2285stat_sz := uint32(unsafe.Sizeof(*st))286var parms [7]unsafe.Pointer287parms[0] = unsafe.Pointer(&sz)288parms[1] = unsafe.Pointer(&namebuf[0])289parms[2] = unsafe.Pointer(&stat_sz)290parms[3] = unsafe.Pointer(st)291parms[4] = unsafe.Pointer(&rv)292parms[5] = unsafe.Pointer(&rc)293parms[6] = unsafe.Pointer(&rn)294bpxcall(parms[:], BPX4STA)295return rv, rc, rn296}297return -1, -1, -1298}299300func BpxFileLStat(name string, st *Bpxystat_t) (rv int32, rc int32, rn int32) {301if len(name) < 1024 {302var namebuf [1024]byte303sz := int32(copy(namebuf[:], name))304A2e(namebuf[:sz])305st.St_id = [4]uint8{0xe2, 0xe3, 0xc1, 0xe3}306st.St_version = 2307stat_sz := uint32(unsafe.Sizeof(*st))308var parms [7]unsafe.Pointer309parms[0] = unsafe.Pointer(&sz)310parms[1] = unsafe.Pointer(&namebuf[0])311parms[2] = unsafe.Pointer(&stat_sz)312parms[3] = unsafe.Pointer(st)313parms[4] = unsafe.Pointer(&rv)314parms[5] = unsafe.Pointer(&rc)315parms[6] = unsafe.Pointer(&rn)316bpxcall(parms[:], BPX4LST)317return rv, rc, rn318}319return -1, -1, -1320}321322func BpxChattr(path string, attr *Bpxyatt_t) (rv int32, rc int32, rn int32) {323if len(path) >= 1024 {324return -1, -1, -1325}326var namebuf [1024]byte327sz := int32(copy(namebuf[:], path))328A2e(namebuf[:sz])329attr_sz := uint32(unsafe.Sizeof(*attr))330var parms [7]unsafe.Pointer331parms[0] = unsafe.Pointer(&sz)332parms[1] = unsafe.Pointer(&namebuf[0])333parms[2] = unsafe.Pointer(&attr_sz)334parms[3] = unsafe.Pointer(attr)335parms[4] = unsafe.Pointer(&rv)336parms[5] = unsafe.Pointer(&rc)337parms[6] = unsafe.Pointer(&rn)338bpxcall(parms[:], BPX4CHR)339return rv, rc, rn340}341342func BpxLchattr(path string, attr *Bpxyatt_t) (rv int32, rc int32, rn int32) {343if len(path) >= 1024 {344return -1, -1, -1345}346var namebuf [1024]byte347sz := int32(copy(namebuf[:], path))348A2e(namebuf[:sz])349attr_sz := uint32(unsafe.Sizeof(*attr))350var parms [7]unsafe.Pointer351parms[0] = unsafe.Pointer(&sz)352parms[1] = unsafe.Pointer(&namebuf[0])353parms[2] = unsafe.Pointer(&attr_sz)354parms[3] = unsafe.Pointer(attr)355parms[4] = unsafe.Pointer(&rv)356parms[5] = unsafe.Pointer(&rc)357parms[6] = unsafe.Pointer(&rn)358bpxcall(parms[:], BPX4LCR)359return rv, rc, rn360}361362func BpxFchattr(fd int32, attr *Bpxyatt_t) (rv int32, rc int32, rn int32) {363attr_sz := uint32(unsafe.Sizeof(*attr))364var parms [6]unsafe.Pointer365parms[0] = unsafe.Pointer(&fd)366parms[1] = unsafe.Pointer(&attr_sz)367parms[2] = unsafe.Pointer(attr)368parms[3] = unsafe.Pointer(&rv)369parms[4] = unsafe.Pointer(&rc)370parms[5] = unsafe.Pointer(&rn)371bpxcall(parms[:], BPX4FCR)372return rv, rc, rn373}374375func BpxCondTimedWait(sec uint32, nsec uint32, events uint32, secrem *uint32, nsecrem *uint32) (rv int32, rc int32, rn int32) {376var parms [8]unsafe.Pointer377parms[0] = unsafe.Pointer(&sec)378parms[1] = unsafe.Pointer(&nsec)379parms[2] = unsafe.Pointer(&events)380parms[3] = unsafe.Pointer(secrem)381parms[4] = unsafe.Pointer(nsecrem)382parms[5] = unsafe.Pointer(&rv)383parms[6] = unsafe.Pointer(&rc)384parms[7] = unsafe.Pointer(&rn)385bpxcall(parms[:], BPX4CTW)386return rv, rc, rn387}388func BpxGetthent(in *Pgtha, outlen *uint32, out unsafe.Pointer) (rv int32, rc int32, rn int32) {389var parms [7]unsafe.Pointer390inlen := uint32(26) // nothing else will work. Go says Pgtha is 28-byte because of alignment, but Pgtha is "packed" and must be 26-byte391parms[0] = unsafe.Pointer(&inlen)392parms[1] = unsafe.Pointer(&in)393parms[2] = unsafe.Pointer(outlen)394parms[3] = unsafe.Pointer(&out)395parms[4] = unsafe.Pointer(&rv)396parms[5] = unsafe.Pointer(&rc)397parms[6] = unsafe.Pointer(&rn)398bpxcall(parms[:], BPX4GTH)399return rv, rc, rn400}401func ZosJobname() (jobname string, err error) {402var pgtha Pgtha403pgtha.Pid = uint32(Getpid())404pgtha.Accesspid = PGTHA_CURRENT405pgtha.Flag1 = PGTHA_PROCESS406var out [256]byte407var outlen uint32408outlen = 256409rv, rc, rn := BpxGetthent(&pgtha, &outlen, unsafe.Pointer(&out[0]))410if rv == 0 {411gthc := []byte{0x87, 0xa3, 0x88, 0x83} // 'gthc' in ebcdic412ix := bytes.Index(out[:], gthc)413if ix == -1 {414err = fmt.Errorf("BPX4GTH: gthc return data not found")415return416}417jn := out[ix+80 : ix+88] // we didn't declare Pgthc, but jobname is 8-byte at offset 80418E2a(jn)419jobname = string(bytes.TrimRight(jn, " "))420421} else {422err = fmt.Errorf("BPX4GTH: rc=%d errno=%d reason=code=0x%x", rv, rc, rn)423}424return425}426func Bpx4ptq(code int32, data string) (rv int32, rc int32, rn int32) {427var userdata [8]byte428var parms [5]unsafe.Pointer429copy(userdata[:], data+" ")430A2e(userdata[:])431parms[0] = unsafe.Pointer(&code)432parms[1] = unsafe.Pointer(&userdata[0])433parms[2] = unsafe.Pointer(&rv)434parms[3] = unsafe.Pointer(&rc)435parms[4] = unsafe.Pointer(&rn)436bpxcall(parms[:], BPX4PTQ)437return rv, rc, rn438}439440const (441PT_TRACE_ME = 0 // Debug this process442PT_READ_I = 1 // Read a full word443PT_READ_D = 2 // Read a full word444PT_READ_U = 3 // Read control info445PT_WRITE_I = 4 //Write a full word446PT_WRITE_D = 5 //Write a full word447PT_CONTINUE = 7 //Continue the process448PT_KILL = 8 //Terminate the process449PT_READ_GPR = 11 // Read GPR, CR, PSW450PT_READ_FPR = 12 // Read FPR451PT_READ_VR = 13 // Read VR452PT_WRITE_GPR = 14 // Write GPR, CR, PSW453PT_WRITE_FPR = 15 // Write FPR454PT_WRITE_VR = 16 // Write VR455PT_READ_BLOCK = 17 // Read storage456PT_WRITE_BLOCK = 19 // Write storage457PT_READ_GPRH = 20 // Read GPRH458PT_WRITE_GPRH = 21 // Write GPRH459PT_REGHSET = 22 // Read all GPRHs460PT_ATTACH = 30 // Attach to a process461PT_DETACH = 31 // Detach from a process462PT_REGSET = 32 // Read all GPRs463PT_REATTACH = 33 // Reattach to a process464PT_LDINFO = 34 // Read loader info465PT_MULTI = 35 // Multi process mode466PT_LD64INFO = 36 // RMODE64 Info Area467PT_BLOCKREQ = 40 // Block request468PT_THREAD_INFO = 60 // Read thread info469PT_THREAD_MODIFY = 61470PT_THREAD_READ_FOCUS = 62471PT_THREAD_WRITE_FOCUS = 63472PT_THREAD_HOLD = 64473PT_THREAD_SIGNAL = 65474PT_EXPLAIN = 66475PT_EVENTS = 67476PT_THREAD_INFO_EXTENDED = 68477PT_REATTACH2 = 71478PT_CAPTURE = 72479PT_UNCAPTURE = 73480PT_GET_THREAD_TCB = 74481PT_GET_ALET = 75482PT_SWAPIN = 76483PT_EXTENDED_EVENT = 98484PT_RECOVER = 99 // Debug a program check485PT_GPR0 = 0 // General purpose register 0486PT_GPR1 = 1 // General purpose register 1487PT_GPR2 = 2 // General purpose register 2488PT_GPR3 = 3 // General purpose register 3489PT_GPR4 = 4 // General purpose register 4490PT_GPR5 = 5 // General purpose register 5491PT_GPR6 = 6 // General purpose register 6492PT_GPR7 = 7 // General purpose register 7493PT_GPR8 = 8 // General purpose register 8494PT_GPR9 = 9 // General purpose register 9495PT_GPR10 = 10 // General purpose register 10496PT_GPR11 = 11 // General purpose register 11497PT_GPR12 = 12 // General purpose register 12498PT_GPR13 = 13 // General purpose register 13499PT_GPR14 = 14 // General purpose register 14500PT_GPR15 = 15 // General purpose register 15501PT_FPR0 = 16 // Floating point register 0502PT_FPR1 = 17 // Floating point register 1503PT_FPR2 = 18 // Floating point register 2504PT_FPR3 = 19 // Floating point register 3505PT_FPR4 = 20 // Floating point register 4506PT_FPR5 = 21 // Floating point register 5507PT_FPR6 = 22 // Floating point register 6508PT_FPR7 = 23 // Floating point register 7509PT_FPR8 = 24 // Floating point register 8510PT_FPR9 = 25 // Floating point register 9511PT_FPR10 = 26 // Floating point register 10512PT_FPR11 = 27 // Floating point register 11513PT_FPR12 = 28 // Floating point register 12514PT_FPR13 = 29 // Floating point register 13515PT_FPR14 = 30 // Floating point register 14516PT_FPR15 = 31 // Floating point register 15517PT_FPC = 32 // Floating point control register518PT_PSW = 40 // PSW519PT_PSW0 = 40 // Left half of the PSW520PT_PSW1 = 41 // Right half of the PSW521PT_CR0 = 42 // Control register 0522PT_CR1 = 43 // Control register 1523PT_CR2 = 44 // Control register 2524PT_CR3 = 45 // Control register 3525PT_CR4 = 46 // Control register 4526PT_CR5 = 47 // Control register 5527PT_CR6 = 48 // Control register 6528PT_CR7 = 49 // Control register 7529PT_CR8 = 50 // Control register 8530PT_CR9 = 51 // Control register 9531PT_CR10 = 52 // Control register 10532PT_CR11 = 53 // Control register 11533PT_CR12 = 54 // Control register 12534PT_CR13 = 55 // Control register 13535PT_CR14 = 56 // Control register 14536PT_CR15 = 57 // Control register 15537PT_GPRH0 = 58 // GP High register 0538PT_GPRH1 = 59 // GP High register 1539PT_GPRH2 = 60 // GP High register 2540PT_GPRH3 = 61 // GP High register 3541PT_GPRH4 = 62 // GP High register 4542PT_GPRH5 = 63 // GP High register 5543PT_GPRH6 = 64 // GP High register 6544PT_GPRH7 = 65 // GP High register 7545PT_GPRH8 = 66 // GP High register 8546PT_GPRH9 = 67 // GP High register 9547PT_GPRH10 = 68 // GP High register 10548PT_GPRH11 = 69 // GP High register 11549PT_GPRH12 = 70 // GP High register 12550PT_GPRH13 = 71 // GP High register 13551PT_GPRH14 = 72 // GP High register 14552PT_GPRH15 = 73 // GP High register 15553PT_VR0 = 74 // Vector register 0554PT_VR1 = 75 // Vector register 1555PT_VR2 = 76 // Vector register 2556PT_VR3 = 77 // Vector register 3557PT_VR4 = 78 // Vector register 4558PT_VR5 = 79 // Vector register 5559PT_VR6 = 80 // Vector register 6560PT_VR7 = 81 // Vector register 7561PT_VR8 = 82 // Vector register 8562PT_VR9 = 83 // Vector register 9563PT_VR10 = 84 // Vector register 10564PT_VR11 = 85 // Vector register 11565PT_VR12 = 86 // Vector register 12566PT_VR13 = 87 // Vector register 13567PT_VR14 = 88 // Vector register 14568PT_VR15 = 89 // Vector register 15569PT_VR16 = 90 // Vector register 16570PT_VR17 = 91 // Vector register 17571PT_VR18 = 92 // Vector register 18572PT_VR19 = 93 // Vector register 19573PT_VR20 = 94 // Vector register 20574PT_VR21 = 95 // Vector register 21575PT_VR22 = 96 // Vector register 22576PT_VR23 = 97 // Vector register 23577PT_VR24 = 98 // Vector register 24578PT_VR25 = 99 // Vector register 25579PT_VR26 = 100 // Vector register 26580PT_VR27 = 101 // Vector register 27581PT_VR28 = 102 // Vector register 28582PT_VR29 = 103 // Vector register 29583PT_VR30 = 104 // Vector register 30584PT_VR31 = 105 // Vector register 31585PT_PSWG = 106 // PSWG586PT_PSWG0 = 106 // Bytes 0-3587PT_PSWG1 = 107 // Bytes 4-7588PT_PSWG2 = 108 // Bytes 8-11 (IA high word)589PT_PSWG3 = 109 // Bytes 12-15 (IA low word)590)591592func Bpx4ptr(request int32, pid int32, addr unsafe.Pointer, data unsafe.Pointer, buffer unsafe.Pointer) (rv int32, rc int32, rn int32) {593var parms [8]unsafe.Pointer594parms[0] = unsafe.Pointer(&request)595parms[1] = unsafe.Pointer(&pid)596parms[2] = unsafe.Pointer(&addr)597parms[3] = unsafe.Pointer(&data)598parms[4] = unsafe.Pointer(&buffer)599parms[5] = unsafe.Pointer(&rv)600parms[6] = unsafe.Pointer(&rc)601parms[7] = unsafe.Pointer(&rn)602bpxcall(parms[:], BPX4PTR)603return rv, rc, rn604}605606func copyU8(val uint8, dest []uint8) int {607if len(dest) < 1 {608return 0609}610dest[0] = val611return 1612}613614func copyU8Arr(src, dest []uint8) int {615if len(dest) < len(src) {616return 0617}618for i, v := range src {619dest[i] = v620}621return len(src)622}623624func copyU16(val uint16, dest []uint16) int {625if len(dest) < 1 {626return 0627}628dest[0] = val629return 1630}631632func copyU32(val uint32, dest []uint32) int {633if len(dest) < 1 {634return 0635}636dest[0] = val637return 1638}639640func copyU32Arr(src, dest []uint32) int {641if len(dest) < len(src) {642return 0643}644for i, v := range src {645dest[i] = v646}647return len(src)648}649650func copyU64(val uint64, dest []uint64) int {651if len(dest) < 1 {652return 0653}654dest[0] = val655return 1656}657658659